Misc. agent cleanup and dead code deletion (#470)

* Fix path to agent::Agent in comment.

Otherwise `cargo doc` emits a rustdoc::broken_intra_doc_links warning.

* Use automatic link in comment for rustdoc.

Otherwise 'cargo doc' emits a warning.

* Delete checkpointer agent.

It is not used in current deployment.

* Delete kms-cli.

Not used in current deployment (no references).

* Include "--all" in precommit cargo fmt -- --check invocation.

* Delete unused and hidden src/bin programs.

These appear to have been introduced over a year ago and appear to be dead
code now.

Unhide them from vscode workspace too -- since they were hidden, automated
refactoring tools wouldn't find them until compiler failed.

* Update github CODEOWNERS to current Abacus team.

Drop optional authors field from Cargo.tomls.

* Drop processordb from .gitignore.

Processor crate has been deleted.

* Delete balance-exporter crate.

It is not used / no references.

* Hoist abacus-cli into its own top-level crate.

It is the only tool now, no reason to hide it inside
of a tools directory.

* Delete old relaese.sh, which only relates to Celo Optics.

* Cleanup top-level rust README.md.

-  Architecture paragraphs outdated, delete.
-  Point to run-locally.sh instead of documentation.

* Explain a bit more about crate deps in README.

* Dockerfile fix after tools directory restructuring.

We had previously hoisted abacus-cli out since it
was the only remaining tool.

* Fix path to agent::Agent in comment.

Otherwise `cargo doc` emits a rustdoc::broken_intra_doc_links warning.

* Use automatic link in coment for rustdoc.

Otherwise 'cargo doc' emits a warning.

* Delete checkpointer agent.

It is not used in current deployment.

* Delete kms-cli.

Not used in current deployment (no references).

* Include "--all" in precommit cargo fmt -- --check invocation.

* Delete unused and hidden src/bin programs.

These appear to have been introduced over a year ago and appear to be dead
code now.

Unhide them from vscode workspace too -- since they were hidden, automated
refactoring tools wouldn't find them until compiler failed.

* Update github CODEOWNERS to current Abacus team.

Drop optional authors field from Cargo.tomls.

* Drop processordb from .gitignore.

Processor crate has been deleted.

* Delete balance-exporter crate.

It is not used / no references.

* Hoist abacus-cli into its own top-level crate.

It is the only tool now, no reason to hide it inside
of a tools directory.

* Delete old relaese.sh, which only relates to Celo Optics.

* Cleanup top-level rust README.md.

-  Architecture paragraphs outdated, delete.
-  Point to run-locally.sh instead of documentation.

* Explain a bit more about crate deps in README.

* Dockerfile fix after tools directory restructuring.

We had previously hoisted abacus-cli out since it
was the only remaining tool.
pull/498/head
webbhorn 3 years ago committed by GitHub
parent 87ee40ec3d
commit 6b3822f664
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .github/CODEOWNERS
  2. 2
      .github/workflows/rust.yml
  3. 1
      rust/.gitignore
  4. 1
      rust/.vscode/settings.json
  5. 219
      rust/Cargo.lock
  6. 5
      rust/Cargo.toml
  7. 4
      rust/Dockerfile
  8. 62
      rust/README.md
  9. 5
      rust/abacus-base/Cargo.toml
  10. 42
      rust/abacus-base/bin/example.rs
  11. 2
      rust/abacus-base/src/macros.rs
  12. 4
      rust/abacus-cli/Cargo.toml
  13. 0
      rust/abacus-cli/README.md
  14. 0
      rust/abacus-cli/src/commands.rs
  15. 0
      rust/abacus-cli/src/inboxes.rs
  16. 0
      rust/abacus-cli/src/main.rs
  17. 0
      rust/abacus-cli/src/rpc.rs
  18. 0
      rust/abacus-cli/src/subcommands/mod.rs
  19. 0
      rust/abacus-cli/src/subcommands/prove.rs
  20. 12
      rust/abacus-core/Cargo.toml
  21. 10
      rust/abacus-core/bin/lib_test_output.rs
  22. 9
      rust/abacus-core/bin/proof_output.rs
  23. 10
      rust/abacus-core/bin/utils_test_output.rs
  24. 1
      rust/abacus-test/Cargo.toml
  25. 34
      rust/agents/checkpointer/Cargo.toml
  26. 74
      rust/agents/checkpointer/src/checkpointer.rs
  27. 44
      rust/agents/checkpointer/src/main.rs
  28. 10
      rust/agents/checkpointer/src/settings.rs
  29. 65
      rust/agents/checkpointer/src/submit.rs
  30. 1
      rust/agents/kathy/Cargo.toml
  31. 1
      rust/agents/relayer/Cargo.toml
  32. 1
      rust/agents/validator/Cargo.toml
  33. 1
      rust/chains/abacus-ethereum/Cargo.toml
  34. 1
      rust/release.sh
  35. 23
      rust/tools/balance-exporter/Cargo.toml
  36. 161
      rust/tools/balance-exporter/src/main.rs
  37. 18
      rust/tools/kms-cli/Cargo.toml
  38. 218
      rust/tools/kms-cli/src/main.rs

@ -1,2 +1 @@
* @prestwich @anna-carroll @erinhales * @asaj @mattiecnvr @nambrot @tkporter @webbhorn @yorhodes @zmanian
rust/ @prestwich @emberian @ltchang

@ -66,7 +66,7 @@ jobs:
with: with:
working-directory: ./rust working-directory: ./rust
- name: Rustfmt - name: Rustfmt
run: cargo fmt -- --check run: cargo fmt --all -- --check
- name: Check - name: Check
run: cargo check --all-features --all-targets --verbose run: cargo check --all-features --all-targets --verbose
- name: Clippy - name: Clippy

1
rust/.gitignore vendored

@ -1,5 +1,4 @@
target target
processordb
validatordb validatordb
relayerdb relayerdb
kathydb kathydb

@ -1,6 +1,5 @@
{ {
"files.exclude": { "files.exclude": {
"target": true, "target": true,
"**/bin": true,
}, },
} }

219
rust/Cargo.lock generated

@ -158,17 +158,6 @@ dependencies = [
"opaque-debug 0.3.0", "opaque-debug 0.3.0",
] ]
[[package]]
name = "ahash"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom 0.2.3",
"once_cell",
"version_check",
]
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.18" version = "0.7.18"
@ -178,15 +167,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "ansi_term"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "ansi_term" name = "ansi_term"
version = "0.12.1" version = "0.12.1"
@ -304,22 +284,6 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "balance-exporter"
version = "0.1.0"
dependencies = [
"abacus-base",
"abacus-ethereum",
"clap 3.1.18",
"color-eyre",
"futures",
"human-panic",
"metrics",
"serde 1.0.130",
"serde_json",
"tokio",
]
[[package]] [[package]]
name = "base16ct" name = "base16ct"
version = "0.1.1" version = "0.1.1"
@ -610,32 +574,6 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "checkpointer"
version = "0.1.0"
dependencies = [
"abacus-base",
"abacus-core",
"abacus-ethereum",
"abacus-test",
"async-trait",
"color-eyre",
"config",
"ethers",
"eyre",
"futures-util",
"prometheus",
"rocksdb",
"serde 1.0.130",
"serde_json",
"thiserror",
"tokio",
"tokio-test",
"tracing",
"tracing-futures",
"tracing-subscriber",
]
[[package]] [[package]]
name = "chrono" name = "chrono"
version = "0.4.19" version = "0.4.19"
@ -671,58 +609,19 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.33.3" version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [ dependencies = [
"ansi_term 0.11.0", "ansi_term",
"atty", "atty",
"bitflags", "bitflags",
"strsim 0.8.0", "strsim",
"textwrap 0.11.0", "textwrap",
"unicode-width", "unicode-width",
"vec_map", "vec_map",
] ]
[[package]]
name = "clap"
version = "3.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"indexmap",
"lazy_static",
"strsim 0.10.0",
"termcolor",
"textwrap 0.15.0",
]
[[package]]
name = "clap_derive"
version = "3.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c"
dependencies = [
"heck 0.4.0",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213"
dependencies = [
"os_str_bytes",
]
[[package]] [[package]]
name = "coins-bip32" name = "coins-bip32"
version = "0.6.0" version = "0.6.0"
@ -1757,12 +1656,6 @@ dependencies = [
"unicode-segmentation", "unicode-segmentation",
] ]
[[package]]
name = "heck"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.19" version = "0.1.19"
@ -1840,21 +1733,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440"
[[package]]
name = "human-panic"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39f357a500abcbd7c5f967c1d45c8838585b36743823b9d43488f24850534e36"
dependencies = [
"backtrace",
"os_type",
"serde 1.0.130",
"serde_derive",
"termcolor",
"toml",
"uuid",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.14.14" version = "0.14.14"
@ -2084,22 +1962,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
[[package]]
name = "kms-cli"
version = "0.1.0"
dependencies = [
"clap 3.1.18",
"color-eyre",
"ethers",
"ethers-signers",
"hex",
"once_cell",
"rusoto_core",
"rusoto_kms",
"serde_json",
"tokio",
]
[[package]] [[package]]
name = "lalrpop" name = "lalrpop"
version = "0.19.7" version = "0.19.7"
@ -2259,27 +2121,6 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "metrics"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e52eb6380b6d2a10eb3434aec0885374490f5b82c8aaf5cd487a183c98be834"
dependencies = [
"ahash",
"metrics-macros",
]
[[package]]
name = "metrics-macros"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49e30813093f757be5cf21e50389a24dc7dbb22c49f23b7e8f51d69b508a5ffa"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.3.16" version = "0.3.16"
@ -2664,21 +2505,6 @@ dependencies = [
"num-traits 0.2.14", "num-traits 0.2.14",
] ]
[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
[[package]]
name = "os_type"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96eaebe22d9f12429b1af6a0b5dd411ccfc5cb5968710abbb8c512046be9df90"
dependencies = [
"regex",
]
[[package]] [[package]]
name = "owo-colors" name = "owo-colors"
version = "3.2.0" version = "3.2.0"
@ -3921,19 +3747,13 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]] [[package]]
name = "structopt" name = "structopt"
version = "0.3.25" version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10"
dependencies = [ dependencies = [
"clap 2.33.3", "clap",
"lazy_static", "lazy_static",
"structopt-derive", "structopt-derive",
] ]
@ -3944,7 +3764,7 @@ version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0"
dependencies = [ dependencies = [
"heck 0.3.3", "heck",
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -3999,15 +3819,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "termtree" name = "termtree"
version = "0.2.3" version = "0.2.3"
@ -4023,12 +3834,6 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "textwrap"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "1.0.30" version = "1.0.30"
@ -4331,7 +4136,7 @@ version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596"
dependencies = [ dependencies = [
"ansi_term 0.12.1", "ansi_term",
"serde 1.0.130", "serde 1.0.130",
"serde_json", "serde_json",
"sharded-slab", "sharded-slab",
@ -4452,9 +4257,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.8.0" version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"

@ -5,13 +5,10 @@ cargo-features = ["edition2021"]
members = [ members = [
"abacus-core", "abacus-core",
"abacus-base", "abacus-base",
"abacus-cli",
"abacus-test", "abacus-test",
"chains/abacus-ethereum", "chains/abacus-ethereum",
"agents/kathy", "agents/kathy",
"agents/checkpointer",
"agents/validator", "agents/validator",
"agents/relayer", "agents/relayer",
"tools/kms-cli",
"tools/abacus-cli",
"tools/balance-exporter"
] ]

@ -12,8 +12,8 @@ RUN apt-get update && \
# Add workspace to workdir # Add workspace to workdir
COPY agents ./agents COPY agents ./agents
COPY chains ./chains COPY chains ./chains
COPY tools ./tools
COPY abacus-base ./abacus-base COPY abacus-base ./abacus-base
COPY abacus-cli ./abacus-cli
COPY abacus-core ./abacus-core COPY abacus-core ./abacus-core
COPY abacus-test ./abacus-test COPY abacus-test ./abacus-test
@ -29,9 +29,7 @@ RUN \
mkdir -p /release && \ mkdir -p /release && \
cp /usr/src/target/release/validator /release && \ cp /usr/src/target/release/validator /release && \
cp /usr/src/target/release/relayer /release && \ cp /usr/src/target/release/relayer /release && \
cp /usr/src/target/release/checkpointer /release && \
cp /usr/src/target/release/kathy /release && \ cp /usr/src/target/release/kathy /release && \
cp /usr/src/target/release/kms-cli /release && \
cp /usr/src/target/release/abacus-cli /release cp /usr/src/target/release/abacus-cli /release
## 2: Copy the binaries to release image ## 2: Copy the binaries to release image

@ -53,27 +53,6 @@ easily described. Each of these agents will connect to a home chain and any
number of replicas. They need to be configured with chain connection details number of replicas. They need to be configured with chain connection details
and have access to a reliable node for each chain. and have access to a reliable node for each chain.
Some agent sketches:
- `updater`
- Needs only a connection to the home chain
- Signs update attestations and submits them to the home chain
- `watcher`
- Observe the home chain
- Observe as many replicas as possible
- Cache updates
- Check for fraud
- Submit fraud to the home chain
- if configured, issue emergency stop transactions
- `relayer`
- Relays signed updates from the home to the replica
- `processor`
- retrieve leaves from home chain
- observe >=1 replica
- generate proofs for the messages
- submit messages and proofs to the replica for processing
- config option: gas params
For Ethereum and Celo connections we use For Ethereum and Celo connections we use
[ethers-rs](https://github.com/gakonst/ethers-rs). Please see the docs [ethers-rs](https://github.com/gakonst/ethers-rs). Please see the docs
[here](https://docs.rs/ethers/0.2.0/ethers/). [here](https://docs.rs/ethers/0.2.0/ethers/).
@ -83,43 +62,28 @@ We use the tokio async runtime environment. Please see the docs
### Repo layout ### Repo layout
- `abacus-core`
- contains implementations of core primitives
- this includes
- traits (interfaces) for the on-chain contracts
- model implementations of the contracts in rust
- merkle tree implementations (for provers)
- `abacus-base` - `abacus-base`
- lowest dependency abacus utilities
- contains shared utilities for building off-chain agents - contains shared utilities for building off-chain agents
- this includes - this includes
- trait implementations for different chains - trait implementations for different chains
- shared configuration file formats - shared configuration file formats
- basic setup for an off-chain agent - basic setup for an off-chain agent
- `abacus-core`
- depends on abacus-base
- contains implementations of core primitives
- this includes
- traits (interfaces) for the on-chain contracts
- model implementations of the contracts in rust
- merkle tree implementations (for provers)
- `chains/abacus-ethereum` - `chains/abacus-ethereum`
- depends on abacus-core (and transitively abacus-base)
- interfaces to the ethereum contracts - interfaces to the ethereum contracts
- `agents` - `agents`
- each of the off-chain agents implemented thus far - each of the off-chain agents implemented thus far
### High-level guide to building an agent
- `cargo new $AGENT_NAME`
- add the new directory name to the workspace `Cargo.toml`
- add dependencies to the new directory's `Cargo.toml`
- copy most of the dependencies from `abacus-base`
- create a new module in `src/$AGENT_NAME.rs`
- add a new struct
- implement `abacus_base::AbacusAgent` for your struct
- your `run` function is the business logic of your agent
- create a new settings module `src/settings.rs`
- reuse the `Settings` objects from `abacus_base::settings`
- make sure to read the docs :)
- add your own new settings
- in `$AGENT_NAME/src/main.rs`
- add `mod _____` declarations for your agent and settings modules
- create `main` and `setup` functions
- follow the pattern in `abacus-base/src/main.rs`
- make a `config` folder and a toml file
- Make sure to include your own settings from above
### Running Locally ### Running Locally
See the guide [here](./running-locally.md) to run the agents locally.
```bash
./rust/run-locally.sh
```

@ -1,7 +1,6 @@
[package] [package]
name = "abacus-base" name = "abacus-base"
version = "0.1.0" version = "0.1.0"
authors = ["James Prestwich <prestwich@clabs.co>"]
edition = "2021" edition = "2021"
@ -53,7 +52,3 @@ color-eyre = "0.6"
[features] [features]
oneline-eyre = [] oneline-eyre = []
[[example]]
name = "example"
path = "./bin/example.rs"

@ -1,42 +0,0 @@
use color_eyre::Result;
use abacus_base::{Agent, Settings};
/// An example main function for any agent that implemented Default
async fn _example_main<OA>(settings: Settings) -> Result<()>
where
OA: Agent<Settings = Settings> + Sized + 'static,
{
// Instantiate an agent
let oa = OA::from_settings(settings).await?;
oa.as_ref()
.settings
.tracing
.start_tracing(oa.metrics().span_duration())?;
// Run the agent
oa.run_all(vec![]).await?
}
/// Read settings from the config file and set up reporting and logging based
/// on the settings
#[allow(dead_code)]
fn setup() -> Result<Settings> {
color_eyre::install()?;
let settings = Settings::new()?;
Ok(settings)
}
#[allow(dead_code)]
fn main() -> Result<()> {
let _settings = setup()?;
// tokio::runtime::Builder::new_current_thread()
// .enable_all()
// .build()
// .unwrap()
// .block_on(_example_main(settings))?;
Ok(())
}

@ -55,7 +55,7 @@ pub use paste;
/// ///
/// Please note that integers must be specified as `String` in order to allow /// Please note that integers must be specified as `String` in order to allow
/// them to be configured via env var. They must then be parsed in the /// them to be configured via env var. They must then be parsed in the
/// [`AbacusAgent::from_settings`](crate::agent::AbacusAgent::from_settings) /// [`Agent::from_settings`](crate::agent::Agent::from_settings)
/// method. /// method.
/// ///
/// ### Usage /// ### Usage

@ -15,5 +15,5 @@ tokio = "1"
serde_json = "1.0" serde_json = "1.0"
structopt = "0.3.23" structopt = "0.3.23"
abacus-ethereum = { path = "../../chains/abacus-ethereum" } abacus-ethereum = { path = "../chains/abacus-ethereum" }
abacus-core = { path = "../../abacus-core" } abacus-core = { path = "../abacus-core" }

@ -31,15 +31,3 @@ color-eyre = "0.6"
[features] [features]
output = [] output = []
[[bin]]
name = "proof_output"
path = "bin/proof_output.rs"
[[bin]]
name = "lib_test_output"
path = "bin/lib_test_output.rs"
[[bin]]
name = "utils_test_output"
path = "bin/utils_test_output.rs"

@ -1,10 +0,0 @@
#[cfg(feature = "output")]
use abacus_core::test_output::output_functions::*;
fn main() {
#[cfg(feature = "output")]
{
output_signed_checkpoints();
output_message_and_leaf();
}
}

@ -1,9 +0,0 @@
#[cfg(feature = "output")]
use abacus_core::test_output::output_functions::*;
fn main() {
#[cfg(feature = "output")]
{
output_merkle_proof();
}
}

@ -1,10 +0,0 @@
#[cfg(feature = "output")]
use abacus_core::test_output::output_functions::*;
fn main() {
#[cfg(feature = "output")]
{
output_domain_hashes();
output_destination_and_nonces();
}
}

@ -1,7 +1,6 @@
[package] [package]
name = "abacus-test" name = "abacus-test"
version = "0.1.0" version = "0.1.0"
authors = ["Luke Tchang <ltchang@stanford.edu>"]
edition = "2021" edition = "2021"
[dependencies] [dependencies]

@ -1,34 +0,0 @@
[package]
name = "checkpointer"
version = "0.1.0"
authors = ["Abacus Team"]
edition = "2021"
[dependencies]
tokio = { version = "1", features = ["rt", "macros"] }
config = "0.10"
serde = "1.0"
serde_json = { version = "1.0", default-features = false }
ethers = { git = "https://github.com/gakonst/ethers-rs", branch = "master" }
thiserror = { version = "1.0.22", default-features = false }
async-trait = { version = "0.1.42", default-features = false }
futures-util = "0.3.12"
eyre = "0.6"
color-eyre = { version = "0.6", optional = true }
tracing = "0.1"
tracing-futures = "0.2"
tracing-subscriber = "0.3"
rocksdb = { git = "https://github.com/rust-rocksdb/rust-rocksdb" }
abacus-core = { path = "../../abacus-core" }
abacus-base = { path = "../../abacus-base" }
abacus-ethereum = { path = "../../chains/abacus-ethereum" }
[dev-dependencies]
tokio-test = "0.4"
abacus-test = { path = "../../abacus-test" }
prometheus = "0.12"
[features]
default = ["color-eyre"]
oneline-errors = ["abacus-base/oneline-eyre"]

@ -1,74 +0,0 @@
use async_trait::async_trait;
use eyre::Result;
use tokio::task::JoinHandle;
use tracing::instrument::Instrumented;
use abacus_base::{AbacusAgentCore, Agent};
use crate::{settings::CheckpointerSettings as Settings, submit::CheckpointSubmitter};
/// A checkpointer agent
#[derive(Debug)]
pub struct Checkpointer {
/// The polling interval (in seconds)
polling_interval: u64,
/// The minimum period between created checkpoints (in seconds)
creation_latency: u64,
pub(crate) core: AbacusAgentCore,
}
impl AsRef<AbacusAgentCore> for Checkpointer {
fn as_ref(&self) -> &AbacusAgentCore {
&self.core
}
}
impl Checkpointer {
/// Instantiate a new checkpointer
pub fn new(polling_interval: u64, creation_latency: u64, core: AbacusAgentCore) -> Self {
Self {
polling_interval,
creation_latency,
core,
}
}
}
#[async_trait]
impl Agent for Checkpointer {
const AGENT_NAME: &'static str = "checkpointer";
type Settings = Settings;
async fn from_settings(settings: Self::Settings) -> Result<Self>
where
Self: Sized,
{
let polling_interval = settings
.pollinginterval
.parse()
.expect("invalid pollinginterval uint");
let creation_latency = settings
.creationlatency
.parse()
.expect("invalid creationlatency uint");
let core = settings
.as_ref()
.try_into_abacus_core(Self::AGENT_NAME)
.await?;
Ok(Self::new(polling_interval, creation_latency, core))
}
}
impl Checkpointer {
pub fn run(&self) -> Instrumented<JoinHandle<Result<()>>> {
let outbox = self.outbox();
let submit = CheckpointSubmitter::new(outbox, self.polling_interval, self.creation_latency);
self.run_all(vec![submit.spawn()])
}
}
#[cfg(test)]
mod test {}

@ -1,44 +0,0 @@
//! The checkpointer observes the Outbox contract and calls checkpoint.
#![forbid(unsafe_code)]
#![warn(missing_docs)]
#![warn(unused_extern_crates)]
use eyre::Result;
use abacus_base::Agent;
use crate::{checkpointer::Checkpointer, settings::CheckpointerSettings as Settings};
mod checkpointer;
mod settings;
mod submit;
async fn _main() -> Result<()> {
#[cfg(feature = "oneline-errors")]
abacus_base::oneline_eyre::install()?;
#[cfg(not(feature = "oneline-errors"))]
color_eyre::install()?;
let settings = Settings::new()?;
let agent = Checkpointer::from_settings(settings).await?;
agent
.as_ref()
.settings
.tracing
.start_tracing(agent.metrics().span_duration())?;
let _ = agent.metrics().run_http_server();
agent.run().await??;
Ok(())
}
fn main() -> Result<()> {
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(_main())
}

@ -1,10 +0,0 @@
//! Configuration
use abacus_base::decl_settings;
decl_settings!(Checkpointer {
/// The polling interval (in seconds)
pollinginterval: String,
/// The minimum period between submitted checkpoints (in seconds)
creationlatency: String,
});

@ -1,65 +0,0 @@
use std::{sync::Arc, time::Duration};
use eyre::Result;
use tokio::{task::JoinHandle, time::sleep};
use tracing::{debug, info, info_span, instrument::Instrumented, Instrument};
use abacus_base::CachingOutbox;
use abacus_core::{AbacusCommon, Checkpoint, Outbox};
pub(crate) struct CheckpointSubmitter {
outbox: Arc<CachingOutbox>,
/// The polling interval
polling_interval: Duration,
/// The minimum period between submitted checkpoints
creation_latency: Duration,
}
impl CheckpointSubmitter {
pub(crate) fn new(
outbox: Arc<CachingOutbox>,
polling_interval: u64,
creation_latency: u64,
) -> Self {
Self {
outbox,
polling_interval: Duration::from_secs(polling_interval),
creation_latency: Duration::from_secs(creation_latency),
}
}
pub(crate) fn spawn(self) -> Instrumented<JoinHandle<Result<()>>> {
let span = info_span!("CheckpointSubmitter");
tokio::spawn(async move {
loop {
sleep(self.polling_interval).await;
// Check the latest checkpointed index
let Checkpoint {
index: latest_checkpoint_index,
..
} = self.outbox.latest_checkpoint(None).await?;
// Get the current count of the tree
let count = self.outbox.count().await?;
info!(
latest_checkpoint_index=?latest_checkpoint_index,
count=?count,
"Got latest checkpoint and count"
);
// If there are any new messages, the count will be greater than
// the latest checkpoint index + 1. Don't checkpoint for count < 2
// since checkpoints with index 0 are disallowed
if count > latest_checkpoint_index + 1 && count > 1 {
debug!("Creating checkpoint");
self.outbox.create_checkpoint().await?;
// Sleep to ensure that another checkpoint isn't made until
// creation_latency has passed
sleep(self.creation_latency).await;
}
}
})
.instrument(span)
}
}

@ -1,7 +1,6 @@
[package] [package]
name = "kathy" name = "kathy"
version = "0.1.0" version = "0.1.0"
authors = ["James Prestwich <james@prestwi.ch>"]
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

@ -1,7 +1,6 @@
[package] [package]
name = "relayer" name = "relayer"
version = "0.1.0" version = "0.1.0"
authors = ["ltchang <ltchang@stanford.edu>"]
edition = "2021" edition = "2021"
[dependencies] [dependencies]

@ -1,7 +1,6 @@
[package] [package]
name = "validator" name = "validator"
version = "0.1.0" version = "0.1.0"
authors = ["Abacus Team"]
edition = "2021" edition = "2021"
[dependencies] [dependencies]

@ -1,7 +1,6 @@
[package] [package]
name = "abacus-ethereum" name = "abacus-ethereum"
version = "0.1.0" version = "0.1.0"
authors = ["Erin Hales <mcbridee093@gmail.com>"]
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

@ -1 +0,0 @@
docker push gcr.io/clabs-optics/optics-agent:$1

@ -1,23 +0,0 @@
[package]
name = "balance-exporter"
version = "0.1.0"
edition = "2021"
description = "Polls chains for optics contract wallet balances and reports them in OpenMetrics format"
authors = ["ember arlynx <ember.arlynx@clabs.co>"]
license = "Apache-2.0"
[dependencies]
tokio = "1"
futures = "0.3"
metrics = "0.18"
serde_json = "1.0"
serde = "1.0"
color-eyre = "0.6"
clap = { version = "3.1", features = ["cargo", "derive"] }
human-panic = "1.0"
abacus-base = { path = "../../abacus-base" }
# SMELL: reaching into the implementation details. abstract eventually.
abacus-ethereum = { path = "../../chains/abacus-ethereum" }

@ -1,161 +0,0 @@
use std::{path::PathBuf, time::Duration};
use abacus_base::ChainSetup;
use clap::Arg;
use color_eyre::eyre::anyhow;
use futures::StreamExt;
use human_panic::setup_panic;
use tokio::time::Instant;
#[derive(serde::Deserialize, Debug)]
struct Contract(String);
#[derive(serde::Deserialize, Debug)]
struct Input {
contracts: Vec<ChainSetup<Contract>>,
}
struct Sample {
balances: Vec<color_eyre::Result<String>>,
}
async fn poll_once(input: &Input, timeout: Duration) -> Sample {
// does this open a new ws connection for each query? probably.
let (send, mut recv) = tokio::sync::mpsc::unbounded_channel();
// moves `send` into the subtask executor. by the time it is complete,
// `recv` will complete to exhaustion, due to `send` clones being dropped
futures::stream::iter(
input
.contracts
.iter()
.enumerate()
.zip(std::iter::repeat(send)),
)
.for_each_concurrent(None, |((ix, _cs), send)| async move {
let sub_result =
tokio::time::timeout(timeout, std::future::ready(Err(anyhow!("WIP")))).await;
send.send((ix, sub_result))
.expect("channel closed before we're done?");
})
.await;
let mut balances: Vec<Option<color_eyre::Result<String>>> =
input.contracts.iter().map(|_| None).collect();
while let Some((ix, sub_result)) = recv.recv().await {
match sub_result {
Ok(Ok(v)) => balances[ix] = Some(Ok(v)),
Ok(Err(e)) => balances[ix] = Some(Err(e)),
Err(_) => balances[ix] = Some(Err(anyhow!("timeout expired"))),
}
}
assert!(balances.iter().all(Option::is_some));
Sample {
balances: balances.into_iter().map(Option::unwrap).collect(),
}
}
#[tokio::main]
async fn main() -> color_eyre::Result<()> {
setup_panic!();
color_eyre::install()?;
let args = clap::command!()
.arg(
Arg::new("polling-interval")
.validator(|s| {
str::parse::<u64>(s).map_err(|_| anyhow!("polling interval must be u64!"))
})
.help("Minimum number of seconds to wait between poll attempts")
.default_value("120"),
)
.arg(
Arg::new("stdin")
.help("Read configuration JSON from stdin")
.required_unless_present("file"),
)
.arg(
Arg::new("file")
.takes_value(true)
.help("Path to configuration JSON file"),
)
.get_matches();
eprintln!("Hello, world!");
eprintln!("You asked me to do this: {:?}", args);
eprintln!("Loading up the input...");
let setup: Input = if !args.is_present("stdin") {
serde_json::from_reader(std::fs::File::open(PathBuf::from(
args.value_of_os("file").expect("malformed --file"),
))?)?
} else {
serde_json::from_reader(std::io::stdin())?
};
let interval = Duration::from_secs(
args.value_of_t("polling-interval")
.expect("malformed --polling-interval"),
);
println!("Going to start exporting these:");
setup.contracts.iter().for_each(|s| println!("\t {:?}", s));
loop {
let start = Instant::now();
let results = poll_once(&setup, interval).await;
for (ix, res) in results.balances.into_iter().enumerate() {
let ChainSetup {
name: network,
addresses,
..
} = &setup.contracts[ix];
match res {
Ok(s) => {
// TODO: export metric
println!("{} {} = {}", network, addresses.0, s);
}
Err(e) => {
eprintln!("Error while querying {:?}: {}", setup.contracts[ix], e);
}
}
}
tokio::time::sleep_until(start + interval).await;
}
}
impl Sample {
#[allow(dead_code)]
fn record(_m: impl metrics::Recorder) {}
}
#[tokio::test]
#[should_panic]
async fn mainnet_works() {
// query ethereum instance of AbacusConnectionManager and asserts the balance is nonzero.
let sample = poll_once(
&Input {
contracts: vec![ChainSetup {
name: "ethereum".into(),
domain: "6648936".into(),
// i would love for this to just be ChainConf::ethereum()
chain: abacus_base::chains::ChainConf::Ethereum(abacus_ethereum::Connection::Ws {
url: "wss://main-light.eth.linkpool.io/ws".into(),
}),
addresses: Contract("0xcEc158A719d11005Bd9339865965bed938BEafA3".into()),
disabled: None,
}],
},
Duration::from_secs(120),
)
.await;
let only_balance = sample.balances[0].as_ref();
assert!(only_balance.expect("failed to query chain!") != "0");
}

@ -1,18 +0,0 @@
[package]
name = "kms-cli"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = "3.0.0-beta.5"
color-eyre = "0.6"
ethers = { git = "https://github.com/gakonst/ethers-rs", branch = "master" }
ethers-signers = { git = "https://github.com/gakonst/ethers-rs", branch = "master", features = ["aws"] }
hex = "0.4.3"
once_cell = "1.8.0"
rusoto_core = "0.47.0"
rusoto_kms = "0.47.0"
tokio = "1"
serde_json = "1.0"

@ -1,218 +0,0 @@
use std::convert::TryFrom;
use color_eyre::Result;
use ethers::{
core::types::{transaction::eip2718::TypedTransaction, Address, TransactionRequest, U256},
providers::{Http, Middleware, Provider},
signers::{AwsSigner, Signer},
};
use once_cell::sync::OnceCell;
use rusoto_core::{credential::EnvironmentProvider, HttpClient};
use rusoto_kms::KmsClient;
use clap::Parser;
static KMS_CLIENT: OnceCell<KmsClient> = OnceCell::new();
fn init_kms(region: String) {
let client =
rusoto_core::Client::new_with(EnvironmentProvider::default(), HttpClient::new().unwrap());
if KMS_CLIENT
.set(KmsClient::new_with_client(
client,
region.parse().expect("invalid region"),
))
.is_err()
{
panic!("couldn't set cell")
}
}
#[derive(Parser)]
pub struct Tx {
// TX
/// The TX value (in wei)
#[clap(short, long)]
value: Option<String>,
/// The TX nonce (pulled from RPC if omitted)
#[clap(long)]
nonce: Option<U256>,
/// The TX gas price (pulled from RPC if omitted)
#[clap(long)]
gas_price: Option<U256>,
/// The TX gas limit (estimated from RPC if omitted)
#[clap(long)]
gas: Option<U256>,
/// The TX data body (omit for simple sends)
#[clap(short, long)]
data: Option<String>,
/// The recipient/contract address
#[clap(short, long)]
to: Address,
/// The chain_id. see https://chainlist.org
#[clap(short, long)]
chain_id: Option<u64>,
// RPC
/// RPC connection details
#[clap(long)]
rpc: String,
}
#[derive(Parser)]
pub struct Info {}
#[derive(Parser)]
/// Subcommands
#[allow(clippy::large_enum_variant)]
pub enum SubCommands {
/// Send a tx signed by the KMS key
Transaction(Tx),
/// Print the key info (region, id, address)
Info(Info),
}
#[derive(Parser)]
#[clap(version = "0.1", author = "James Prestwich")]
pub struct Opts {
#[clap(subcommand)]
sub: SubCommands,
// AWS
/// AWS Key ID
#[clap(short, long)]
key_id: String,
/// AWS Region string
#[clap(long)]
region: String,
// Behavior
/// Print the tx req and signature instead of broadcasting
#[clap(short, long)]
print_only: bool,
}
macro_rules! apply_if {
($tx_req:ident, $method:ident, $prop:expr) => {{
if let Some(prop) = $prop {
$tx_req.$method(prop)
} else {
$tx_req
}
}};
($tx_req:ident, $opts:ident.$prop:ident) => {{
let prop = $opts.$prop;
apply_if!($tx_req, $prop, prop)
}};
}
fn prep_tx_request(opts: &Tx) -> TransactionRequest {
let tx_req = TransactionRequest::default().to(opts.to);
// These swallow parse errors
let tx_req = apply_if!(
tx_req,
data,
opts.data.clone().and_then(|data| hex::decode(&data).ok())
);
let tx_req = apply_if!(
tx_req,
value,
opts.value
.clone()
.and_then(|value| U256::from_dec_str(&value).ok())
);
let tx_req = apply_if!(tx_req, opts.nonce);
let tx_req = apply_if!(tx_req, opts.gas);
let data = opts
.data
.clone()
.and_then(|s| hex::decode(s).ok())
.unwrap_or_default();
let tx_req = tx_req.data(data);
apply_if!(tx_req, opts.gas_price)
}
async fn _send_tx(signer: &AwsSigner<'_>, opts: &Opts) -> Result<()> {
let tx: &Tx = match opts.sub {
SubCommands::Transaction(ref tx) => tx,
SubCommands::Info(_) => unreachable!(),
};
let provider = Provider::<Http>::try_from(tx.rpc.clone())?;
let tx_req = prep_tx_request(tx);
let mut typed_tx: TypedTransaction = tx_req.clone().into();
typed_tx.set_from(signer.address());
typed_tx.set_nonce(
provider
.get_transaction_count(signer.address(), None)
.await?,
);
// TODO: remove this these ethers is fixed
typed_tx.set_gas(21000);
typed_tx.set_gas_price(20_000_000_000u64); // 20 gwei
typed_tx.set_chain_id(signer.chain_id());
let sig = signer.sign_transaction(&typed_tx).await?;
let rlp = typed_tx.rlp_signed(&sig);
println!(
"Tx request details:\n{}",
serde_json::to_string_pretty(&typed_tx)?
);
println!("\nSigned Tx:\n 0x{}", hex::encode(&rlp));
if !opts.print_only {
let res = provider.send_raw_transaction(rlp).await?;
println!("Broadcast tx with hash {:?}", *res);
println!("Awaiting confirmation. Ctrl+c to exit");
dbg!(res.await?);
}
Ok(())
}
async fn _print_info(signer: &AwsSigner<'_>, opts: &Opts) -> Result<()> {
println!("Key ID: {}", opts.key_id);
println!("Region: {}", opts.region);
println!("Address: {}", signer.address());
Ok(())
}
async fn _main() -> Result<()> {
let opts: Opts = Opts::parse();
init_kms(opts.region.to_owned());
let chain_id = match opts.sub {
SubCommands::Transaction(ref tx) => tx.chain_id.unwrap_or(1),
SubCommands::Info(_) => 1,
};
let signer = AwsSigner::new(KMS_CLIENT.get().unwrap(), opts.key_id.clone(), 0)
.await?
.with_chain_id(chain_id);
match opts.sub {
SubCommands::Transaction(_) => _send_tx(&signer, &opts).await,
SubCommands::Info(_) => _print_info(&signer, &opts).await,
}
}
fn main() -> Result<()> {
color_eyre::install()?;
tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(_main())
}
Loading…
Cancel
Save