Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keepalive with Fibonacci Backoff, fault tolerant + randomised + concurrent orchestrator signing logic and more #18

Merged
merged 6 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ bitcoincore-rpc = "0.18"
clap = { version = "4.4.10", features = ["derive", "env"] }
env_logger = "0.10.1"
frost-secp256k1-tr = { git = "https://github.com/mimoo/frost", branch = "mimoo/fix5" }
futures = "0.3.30"
hex = "0.4.3"
home = "0.5.9"
itertools = "0.12.0"
Expand Down
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ Jump straight to [usage](#usage) if you want to see some examples, but make sure

### Circom/snarkjs

We build on top of the well-known [circom](https://github.com/iden3/circom)/[snarkjs](https://github.com/iden3/snarkjs) stack.
We build on top of the well-known [circom](https://github.com/iden3/circom)/[snarkjs](https://github.com/iden3/snarkjs) stack.

To install `circom`, please follow [their guide](https://docs.circom.io/getting-started/installation/).

To install `snarkjs`, just run:

```
npm install -g snarkjs@latest
```

### Bitcoin wallet

Expand Down Expand Up @@ -44,7 +52,7 @@ There are two types of zkapps: [stateless](#stateless-zkapps) and [stateful](#st

### Stateless zkapps

A stateless zkapp is single-use, and the bitcoin it locks can be redeemed by anyone who can provide a proof of correct execution. An example of a stateless zkapp is in [`examples/circuit/stateless.circom`](examples/circuit/stateless.circom) (which releases funds to anyone who can find the preimage of a hash function).
A stateless zkapp is single-use, and the bitcoin it locks can be redeemed by anyone who can provide a proof of correct execution. An example of a stateless zkapp is in [`examples/circuit/stateless.circom`](examples/circuit/stateless.circom) (which releases funds to anyone who can find the preimage of a hash function).
A stateless zkapp must always contains one public input that authenticates the transaction that spends it:

```circom
Expand All @@ -66,7 +74,7 @@ $ zkbtc deploy-zkapp --circom-circuit-path examples/circuit/stateless.circom --s

This will lock 1,000 satoshis in the zkapp and return the transaction ID of the transaction that deployed the zkapp. A stateless zkapp can be referenced by that transaction ID.

Bob can then unlock the funds from the stateless zkapp with the following command:
Bob can then unlock the funds from the stateless zkapp with the following command:

```shell
$ zkbtc use-zkapp --txid "e793bdd8dfdd9912d971790a5f385ad3f1215dce97e25dbefe5449faba632836" --circom-circuit-path examples/circuit/stateless.circom --proof-inputs '{"preimage":["1"]}' --recipient-address "tb1q6nkpv2j9lxrm6h3w4skrny3thswgdcca8cx9k6"
Expand Down Expand Up @@ -94,7 +102,7 @@ component main{public [prev_state, truncated_txid, amount_out, amount_in]} = Mai
You can deploy a stateful zkapp with the following command:

```shell
$ zkbtc deploy-zkapp --circom-circuit-path examples/circuit/stateful.circom --initial-state "1" --satoshi-amount 1000
$ zkbtc deploy-zkapp --circom-circuit-path examples/circuit/stateful.circom --initial-state "1" --satoshi-amount 1000
```

You can use a stateful zkapps with the following command:
Expand All @@ -105,8 +113,8 @@ $ zkbtc use-zkapp --circom-circuit-path examples/circuit/stateful.circom --proof

specifying the following inputs:

* `amount_out`: amount being withdrawn
* `amount_in`: amount being deposited
- `amount_out`: amount being withdrawn
- `amount_in`: amount being deposited

Other inputs will be automatically filled in (for example, it will use the zkapp's state as `prev_state` input).

Expand Down
2 changes: 2 additions & 0 deletions src/bin/zkbtc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ async fn main() -> Result<()> {
let filename = format!("key-{id}.json");

let path = output_dir.join(filename);
std::fs::create_dir_all(path.clone().parent().unwrap())
.expect("Couldn't create directory");
let file = std::fs::File::create(&path)
.expect("couldn't create file given output dir");
serde_json::to_writer_pretty(file, key_package).unwrap();
Expand Down
6 changes: 3 additions & 3 deletions src/committee/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,8 @@ async fn round_2_signing(
RpcResult::Ok(round2_response)
}

async fn is_alive(_params: Params<'static>, _context: Arc<NodeState>) -> String {
"hello".to_string()
async fn is_alive(params: Params<'static>, _context: Arc<NodeState>) -> RpcResult<u64> {
Ok(params.parse::<[u64; 1]>()?[0].clone())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this actually best practice in order to ensure it's not a cached response or smthg?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, a lot of APIs use the current timestamp in ping keepalive requests, so yeah it can be considered a standard. In this case it's more of a sanity check, but just in case the node has a weird caching reverse proxy set up, this is good to have.

}

//
Expand Down Expand Up @@ -243,7 +243,7 @@ pub async fn run_server(

module.register_async_method("round_1_signing", round_1_signing)?;
module.register_async_method("round_2_signing", round_2_signing)?;
module.register_async_method("is_alive", is_alive)?;
module.register_async_method("ping", is_alive)?;

let addr = server.local_addr()?;
let handle = server.start(module);
Expand Down
Loading