diff --git a/.drone.yml b/.drone.yml index 67d60e676..039fceae2 100644 --- a/.drone.yml +++ b/.drone.yml @@ -57,7 +57,7 @@ steps: image: rust:1.75-bullseye commands: - apt-get update && apt-get install -y libssl-dev libjemalloc-dev jq - - rustup update nightly-2023-12-21 && rustup default nightly-2023-12-21 + - rustup update 1.75 && rustup default 1.75 - rustup component add rustfmt - cargo test --release -p cli - cargo build --release -p cli --bin openmina diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 15c0e0c5e..8e7b3125a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,16 +10,41 @@ concurrency: cancel-in-progress: true jobs: - build: + ledger-tests: runs-on: ubuntu-20.04 + env: + CARGO_TERM_COLOR: always steps: - name: Git checkout uses: actions/checkout@v3 - - name: Setup Rust run: | + # Nightly to be able to use `--report-time` below rustup install nightly rustup override set nightly + - name: Download circuits files + run: | + git clone --depth 1 https://github.com/openmina/circuit-blobs.git + ln -s -b $PWD/circuit-blobs/* ledger/ + - name: Build ledger tests + run: | + cd ledger + cargo build --release --tests + - name: Run ledger tests + run: | + cd ledger + cargo test --release -- -Z unstable-options --report-time + + build: + runs-on: ubuntu-20.04 + steps: + - name: Git checkout + uses: actions/checkout@v3 + + - name: Setup Rust + run: | + rustup install 1.75 + rustup override set 1.75 rustup component add clippy rustfmt # - name: Check @@ -75,7 +100,7 @@ jobs: needs: [ build ] runs-on: ubuntu-20.04 container: - image: minaprotocol/mina-daemon:2.0.0rampup4-14047c5-focal-berkeley + image: minaprotocol/mina-daemon:2.0.0berkeley-rc1-1551e2f-focal-berkeley strategy: matrix: test: [p2p_basic_connections, p2p_basic_incoming, p2p_basic_outgoing] @@ -99,7 +124,7 @@ jobs: needs: [ build ] runs-on: ubuntu-20.04 container: - image: minaprotocol/mina-daemon:2.0.0rampup4-14047c5-focal-berkeley + image: minaprotocol/mina-daemon:2.0.0berkeley-rc1-1551e2f-focal-berkeley strategy: matrix: test: [single_node, multi_node, connection_discovery, webrtc_single_node, webrtc_multi_node] diff --git a/CHANGELOG.md b/CHANGELOG.md index 51581f4fa..c6c9c0dff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.2.0] - 2024-02-29 + +### Changed + +- Default Rust toolchain switched to stable channel (as of 1.75). +- Internal refactoring to how leaf actions in the state machine are organized. + +### Fixed + +- Node can now connect to the current berkeleynet after updates to: + - Wire type definitions. + - Verification, proving and circuits. + - Ledger and transaction application logic. + +### Added + +- Ledger tests on CI. + ## [0.1.0] - 2024-02-02 ### Fixed @@ -34,6 +52,7 @@ First public release. - Alpha version of the node which can connect and syncup to the berkeleynet network, and keep applying new blocks to maintain consensus state and ledger up to date. - Web-based frontend for the node. -[unreleased]: https://github.com/openmina/openmina/compare/v0.1.0...develop +[unreleased]: https://github.com/openmina/openmina/compare/v0.2.0...develop +[0.2.0]: https://github.com/openmina/openmina/releases/tag/v0.1.0...v0.2.0 [0.1.0]: https://github.com/openmina/openmina/releases/tag/v0.0.1...v0.1.0 [0.0.1]: https://github.com/openmina/openmina/releases/tag/v0.0.1 diff --git a/Cargo.lock b/Cargo.lock index 2d518d8f7..1cab17672 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,9 +143,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom 0.2.10", "once_cell", @@ -154,9 +154,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff" dependencies = [ "cfg-if", "once_cell", @@ -178,7 +178,7 @@ name = "alloc-test" version = "0.1.1" source = "git+https://github.com/openmina/alloc-test.git#0d3951eaddc58a6ea2d2134966ed5954234889d3" dependencies = [ - "clap", + "clap 4.4.7", "derive_builder", "derive_more", "num", @@ -211,6 +211,15 @@ dependencies = [ "libc", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + [[package]] name = "anstream" version = "0.6.4" @@ -505,6 +514,17 @@ dependencies = [ "url", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -872,6 +892,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-targets 0.48.5", ] @@ -904,6 +925,21 @@ dependencies = [ "inout", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + [[package]] name = "clap" version = "4.4.7" @@ -923,7 +959,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.10.0", ] [[package]] @@ -932,7 +968,7 @@ version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 2.0.38", @@ -946,10 +982,10 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "cli" -version = "0.1.0" +version = "0.2.0" dependencies = [ "bytes", - "clap", + "clap 4.4.7", "console", "dialoguer", "hex", @@ -1236,9 +1272,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -1282,6 +1318,16 @@ dependencies = [ "darling_macro 0.14.4", ] +[[package]] +name = "darling" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c376d08ea6aa96aafe61237c7200d1241cb177b7d3a542d791f2d118e9cbb955" +dependencies = [ + "darling_core 0.20.6", + "darling_macro 0.20.6", +] + [[package]] name = "darling_core" version = "0.13.4" @@ -1292,7 +1338,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] @@ -1306,10 +1352,24 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.10.0", "syn 1.0.109", ] +[[package]] +name = "darling_core" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33043dcd19068b8192064c704b3f83eb464f91f1ff527b44a4e2b08d9cdb8855" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.38", +] + [[package]] name = "darling_macro" version = "0.13.4" @@ -1332,6 +1392,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "darling_macro" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5a91391accf613803c2a9bf9abccdbaa07c54b4244a5b64883f9c3c137c86be" +dependencies = [ + "darling_core 0.20.6", + "quote", + "syn 2.0.38", +] + [[package]] name = "data-encoding" version = "2.4.0" @@ -1390,6 +1461,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1602,7 +1674,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "ed25519", "rand_core 0.6.4", "serde", @@ -1658,7 +1730,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 2.0.38", @@ -1949,7 +2021,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee76e8096c3fcd82ab23177edddcc9b81b72c123caab54bb1e2dc19fd09d2dec" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", "bit-vec", "cc", "cfg-if", @@ -2149,7 +2221,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", ] [[package]] @@ -2164,7 +2236,7 @@ version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.8", "allocator-api2", ] @@ -2192,12 +2264,30 @@ dependencies = [ "http", ] +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.3" @@ -2448,6 +2538,7 @@ checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" dependencies = [ "equivalent", "hashbrown 0.14.2", + "serde", ] [[package]] @@ -2493,7 +2584,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.3", "libc", "windows-sys 0.48.0", ] @@ -2645,7 +2736,7 @@ dependencies = [ "rayon", "rmp-serde", "serde", - "serde_with", + "serde_with 1.14.0", "strum", "strum_macros", "thiserror", @@ -2658,6 +2749,21 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "ledger-tool" +version = "0.2.0" +dependencies = [ + "anyhow", + "mina-curves", + "mina-p2p-messages", + "mina-signer", + "mina-tree", + "reqwest", + "serde", + "serde_json", + "structopt", +] + [[package]] name = "libc" version = "0.2.149" @@ -2907,7 +3013,7 @@ version = "0.44.0" source = "git+https://github.com/openmina/rust-libp2p?rev=cd5425a759d959d7fde58a42f71ab059449760c5#cd5425a759d959d7fde58a42f71ab059449760c5" dependencies = [ "bytes", - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "futures", "getrandom 0.2.10", "libp2p-core", @@ -2964,7 +3070,7 @@ dependencies = [ [[package]] name = "libp2p-rpc-behaviour" -version = "0.1.0" +version = "0.2.0" dependencies = [ "libp2p", "log", @@ -2998,7 +3104,7 @@ name = "libp2p-swarm-derive" version = "0.34.0" source = "git+https://github.com/openmina/rust-libp2p?rev=cd5425a759d959d7fde58a42f71ab059449760c5#cd5425a759d959d7fde58a42f71ab059449760c5" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-warning", "proc-macro2", "quote", @@ -3240,7 +3346,7 @@ dependencies = [ "binprot_derive", "blake2", "bs58 0.4.0", - "clap", + "clap 4.4.7", "derive_more", "fuzzcheck", "gloo-utils 0.1.7", @@ -3250,6 +3356,7 @@ dependencies = [ "mina-poseidon", "mina-signer", "o1-utils", + "rsexp", "serde", "serde_json", "sha2 0.10.8", @@ -3275,7 +3382,7 @@ dependencies = [ "rand 0.8.5", "rayon", "serde", - "serde_with", + "serde_with 1.14.0", ] [[package]] @@ -3299,7 +3406,7 @@ dependencies = [ [[package]] name = "mina-tree" -version = "0.1.0" +version = "0.2.0" dependencies = [ "ark-ec", "ark-ff", @@ -3337,6 +3444,7 @@ dependencies = [ "rayon", "serde", "serde_json", + "serde_with 3.6.1", "sha2 0.10.8", "static_assertions", "tuple-map", @@ -3598,7 +3706,7 @@ dependencies = [ [[package]] name = "node" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "bincode", @@ -3758,7 +3866,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.3", "libc", ] @@ -3831,7 +3939,7 @@ dependencies = [ "rand_core 0.6.4", "rayon", "serde", - "serde_with", + "serde_with 1.14.0", "sha2 0.10.8", "thiserror", ] @@ -3905,12 +4013,13 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openmina-core" -version = "0.1.0" +version = "0.2.0" dependencies = [ "mina-hasher", "mina-p2p-messages", "redux", "serde", + "serde_json", "sha2 0.10.8", "slab", "tokio", @@ -3919,7 +4028,7 @@ dependencies = [ [[package]] name = "openmina-node-invariants" -version = "0.1.0" +version = "0.2.0" dependencies = [ "documented", "lazy_static", @@ -3933,7 +4042,7 @@ dependencies = [ [[package]] name = "openmina-node-native" -version = "0.1.0" +version = "0.2.0" dependencies = [ "bytes", "juniper", @@ -3960,12 +4069,12 @@ dependencies = [ [[package]] name = "openmina-node-testing" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "axum", "bincode", - "clap", + "clap 4.4.7", "console", "ctrlc", "derive_more", @@ -4066,7 +4175,7 @@ dependencies = [ [[package]] name = "p2p" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "binprot", @@ -4312,7 +4421,7 @@ dependencies = [ "rand_core 0.6.4", "rayon", "serde", - "serde_with", + "serde_with 1.14.0", "thiserror", ] @@ -4778,7 +4887,7 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "replay_dynamic_effects" -version = "0.1.0" +version = "0.2.0" dependencies = [ "cli", "node", @@ -4788,9 +4897,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.5", "bytes", @@ -4810,9 +4919,11 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -4895,6 +5006,12 @@ dependencies = [ "serde", ] +[[package]] +name = "rsexp" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3df9a9b6491d42c0fc527e92a87525c17e45c6b9c22345702a6dc0400320bf1" + [[package]] name = "rtcp" version = "0.10.0" @@ -5230,7 +5347,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ "serde", - "serde_with_macros", + "serde_with_macros 1.5.2", +] + +[[package]] +name = "serde_with" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15d167997bd841ec232f5b2b8e0e26606df2e7caa4c31b95ea9ca52b200bd270" +dependencies = [ + "base64 0.21.5", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.0.2", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros 3.6.1", + "time", ] [[package]] @@ -5245,6 +5380,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "serde_with_macros" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865f9743393e638991566a8b7a479043c2c8da94a33e0a31f18214c9cae0a64d" +dependencies = [ + "darling 0.20.6", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "sha-1" version = "0.10.1" @@ -5382,7 +5529,7 @@ dependencies = [ [[package]] name = "snark" -version = "0.1.0" +version = "0.2.0" dependencies = [ "ark-ec", "ark-ff", @@ -5420,7 +5567,7 @@ dependencies = [ "aes-gcm 0.9.4", "blake2", "chacha20poly1305", - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "rand_core 0.6.4", "ring 0.16.20", "rustc_version 0.4.0", @@ -5476,12 +5623,42 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap 2.34.0", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "strum" version = "0.24.1" @@ -5494,7 +5671,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -5620,6 +5797,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.50" @@ -6074,6 +6260,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" version = "0.1.11" @@ -6187,6 +6379,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "vergen" version = "8.2.5" @@ -6213,7 +6411,7 @@ checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" [[package]] name = "vrf" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "ark-ec", @@ -6894,7 +7092,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" dependencies = [ - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "rand_core 0.6.4", "serde", "zeroize", @@ -6959,18 +7157,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.15" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ba595b9f2772fbee2312de30eeb80ec773b4cb2f1e8098db024afadda6c06f" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.15" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772666c41fb6dceaf520b564b962d738a8e1a83b41bd48945f50837aed78bb1d" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 81882c337..ee7ea9abd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,8 @@ members = [ "mina-p2p-messages", "ledger", + + "tools/*", ] resolver = "2" diff --git a/Dockerfile b/Dockerfile index 1b8ec9206..ced0e2df7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ ARG MINA_SNARK_WORKER_TAG=0.0.9 FROM rust:buster AS build -RUN rustup default nightly-2023-12-21 && rustup component add rustfmt +RUN rustup default 1.75 && rustup component add rustfmt WORKDIR /openmina COPY . . RUN cargo build --release --package=cli --bin=openmina diff --git a/README.md b/README.md index 6074d97ce..cbe254f56 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Open up the command line and enter the following: ``` sh apt install curl git -curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly-2023-10-07 +curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain 1.75 source "$HOME/.cargo/env" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 0021a15f8..df00cfc13 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cli" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/cli/replay_dynamic_effects/Cargo.toml b/cli/replay_dynamic_effects/Cargo.toml index 33b6bf420..bb3042833 100644 --- a/cli/replay_dynamic_effects/Cargo.toml +++ b/cli/replay_dynamic_effects/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "replay_dynamic_effects" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/cli/src/commands/node/mod.rs b/cli/src/commands/node/mod.rs index 589070afc..335eef2e3 100644 --- a/cli/src/commands/node/mod.rs +++ b/cli/src/commands/node/mod.rs @@ -14,9 +14,7 @@ use tokio::select; use node::account::AccountPublicKey; use node::core::channels::mpsc; use node::core::log::inner::Level; -use node::event_source::{ - EventSourceProcessEventsAction, EventSourceWaitForEventsAction, EventSourceWaitTimeoutAction, -}; +use node::event_source::EventSourceAction; use node::ledger::LedgerCtx; use node::p2p::channels::ChannelId; use node::p2p::connection::outgoing::P2pConnectionOutgoingInitOpts; @@ -35,7 +33,7 @@ use node::{ use openmina_node_native::rpc::RpcService; use openmina_node_native::{http_server, tracing, NodeService, P2pTaskSpawner, RpcSender}; -const CHAIN_ID: &'static str = "3c41383994b87449625df91769dff7b507825c064287d30fada9286f3f1cb15e"; +const CHAIN_ID: &'static str = "fd7d111973bf5a9e3e87384f560fdead2f272589ca00b6d9e357fca9839631da"; /// Openmina node #[derive(Debug, clap::Args)] @@ -236,14 +234,16 @@ impl Node { .unwrap(); let (redux_exited_tx, redux_exited) = tokio::sync::oneshot::channel(); let record = self.record; + std::thread::Builder::new() .name("openmina_redux".to_owned()) .spawn(move || { - let ledger = if let Some(path) = &self.additional_ledgers_path { + let mut ledger = if let Some(path) = &self.additional_ledgers_path { LedgerCtx::new_with_additional_snarked_ledgers(path) } else { LedgerCtx::default() }; + ledger.load_genesis_ledger("genesis_ledgers/berkeley_genesis_ledger.bin"); let local_set = tokio::task::LocalSet::new(); local_set.block_on(&runtime, async move { @@ -283,11 +283,11 @@ impl Node { node .store_mut() - .dispatch(EventSourceProcessEventsAction {}); + .dispatch(EventSourceAction::ProcessEvents); loop { node .store_mut() - .dispatch(EventSourceWaitForEventsAction {}); + .dispatch(EventSourceAction::WaitForEvents); let service = &mut node.store_mut().service; let wait_for_events = service.event_receiver.wait_for_events(); @@ -303,7 +303,7 @@ impl Node { select! { _ = wait_for_events => { while node.store_mut().service.event_receiver.has_next() { - node.store_mut().dispatch(EventSourceProcessEventsAction {}); + node.store_mut().dispatch(EventSourceAction::ProcessEvents); } } req = rpc_req_fut => { @@ -314,7 +314,7 @@ impl Node { } } _ = timeout => { - node.store_mut().dispatch(EventSourceWaitTimeoutAction {}); + node.store_mut().dispatch(EventSourceAction::WaitTimeout); } } } diff --git a/core/Cargo.toml b/core/Cargo.toml index 63f3bd7d0..fbe97f023 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmina-core" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" @@ -14,3 +14,6 @@ tokio = { version = "1.26", features = ["sync"] } mina-hasher = { workspace = true } mina-p2p-messages = { workspace = true } + +[dev-dependencies] +serde_json = { version = "1" } diff --git a/core/src/block.rs b/core/src/block.rs index 71ee9dcd5..a14cdf402 100644 --- a/core/src/block.rs +++ b/core/src/block.rs @@ -89,6 +89,10 @@ impl> BlockWithHash { producer(self.header()) } + pub fn genesis_ledger_hash(&self) -> &LedgerHash { + genesis_ledger_hash(self.header()) + } + pub fn snarked_ledger_hash(&self) -> &LedgerHash { snarked_ledger_hash(self.header()) } @@ -118,14 +122,17 @@ impl> BlockWithHash { &self.block.as_ref().body.staged_ledger_diff.diff } - pub fn commands_iter( - &self, - ) -> impl Iterator { + pub fn commands_iter<'a>( + &'a self, + ) -> Box> + { let diff = self.staged_ledger_diff(); - diff.0.commands.iter().chain(match &diff.1.as_ref() { - None => &[], - Some(v) => &v.commands[..], - }) + let iter = diff.0.commands.iter(); + if let Some(_1) = diff.1.as_ref() { + Box::new(iter.chain(_1.commands.iter())) + } else { + Box::new(iter) + } } pub fn coinbases_iter(&self) -> impl Iterator { @@ -158,12 +165,16 @@ impl> BlockWithHash { coinbases.into_iter().filter_map(|v| v) } - pub fn completed_works_iter(&self) -> impl Iterator { + pub fn completed_works_iter<'a>( + &'a self, + ) -> Box> { let diff = self.staged_ledger_diff(); - diff.0.completed_works.iter().chain(match &diff.1.as_ref() { - None => &[], - Some(v) => &v.completed_works[..], - }) + let _0 = &diff.0; + if let Some(_1) = diff.1.as_ref() { + Box::new(_0.completed_works.iter().chain(_1.completed_works.iter())) + } else { + Box::new(_0.completed_works.iter()) + } } } @@ -223,6 +234,10 @@ impl> BlockHeaderWithHash { producer(self.header()) } + pub fn genesis_ledger_hash(&self) -> &LedgerHash { + genesis_ledger_hash(self.header()) + } + pub fn snarked_ledger_hash(&self) -> &LedgerHash { snarked_ledger_hash(self.header()) } @@ -289,6 +304,14 @@ fn producer(header: &BlockHeader) -> &NonZeroCurvePoint { &header.protocol_state.body.consensus_state.block_creator } +fn genesis_ledger_hash(header: &BlockHeader) -> &LedgerHash { + &header + .protocol_state + .body + .blockchain_state + .genesis_ledger_hash +} + fn snarked_ledger_hash(header: &BlockHeader) -> &LedgerHash { &header .protocol_state diff --git a/core/src/consensus.rs b/core/src/consensus.rs index bae71d9be..3d0ddf4bf 100644 --- a/core/src/consensus.rs +++ b/core/src/consensus.rs @@ -27,7 +27,7 @@ pub enum ConsensusLongRangeForkDecisionReason { // using block proof verification, but check just to be sure. pub fn is_short_range_fork(a: &MinaConsensusState, b: &MinaConsensusState) -> bool { let check = |s1: &MinaConsensusState, s2: &MinaConsensusState| { - let slots_per_epoch = s2.curr_global_slot.slots_per_epoch.as_u32(); + let slots_per_epoch = s2.curr_global_slot_since_hard_fork.slots_per_epoch.as_u32(); let s2_epoch_slot = s2.global_slot() % slots_per_epoch; if s1.epoch_count.as_u32() == s2.epoch_count.as_u32() + 1 && s2_epoch_slot >= slots_per_epoch * 2 / 3 @@ -104,7 +104,7 @@ fn relative_sub_window(global_slot: u32) -> u32 { } fn global_slot(b: &MinaConsensusState) -> u32 { - b.curr_global_slot.slot_number.as_u32() + b.curr_global_slot_since_hard_fork.slot_number.as_u32() } pub fn short_range_fork_take( @@ -200,7 +200,8 @@ mod tests { macro_rules! fork_file { ($prefix:expr, $tip:expr, $cnd:expr, $suffix:expr) => { concat!( - "../../../tests/files/forks/", + env!("CARGO_MANIFEST_DIR"), + "/../tests/files/forks/", $prefix, "-", $tip, diff --git a/frontend/README.md b/frontend/README.md index d005ba2ae..8cc1446f3 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,50 +1,35 @@ -# Angular Application +# Openmina Frontend This is a simple Angular application that will help you to see the behaviour of your local rust based mina node. - ## Prerequisites -Before you begin, ensure you have the following tools installed: - -- [Node.js](https://nodejs.org/) -- [npm](https://www.npmjs.com/) -- [Angular CLI](https://cli.angular.io/) - -Here are the steps to install the prerequisites listed above: - ### 1. Node.js -Download and install [Node.js](https://nodejs.org/) for your OS, which includes Node Package Manager (npm). - -- Verify your Node.js installation: - - ```bash - node -v - ``` - This command should print the version number of your Node.js installation. +Install Node.js v20.11.1: -### 2. npm -- Verify that you are running a version of npm that is at least 6.x.x or higher: +#### MacOS +```bash +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" +brew install node@20.11.1 +``` - ```bash - npm -v - ``` - This command should print the version number of your npm installation. +#### Linux +```bash +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash +source ~/.bashrc +nvm install 20.11.1 +``` -### 3. Angular CLI -- Install the Angular CLI globally: +#### Windows +Download [Node.js v20.11.1](https://nodejs.org/) from the official website, open the installer and follow the prompts to complete the installation. - ```bash - npm install -g @angular/cli - ``` - This command installs the Angular CLI globally on your system. -- Verify your Angular CLI installation: +### 2. Angular CLI +Install the Angular CLI v16.2.0 globally: ```bash - ng --version + npm install -g @angular/cli@16.2.0 ``` - This command should print the version number of your Angular CLI installation. ## Installation @@ -59,6 +44,5 @@ Download and install [Node.js](https://nodejs.org/) for your OS, which includes ```bash npm start ``` -4. Open your browser and navigate to [http://localhost:4200](http://localhost:4200). Next time you want to run the application, just run `npm start` again. diff --git a/frontend/cypress/e2e/resources/memory/memory-resources-table.cy.ts b/frontend/cypress/e2e/resources/memory/memory-resources-table.cy.ts index dd1a70179..791e6e9b5 100644 --- a/frontend/cypress/e2e/resources/memory/memory-resources-table.cy.ts +++ b/frontend/cypress/e2e/resources/memory/memory-resources-table.cy.ts @@ -205,8 +205,14 @@ describe('MEMORY RESOURCES TABLE', () => { .wait(500) .get('app-memory-resources-table .row:not(.head)') .each((row: any, i: number) => { - expect(row.find('span:nth-child(3)').text().trim()).equals(state.activeResource.children[i].name.executableName); expect(row.find('span:nth-child(4)').text().trim()).equals(transform(state.activeResource.children[i].value)); + const actual = row.find('span:nth-child(3)').text().trim(); + const expected = state.activeResource.children[i].name.executableName; + if (actual.length < expected.length) { + expect(expected.startsWith(actual.slice(0, actual.length - 3))).to.be.true; + } else { + expect(actual).equals(expected); + } }) .window() .its('store') @@ -232,15 +238,27 @@ describe('MEMORY RESOURCES TABLE', () => { .wait(500) .get(`app-memory-resources-table .row:not(.head)`) .each((row: any, i: number) => { - expect(row.find('span:nth-child(3)').text().trim()).equals(state.activeResource.children[rowIndex].children[i].name.executableName); expect(row.find('span:nth-child(4)').text().trim()).equals(transform(state.activeResource.children[rowIndex].children[i].value)); + const actual = row.find('span:nth-child(3)').text().trim(); + const expected = state.activeResource.children[rowIndex].children[i].name.executableName; + if (actual.length < expected.length) { + expect(expected.startsWith(actual.slice(0, actual.length - 3))).to.be.true; + } else { + expect(actual).equals(expected); + } }) .get('app-memory-resources-toolbar .fx-row-vert-cent .fx-row-vert-cent:nth-child(1) > span') .click() .wait(500) .get('app-memory-resources-table .row:not(.head)') .each((row: any, i: number) => { - expect(row.find('span:nth-child(3)').text().trim()).equals(state.activeResource.children[i].name.executableName); + const actual = row.find('span:nth-child(3)').text().trim(); + const expected = state.activeResource.children[i].name.executableName; + if (actual.length < expected.length) { + expect(expected.startsWith(actual.slice(0, actual.length - 3))).to.be.true; + } else { + expect(actual).equals(expected); + } expect(row.find('span:nth-child(4)').text().trim()).equals(transform(state.activeResource.children[i].value)); }); } @@ -261,15 +279,28 @@ describe('MEMORY RESOURCES TABLE', () => { .wait(500) .get(`app-memory-resources-table .row:not(.head)`) .each((row: any, i: number) => { - expect(row.find('span:nth-child(3)').text().trim()).equals(state.activeResource.children[rowIndex].children[i].name.executableName); expect(row.find('span:nth-child(4)').text().trim()).equals(transform(state.activeResource.children[rowIndex].children[i].value)); + const actual = row.find('span:nth-child(3)').text().trim(); + const expected = state.activeResource.children[rowIndex].children[i].name.executableName; + if (actual.length < expected.length) { + expect(expected.startsWith(actual.slice(0, actual.length - 3))).to.be.true; + } else { + expect(actual).equals(expected); + } }) .get('body') .type('{esc}') .wait(500) .get('app-memory-resources-table .row:not(.head)') .each((row: any, i: number) => { - expect(row.find('span:nth-child(3)').text().trim()).equals(state.activeResource.children[i].name.executableName); + const actual = row.find('span:nth-child(3)').text().trim(); + const expected = state.activeResource.children[i].name.executableName; + if (actual.length < expected.length) { + expect(expected.startsWith(actual.slice(0, actual.length - 3))).to.be.true; + } else { + expect(actual).equals(expected); + } + expect(row.find('span:nth-child(4)').text().trim()).equals(transform(state.activeResource.children[i].value)); }); } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b52d01b46..241caafc8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -24,6 +24,8 @@ "@ngrx/store": "^16.2.0", "@openmina/shared": "^0.60.0", "d3": "^7.8.4", + "eigen": "^0.2.2", + "mathjs": "^12.3.0", "ngx-json-viewer": "^3.2.1", "rxjs": "~7.8.0", "tslib": "^2.3.0", @@ -4821,6 +4823,11 @@ "integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==", "dev": true }, + "node_modules/@types/hashmap": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/hashmap/-/hashmap-2.3.4.tgz", + "integrity": "sha512-IoFSb7S7cwCM23HcAhUS57DBWPU0dPSF6Wz4M4y0S+B1xgGmM08WOzd1wBldesmZ28jhzRNmXda/FO5uY3tLlw==" + }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -6404,6 +6411,18 @@ "node": ">=4.0.0" } }, + "node_modules/complex.js": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", + "integrity": "sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -7618,8 +7637,7 @@ "node_modules/decimal.js": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, "node_modules/default-gateway": { "version": "6.0.3", @@ -7878,6 +7896,15 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, + "node_modules/eigen": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/eigen/-/eigen-0.2.2.tgz", + "integrity": "sha512-M+g7PKbPTJmQFOl60PYj0/jfU43qyuFrrPHZJCQYxfprV6jwRVaVHFJLhGH+eG8y9W/I/YjwzJTmIWLdLv2o2g==", + "dependencies": { + "@types/hashmap": "^2.3.1", + "hashmap": "^2.4.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.601", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.601.tgz", @@ -8142,6 +8169,11 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, + "node_modules/escape-latex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/escape-latex/-/escape-latex-1.2.0.tgz", + "integrity": "sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==" + }, "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -9155,6 +9187,14 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, + "node_modules/hashmap": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/hashmap/-/hashmap-2.4.0.tgz", + "integrity": "sha512-Ngj48lhnxJdnBAEVbubKBJuN1elfVLZJs94ZixRi98X3GCU4v6pgj9qRkHt6H8WaVJ69Wv0r1GhtS7hvF9zCgg==", + "engines": { + "node": "*" + } + }, "node_modules/hasown": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", @@ -10123,6 +10163,11 @@ "integrity": "sha512-O236+gd0ZXS8YAjFx8xKaJ94/erqUliEkJTDedyE7iHvv4ZVqi+q+8acJxu05/WJDKm512EUNn809In37nWlAQ==", "dev": true }, + "node_modules/javascript-natural-sort": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", + "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==" + }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", @@ -11159,6 +11204,56 @@ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, + "node_modules/mathjs": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-12.3.0.tgz", + "integrity": "sha512-Mik+O8gbH14/1V2D/vdJNgu+qGXpF+2oeBJVBqN8nbOdZNuu4Nxw6aDbJ0QOkDSq/9bQ+AZpXoIxBuErRODS8w==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "complex.js": "^2.1.1", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "4.3.4", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.1.1" + }, + "bin": { + "mathjs": "bin/cli.js" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mathjs/node_modules/@babel/runtime": { + "version": "7.23.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", + "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/mathjs/node_modules/fraction.js": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.4.tgz", + "integrity": "sha512-pwiTgt0Q7t+GHZA4yaLjObx4vXmmdcS0iSJ19o8d/goUGgItX9UZWKWNnLHehxviD8wU2IWRsnR8cD5+yOJP2Q==", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/mathjs/node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -13526,6 +13621,11 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==" + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -14649,6 +14749,11 @@ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "node_modules/tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -14963,6 +15068,14 @@ "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", "dev": true }, + "node_modules/typed-function": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.1.1.tgz", + "integrity": "sha512-Pq1DVubcvibmm8bYcMowjVnnMwPVMeh0DIdA8ad8NZY2sJgapANJmiigSUwlt+EgXxpfIv8MWrQXTIzkfYZLYQ==", + "engines": { + "node": ">= 14" + } + }, "node_modules/typescript": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", diff --git a/frontend/package.json b/frontend/package.json index a53458362..c2af93a95 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,7 +3,7 @@ "version": "0.1", "scripts": { "ng": "ng", - "start": "ng serve --configuration local", + "start": "ng serve --configuration local --open", "start:dev": "ng serve --configuration development", "build": "ng build", "build:prod": "ng build --configuration production", @@ -30,6 +30,8 @@ "@ngrx/store": "^16.2.0", "@openmina/shared": "^0.60.0", "d3": "^7.8.4", + "eigen": "^0.2.2", + "mathjs": "^12.3.0", "ngx-json-viewer": "^3.2.1", "rxjs": "~7.8.0", "tslib": "^2.3.0", diff --git a/frontend/src/app/features/network/network.reducer.ts b/frontend/src/app/features/network/network.reducer.ts index a4d744d79..c636c5b25 100644 --- a/frontend/src/app/features/network/network.reducer.ts +++ b/frontend/src/app/features/network/network.reducer.ts @@ -8,6 +8,7 @@ import * as fromBlocks from '@network/blocks/network-blocks.reducer'; import { NetworkMessagesAction, NetworkMessagesActions } from '@network/messages/network-messages.actions'; import { NetworkConnectionsAction, NetworkConnectionsActions } from '@network/connections/network-connections.actions'; import { NetworkBlocksAction, NetworkBlocksActions } from '@network/blocks/network-blocks.actions'; +import { topologyReducer } from '@network/splits/dashboard-splits.reducer'; export type NetworkActions = NetworkMessagesActions & NetworkConnectionsActions & NetworkBlocksActions; export type NetworkAction = NetworkMessagesAction & NetworkConnectionsAction & NetworkBlocksAction; @@ -16,4 +17,5 @@ export const networkReducer: ActionReducer = combi messages: fromMessages.reducer, connections: fromConnections.reducer, blocks: fromBlocks.reducer, + splits: topologyReducer, }); diff --git a/frontend/src/app/features/network/network.routing.ts b/frontend/src/app/features/network/network.routing.ts index ab1b5dbe9..eee3298e4 100644 --- a/frontend/src/app/features/network/network.routing.ts +++ b/frontend/src/app/features/network/network.routing.ts @@ -23,6 +23,16 @@ const routes: Routes = [ loadChildren: () => import('./blocks/network-blocks.module').then(m => m.NetworkBlocksModule), title: NETWORK_TITLE, }, + { + path: 'topology', + loadChildren: () => import('./splits/dashboard-splits.module').then(m => m.DashboardSplitsModule), + title: NETWORK_TITLE, + }, + { + path: 'node-dht', + loadChildren: () => import('./node-dht/node-dht.module').then(m => m.NodeDhtModule), + title: NETWORK_TITLE, + }, { path: '**', redirectTo: 'messages', diff --git a/frontend/src/app/features/network/network.state.ts b/frontend/src/app/features/network/network.state.ts index a3ac1c031..2665694b6 100644 --- a/frontend/src/app/features/network/network.state.ts +++ b/frontend/src/app/features/network/network.state.ts @@ -3,11 +3,13 @@ import { createFeatureSelector, createSelector, MemoizedSelector } from '@ngrx/s import { NetworkMessagesState } from '@network/messages/network-messages.state'; import { NetworkConnectionsState } from '@network/connections/network-connections.state'; import { NetworkBlocksState } from '@network/blocks/network-blocks.state'; +import { DashboardSplitsState } from '@network/splits/dashboard-splits.state'; export interface NetworkState { messages: NetworkMessagesState; connections: NetworkConnectionsState; blocks: NetworkBlocksState; + splits: DashboardSplitsState; } const select = (selector: (state: NetworkState) => T): MemoizedSelector => createSelector( @@ -19,3 +21,4 @@ export const selectNetworkState = createFeatureSelector('network') export const selectNetworkMessagesState = select((state: NetworkState): NetworkMessagesState => state.messages); export const selectNetworkConnectionsState = select((state: NetworkState): NetworkConnectionsState => state.connections); export const selectNetworkBlocksState = select((state: NetworkState): NetworkBlocksState => state.blocks); +export const selectDashboardSplitsState = select((state: NetworkState): DashboardSplitsState => state.splits); diff --git a/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.html b/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.html new file mode 100644 index 000000000..153712039 --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.html @@ -0,0 +1,12 @@ +
+ Communication with 1110110101 + close + +
+
+
+
FIND NODE
+
3m ago
+
+
diff --git a/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.scss b/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.ts b/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.ts new file mode 100644 index 000000000..948b1c862 --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht-side-panel/node-dht-side-panel.component.ts @@ -0,0 +1,14 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; + +@Component({ + selector: 'app-node-dht-side-panel', + templateUrl: './node-dht-side-panel.component.html', + styleUrls: ['./node-dht-side-panel.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class NodeDhtSidePanelComponent { + + closeSidePanel() { + + } +} diff --git a/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.html b/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.html new file mode 100644 index 000000000..789e8b06b --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.html @@ -0,0 +1,14 @@ + + + + + + {{ row.peerStatus }} + + {{ row.id }} + {{ row.address }} + {{ row.lastUpdate }} + {{ row.xorDistance }} + {{ row.bucketRange }} + {{ row.bucketCapacity }} + diff --git a/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.scss b/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.scss new file mode 100644 index 000000000..78c310f45 --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.scss @@ -0,0 +1,22 @@ +@import 'openmina'; + +.green { + color: $success-primary; +} + +.circle { + width: 10px; + height: 10px; + border-radius: 12px; + background-color: $base-tertiary; + + &.Connected { + background-color: $success-primary; + } +} + +:host ::ng-deep mina-table .row.active { + .circle { + background-color: $selected-primary !important; + } +} diff --git a/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.ts b/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.ts new file mode 100644 index 000000000..058e5818a --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht-table/node-dht-table.component.ts @@ -0,0 +1,89 @@ +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { MinaTableRustWrapper } from '@shared/base-classes/mina-table-rust-wrapper.class'; +import { TableColumnList } from '@openmina/shared'; +import { Router } from '@angular/router'; + +export interface NetworkNodeDHT { + peerStatus: string; + id: string; + address: string; + lastUpdate: string; + xorDistance: string; + bucketRange: string; + bucketCapacity: string; +} + +@Component({ + selector: 'app-node-dht-table', + templateUrl: './node-dht-table.component.html', + styleUrls: ['./node-dht-table.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'flex-column h-100' }, +}) +export class NodeDhtTableComponent extends MinaTableRustWrapper implements OnInit { + + protected readonly tableHeads: TableColumnList = [ + { name: 'peer status' }, + { name: 'id' }, + { name: 'address' }, + { name: 'last update' }, + { name: 'XOR distance' }, + { name: 'bucket range' }, + { name: 'bucket capacity' }, + ]; + + rows: NetworkNodeDHT[] = []; + activeRow: NetworkNodeDHT; + + constructor(private router: Router) { super(); } + + override async ngOnInit(): Promise { + await super.ngOnInit(); + this.listenToNetworkConnectionsChanges(); + this.listenToActiveRowChange(); + } + + protected override setupTable(): void { + this.table.gridTemplateColumns = [140, 110, 165, 110, 100, 120, 110]; + this.table.propertyForActiveCheck = 'id'; + } + + private listenToNetworkConnectionsChanges(): void { + const rows: NetworkNodeDHT[] = [ + //@formatter:off + { peerStatus: 'Connected', id: '10101001011', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '8', bucketRange: '1-2', bucketCapacity: '3' }, + { peerStatus: 'Connected', id: '010101010101', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '8', bucketRange: '1-2', bucketCapacity: '5' }, + { peerStatus: 'Connected', id: '0100000100', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '8', bucketRange: '1-2', bucketCapacity: '4' }, + { peerStatus: 'Connected', id: '1010101111', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '1', bucketRange: '1-2', bucketCapacity: '4' }, + { peerStatus: 'Discovered', id: '1110110101', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '7', bucketRange: '1-2', bucketCapacity: '4' }, + { peerStatus: 'Connected', id: '0010100000', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '8', bucketRange: '1-2', bucketCapacity: '2' }, + { peerStatus: 'Connected', id: '0101000010', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '8', bucketRange: '1-2', bucketCapacity: '4' }, + { peerStatus: 'Connected', id: '101010101010', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '8', bucketRange: '1-2', bucketCapacity: '1' }, + { peerStatus: 'Discovered', id: '0011010101', address: '2432.53.36.45:8302', lastUpdate: '2m ago', xorDistance: '10', bucketRange: '1-2', bucketCapacity: '4' }, + { peerStatus: 'Discovered', id: '11111010101', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '2', bucketRange: '1-3', bucketCapacity: '7' }, + { peerStatus: 'Connected', id: '111010111', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '2', bucketRange: '1-3', bucketCapacity: '7' }, + { peerStatus: 'Discovered', id: '0001010100', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '2', bucketRange: '1-3', bucketCapacity: '7' }, + { peerStatus: 'Connected', id: '01000010101', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '2', bucketRange: '1-3', bucketCapacity: '7' }, + { peerStatus: 'Connected', id: '001010001', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '2', bucketRange: '1-3', bucketCapacity: '7' }, + { peerStatus: 'Discovered', id: '0100010101', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '4', bucketRange: '1-3', bucketCapacity: '11' }, + { peerStatus: 'Connected', id: '011010101', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '5', bucketRange: '1-3', bucketCapacity: '33' }, + { peerStatus: 'Connected', id: '101010010', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '2', bucketRange: '1-3', bucketCapacity: '7' }, + { peerStatus: 'Connected', id: '00001010', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '22', bucketRange: '1-3', bucketCapacity: '9' }, + { peerStatus: 'Discovered', id: '0101001', address: '2432.24.36.45:8302', lastUpdate: '4m ago', xorDistance: '2', bucketRange: '1-3', bucketCapacity: '6' }, + { peerStatus: 'Discovered', id: '1010011001', address: '2432.25.36.45:8302', lastUpdate: '4m ago', xorDistance: '1', bucketRange: '1-3', bucketCapacity: '8' }, + ]; + this.rows = rows; + this.table.rows = rows; + this.table.detect(); + } + + private listenToActiveRowChange(): void { + this.activeRow = this.rows[4]; + this.table.activeRow = this.activeRow; + } + + protected override onRowClick(row: NetworkNodeDHT): void { + this.activeRow = row; + this.table.activeRow = this.activeRow; + } +} diff --git a/frontend/src/app/features/network/node-dht/node-dht.component.html b/frontend/src/app/features/network/node-dht/node-dht.component.html new file mode 100644 index 000000000..2a01523e1 --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht.component.html @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/frontend/src/app/features/network/node-dht/node-dht.component.scss b/frontend/src/app/features/network/node-dht/node-dht.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/features/network/node-dht/node-dht.component.ts b/frontend/src/app/features/network/node-dht/node-dht.component.ts new file mode 100644 index 000000000..0191c8e09 --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht.component.ts @@ -0,0 +1,15 @@ +import { ChangeDetectionStrategy, Component, ElementRef, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-node-dht', + templateUrl: './node-dht.component.html', + styleUrls: ['./node-dht.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class NodeDhtComponent implements OnInit { + + constructor(public el: ElementRef) { } + + ngOnInit(): void { + } +} diff --git a/frontend/src/app/features/network/node-dht/node-dht.module.ts b/frontend/src/app/features/network/node-dht/node-dht.module.ts new file mode 100644 index 000000000..8cda31728 --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht.module.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; + +import { NodeDhtRouting } from './node-dht.routing'; +import { NodeDhtTableComponent } from './node-dht-table/node-dht-table.component'; +import { NodeDhtSidePanelComponent } from './node-dht-side-panel/node-dht-side-panel.component'; +import { SharedModule } from '@shared/shared.module'; +import { NodeDhtComponent } from '@network/node-dht/node-dht.component'; +import { HorizontalResizableContainerComponent, MinaJsonViewerComponent } from '@openmina/shared'; + + +@NgModule({ + declarations: [ + NodeDhtComponent, + NodeDhtTableComponent, + NodeDhtSidePanelComponent, + ], + imports: [ + SharedModule, + NodeDhtRouting, + HorizontalResizableContainerComponent, + MinaJsonViewerComponent, + ], +}) +export class NodeDhtModule {} diff --git a/frontend/src/app/features/network/node-dht/node-dht.routing.ts b/frontend/src/app/features/network/node-dht/node-dht.routing.ts new file mode 100644 index 000000000..288d3d656 --- /dev/null +++ b/frontend/src/app/features/network/node-dht/node-dht.routing.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { NodeDhtComponent } from '@network/node-dht/node-dht.component'; + +const routes: Routes = [ + { + path: '', + component: NodeDhtComponent, + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class NodeDhtRouting {} diff --git a/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.html b/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.html new file mode 100644 index 000000000..fa7f33a39 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.html @@ -0,0 +1,14 @@ +
+
+ + + +
+ +
diff --git a/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.scss b/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.scss new file mode 100644 index 000000000..aa6315f8b --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.scss @@ -0,0 +1,7 @@ +@import 'openmina'; + +:host ::ng-deep { + svg g:not(.links) > * { + cursor: pointer; + } +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.ts b/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.ts new file mode 100644 index 000000000..755b73c63 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-graph/dashboard-splits-graph.component.ts @@ -0,0 +1,408 @@ +import { ChangeDetectionStrategy, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import * as d3 from 'd3'; +import { Simulation } from 'd3'; +import { delay, filter, tap } from 'rxjs'; +import { zoom } from 'd3-zoom'; +import { SimulationNodeDatum } from 'd3-force'; +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class'; +import { DashboardSplitsLink } from '@shared/types/network/splits/dashboard-splits-link.type'; +import { + selectDashboardSplitsActivePeer, + selectDashboardSplitsOpenSidePanel, + selectDashboardSplitsPeersAndLinksAndSetsAndFetching, +} from '@network/splits/dashboard-splits.state'; +import { DashboardSplitsSet } from '@shared/types/network/splits/dashboard-splits-set.type'; +import { DashboardSplitsSetActivePeer } from '@network/splits/dashboard-splits.actions'; +import { eigs } from 'mathjs'; +import * as math from 'mathjs'; + +type DashboardSplitsPeerSimulation = DashboardSplitsPeer & SimulationNodeDatum; +type DashboardSplitsLinkSimulation = { + index?: number, + source: DashboardSplitsPeerSimulation, + target: DashboardSplitsPeerSimulation, +} + +@Component({ + selector: 'mina-dashboard-splits-graph', + templateUrl: './dashboard-splits-graph.component.html', + styleUrls: ['./dashboard-splits-graph.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'flex-column h-minus-xl w-100' }, +}) +export class DashboardSplitsGraphComponent extends StoreDispatcher implements OnInit { + + @ViewChild('chart', { static: true }) private chart: ElementRef; + @ViewChild('tooltip', { static: true }) private tooltipRef: ElementRef; + + private width: number; + private height: number; + private svg: d3.Selection; + private tooltip: d3.Selection; + private simulation: Simulation; + private circles: d3.Selection; + private triangles: d3.Selection; + private squares: d3.Selection; + private diamonds: d3.Selection; + private hoveredConnectedLinks: d3.Selection; + private clickedConnectedLinks: d3.Selection; + private connections: d3.Selection; + private zoom: d3.ZoomBehavior; + private activePeer: DashboardSplitsPeer; + private peers: DashboardSplitsPeer[] = []; + private links: DashboardSplitsLink[] = []; + private fetching: boolean = true; + + ngOnInit(): void { + this.listenToActivePeerChanges(); + this.listenToPeersLinksSets(); + this.listenToSidePanelToggling(); + this.width = this.chart.nativeElement.offsetWidth; + this.height = this.chart.nativeElement.offsetHeight; + this.tooltip = d3.select(this.tooltipRef.nativeElement); + this.svg = d3.select(this.chart.nativeElement) + .append('svg') + .attr('width', this.width) + .attr('height', this.height); + + this.zoom = zoom() + .scaleExtent([0.1, 10]) + .on('zoom', (event: any) => { + const { transform } = event; + this.svg.selectAll('g').attr('transform', transform); + }); + this.svg.call(this.zoom as any); + } + + private listenToSidePanelToggling(): void { + this.select(selectDashboardSplitsOpenSidePanel, () => { + this.svg?.attr('width', this.chart.nativeElement.offsetWidth); + }, delay(350)); + } + + private listenToPeersLinksSets() { + this.select(selectDashboardSplitsPeersAndLinksAndSetsAndFetching, async ({ peers, links, sets, fetching }) => { + this.fetching = fetching; + this.peers = peers; + this.links = links; + + // Step 1: Determine the number of vertices + const addresses: string[] = [ + ...new Set([ + ...links.flatMap((link: any) => [link.source, link.target]), + ...peers.map((node: any) => node.address), + ]), + ]; + const numVertices: number = addresses.length; + + // Step 2: Initialize the adjacency matrix + const adjacencyMatrix: number[][] = Array.from({ length: numVertices }, () => + Array.from({ length: numVertices }, () => 0) + ); + + // Step 3: Populate the adjacency matrix + links.forEach((link: any) => { + const sourceIndex = addresses.indexOf(link.source); + const targetIndex = addresses.indexOf(link.target); + + // Check if source and target addresses exist in the data array + if (sourceIndex !== -1 && targetIndex !== -1) { + adjacencyMatrix[sourceIndex][targetIndex] = 1; + adjacencyMatrix[targetIndex][sourceIndex] = 1; + } + }); + + const degreeMatrix: number[][] = Array.from({ length: numVertices }, () => + Array.from({ length: numVertices }, () => 0) + ); + + adjacencyMatrix.forEach((row, rowIndex) => { + const degree = row.reduce((sum, value) => sum + value, 0); + degreeMatrix[rowIndex][rowIndex] = degree; + }); + + const laplacianMatrix: number[][] = degreeMatrix.map((row, i) => + row.map((val, j) => (i === j ? row.reduce((acc, cur, k) => acc + adjacencyMatrix[i][k], 0) : (adjacencyMatrix[i][j] === 0 ? 0 : -adjacencyMatrix[i][j]))), + ); + console.log('Laplacian Matrix:', laplacianMatrix); + + // check is same as localstorage + let item = localStorage.getItem('laplacianMatrix'); + if (item) { + let storedMatrix = JSON.parse(item); + let storedMatrixString = JSON.stringify(storedMatrix); + let laplacianMatrixString = JSON.stringify(laplacianMatrix); + if (storedMatrixString === laplacianMatrixString) { + console.log('Laplacian Matrix is the same as the stored one'); + } else { + console.log('Laplacian Matrix is different from the stored one'); + } + } + localStorage.setItem('laplacianMatrix', JSON.stringify(laplacianMatrix)); + + const computeEigenvalues = async (matrix: number[][]): Promise => { + return eigs(matrix).values as number[]; + }; +// Step 2: Compute the eigenvalues of the Laplacian matrix + const eigenvalues: number[] = await computeEigenvalues(laplacianMatrix); // Use an appropriate method to compute eigenvalues + + console.log('Eigenvalues:', eigenvalues); +// Step 3: Sort the eigenvalues + const sortedEigenvalues: number[] = eigenvalues.sort((a, b) => a - b); + +// Step 4: Calculate the spectral gap + const spectralGap: number = sortedEigenvalues[1] - sortedEigenvalues[0]; + + console.log('Spectral Gap:', spectralGap); + + this.renderGraph({ peers, links, sets }); + }, tap(({ fetching }) => { + if (fetching) { + this.fetching = fetching; + } + }), + filter(({ peers, links, fetching }) => peers.length > 0 && links.length > 0 && (this.fetching && !fetching)), + ); + } + + private listenToActivePeerChanges(): void { + this.select(selectDashboardSplitsActivePeer, (activePeer: DashboardSplitsPeer) => { + if (activePeer) { + this.highlightPeer(activePeer); + } else { + this.removeHighlight(); + } + this.activePeer = activePeer; + }); + } + + private highlightPeer(activePeer: DashboardSplitsPeer): void { + this.removeHighlight(); + const addNewColors = (selection: d3.Selection) => { + selection.filter((peer: DashboardSplitsPeerSimulation) => peer.address === activePeer.address) + .attr('fill', 'var(--selected-primary)') + .attr('stroke', (d: DashboardSplitsPeerSimulation) => `var(--${this.links.some(link => link.source === d.address || link.target === d.address) ? 'selected' : 'warn'}-primary)`); + }; + addNewColors(this.circles); + addNewColors(this.triangles); + addNewColors(this.squares); + addNewColors(this.diamonds); + this.clickedConnectedLinks = this.connections.filter((link: DashboardSplitsLinkSimulation) => link.source.address === activePeer.address || link.target.address === activePeer.address); + this.clickedConnectedLinks.attr('stroke', 'var(--selected-primary)'); + } + + private removeHighlight(): void { + if (!this.activePeer) { + return; + } + const addInitialColors = (selection: d3.Selection) => { + selection.filter((peer: DashboardSplitsPeerSimulation) => peer.address === this.activePeer.address) + .attr('fill', 'var(--special-node)') + .attr('stroke', (d: DashboardSplitsPeerSimulation) => `var(--${this.links.some(link => link.source === d.address || link.target === d.address) ? 'success' : 'warn'}-primary)`); + }; + addInitialColors(this.circles); + addInitialColors(this.triangles); + addInitialColors(this.squares); + addInitialColors(this.diamonds); + this.clickedConnectedLinks.attr('stroke', 'var(--base-divider)'); + } + + zoomIn(): void { + this.svg.transition().duration(500).call(this.zoom.scaleBy as any, 1.5); + } + + zoomOut(): void { + this.svg.transition().duration(500).call(this.zoom.scaleBy as any, 0.5); + } + + zoomReset(): void { + this.svg.transition().duration(500).call(this.zoom.transform as any, d3.zoomIdentity); + } + + private renderGraph({ peers, links, sets }: { peers: DashboardSplitsPeer[], links: DashboardSplitsLink[], sets: DashboardSplitsSet[] }): void { + const nodes: DashboardSplitsPeerSimulation[] = peers.map(peer => ({ ...peer })); + let lines: DashboardSplitsLinkSimulation[] = []; + links.forEach(link => { + const line = { + source: nodes.find(node => node.address === link.source), + target: nodes.find(node => node.address === link.target), + }; + const mutualConnection = lines.some(l => l.source.address === line.target.address && l.target.address === line.source.address); + const sameConnection = lines.some(l => l.source.address === line.source.address && l.target.address === line.target.address); + if (!mutualConnection && !sameConnection) { + lines.push(line); + } + }); + this.createSimulation(sets, nodes, lines); + + this.connections = this.getG('links', 'line') + .selectAll('line') + .data(lines) + .enter() + .append('line') + .attr('class', d => `link ${d.source.address} ${d.target.address}`) + .attr('stroke', 'var(--base-divider)'); + + const circleNodes = nodes.filter(peer => !peer.node || ['node', 'generator'].some(n => peer.node.toLowerCase().includes(n))); + const triangleNodes = nodes.filter(p => p.node).filter(peer => peer.node.toLowerCase().includes('snark')); + const squareNodes = nodes.filter(p => p.node).filter(peer => peer.node.toLowerCase().includes('prod')); + const diamondNodes = nodes.filter(p => p.node).filter(peer => peer.node.toLowerCase().includes('seed')); + + this.circles = this.getG('circles', 'circle') + .attr('class', 'circles') + .selectAll('circle') + .data(circleNodes) + .enter() + .append('circle') + .attr('r', (d: DashboardSplitsPeerSimulation) => d.radius); + this.addCommonProperties(this.circles, lines); + + this.triangles = this.getG('triangles', 'path') + .attr('class', 'triangles') + .selectAll('path') + .data(triangleNodes) + .enter() + .append('path') + .attr('d', d3.symbol().type(d3.symbolTriangle2).size(d => d.radius * 20)); + this.addCommonProperties(this.triangles, lines); + + this.squares = this.getG('squares', 'rect') + .attr('class', 'squares') + .selectAll('rect') + .data(squareNodes) + .enter() + .append('rect') + .attr('width', (d: DashboardSplitsPeerSimulation) => d.radius * 2) + .attr('height', (d: DashboardSplitsPeerSimulation) => d.radius * 2); + this.addCommonProperties(this.squares, lines); + + this.diamonds = this.getG('diamonds', 'path') + .attr('class', 'diamonds') + .selectAll('path') + .data(diamondNodes) + .enter() + .append('path') + .attr('d', d3.symbol().type(d3.symbolDiamond2).size(d => d.radius * 20)); + this.addCommonProperties(this.diamonds, lines); + } + + private createSimulation(sets: DashboardSplitsSet[], nodes: DashboardSplitsPeerSimulation[], lines: DashboardSplitsLinkSimulation[]): void { + const numberOfSets = sets.length; + const matrixSize = Math.ceil(Math.sqrt(numberOfSets)); + this.simulation = d3.forceSimulation(nodes) + .force('link', d3.forceLink(lines).distance(numberOfSets === 1 ? 250 : 100)) // This adds links between nodes and sets the distance between them + .force('charge', d3.forceManyBody().strength(-30)) // control the repulsion between groups - negative means bigger distance + .force('x', d3.forceX().x((d: DashboardSplitsPeerSimulation) => { + for (let i = 0; i < numberOfSets; i++) { + if (sets[i].peers.some(p => p.address === d.address)) { + return (i % matrixSize) * this.width / matrixSize; + } + } + return this.width; + }).strength(0.05)) + .force('y', d3.forceY().y((d: DashboardSplitsPeerSimulation) => { + for (let i = 0; i < numberOfSets; i++) { + if (sets[i].peers.some(p => p.address === d.address)) { + return Math.floor(i / matrixSize) * this.height / matrixSize; + } + } + return this.height; + }).strength(0.05)) + .force('collide', d3.forceCollide().radius(numberOfSets < 3 ? 25 : 17)) // This adds repulsion between nodes. Play with the radius + .force('center', d3.forceCenter(this.width / 2, this.height / 2)) + .force('bounds', () => { + for (let node of nodes) { + const minAllowedX = node.x < 0 ? -node.x : node.x; + const minAllowedY = node.y < 0 ? -node.y : node.y; + const maxAllowedX = node.x > this.width ? this.width - (node.x - this.width) : node.x; + const maxAllowedY = node.y > this.height ? this.height - (node.y - this.height) : node.y; + node.x = Math.min(maxAllowedX, minAllowedX); + node.y = Math.min(maxAllowedY, minAllowedY); + } + }); + + this.simulation.on('tick', () => { + this.connections.attr('x1', (d: DashboardSplitsLinkSimulation) => d.source.x) + .attr('y1', (d: DashboardSplitsLinkSimulation) => d.source.y) + .attr('x2', (d: DashboardSplitsLinkSimulation) => d.target.x) + .attr('y2', (d: DashboardSplitsLinkSimulation) => d.target.y); + this.circles + .attr('cx', (d: DashboardSplitsPeerSimulation) => d.x) + .attr('cy', (d: DashboardSplitsPeerSimulation) => d.y); + this.triangles + .attr('transform', (d: DashboardSplitsPeerSimulation) => `translate(${d.x}, ${d.y})`); + this.squares + .attr('x', (d: DashboardSplitsPeerSimulation) => d.x - d.radius) + .attr('y', (d: DashboardSplitsPeerSimulation) => d.y - d.radius); + this.diamonds + .attr('transform', (d: DashboardSplitsPeerSimulation) => `translate(${d.x}, ${d.y})`); + }); + + for (let i = 0; i < 20; ++i) { + this.simulation.tick(); + } + this.simulation.alpha(0.1); // controls how much the animation lasts + } + + private addCommonProperties(selection: d3.Selection, lines: DashboardSplitsLinkSimulation[]): void { + selection + .attr('fill', 'var(--special-node)') + .attr('stroke', (d: DashboardSplitsPeerSimulation) => `var(--${lines.some(link => link.source.address === d.address || link.target.address === d.address) ? 'success' : 'warn'}-primary)`) + .attr('stroke-width', 1) + .on('mouseover', (event: MouseEvent & { target: HTMLElement }, peer: DashboardSplitsPeerSimulation) => this.mouseOverHandle(peer, event)) + .on('mouseout', (event: MouseEvent & { target: HTMLElement }, peer: DashboardSplitsPeerSimulation) => this.mouseOutHandler(peer, event)) + .on('click', (event: MouseEvent & { target: HTMLElement }, peer: DashboardSplitsPeerSimulation) => { + let selectedPeer = this.peers.find(p => p.address === peer.address); + if (selectedPeer === this.activePeer) { + selectedPeer = undefined; + } + this.dispatch(DashboardSplitsSetActivePeer, selectedPeer); + }); + } + + private getG(cls: string, subItem: string): d3.Selection { + const selection = this.svg.select('g.' + cls); + if (selection.size() > 0) { + this.svg.selectAll('g.' + cls + ' ' + subItem).remove(); + return selection; + } + return this.svg.append('g') + .attr('class', cls); + } + + private mouseOverHandle(peer: DashboardSplitsPeerSimulation, event: MouseEvent & { target: HTMLElement }): void { + const selection = this.tooltip.html(`${peer.node || peer.address}, ${peer.incomingConnections} / ${peer.outgoingConnections} `) + .style('display', 'block'); + + const nodeRect = event.target.getBoundingClientRect(); + const tooltipWidth = selection.node().getBoundingClientRect().width; + + selection + .style('left', `${nodeRect.left + nodeRect.width / 2 - tooltipWidth / 2}px`) + .style('top', `${nodeRect.top - 50}px`); + + if (this.activePeer?.address === peer.address) { + return; + } + d3.select(event.target).attr('fill', 'var(--special-node-selected)'); + this.hoveredConnectedLinks = this.connections.filter(link => { + const isDirectConnection = link.source.address === peer.address || link.target.address === peer.address; + if (this.activePeer) { + return isDirectConnection && link.target.address !== this.activePeer.address && link.source.address !== this.activePeer.address; + } + return isDirectConnection; + }); + + this.hoveredConnectedLinks.attr('stroke', 'var(--success-primary)'); + } + + private mouseOutHandler(peer: DashboardSplitsPeerSimulation, event: MouseEvent & { target: HTMLElement }): void { + this.tooltip.style('display', 'none'); + if (this.activePeer?.address === peer.address) { + return; + } + d3.select(event.target).attr('fill', 'var(--special-node)'); + this.hoveredConnectedLinks.attr('stroke', 'var(--base-divider)'); + } +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.html b/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.html new file mode 100644 index 000000000..40eab500d --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.html @@ -0,0 +1,14 @@ + + + + + + + {{ row.node || '-' }} + + + + + {{ row.incomingConnections }} / {{ row.outgoingConnections }} + + diff --git a/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.scss b/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.ts b/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.ts new file mode 100644 index 000000000..f532cfedf --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component.ts @@ -0,0 +1,66 @@ +import { ChangeDetectionStrategy, Component, HostBinding, Input, OnInit } from '@angular/core'; +import { isDesktop, TableColumnList } from '@openmina/shared'; +import { Router } from '@angular/router'; +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { MinaTableRustWrapper } from '@shared/base-classes/mina-table-rust-wrapper.class'; +import { DashboardSplitsSetActivePeer, DashboardSplitsSortPeers } from '@network/splits/dashboard-splits.actions'; +import { selectDashboardSplitsActivePeer, selectDashboardSplitsSort } from '@network/splits/dashboard-splits.state'; +import { Routes } from '@shared/enums/routes.enum'; + +@Component({ + selector: 'mina-dashboard-splits-side-panel-table', + templateUrl: './dashboard-splits-side-panel-table.component.html', + styleUrls: ['./dashboard-splits-side-panel-table.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class DashboardSplitsSidePanelTableComponent extends MinaTableRustWrapper implements OnInit { + + @Input() peers: DashboardSplitsPeer[]; + @HostBinding('style.height.px') private height: number; + + protected readonly tableHeads: TableColumnList = [ + { name: 'address' }, + { name: 'name', sort: 'node' }, + { name: 'peer ID', sort: 'peerId' }, + { name: 'Conn. \nIn / Out', sort: 'outgoingConnections' }, + ]; + + private activePeer: DashboardSplitsPeer; + + constructor(private router: Router) { super(); } + + override async ngOnInit(): Promise { + this.height = isDesktop() ? ((this.peers.length + 1) * 36 +1) : ((this.peers.length) * 104) + 90; + await super.ngOnInit(); + this.listenToActivePeerChanges(); + } + + protected override setupTable(): void { + this.table.gridTemplateColumns = [115, 85, 80, '1fr']; + this.table.minWidth = 400; + this.table.sortClz = DashboardSplitsSortPeers; + this.table.sortSelector = selectDashboardSplitsSort; + this.table.rows = this.peers; + } + + protected override onRowClick(row: DashboardSplitsPeer): void { + if (row) { + this.router.navigate([Routes.NETWORK, Routes.TOPOLOGY, row.address]); + } + if (this.activePeer === row) { + this.router.navigate([Routes.NETWORK, Routes.TOPOLOGY]); + this.dispatch(DashboardSplitsSetActivePeer, undefined); + return; + } + this.dispatch(DashboardSplitsSetActivePeer, row); + } + + private listenToActivePeerChanges(): void { + this.select(selectDashboardSplitsActivePeer, (activePeer: DashboardSplitsPeer) => { + this.activePeer = activePeer; + this.table.activeRow = activePeer; + this.table.detect(); + this.detect(); + }); + } +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.html b/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.html new file mode 100644 index 000000000..ad91aacf3 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.html @@ -0,0 +1,27 @@ +
+ Nodes + close + +
+
+
+
+
+
+ Branch {{ i + 1 }} + {{ set.peers.length }} Nodes +
+ chevron_right + +
+ +
+
+
diff --git a/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.scss b/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.ts b/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.ts new file mode 100644 index 000000000..65ea6b6ff --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-side-panel/dashboard-splits-side-panel.component.ts @@ -0,0 +1,106 @@ +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { getMergedRoute, MergedRoute, toggleItem } from '@openmina/shared'; +import { Router } from '@angular/router'; +import { untilDestroyed } from '@ngneat/until-destroy'; +import { take } from 'rxjs'; +import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class'; +import { DashboardSplitsSet } from '@shared/types/network/splits/dashboard-splits-set.type'; +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { selectDashboardSplitsActivePeer, selectDashboardSplitsPeersAndSets } from '@network/splits/dashboard-splits.state'; +import { Routes } from '@shared/enums/routes.enum'; +import { DashboardSplitsSetActivePeer, DashboardSplitsToggleSidePanel } from '@network/splits/dashboard-splits.actions'; + +@Component({ + selector: 'mina-dashboard-splits-side-panel', + templateUrl: './dashboard-splits-side-panel.component.html', + styleUrls: ['./dashboard-splits-side-panel.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'flex-column h-100 w-100' }, +}) +export class DashboardSplitsSidePanelComponent extends StoreDispatcher implements OnInit { + + sets: DashboardSplitsSet[]; + expandedItems: number[] = []; + activePeer: DashboardSplitsPeer; + + private idFromRoute: string; + + constructor(private router: Router) {super();} + + ngOnInit(): void { + this.listenToRouteChange(); + this.selectSplitsPeersAndLinks(); + this.listenToActivePeerChanges(); + } + + private listenToRouteChange(): void { + this.store.select(getMergedRoute) + .pipe(untilDestroyed(this), take(1)) + .subscribe((route: MergedRoute) => { + if (route.params['addr']) { + this.idFromRoute = route.params['addr']; + } + }); + } + + private selectSplitsPeersAndLinks(): void { + this.select(selectDashboardSplitsPeersAndSets, ({ peers, sets }: { + peers: DashboardSplitsPeer[], + sets: DashboardSplitsSet[] + }) => { + this.sets = sets; + if (this.idFromRoute) { + const peer = peers.find((peer: DashboardSplitsPeer) => peer.address === this.idFromRoute); + if (peer) { + const setIndex = sets.findIndex((set: DashboardSplitsSet) => set.peers.includes(peer)); + this.toggleExpandedItems(setIndex); + this.selectPeer(peer); + delete this.idFromRoute; + } + } + if (sets.length === 1) { + this.expandedItems = [0]; + } + this.detect(); + }); + } + + private listenToActivePeerChanges(): void { + this.select(selectDashboardSplitsActivePeer, (activePeer: DashboardSplitsPeer) => { + this.activePeer = activePeer; + const activeSetIndex = this.sets.findIndex((set: DashboardSplitsSet) => set.peers.includes(activePeer)); + if (!this.expandedItems.includes(activeSetIndex)) { + this.expandedItems = toggleItem(this.expandedItems, activeSetIndex); + } + this.detect(); + }); + } + + toggleExpandedItems(i: number): void { + this.expandedItems = toggleItem(this.expandedItems, i); + if (this.activePeer) { + const index = this.expandedItems.indexOf(this.sets.findIndex((set: DashboardSplitsSet) => set.peers.includes(this.activePeer))); + if (index === -1) { + this.activePeer = undefined; + this.selectPeer(undefined); + } + } + this.detect(); + } + + selectPeer(peer: DashboardSplitsPeer): void { + if (peer) { + this.router.navigate([Routes.NETWORK, Routes.TOPOLOGY, peer.address]); + } + if (this.activePeer === peer) { + this.router.navigate([Routes.NETWORK, Routes.TOPOLOGY]); + this.dispatch(DashboardSplitsSetActivePeer, undefined); + return; + } + this.dispatch(DashboardSplitsSetActivePeer, peer); + } + + closeSidePanel(): void { + this.dispatch(DashboardSplitsToggleSidePanel); + } +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.html b/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.html new file mode 100644 index 000000000..3abc7e34b --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.html @@ -0,0 +1,49 @@ + + + +
+
+
{{ setsLength === undefined ? 'Loading ' : setsLength }} Branch{{ setsLength | plural: 'es' }}
+ + + +
+
+ crop_square + {{ stats.producers }} +  Producer{{ stats.producers | plural }} + crop_square + {{ stats.seeders }} +  Seeder{{ stats.seeders | plural }} + change_history + {{ stats.snarkers }} +  Snarker{{ stats.snarkers | plural }} + circle + {{ stats.nodes + stats.transactionGenerators }} +  Other +
+
+
diff --git a/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.scss b/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.ts b/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.ts new file mode 100644 index 000000000..7387df6f9 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits-toolbar/dashboard-splits-toolbar.component.ts @@ -0,0 +1,82 @@ +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { filter } from 'rxjs'; +import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class'; +import { DashboardSplitsSet } from '@shared/types/network/splits/dashboard-splits-set.type'; +import { DashboardNodeCount } from '@shared/types/network/splits/dashboard-node-count.type'; +import { selectLoadingStateLength } from '@app/layout/toolbar/loading.reducer'; +import { + selectDashboardSplitsNetworkMergeDetails, + selectDashboardSplitsNetworkSplitsDetails, + selectDashboardSplitsNodeStats, selectDashboardSplitsSets, +} from '@network/splits/dashboard-splits.state'; +import { DashboardSplitsGetSplits, DashboardSplitsMergeNodes, DashboardSplitsSplitNodes } from '@network/splits/dashboard-splits.actions'; + +@Component({ + selector: 'mina-dashboard-splits-toolbar', + templateUrl: './dashboard-splits-toolbar.component.html', + styleUrls: ['./dashboard-splits-toolbar.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'h-xl' }, +}) +export class DashboardSplitsToolbarComponent extends StoreDispatcher implements OnInit { + + setsLength: number; + sets: DashboardSplitsSet[] = []; + networkSplitTime: string; + networkMergeTime: string; + stats: DashboardNodeCount; + fetching: boolean; + + ngOnInit(): void { + this.listenToSetsChanges(); + this.listenToSplitTimeChanges(); + this.listenToMergeTimeChanges(); + this.listenToNodeStatsChanges(); + } + + private listenToSetsChanges(): void { + this.select(selectLoadingStateLength, (length: number) => { + this.fetching = length > 0; + this.detect(); + }, filter((length: number) => this.fetching !== (length > 0))); + + this.select(selectDashboardSplitsSets, (sets: DashboardSplitsSet[]) => { + this.setsLength = sets.length; + this.sets = sets; + this.detect(); + }, filter(sets => sets.length > 0)); + } + + private listenToSplitTimeChanges(): void { + this.select(selectDashboardSplitsNetworkSplitsDetails, (time: string) => { + this.networkSplitTime = time; + this.detect(); + }); + } + + private listenToMergeTimeChanges(): void { + this.select(selectDashboardSplitsNetworkMergeDetails, (time: string) => { + this.networkMergeTime = time; + this.detect(); + }); + } + + private listenToNodeStatsChanges(): void { + this.select(selectDashboardSplitsNodeStats, (stats: DashboardNodeCount) => { + this.stats = stats; + this.detect(); + }); + } + + splitNodes(): void { + this.dispatch(DashboardSplitsSplitNodes); + } + + refresh(): void { + this.dispatch(DashboardSplitsGetSplits); + } + + mergeNodes(): void { + this.dispatch(DashboardSplitsMergeNodes); + } +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits.actions.ts b/frontend/src/app/features/network/splits/dashboard-splits.actions.ts new file mode 100644 index 000000000..aa560fd9b --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.actions.ts @@ -0,0 +1,90 @@ +import { FeatureAction, TableSort } from '@openmina/shared'; +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { DashboardSplits } from '@shared/types/network/splits/dashboard-splits.type'; + +enum DashboardSplitsActionTypes { + DASHBOARD_SPLITS_CLOSE = 'DASHBOARD_SPLITS_CLOSE', + DASHBOARD_SPLITS_GET_SPLITS = 'DASHBOARD_SPLITS_GET_SPLITS', + DASHBOARD_SPLITS_GET_SPLITS_SUCCESS = 'DASHBOARD_SPLITS_GET_SPLITS_SUCCESS', + DASHBOARD_SPLITS_SET_ACTIVE_PEER = 'DASHBOARD_SPLITS_SET_ACTIVE_PEER', + DASHBOARD_SPLITS_SPLIT_NODES = 'DASHBOARD_SPLITS_SPLIT_NODES', + DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS = 'DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS', + DASHBOARD_SPLITS_MERGE_NODES = 'DASHBOARD_SPLITS_MERGE_NODES', + DASHBOARD_SPLITS_MERGE_NODES_SUCCESS = 'DASHBOARD_SPLITS_MERGE_NODES_SUCCESS', + DASHBOARD_SPLITS_SORT_PEERS = 'DASHBOARD_SPLITS_SORT_PEERS', + DASHBOARD_SPLITS_TOGGLE_SIDE_PANEL = 'DASHBOARD_SPLITS_TOGGLE_SIDE_PANEL', +} + +export const DASHBOARD_SPLITS_CLOSE = DashboardSplitsActionTypes.DASHBOARD_SPLITS_CLOSE; +export const DASHBOARD_SPLITS_GET_SPLITS = DashboardSplitsActionTypes.DASHBOARD_SPLITS_GET_SPLITS; +export const DASHBOARD_SPLITS_GET_SPLITS_SUCCESS = DashboardSplitsActionTypes.DASHBOARD_SPLITS_GET_SPLITS_SUCCESS; +export const DASHBOARD_SPLITS_SET_ACTIVE_PEER = DashboardSplitsActionTypes.DASHBOARD_SPLITS_SET_ACTIVE_PEER; +export const DASHBOARD_SPLITS_SPLIT_NODES = DashboardSplitsActionTypes.DASHBOARD_SPLITS_SPLIT_NODES; +export const DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS = DashboardSplitsActionTypes.DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS; +export const DASHBOARD_SPLITS_MERGE_NODES = DashboardSplitsActionTypes.DASHBOARD_SPLITS_MERGE_NODES; +export const DASHBOARD_SPLITS_MERGE_NODES_SUCCESS = DashboardSplitsActionTypes.DASHBOARD_SPLITS_MERGE_NODES_SUCCESS; +export const DASHBOARD_SPLITS_SORT_PEERS = DashboardSplitsActionTypes.DASHBOARD_SPLITS_SORT_PEERS; +export const DASHBOARD_SPLITS_TOGGLE_SIDE_PANEL = DashboardSplitsActionTypes.DASHBOARD_SPLITS_TOGGLE_SIDE_PANEL; + +export interface DashboardSplitsAction extends FeatureAction { + readonly type: DashboardSplitsActionTypes; +} + +export class DashboardSplitsClose implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_CLOSE; +} + +export class DashboardSplitsGetSplits implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_GET_SPLITS; +} + +export class DashboardSplitsGetSplitsSuccess implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_GET_SPLITS_SUCCESS; + + constructor(public payload: DashboardSplits) { } +} + +export class DashboardSplitsSetActivePeer implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_SET_ACTIVE_PEER; + + constructor(public payload: DashboardSplitsPeer) { } +} + +export class DashboardSplitsSplitNodes implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_SPLIT_NODES; +} + +export class DashboardSplitsMergeNodesSuccess implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_MERGE_NODES_SUCCESS; +} + +export class DashboardSplitsMergeNodes implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_MERGE_NODES; +} + +export class DashboardSplitsSplitNodesSuccess implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS; +} + +export class DashboardSplitsSortPeers implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_SORT_PEERS; + + constructor(public payload: TableSort) { } +} + +export class DashboardSplitsToggleSidePanel implements DashboardSplitsAction { + readonly type = DASHBOARD_SPLITS_TOGGLE_SIDE_PANEL; +} + +export type DashboardSplitsActions = + | DashboardSplitsClose + | DashboardSplitsGetSplits + | DashboardSplitsGetSplitsSuccess + | DashboardSplitsSetActivePeer + | DashboardSplitsSplitNodes + | DashboardSplitsSplitNodesSuccess + | DashboardSplitsMergeNodes + | DashboardSplitsMergeNodesSuccess + | DashboardSplitsSortPeers + | DashboardSplitsToggleSidePanel + ; diff --git a/frontend/src/app/features/network/splits/dashboard-splits.component.html b/frontend/src/app/features/network/splits/dashboard-splits.component.html new file mode 100644 index 000000000..a61259c91 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.component.html @@ -0,0 +1,19 @@ +
+ +
+ + +
+ + +
+
+ + + + diff --git a/frontend/src/app/features/network/splits/dashboard-splits.component.scss b/frontend/src/app/features/network/splits/dashboard-splits.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/frontend/src/app/features/network/splits/dashboard-splits.component.ts b/frontend/src/app/features/network/splits/dashboard-splits.component.ts new file mode 100644 index 000000000..c5b3e81bd --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.component.ts @@ -0,0 +1,33 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class'; +import { DashboardSplitsClose, DashboardSplitsGetSplits } from '@network/splits/dashboard-splits.actions'; +import { selectDashboardSplitsOpenSidePanel } from '@network/splits/dashboard-splits.state'; + +@Component({ + selector: 'mina-splits', + templateUrl: './dashboard-splits.component.html', + styleUrls: ['./dashboard-splits.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'flex-column h-100 w-100' }, +}) +export class DashboardSplitsComponent extends StoreDispatcher implements OnInit, OnDestroy { + + show: boolean = true; + + ngOnInit(): void { + this.listenToSidePanelChanges(); + this.dispatch(DashboardSplitsGetSplits); + } + + private listenToSidePanelChanges(): void { + this.select(selectDashboardSplitsOpenSidePanel, (show: boolean) => { + this.show = show; + this.detect(); + }); + } + + override ngOnDestroy(): void { + super.ngOnDestroy(); + this.dispatch(DashboardSplitsClose); + } +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits.effects.ts b/frontend/src/app/features/network/splits/dashboard-splits.effects.ts new file mode 100644 index 000000000..ad1ec98a5 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.effects.ts @@ -0,0 +1,69 @@ +import { Injectable } from '@angular/core'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { Store } from '@ngrx/store'; +import { Effect } from '@openmina/shared'; +import { EMPTY, map, switchMap } from 'rxjs'; +import { MinaRustBaseEffect } from '@shared/base-classes/mina-rust-base.effect'; +import { + DASHBOARD_SPLITS_CLOSE, + DASHBOARD_SPLITS_GET_SPLITS, + DASHBOARD_SPLITS_GET_SPLITS_SUCCESS, + DASHBOARD_SPLITS_MERGE_NODES, DASHBOARD_SPLITS_MERGE_NODES_SUCCESS, + DASHBOARD_SPLITS_SPLIT_NODES, + DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS, + DashboardSplitsActions, + DashboardSplitsClose, + DashboardSplitsGetSplits, + DashboardSplitsMergeNodes, +} from '@network/splits/dashboard-splits.actions'; +import { DashboardSplitsService } from '@network/splits/dashboard-splits.service'; +import { MinaState, selectMinaState } from '@app/app.setup'; +import { DashboardSplits } from '@shared/types/network/splits/dashboard-splits.type'; +import { MinaErrorType } from '@shared/types/error-preview/mina-error-type.enum'; +import { catchErrorAndRepeat } from '@shared/constants/store-functions'; +import { DashboardSplitsState } from '@network/splits/dashboard-splits.state'; + +@Injectable({ + providedIn: 'root', +}) +export class DashboardSplitsEffects extends MinaRustBaseEffect { + + readonly getSplits$: Effect; + readonly splitNodes$: Effect; + readonly mergeNodes$: Effect; + + constructor(private actions$: Actions, + private splitService: DashboardSplitsService, + store: Store) { + + super(store, selectMinaState); + + this.getSplits$ = createEffect(() => this.actions$.pipe( + ofType(DASHBOARD_SPLITS_GET_SPLITS, DASHBOARD_SPLITS_CLOSE), + this.latestActionState(), + switchMap(({ action }) => + action.type === DASHBOARD_SPLITS_CLOSE + ? EMPTY + : this.splitService.getPeers(), + ), + map((payload: DashboardSplits) => ({ type: DASHBOARD_SPLITS_GET_SPLITS_SUCCESS, payload })), + catchErrorAndRepeat(MinaErrorType.RUST, DASHBOARD_SPLITS_GET_SPLITS_SUCCESS, { peers: [], links: [] }), + )); + + this.splitNodes$ = createEffect(() => this.actions$.pipe( + ofType(DASHBOARD_SPLITS_SPLIT_NODES), + this.latestStateSlice('network.splits'), + switchMap(state => this.splitService.splitNodes(state.peers)), + map(() => ({ type: DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS })), + catchErrorAndRepeat(MinaErrorType.RUST, DASHBOARD_SPLITS_SPLIT_NODES_SUCCESS), + )); + + this.mergeNodes$ = createEffect(() => this.actions$.pipe( + ofType(DASHBOARD_SPLITS_MERGE_NODES), + this.latestStateSlice('network.splits'), + switchMap(state => this.splitService.mergeNodes(state.peers)), + map(() => ({ type: DASHBOARD_SPLITS_MERGE_NODES_SUCCESS })), + catchErrorAndRepeat(MinaErrorType.RUST, DASHBOARD_SPLITS_MERGE_NODES_SUCCESS), + )); + } +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits.module.ts b/frontend/src/app/features/network/splits/dashboard-splits.module.ts new file mode 100644 index 000000000..f0f7428c6 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.module.ts @@ -0,0 +1,34 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { DashboardSplitsRouting } from './dashboard-splits.routing'; +import { DashboardSplitsGraphComponent } from './dashboard-splits-graph/dashboard-splits-graph.component'; +import { DashboardSplitsToolbarComponent } from './dashboard-splits-toolbar/dashboard-splits-toolbar.component'; +import { DashboardSplitsSidePanelComponent } from './dashboard-splits-side-panel/dashboard-splits-side-panel.component'; +import { EffectsModule } from '@ngrx/effects'; +import { DashboardSplitsSidePanelTableComponent } from './dashboard-splits-side-panel-table/dashboard-splits-side-panel-table.component'; +import { CopyComponent, HorizontalMenuComponent, HorizontalResizableContainerComponent } from '@openmina/shared'; +import { DashboardSplitsComponent } from '@network/splits/dashboard-splits.component'; +import { SharedModule } from '@shared/shared.module'; +import { DashboardSplitsEffects } from '@network/splits/dashboard-splits.effects'; + + +@NgModule({ + declarations: [ + DashboardSplitsComponent, + DashboardSplitsGraphComponent, + DashboardSplitsToolbarComponent, + DashboardSplitsSidePanelComponent, + DashboardSplitsSidePanelTableComponent, + ], + imports: [ + CommonModule, + CopyComponent, + DashboardSplitsRouting, + SharedModule, + EffectsModule.forFeature([DashboardSplitsEffects]), + HorizontalMenuComponent, + HorizontalResizableContainerComponent, + ], +}) +export class DashboardSplitsModule {} diff --git a/frontend/src/app/features/network/splits/dashboard-splits.reducer.ts b/frontend/src/app/features/network/splits/dashboard-splits.reducer.ts new file mode 100644 index 000000000..7b76a7c68 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.reducer.ts @@ -0,0 +1,180 @@ +import { isMobile, noMillisFormat, sort, SortDirection, TableSort, toReadableDate } from '@openmina/shared'; +import { DashboardSplitsState } from '@network/splits/dashboard-splits.state'; +import { + DASHBOARD_SPLITS_CLOSE, + DASHBOARD_SPLITS_GET_SPLITS, + DASHBOARD_SPLITS_GET_SPLITS_SUCCESS, + DASHBOARD_SPLITS_MERGE_NODES, + DASHBOARD_SPLITS_SET_ACTIVE_PEER, + DASHBOARD_SPLITS_SORT_PEERS, + DASHBOARD_SPLITS_SPLIT_NODES, + DASHBOARD_SPLITS_TOGGLE_SIDE_PANEL, + DashboardSplitsActions, +} from '@network/splits/dashboard-splits.actions'; +import { DashboardSplitsLink } from '@shared/types/network/splits/dashboard-splits-link.type'; +import { DashboardNodeCount } from '@shared/types/network/splits/dashboard-node-count.type'; +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { DashboardSplitsSet } from '@shared/types/network/splits/dashboard-splits-set.type'; + +const initialState: DashboardSplitsState = { + peers: [], + links: [], + sets: [], + activePeer: undefined, + networkSplitsDetails: undefined, + networkMergeDetails: undefined, + nodeStats: undefined, + fetching: true, + sort: { + sortBy: 'outgoingConnections', + sortDirection: SortDirection.DSC, + }, + openSidePanel: !isMobile(), +}; + +export function topologyReducer(state: DashboardSplitsState = initialState, action: DashboardSplitsActions): DashboardSplitsState { + switch (action.type) { + + case DASHBOARD_SPLITS_GET_SPLITS: { + return { + ...state, + activePeer: undefined, + fetching: true, + }; + } + + case DASHBOARD_SPLITS_GET_SPLITS_SUCCESS: { + const peers = action.payload.peers.map((p) => ({ + ...p, + radius: getRadius(p.address, action.payload.links), + outgoingConnections: action.payload.links.filter(l => l.source === p.address).length, + incomingConnections: action.payload.links.filter(l => l.target === p.address).length, + })); + const sets = splitThePeers(peers, action.payload.links); + return { + ...state, + peers, + sets: sets.map(set => ({ ...set, peers: sortPeers(set.peers, state.sort) })), + links: action.payload.links, + nodeStats: getNodeCount(peers.map(p => ({ url: !p.node ? 'node' : p.node.toLowerCase() }))), + fetching: false, + }; + } + + case DASHBOARD_SPLITS_SET_ACTIVE_PEER: { + return { + ...state, + activePeer: action.payload, + openSidePanel: true, + }; + } + + case DASHBOARD_SPLITS_SPLIT_NODES: { + return { + ...state, + networkSplitsDetails: 'Last split: ' + toReadableDate(Date.now(), noMillisFormat), + }; + } + + case DASHBOARD_SPLITS_MERGE_NODES: { + return { + ...state, + networkMergeDetails: 'Last merge: ' + toReadableDate(Date.now(), noMillisFormat), + }; + } + + case DASHBOARD_SPLITS_SORT_PEERS: { + return { + ...state, + sort: action.payload, + sets: state.sets.map(set => ({ + ...set, + peers: sortPeers(set.peers, action.payload), + })), + }; + } + + case DASHBOARD_SPLITS_TOGGLE_SIDE_PANEL: { + return { + ...state, + openSidePanel: !state.openSidePanel, + }; + } + + case DASHBOARD_SPLITS_CLOSE: + return initialState; + + default: + return state; + } +} + + +function getRadius(address: string, links: DashboardSplitsLink[]): number { + const occurrence = links.filter(link => link.source === address || link.target === address).length; + if (occurrence < 6) { + return 4; + } else if (occurrence < 8) { + return 6; + } else if (occurrence < 10) { + return 8; + } else if (occurrence < 12) { + return 10; + } else if (occurrence < 14) { + return 12; + } else { + return 14; + } +} + +function getNodeCount(nodes: T[]): DashboardNodeCount { + return { + nodes: (nodes.filter(node => node.url.includes('node')).map(n => n.url)).length, + producers: (nodes.filter(node => node.url.includes('prod')).map(n => n.url)).length, + snarkers: (nodes.filter(node => node.url.includes('snarker')).map(n => n.url)).length, + seeders: (nodes.filter(node => node.url.includes('seed')).map(n => n.url)).length, + transactionGenerators: (nodes.filter(node => node.url.includes('transaction-generator')).map(n => n.url)).length, + }; +} + +function splitThePeers(peers: DashboardSplitsPeer[], links: DashboardSplitsLink[]): DashboardSplitsSet[] { + const sets: DashboardSplitsSet[] = []; + const visited = new Set(); + + for (const peer of peers) { + if (!visited.has(peer.address)) { + const peersForCurrentSet = new Set(); + const queue = [peer]; + + while (queue.length > 0) { + const currentPeer = queue.shift()!; + + if (!peersForCurrentSet.has(currentPeer)) { + peersForCurrentSet.add(currentPeer); + visited.add(currentPeer.address); + + for (const link of links) { + if (link.source === currentPeer.address && !visited.has(link.target)) { + queue.push(peers.find(p => p.address === link.target)); + } else if (link.target === currentPeer.address && !visited.has(link.source)) { + queue.push(peers.find(p => p.address === link.source)); + } + } + } + } + + sets.push({ + peers: sortPeers(Array.from(peersForCurrentSet), { + sortBy: 'outgoingConnections', + sortDirection: SortDirection.DSC, + }), + }); + } + } + + return sets; +} + +function sortPeers(messages: DashboardSplitsPeer[], tableSort: TableSort): DashboardSplitsPeer[] { + return sort(messages, tableSort, ['address', 'peerId', 'node'], true); +} diff --git a/frontend/src/app/features/network/splits/dashboard-splits.routing.ts b/frontend/src/app/features/network/splits/dashboard-splits.routing.ts new file mode 100644 index 000000000..dde7fec8d --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.routing.ts @@ -0,0 +1,24 @@ +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import { DashboardSplitsComponent } from '@network/splits/dashboard-splits.component'; +import { NETWORK_TITLE } from '@app/app.routing'; + +const routes: Routes = [ + { + path: '', + component: DashboardSplitsComponent, + children: [ + { + path: ':addr', + component: DashboardSplitsComponent, + title: NETWORK_TITLE, + }, + ], + }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class DashboardSplitsRouting {} diff --git a/frontend/src/app/features/network/splits/dashboard-splits.service.ts b/frontend/src/app/features/network/splits/dashboard-splits.service.ts new file mode 100644 index 000000000..92b32552b --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.service.ts @@ -0,0 +1,216 @@ +import { Injectable } from '@angular/core'; +import { concatAll, forkJoin, from, map, Observable, toArray } from 'rxjs'; +import { HttpClient } from '@angular/common/http'; +import { DashboardSplits } from '@shared/types/network/splits/dashboard-splits.type'; +import { CONFIG } from '@shared/constants/config'; +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { DashboardSplitsLink } from '@shared/types/network/splits/dashboard-splits-link.type'; +import { peersMock } from '@network/splits/mock'; + +@Injectable({ providedIn: 'root' }) +export class DashboardSplitsService { + + private readonly options = { headers: { 'Content-Type': 'application/json' } }; + + constructor(private http: HttpClient) { } + + getPeers(): Observable { + return from( + [ + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node1', + // 'name': 'node1', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node2', + // 'name': 'node2', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node3', + // 'name': 'node3', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node4', + // 'name': 'node4', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node5', + // 'name': 'node5', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node6', + // 'name': 'node6', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node7', + // 'name': 'node7', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node8', + // 'name': 'node8', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node9', + // 'name': 'node9', + // }, + // { + // 'graphql': 'http://1.k8.openmina.com:31754/node10', + // 'name': 'node10', + // }, + ].map(node => + this.http + .post<{ data: GetPeersResponse }>(`${node.graphql}/graphql`, { query: peersQuery }, this.options) + .pipe( + map(response => ({ data: response.data, node: node.name })), + ), + ), + ).pipe( + concatAll(), + toArray(), + map(() => peersMock), + map((array/*: { data: GetPeersResponse, node: string }[]*/) => { + const map = new Map(); + array.forEach(({ data, node }: { data: GetPeersResponse, node: string }) => { + node = node.charAt(0).toUpperCase() + node.slice(1); + node = node.replace(/(\d+)/g, ' $1'); + map.set(data.daemonStatus.addrsAndPorts.externalIp, node); + }); + return array.reduce((acc: DashboardSplits, { data }: { data: GetPeersResponse }) => { + (acc as any).peers.push( + ...[ + ...data.getPeers + .slice(0, 10) + .map((p: GetPeers) => ({ address: p.host, /*peerId: p.peerId,*/ node: map.get(p.host) })), + { + address: data.daemonStatus.addrsAndPorts.externalIp, + // peerId: data.daemonStatus.addrsAndPorts.peer.peerId, + node: map.get(data.daemonStatus.addrsAndPorts.externalIp), + }, + { + address: 'rand', + node: 'seed16', + }, + { + address: 'rand2', + node: 'seed15', + }, + ], + ); + acc.links.push( + ...data.getPeers + .slice(0, 10) + .map((p: GetPeers) => ({ + source: data.daemonStatus.addrsAndPorts.externalIp, + target: p.host, + })), + ); + acc.links.push( + { + source: 'rand2', + target: 'rand', + } + ) + return acc; + }, { peers: new Array(), links: new Array() }); + }), + map((response: DashboardSplits) => this.removeDuplicatedPeers(response)), + ); + } + + splitNodes(peers: DashboardSplitsPeer[]): Observable { + const nodeName = (peer: DashboardSplitsPeer) => peer.node.toLowerCase().replace(' ', ''); + const lastChar = (str: string) => str[str.length - 1]; + const leftList = peers.filter(p => p.node).filter(p => Number(lastChar(p.node)) % 2 === 0); + const rightList = peers.filter(p => p.node).filter(p => Number(lastChar(p.node)) % 2 !== 0); + + const leftObs = from( + leftList.map(node => + this.http + .post(CONFIG.configs.find(c => c.name === nodeName(node)).debugger + '/firewall/whitelist/enable', { + 'ips': leftList.map(n => n.address.split(':')[0]), + 'ports': [10909, 10001], + }, this.options), + ), + ).pipe( + concatAll(), + toArray(), + ); + const rightObs = from( + rightList.map(node => + this.http + .post(CONFIG.configs.find(c => c.name === nodeName(node)).debugger + '/firewall/whitelist/enable', { + 'ips': rightList.map(n => n.address.split(':')[0]), + 'ports': [10909, 10001], + }, this.options), + ), + ).pipe( + concatAll(), + toArray(), + ); + + return forkJoin([leftObs, rightObs]).pipe(map(() => void 0)); + } + + mergeNodes(peers: DashboardSplitsPeer[]): Observable { + const nodeName = (peer: DashboardSplitsPeer) => peer.node.toLowerCase().replace(' ', ''); + + return from( + peers.filter(p => p.node).map(node => + this.http.post( + CONFIG.configs.find(c => c.name === nodeName(node)).debugger + '/firewall/whitelist/disable', null, this.options, + ), + ), + ).pipe( + concatAll(), + toArray(), + map(() => void 0), + ); + } + + private removeDuplicatedPeers(response: DashboardSplits): DashboardSplits { + response.peers = response.peers.filter((peer: DashboardSplitsPeer, index: number, peers: DashboardSplitsPeer[]) => + index === peers.findIndex(p => p.address === peer.address), + ); + return response; + } +} + +interface GetPeersResponse { + getPeers: GetPeers[]; + daemonStatus: DaemonStatus; +} + +interface GetPeers { + host: string; + libp2pPort: number; + peerId: string; +} + +interface DaemonStatus { + addrsAndPorts: AddrsAndPorts; +} + +interface AddrsAndPorts { + externalIp: string; + libp2pPort: number; + peer: { peerId: string; }; +} + +const peersQuery = ` + query Peers { + daemonStatus { + addrsAndPorts { + peer { + peerId + } + externalIp + libp2pPort + } + } + getPeers { + host + libp2pPort + peerId + } + } +`; diff --git a/frontend/src/app/features/network/splits/dashboard-splits.state.ts b/frontend/src/app/features/network/splits/dashboard-splits.state.ts new file mode 100644 index 000000000..11cdc04d5 --- /dev/null +++ b/frontend/src/app/features/network/splits/dashboard-splits.state.ts @@ -0,0 +1,50 @@ +import { createSelector, MemoizedSelector } from '@ngrx/store'; +import { TableSort } from '@openmina/shared'; +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { DashboardSplitsSet } from '@shared/types/network/splits/dashboard-splits-set.type'; +import { DashboardSplitsLink } from '@shared/types/network/splits/dashboard-splits-link.type'; +import { MinaState } from '@app/app.setup'; +import { selectDashboardSplitsState } from '@network/network.state'; +import { DashboardNodeCount } from '@shared/types/network/splits/dashboard-node-count.type'; + +export interface DashboardSplitsState { + peers: DashboardSplitsPeer[]; + links: DashboardSplitsLink[]; + sets: DashboardSplitsSet[]; + activePeer: DashboardSplitsPeer; + networkSplitsDetails: string; + networkMergeDetails: string; + nodeStats: DashboardNodeCount; + fetching: boolean; + sort: TableSort; + openSidePanel: boolean; +} + +const select = (selector: (state: DashboardSplitsState) => T): MemoizedSelector => createSelector( + selectDashboardSplitsState, + selector, +); + +export const selectDashboardSplitsPeers = select((state: DashboardSplitsState): DashboardSplitsPeer[] => state.peers); +export const selectDashboardSplitsLinks = select((state: DashboardSplitsState): DashboardSplitsLink [] => state.links); +export const selectDashboardSplitsSets = select((state: DashboardSplitsState): DashboardSplitsSet[] => state.sets); +export const selectDashboardSplitsFetching = select((state: DashboardSplitsState): boolean => state.fetching); +export const selectDashboardSplitsPeersAndLinksAndSetsAndFetching = createSelector( + selectDashboardSplitsPeers, + selectDashboardSplitsLinks, + selectDashboardSplitsSets, + selectDashboardSplitsFetching, + (peers: DashboardSplitsPeer[], links: DashboardSplitsLink[], sets: DashboardSplitsSet[], fetching: boolean) => ({ peers, links, sets, fetching }), +); +export const selectDashboardSplitsPeersAndSets = createSelector( + selectDashboardSplitsPeers, + selectDashboardSplitsSets, + (peers: DashboardSplitsPeer[], sets: DashboardSplitsSet[]) => ({ peers, sets }), +); +export const selectDashboardSplitsActivePeer = select((state: DashboardSplitsState): DashboardSplitsPeer => state.activePeer); +export const selectDashboardSplitsNetworkSplitsDetails = select((state: DashboardSplitsState): string => state.networkSplitsDetails); +export const selectDashboardSplitsNetworkMergeDetails = select((state: DashboardSplitsState): string => state.networkMergeDetails); +export const selectDashboardSplitsNodeStats = select((state: DashboardSplitsState): DashboardNodeCount => state.nodeStats); +export const selectDashboardSplitsSort = select((state: DashboardSplitsState): TableSort => state.sort); +export const selectDashboardSplitsOpenSidePanel = select((state: DashboardSplitsState): boolean => state.openSidePanel); + diff --git a/frontend/src/app/features/network/splits/mock.ts b/frontend/src/app/features/network/splits/mock.ts new file mode 100644 index 000000000..f67fa3610 --- /dev/null +++ b/frontend/src/app/features/network/splits/mock.ts @@ -0,0 +1,89 @@ +export const peersMock: any = [ + { + "data": { + "daemonStatus": { + "addrsAndPorts": { + "externalIp": "10.233.90.145", + } + }, + "getPeers": [ + { + "host": "10.233.113.61", + }, + { + "host": "10.233.64.200", + }, + { + "host": "10.233.76.157", + }, + { + "host": "10.233.85.48", + } + ] + }, + "node": "node1" + }, + { + "data": { + "daemonStatus": { + "addrsAndPorts": { + "externalIp": "10.233.77.35", + } + }, + "getPeers": [ + { + "host": "10.233.92.19", + }, + { + "host": "10.233.64.200", + }, + { + "host": "10.233.120.155", + } + ] + }, + "node": "node2" + }, + { + "data": { + "daemonStatus": { + "addrsAndPorts": { + "externalIp": "10.233.101.234", + } + }, + "getPeers": [ + { + "host": "10.233.64.200", + }, + { + "host": "10.233.123.39", + }, + { + "host": "10.233.82.173", + } + ] + }, + "node": "node3" + }, + { + "data": { + "daemonStatus": { + "addrsAndPorts": { + "externalIp": "10.233.110.50", + } + }, + "getPeers": [ + { + "host": "10.233.64.200", + }, + { + "host": "10.233.127.9", + }, + { + "host": "10.233.80.87", + } + ] + }, + "node": "node4" + } +] diff --git a/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.html b/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.html index 3ddf7be15..9d10bf0ca 100644 --- a/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.html +++ b/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.html @@ -1,9 +1,7 @@
-
- -
- +
-
diff --git a/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.scss b/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.scss index df932492d..0030ec84b 100644 --- a/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.scss +++ b/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.scss @@ -7,6 +7,7 @@ position: absolute; left: -100px; height: calc(100% - 40px); + min-height: 70px; &::before { content: ''; diff --git a/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.ts b/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.ts index 1bfd34cb3..8e102c48e 100644 --- a/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.ts +++ b/frontend/src/app/features/nodes/live/nodes-live-blocks-map/nodes-live-blocks-map.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { NodesOverviewBlock } from '@shared/types/nodes/dashboard/nodes-overview-block.type'; +import { NodesOverviewBlock, NodesOverviewNodeBlockStatus } from '@shared/types/nodes/dashboard/nodes-overview-block.type'; import { NodesLiveNode } from '@shared/types/nodes/live/nodes-live-node.type'; import { StoreDispatcher } from '@shared/base-classes/store-dispatcher.class'; import { selectNodesLiveActiveNode } from '../nodes-live.state'; @@ -27,6 +27,7 @@ export class NodesLiveBlocksMapComponent extends StoreDispatcher implements OnIn this.rootBlock = null; this.bestTipBlock = null; this.blocks = (node?.blocks || []).slice().reverse(); + if (this.blocks.length === 291) { this.rootBlock = this.blocks[0]; this.blocks = this.blocks.slice(1); diff --git a/frontend/src/app/features/nodes/live/nodes-live.service.ts b/frontend/src/app/features/nodes/live/nodes-live.service.ts index 508b3f25b..a77ec82d8 100644 --- a/frontend/src/app/features/nodes/live/nodes-live.service.ts +++ b/frontend/src/app/features/nodes/live/nodes-live.service.ts @@ -40,6 +40,7 @@ export class NodesLiveService { const COMPLETED = 'Completed'; node.blocks.forEach((block: NodesOverviewBlock, index: number) => { + const isBestTip = index === 0; if (block.fetchStart) { const event = {} as NodesLiveBlockEvent; event.height = block.height; @@ -47,7 +48,7 @@ export class NodesLiveService { event.timestamp = block.fetchStart; event.datetime = toReadableDate(block.fetchStart / ONE_MILLION); event.status = STARTED; - event.isBestTip = index === 0; + event.isBestTip = isBestTip; events.push(event); } if (block.fetchEnd) { @@ -58,7 +59,7 @@ export class NodesLiveService { event.datetime = toReadableDate(block.fetchEnd / ONE_MILLION); event.elapsed = block.fetchDuration; event.status = COMPLETED; - event.isBestTip = index === 0; + event.isBestTip = isBestTip; events.push(event); } if (block.applyStart) { @@ -68,7 +69,7 @@ export class NodesLiveService { event.timestamp = block.applyStart; event.datetime = toReadableDate(block.applyStart / ONE_MILLION); event.status = STARTED; - event.isBestTip = index === 0; + event.isBestTip = isBestTip; events.push(event); } if (block.applyEnd) { @@ -79,7 +80,7 @@ export class NodesLiveService { event.datetime = toReadableDate(block.applyEnd / ONE_MILLION); event.elapsed = block.applyDuration; event.status = COMPLETED; - event.isBestTip = index === 0; + event.isBestTip = isBestTip; events.push(event); } }); diff --git a/frontend/src/app/features/nodes/overview/nodes-overview-side-panel/nodes-overview-side-panel.component.ts b/frontend/src/app/features/nodes/overview/nodes-overview-side-panel/nodes-overview-side-panel.component.ts index c2875e831..d9da414c5 100644 --- a/frontend/src/app/features/nodes/overview/nodes-overview-side-panel/nodes-overview-side-panel.component.ts +++ b/frontend/src/app/features/nodes/overview/nodes-overview-side-panel/nodes-overview-side-panel.component.ts @@ -22,6 +22,7 @@ export class NodesOverviewSidePanelComponent extends StoreDispatcher implements private interval: any; private secondsPassed: number = 0; private timeReference: number = 0; + private timerRemoved: boolean; constructor(private router: Router, private zone: NgZone) { super(); } @@ -34,9 +35,19 @@ export class NodesOverviewSidePanelComponent extends StoreDispatcher implements private listenToActiveNodesOverviewNode(): void { this.select(selectNodesOverviewActiveNode, (node: NodesOverviewNode) => { this.node = node; - this.timeReference = node.bestTipReceivedTimestamp; - this.secondsPassed = (Date.now() - this.timeReference) / 1000; - this.updateTimeInView(); + if (node.bestTipReceivedTimestamp) { + if (this.timerRemoved) { + this.createTimer(); + this.timerRemoved = false; + } + this.timeReference = node.bestTipReceivedTimestamp; + this.secondsPassed = (Date.now() - this.timeReference) / 1000; + this.updateTimeInView(); + } else { + this.clearTimer(); + this.timerRemoved = true; + this.bestTipRef.nativeElement.innerText = '-'; + } this.detect(); }, filter(node => !!node)); } @@ -48,11 +59,15 @@ export class NodesOverviewSidePanelComponent extends StoreDispatcher implements private createTimer(): void { this.zone.run(() => { - clearInterval(this.interval); + this.clearTimer(); this.interval = setInterval(() => this.updateTimeInView(), 1000); }); } + private clearTimer(): void { + clearInterval(this.interval); + } + private updateTimeInView(): void { const next = this.secondsPassed + 1; this.secondsPassed++; diff --git a/frontend/src/app/features/nodes/overview/nodes-overview.service.ts b/frontend/src/app/features/nodes/overview/nodes-overview.service.ts index 23d3a1509..5eca86491 100644 --- a/frontend/src/app/features/nodes/overview/nodes-overview.service.ts +++ b/frontend/src/app/features/nodes/overview/nodes-overview.service.ts @@ -27,10 +27,12 @@ export class NodesOverviewService { } getNodeTips(nodeParam: { url: string, name: string }, qp: string = ''): Observable { - // return of(JSON.parse(JSON.stringify(mock2()))).pipe(delay(250)) return this.http.get(nodeParam.url + '/stats/sync' + qp) .pipe( map((response: any[]) => { + if (response.length === 0) { + throw new Error('Empty response'); + } return response.map((node: any) => { const blocks = node.blocks.map((block: any) => { return { @@ -116,13 +118,13 @@ export class NodesOverviewService { }; if (ledgers.staking_epoch) { ledger.stakingEpoch = getLedgerStep(ledgers.staking_epoch); - if (ledger.stakingEpoch.state !== NodesOverviewLedgerStepState.SUCCESS && (ledgers.staking_epoch.synced || ledgers.next_epoch.synced || ledgers.root.synced)) { + if (ledger.stakingEpoch.state !== NodesOverviewLedgerStepState.SUCCESS && (ledgers.staking_epoch?.synced || ledgers.next_epoch?.synced || ledgers.root?.synced)) { ledger.stakingEpoch.state = NodesOverviewLedgerStepState.SUCCESS; } } if (ledgers.next_epoch) { ledger.nextEpoch = getLedgerStep(ledgers.next_epoch); - if (ledger.nextEpoch.state !== NodesOverviewLedgerStepState.SUCCESS && (ledgers.next_epoch.synced || ledgers.root.synced)) { + if (ledger.nextEpoch.state !== NodesOverviewLedgerStepState.SUCCESS && (ledgers.next_epoch?.synced || ledgers.root?.synced)) { ledger.nextEpoch.state = NodesOverviewLedgerStepState.SUCCESS; } } diff --git a/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.scss b/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.scss index 1bd6e5e89..5fcb6f1b2 100644 --- a/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.scss +++ b/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.scss @@ -8,6 +8,7 @@ .tree-map { height: calc(50vh - 2px); border: 0.5px solid $base-tertiary; + overflow: hidden; @media (max-width: 768px) { height: calc(30vh - 2px); diff --git a/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.ts b/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.ts index 31d2fbc93..76ed47bb1 100644 --- a/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.ts +++ b/frontend/src/app/features/resources/memory/memory-resources-treemap/memory-resources-treemap.component.ts @@ -14,7 +14,7 @@ import { ResourcesSizePipe } from '@resources/memory/memory-resources.pipe'; import { MemoryResourcesSetActiveResource } from '@resources/memory/memory-resources.actions'; import { untilDestroyed } from '@ngneat/until-destroy'; import { TreemapView } from '@shared/types/resources/memory/treemap-view.type'; -import { isDesktop, isMobile, TooltipService } from '@openmina/shared'; +import { isDesktop, TooltipService } from '@openmina/shared'; import { selectAppMenu } from '@app/app.state'; @Component({ @@ -456,12 +456,7 @@ export class MemoryResourcesTreemapComponent extends StoreDispatcher implements }; private findNodeByName(node: MemoryResource, root: HierarchyRectangularNode): HierarchyRectangularNode { - if ( - root.data.name.executableName === node.name.executableName - && root.data.name.functionName === node.name.functionName - && root.data.value === node.value - && root.data.children.length === node.children.length - ) { + if (root.data.id === node.id) { return root; } else if (root.children) { let found: HierarchyRectangularNode = null; diff --git a/frontend/src/app/features/resources/memory/memory-resources.reducer.ts b/frontend/src/app/features/resources/memory/memory-resources.reducer.ts index 6c56b659c..9d4978bbc 100644 --- a/frontend/src/app/features/resources/memory/memory-resources.reducer.ts +++ b/frontend/src/app/features/resources/memory/memory-resources.reducer.ts @@ -2,7 +2,9 @@ import { MemoryResourcesState } from '@resources/memory/memory-resources.state'; import { MEMORY_RESOURCES_CLOSE, MEMORY_RESOURCES_GET_SUCCESS, - MEMORY_RESOURCES_SET_ACTIVE_RESOURCE, MEMORY_RESOURCES_SET_GRANULARITY, MEMORY_RESOURCES_SET_TREEMAP_VIEW, + MEMORY_RESOURCES_SET_ACTIVE_RESOURCE, + MEMORY_RESOURCES_SET_GRANULARITY, + MEMORY_RESOURCES_SET_TREEMAP_VIEW, MemoryResourcesActions, } from '@resources/memory/memory-resources.actions'; import { TreemapView } from '@shared/types/resources/memory/treemap-view.type'; @@ -33,10 +35,13 @@ export function memoryResourcesReducer(state: MemoryResourcesState = initialStat let breadcrumbs = state.breadcrumbs; if (action.payload.name.executableName === 'root') { breadcrumbs = [state.resource]; - } else if (breadcrumbs.map(b => b.name.executableName).some(b => b === action.payload.name.executableName)) { - breadcrumbs = breadcrumbs.slice(0, breadcrumbs.findIndex(b => b.name.executableName === action.payload.name.executableName) + 1); } else { - breadcrumbs = [...breadcrumbs, action.payload]; + const indexOfSameResource = breadcrumbs.findIndex(b => b.id === action.payload.id); + if (indexOfSameResource !== -1) { + breadcrumbs = breadcrumbs.slice(0, indexOfSameResource + 1); + } else { + breadcrumbs = [...breadcrumbs, action.payload]; + } } return { ...state, diff --git a/frontend/src/app/features/resources/memory/memory-resources.service.ts b/frontend/src/app/features/resources/memory/memory-resources.service.ts index 27a87051a..01be06c54 100644 --- a/frontend/src/app/features/resources/memory/memory-resources.service.ts +++ b/frontend/src/app/features/resources/memory/memory-resources.service.ts @@ -5,13 +5,16 @@ import { map, Observable } from 'rxjs'; import { RustService } from '@core/services/rust.service'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class MemoryResourcesService { + private id: number = 0; + constructor(private rust: RustService) { } getStorageResources(threshold: number, reversed: boolean = false): Observable { + this.id = 0; return this.rust.getMemProfiler(`/v1/tree?threshold=${threshold}&reverse=${reversed}`) .pipe(map((response: MemoryResourceTree) => this.mapMemoryResponse(response, threshold))); } @@ -20,7 +23,8 @@ export class MemoryResourcesService { return { name: { ...response.name, executableName: 'root' }, value: round(response.value/* - (response.cacheValue || 0)*/), - children: this.build(response.frames, threshold) + children: this.build(response.frames, threshold), + id: this.nextId, }; } @@ -33,6 +37,7 @@ export class MemoryResourcesService { name: this.getFrameName(frame.name, threshold), value: size, children: this.build(frame.frames || [], threshold), + id: this.nextId, }; children.push(items); }); @@ -49,9 +54,13 @@ export class MemoryResourcesService { return { executableName: `${name.executable}@${name.offset}`, - functionName: name.functionName + functionName: name.functionName, }; } + + private get nextId(): number { + return this.id++; + } } const round = (num: number): number => +(Math.round(Number(num + 'e+2')) + 'e-2'); diff --git a/frontend/src/app/shared/types/network/splits/dashboard-node-count.type.ts b/frontend/src/app/shared/types/network/splits/dashboard-node-count.type.ts new file mode 100644 index 000000000..a2291c6a0 --- /dev/null +++ b/frontend/src/app/shared/types/network/splits/dashboard-node-count.type.ts @@ -0,0 +1,7 @@ +export interface DashboardNodeCount { + nodes: number; + producers: number; + snarkers?: number; + seeders?: number; + transactionGenerators?: number; +} diff --git a/frontend/src/app/shared/types/network/splits/dashboard-splits-link.type.ts b/frontend/src/app/shared/types/network/splits/dashboard-splits-link.type.ts new file mode 100644 index 000000000..7da12b96f --- /dev/null +++ b/frontend/src/app/shared/types/network/splits/dashboard-splits-link.type.ts @@ -0,0 +1,4 @@ +export interface DashboardSplitsLink { + source: string; + target: string; +} diff --git a/frontend/src/app/shared/types/network/splits/dashboard-splits-peer.type.ts b/frontend/src/app/shared/types/network/splits/dashboard-splits-peer.type.ts new file mode 100644 index 000000000..83ba01ce0 --- /dev/null +++ b/frontend/src/app/shared/types/network/splits/dashboard-splits-peer.type.ts @@ -0,0 +1,8 @@ +export class DashboardSplitsPeer { + address: string; + peerId: string; + node: string; + radius?: number; + outgoingConnections?: number; + incomingConnections?: number; +} diff --git a/frontend/src/app/shared/types/network/splits/dashboard-splits-set.type.ts b/frontend/src/app/shared/types/network/splits/dashboard-splits-set.type.ts new file mode 100644 index 000000000..8bdd402da --- /dev/null +++ b/frontend/src/app/shared/types/network/splits/dashboard-splits-set.type.ts @@ -0,0 +1,5 @@ +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; + +export interface DashboardSplitsSet { + peers: DashboardSplitsPeer[]; +} diff --git a/frontend/src/app/shared/types/network/splits/dashboard-splits.type.ts b/frontend/src/app/shared/types/network/splits/dashboard-splits.type.ts new file mode 100644 index 000000000..8633639df --- /dev/null +++ b/frontend/src/app/shared/types/network/splits/dashboard-splits.type.ts @@ -0,0 +1,7 @@ +import { DashboardSplitsPeer } from '@shared/types/network/splits/dashboard-splits-peer.type'; +import { DashboardSplitsLink } from '@shared/types/network/splits/dashboard-splits-link.type'; + +export interface DashboardSplits { + peers: DashboardSplitsPeer[]; + links: DashboardSplitsLink[]; +} diff --git a/frontend/src/app/shared/types/resources/memory/memory-resource.type.ts b/frontend/src/app/shared/types/resources/memory/memory-resource.type.ts index fc719afaf..a9f31f6e1 100644 --- a/frontend/src/app/shared/types/resources/memory/memory-resource.type.ts +++ b/frontend/src/app/shared/types/resources/memory/memory-resource.type.ts @@ -4,4 +4,5 @@ export class MemoryResource { name: MemoryResourceName; children: MemoryResource[]; value?: number; + id: number; } diff --git a/frontend/src/environments/environment.ts b/frontend/src/environments/environment.ts index 0cfd1ec3e..4b7b23b4f 100644 --- a/frontend/src/environments/environment.ts +++ b/frontend/src/environments/environment.ts @@ -9,7 +9,7 @@ export const environment: Readonly = { nodes: ['overview', 'live', 'bootstrap'], state: ['actions'], network: ['messages', 'connections', 'blocks'], - snarks: ['scan-state', /*'work-pool'*/], + snarks: ['scan-state' /*'work-pool'*/], // 'testing-tool': ['scenarios'], }, }, @@ -34,6 +34,7 @@ export const environment: Readonly = { state: ['actions'], snarks: ['scan-state'], resources: ['memory'], + network: ['topology', 'node-dht', 'graph-overview'], }, }, { @@ -59,7 +60,7 @@ export const environment: Readonly = { { name: 'Snarker 3', url: 'http://webrtc4.webnode.openmina.com:10000', - } + }, ], }; diff --git a/genesis_ledgers/berkeley_genesis_ledger.bin b/genesis_ledgers/berkeley_genesis_ledger.bin new file mode 100644 index 000000000..2f9562653 Binary files /dev/null and b/genesis_ledgers/berkeley_genesis_ledger.bin differ diff --git a/ledger/.github/workflows/rust-tests.yml b/ledger/.github/workflows/rust-tests.yml index 0708b9387..25311f4de 100644 --- a/ledger/.github/workflows/rust-tests.yml +++ b/ledger/.github/workflows/rust-tests.yml @@ -27,7 +27,7 @@ jobs: - name: Install toolchain uses: actions-rs/toolchain@v1 with: - toolchain: nightly + toolchain: 1.75 override: true profile: minimal components: rust-src @@ -50,7 +50,7 @@ jobs: - name: Install toolchain uses: actions-rs/toolchain@v1 with: - toolchain: nightly + toolchain: 1.75 override: true profile: minimal diff --git a/ledger/Cargo.toml b/ledger/Cargo.toml index eca29e181..2aa70f396 100644 --- a/ledger/Cargo.toml +++ b/ledger/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mina-tree" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" @@ -68,6 +68,7 @@ rand_seeder = "0.2" blake2 = "0.10" crc32fast = "1" chrono = "0.4" +serde_with = "3.6.1" [target.'cfg(target_family = "wasm")'.dependencies] getrandom = { version = "0.2", features = ["js"] } diff --git a/ledger/src/account/account.rs b/ledger/src/account/account.rs index 7495ac1c0..a4a0acfc5 100644 --- a/ledger/src/account/account.rs +++ b/ledger/src/account/account.rs @@ -23,7 +23,7 @@ use crate::{ witness::Witness, }, scan_state::{ - currency::{Balance, Magnitude, Nonce, Slot}, + currency::{Balance, Magnitude, Nonce, Slot, TxnVersion}, transaction_logic::account_min_balance_at_slot, }, zkapps::snark::FlaggedOption, @@ -32,6 +32,9 @@ use crate::{ use super::common::*; +/// Mina_numbers.Txn_version.current +pub const TXN_VERSION_CURRENT: TxnVersion = TxnVersion::from_u32(2); + #[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct TokenId(pub Fp); @@ -129,6 +132,12 @@ impl ToInputs for TokenSymbol { } } +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct SetVerificationKey { + pub auth: Controller, + pub txn_version: TxnVersion, +} + // https://github.com/MinaProtocol/mina/blob/develop/src/lib/mina_base/permissions.mli#L49 #[derive(Clone, Debug, PartialEq, Eq)] pub struct Permissions { @@ -138,7 +147,7 @@ pub struct Permissions { pub receive: Controller, pub set_delegate: Controller, pub set_permissions: Controller, - pub set_verification_key: Controller, + pub set_verification_key: SetVerificationKey, pub set_zkapp_uri: Controller, pub edit_action_state: Controller, pub set_token_symbol: Controller, @@ -147,10 +156,15 @@ pub struct Permissions { pub set_timing: Controller, } +pub enum AuthOrVersion<'a, T> { + Auth(&'a T), + Version(TxnVersion), +} + impl Permissions { pub fn iter_as_bits(&self, mut fun: F) where - F: FnMut(bool), + F: FnMut(AuthOrVersion<'_, bool>), { let Self { edit_state, @@ -159,7 +173,11 @@ impl Permissions { receive, set_delegate, set_permissions, - set_verification_key, + set_verification_key: + SetVerificationKey { + auth: set_verification_key_auth, + txn_version, + }, set_zkapp_uri, edit_action_state, set_token_symbol, @@ -169,22 +187,30 @@ impl Permissions { } = self; for auth in [ - edit_state, - access, - send, - receive, - set_delegate, - set_permissions, - set_verification_key, - set_zkapp_uri, - edit_action_state, - set_token_symbol, - increment_nonce, - set_voting_for, - set_timing, + AuthOrVersion::Auth(edit_state), + AuthOrVersion::Auth(access), + AuthOrVersion::Auth(send), + AuthOrVersion::Auth(receive), + AuthOrVersion::Auth(set_delegate), + AuthOrVersion::Auth(set_permissions), + AuthOrVersion::Auth(set_verification_key_auth), + AuthOrVersion::Version(*txn_version), + AuthOrVersion::Auth(set_zkapp_uri), + AuthOrVersion::Auth(edit_action_state), + AuthOrVersion::Auth(set_token_symbol), + AuthOrVersion::Auth(increment_nonce), + AuthOrVersion::Auth(set_voting_for), + AuthOrVersion::Auth(set_timing), ] { - for bit in auth.encode().to_bits() { - fun(bit); + match auth { + AuthOrVersion::Auth(auth) => { + for bit in auth.encode().to_bits() { + fun(AuthOrVersion::Auth(&bit)); + } + } + AuthOrVersion::Version(version) => { + fun(AuthOrVersion::Version(version)); + } } } } @@ -192,12 +218,39 @@ impl Permissions { impl ToInputs for Permissions { fn to_inputs(&self, inputs: &mut Inputs) { - self.iter_as_bits(|bit| { - inputs.append_bool(bit); + self.iter_as_bits(|bit| match bit { + AuthOrVersion::Auth(bit) => inputs.append_bool(*bit), + AuthOrVersion::Version(version) => inputs.append(&version), }); } } +impl Check for Permissions { + fn check(&self, w: &mut Witness) { + let Self { + edit_state: _, + access: _, + send: _, + receive: _, + set_delegate: _, + set_permissions: _, + set_verification_key: + SetVerificationKey { + auth: _, + txn_version, + }, + set_zkapp_uri: _, + edit_action_state: _, + set_token_symbol: _, + increment_nonce: _, + set_voting_for: _, + set_timing: _, + } = self; + + txn_version.check(w); + } +} + impl Default for Permissions { fn default() -> Self { Self::user_default() @@ -213,7 +266,10 @@ impl Permissions { receive: None, set_delegate: Signature, set_permissions: Signature, - set_verification_key: Signature, + set_verification_key: SetVerificationKey { + auth: Signature, + txn_version: TXN_VERSION_CURRENT, + }, set_zkapp_uri: Signature, edit_action_state: Signature, set_token_symbol: Signature, @@ -233,7 +289,10 @@ impl Permissions { access: None, set_delegate: None, set_permissions: None, - set_verification_key: None, + set_verification_key: SetVerificationKey { + auth: None, + txn_version: TXN_VERSION_CURRENT, + }, set_zkapp_uri: None, edit_action_state: None, set_token_symbol: None, @@ -259,7 +318,10 @@ impl Permissions { receive: auth_required_gen(&mut rng), set_delegate: auth_required_gen(&mut rng), set_permissions: auth_required_gen(&mut rng), - set_verification_key: auth_required_gen(&mut rng), + set_verification_key: SetVerificationKey { + auth: auth_required_gen(&mut rng), + txn_version: TXN_VERSION_CURRENT, + }, set_zkapp_uri: auth_required_gen(&mut rng), edit_action_state: auth_required_gen(&mut rng), set_token_symbol: auth_required_gen(&mut rng), @@ -963,6 +1025,7 @@ pub struct Account { } impl Account { + #[cfg(test)] pub fn create() -> Self { let pubkey = CompressedPubKey::from_address( "B62qnzbXmRNo9q32n4SNu2mpB8e7FYYLH8NmaX6oFCBYjjQ8SbD7uzV", @@ -1252,7 +1315,10 @@ impl Account { receive: gen_perm(rng), set_delegate: gen_perm(rng), set_permissions: gen_perm(rng), - set_verification_key: gen_perm(rng), + set_verification_key: SetVerificationKey { + auth: gen_perm(rng), + txn_version: TXN_VERSION_CURRENT, // TODO: Make the version random ? + }, set_zkapp_uri: gen_perm(rng), edit_action_state: gen_perm(rng), set_token_symbol: gen_perm(rng), @@ -1440,7 +1506,7 @@ mod tests { assert_eq!( hash.to_hex(), - "98cf7cf3a885d0523ac3ac51c3aca17ebb93ec94a15aed43787352cfe8e47204" + "d17c17038db495e03eb95af0e4e79248b9ad1363862f4b194644d46932a62c1c" ); let acc = Account { @@ -1462,7 +1528,7 @@ mod tests { assert_eq!( acc.hash().to_hex(), - "ef40252c54fa9e7539ae91db89c8104778ad19e1afab1b8df4a4dee51a270e1e" + "d39fb6f37dd1d7fb3928c8f493bbeade214fdeae89d3703192e2b4f1373e421c" ); } @@ -1541,38 +1607,4 @@ mod tests { db.root_hash(); elog!("root hash computed in {:?}", now.elapsed()); } - - #[test] - fn test_verify_merkle_path() { - use mina_p2p_messages::v2::{MerkleTreeNode, MinaBaseAccountBinableArgStableV2}; - - let account = "6c88f36f4a0fcbaaaf12e91f030ca5e33bd7b26a0b8e6c22bc2af33924f2ce3400010000000000000000000000000000000000000000000000000000000000000000fc00aaa0680b000000009be4b7c51ed9c2e4524727805fd36f5220fbfc70a749f62623b0ed2908433320016c88f36f4a0fcbaaaf12e91f030ca5e33bd7b26a0b8e6c22bc2af33924f2ce34000000000000000000000000000000000000000000000000000000000000000000000300030003030303030303030300"; - - let merkle_path = "234f6812650aa27ce35d904b875809d380b2a7184dedd52d4c289274d6626e65ce5fff34354f681265d95c4d0208bcfd7d4ede27bbd1653d41ac8b0f37fe3fb6f39b5e8113df33f32279f722f9c7bbe7408ca42e90ef121191832b460ce9e990b3731abca9558f4df132614e294f68126502666e211f4d489e821916367014e5487bcbcaa582dc1154d8fdefd4b195ad1e79f722f9399038b193d310c012f421e9babd49367a32a3238eb02c584b936d5d07037b1f79f722f92bbd58fa3e868c956b31e5dfa31ad64f343694a46086659d9d63db0ddf70fb0d4f6812650c0b59c6d6ffab5339590603a2b00695d553784cc74e379cfa5c597266fbe0064f6812659c60712fd3e9663d535ade06b19c14a00d0d6214fc434bd374a34826dcfb7e1379f722f98422f50661c5e0c2b294bba3ebc22ff4f7f86f22d1611b308ea49e93e92d913b4f68126503518a63bb9daf70e3729f3922344dd470f721947cc07a4e4598ec871e4e64384f681265e16eed60ec1e56541360983741bde52a606f37da9495c6cd7244f9f30d9ac7154f681265ddaa309c792e62a1bbf6b4db04c323acf3a0fb702e1313c72755d7bbdb6c4f1e4f68126528405defcf11f365d0ccb31c9e68433441a8d0c77b3a798b7bb45d526715d43d79f722f96585a90bbfa518dafd94f5a2391a162299fd3c61c69b26be09be0c0905c4393d4f681265b2fca6df0ddacc2bb3561c695639837d39253baa3516f97c16556b1e7e6a7b3e4f681265ba91cd781a83e8f733213ef9817d2d958d26139adc4100c66150a169788cf0394f6812654e4fe5ed5ace8dc48426c601162e079b24b4adb72058d1211096ca709305f41f4f681265fb233966427765d8e0e0fb0116d5ee3bb10c5f41289193105c5b7c9c2a51c6094f681265ddf2b009d56e1f3bdfc22e9ef1850d097f6851458acf065816d443d2cd8894264f681265a9dc4535f5784e6148f2fdbcaa6e52d44999ce753cee4bad9de2df945129c1014f681265080aeeaab1058ef1663494607583ad838485b3abcfc5635b497f0c1aead8c2304f68126580be734b9057133b7d2c05187f18f2563dea8cf0bd238a17ee0242b60d98302c4f68126599ba4df1ad24dbc8090b66897d71f2a0cf21b1fb84d261b172e9333156358a3d4f681265f05f173a096c75c0f0148e426558139543535493a1933bd495d5a336e9eba1044f68126551c28fa437d4d89c1b839a1914529144cb3a3d9f8dc9cf4a95107e8cc9e5ee124f6812658ee873cbef184d38c2107cabd69ff87f710637ab9de8a1d7acb653949a72702c4f681265523e5324a58d7cca8ff8f40837656a7390e2515f265781aae422fff6a21b8b214f6812653555315baded133cd65e9d388fb7400f4323d5e79c44d7aee86a91712cdc30374f6812650bf6a75de59539f1be2a12bf307eaee979618e192c1e22d39fc53f98ab5375334f681265d199ee8af504dfc85afd7dd10da4e8872c096fc81e47dcfd2757ac6d9bd4312b4f6812659e2d0a145842af4119df8a7616e8a9687931e800cde90daaf3f7509aa081c10b4f68126593e74d2016c3711fb9486c5e4acb3435f5bf29ccfeefa37fde149bbee5b2430e4f6812651d7ba0bcbe637533740fcb73dfaaf254aea8830cc5555484479f80f2755f5b3d4f6812650146c059f09bc14cfadd69ebc5814dcf5a4301123a74bfa8f3514c5b161f81004f681265db914425a7d4c3bd6b9dc012a040cd94cb5857bb5051ccb6c61c90ada034f93d"; - - let account = hex::decode(account).unwrap(); - let mut cursor = std::io::Cursor::new(account); - let account = MinaBaseAccountBinableArgStableV2::binprot_read(&mut cursor).unwrap(); - let account: Account = (&account).into(); - - let merkle_path = hex::decode(merkle_path).unwrap(); - let mut cursor = std::io::Cursor::new(merkle_path); - let merkle_path = Vec::::binprot_read(&mut cursor).unwrap(); - let merkle_path: Vec<_> = merkle_path - .into_iter() - .map(|node| match node { - MerkleTreeNode::Left(f) => MerklePath::Left(f.to_field()), - MerkleTreeNode::Right(f) => MerklePath::Right(f.to_field()), - }) - .collect(); - - let root_hash = verify_merkle_path(&account, merkle_path.as_slice()); - - let expected_root_hash = Fp::from_str( - "13294139316831045628856068053543468709149714488527059099223047292955286511556", - ) - .unwrap(); - - assert_eq!(root_hash, expected_root_hash); - } } diff --git a/ledger/src/account/common.rs b/ledger/src/account/common.rs index 1e40b95c0..9e8c95d87 100644 --- a/ledger/src/account/common.rs +++ b/ledger/src/account/common.rs @@ -272,6 +272,15 @@ impl AuthRequired { pub fn gen_for_none_given_authorization(_rng: &mut rand::rngs::ThreadRng) -> Self { Self::None } + + pub fn verification_key_perm_fallback_to_signature_with_older_version(&self) -> Self { + use AuthRequired::*; + + match self { + Impossible | Proof => Signature, + x => x.clone(), + } + } } impl AuthRequiredEncoded { diff --git a/ledger/src/account/conv.rs b/ledger/src/account/conv.rs index a16e2467f..41a0c2792 100644 --- a/ledger/src/account/conv.rs +++ b/ledger/src/account/conv.rs @@ -21,9 +21,9 @@ use crate::{ field::FieldWitness, transaction::{make_group, InnerCurve, PlonkVerificationKeyEvals}, }, - scan_state::currency::{Amount, Balance, Nonce, Slot, SlotSpan}, - Permissions, ProofVerified, ReceiptChainHash, Timing, TokenSymbol, VerificationKey, VotingFor, - ZkAppAccount, + scan_state::currency::{Amount, Balance, Nonce, Slot, SlotSpan, TxnVersion}, + Permissions, ProofVerified, ReceiptChainHash, SetVerificationKey, Timing, TokenSymbol, + VerificationKey, VotingFor, ZkAppAccount, }; use super::{Account, AccountId, AuthRequired, TokenId}; @@ -259,7 +259,7 @@ impl From<&Account> for mina_p2p_messages::v2::MinaBaseAccountBinableArgStableV2 Self { public_key: (&acc.public_key).into(), token_id: (&acc.token_id).into(), - token_symbol: MinaBaseZkappAccountZkappUriStableV1(acc.token_symbol.as_bytes().into()), + token_symbol: acc.token_symbol.as_bytes().into(), balance: CurrencyBalanceStableV1(CurrencyAmountStableV1( UnsignedExtendedUInt64Int64ForVersionTagsStableV1(acc.balance.as_u64().into()), )), @@ -290,9 +290,7 @@ impl From<&Account> for mina_p2p_messages::v2::MinaBaseAccountBinableArgStableV2 action_state, last_action_slot: (&zkapp.last_action_slot).into(), proved_state: zkapp.proved_state, - zkapp_uri: MinaBaseZkappAccountZkappUriStableV1( - zkapp.zkapp_uri.as_bytes().into(), - ), + zkapp_uri: zkapp.zkapp_uri.as_bytes().into(), } }), } @@ -428,7 +426,7 @@ impl From<&MinaBasePermissionsStableV2> for Permissions { receive, set_delegate, set_permissions, - set_verification_key, + set_verification_key: (auth, txn_version), set_zkapp_uri, edit_action_state, set_token_symbol, @@ -443,7 +441,10 @@ impl From<&MinaBasePermissionsStableV2> for Permissions { receive: receive.into(), set_delegate: set_delegate.into(), set_permissions: set_permissions.into(), - set_verification_key: set_verification_key.into(), + set_verification_key: SetVerificationKey { + auth: auth.into(), + txn_version: TxnVersion::from_u32(txn_version.as_u32()), + }, set_zkapp_uri: set_zkapp_uri.into(), edit_action_state: edit_action_state.into(), set_token_symbol: set_token_symbol.into(), @@ -464,7 +465,7 @@ impl From<&Permissions> for MinaBasePermissionsStableV2 { receive, set_delegate, set_permissions, - set_verification_key, + set_verification_key: SetVerificationKey { auth, txn_version }, set_zkapp_uri, edit_action_state, set_token_symbol, @@ -479,7 +480,7 @@ impl From<&Permissions> for MinaBasePermissionsStableV2 { receive: receive.into(), set_delegate: set_delegate.into(), set_permissions: set_permissions.into(), - set_verification_key: set_verification_key.into(), + set_verification_key: (auth.into(), txn_version.as_u32().into()), set_zkapp_uri: set_zkapp_uri.into(), edit_action_state: edit_action_state.into(), set_token_symbol: set_token_symbol.into(), @@ -497,7 +498,7 @@ impl From<&MinaBaseAccountBinableArgStableV2> for Account { public_key: acc.public_key.inner().into(), token_id: acc.token_id.inner().into(), token_symbol: { - let s: String = (&acc.token_symbol.0).try_into().unwrap(); + let s: String = (&acc.token_symbol).try_into().unwrap(); TokenSymbol::from(s) }, balance: Balance::from_u64(acc.balance.0 .0 .0 .0 as u64), @@ -517,7 +518,7 @@ impl From<&MinaBaseAccountBinableArgStableV2> for Account { action_state: std::array::from_fn(|i| zkapp.action_state[i].to_field()), last_action_slot: Slot::from_u32(zkapp.last_action_slot.as_u32()), proved_state: zkapp.proved_state, - zkapp_uri: (&zkapp.zkapp_uri.0).try_into().unwrap(), + zkapp_uri: (&zkapp.zkapp_uri).try_into().unwrap(), } }), } diff --git a/ledger/src/database/database.rs b/ledger/src/database/database.rs index b46cddf10..f2380b67e 100644 --- a/ledger/src/database/database.rs +++ b/ledger/src/database/database.rs @@ -574,12 +574,12 @@ export function performance_now() { let heights = [0, 5, 10, 11, 100, 2000]; let hexs = [ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "c7395b8d4f69803d5d370440149b566899a4cb97ee4e1f41755c0a4b2b502417", - "974f176751486771b15506d5e834e046516e715f70b779d3d1041d20333d0e38", - "0a996bda7205e4e86a4778c5c659e6712105590342b9f80e3676cc64cceaeb37", - "e6e0802e9e8503a021752e37707531ccf88075bca072e3c0f37e1db6133bf01d", - "369f340cd9ff975c1f11521d52f6e4bd07eb8457d694b50568e0bb41ab26a921", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "74b944d727eb03f8cde5eaff612ffb6b6973fa81b05731e7c7fef2c7ec590c12", + "c1f74735376caec045bb3eda019edb1aaed1d4c192d80ecf31a9b9d85c52d41c", + "c749e5166b5d9361f40816b01ab0a2d77afd23c5cad55e87cf9e07659cf75321", + "8f2142a5ddf1653a87fa67e117aad328519200b4ae8f6f8ca27b3f8c9ea6cf3e", + "495ec83e28971701449d474af9b5f0400cc5e268a2d4706e7483e28875f1f713", ]; let result: Vec<_> = heights @@ -1147,100 +1147,100 @@ mod tests_ocaml { let expected = [ &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "79c1db32ee6d619da6f8bc08dba1f2a261084a420165a2157b61c9061980561f", - "7267f46de5e3dfc4f6524a783d5f994deeb5636b37e68657ba644029893ea331", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "d525794afb5f4cd15ddadd759349a63bbd9e4d65113b89a7c1710e2f251a0202", + "cdc18ed79aa8bde9a857184b9631beb509ca04fb69e3ba13594efd01db820c28", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "2a80873b7e8f5353559382c378b36de4f8d4418cd1f84deee29118b9da590938", - "79c1db32ee6d619da6f8bc08dba1f2a261084a420165a2157b61c9061980561f", - "7267f46de5e3dfc4f6524a783d5f994deeb5636b37e68657ba644029893ea331", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "da78034b429d205058740c36e67ef834eee6f5b82c270914469422d14b4d0935", + "d525794afb5f4cd15ddadd759349a63bbd9e4d65113b89a7c1710e2f251a0202", + "cdc18ed79aa8bde9a857184b9631beb509ca04fb69e3ba13594efd01db820c28", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "22ea36807303b811f914db34ccb0107f7f1eb84b8e96f45aeec844aaad200a1e", - "0666d129cd813c3437c083de4919d0e257ad6532f127edd47fd6bccf84e94420", - "7267f46de5e3dfc4f6524a783d5f994deeb5636b37e68657ba644029893ea331", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "562637b022f6e9effd65e672f29b802448d2fcaa9577d54cd259ae167e374023", + "b7d5a87a09327b6f20710bfb0f1339c0ecef17ca23142e5b47d1bd9ce1a35018", + "cdc18ed79aa8bde9a857184b9631beb509ca04fb69e3ba13594efd01db820c28", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "9d209194cce941f940f89d86f347b7a065f60df42e6e7a3c9103b2c5155a9b3d", - "0666d129cd813c3437c083de4919d0e257ad6532f127edd47fd6bccf84e94420", - "7267f46de5e3dfc4f6524a783d5f994deeb5636b37e68657ba644029893ea331", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "d81f3a9036cf3d6d227ed89873ed22c0e99405c154a76de634eb0028ba449b20", + "b7d5a87a09327b6f20710bfb0f1339c0ecef17ca23142e5b47d1bd9ce1a35018", + "cdc18ed79aa8bde9a857184b9631beb509ca04fb69e3ba13594efd01db820c28", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "9ae5daaa32ef289096f177999b67a42a4a6b853c635988061c19d512c5565f22", - "a24d416694fca44b22fe0a9113efad48db9aecc677fa337d274d72ab18899215", - "1ba655cfb279350f419e91d3940f943ca8c1b0c0e56b9766b722621e29080839", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "8b488c70df375a647ad0d68fdd07d83ab29bc9e0082ef319e16fe6dda8f0cf03", + "1bfd3e0384a3ed30a839c6173b7692cc707f2e18b9d972b32550306d0719ba29", + "4ebbb49331f48c126de53406c9fabe490193028ad84f5a26a17516ad9564791c", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "2ff67e7a945419204074dceaf8d6ed51ad2cf0db26452401c044ac3acabaf302", - "a24d416694fca44b22fe0a9113efad48db9aecc677fa337d274d72ab18899215", - "1ba655cfb279350f419e91d3940f943ca8c1b0c0e56b9766b722621e29080839", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "63486122749d5e79f2e8c061aa41593c791b919eb5f459289d262c3ee74b7821", + "1bfd3e0384a3ed30a839c6173b7692cc707f2e18b9d972b32550306d0719ba29", + "4ebbb49331f48c126de53406c9fabe490193028ad84f5a26a17516ad9564791c", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "1a1627becaf200aec6560e6bf9c812de8ffb75ec4285e34a2da62b7f95f81a2b", - "68b50ac31582a7ce46565f5459b8fbe03f5243aae4b91aa59ef9b0458b35e424", - "1ba655cfb279350f419e91d3940f943ca8c1b0c0e56b9766b722621e29080839", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "99448a9e0b20160f2b8dd76acde93a8ccf484f71891f87545fc3a81ec487a40e", + "68485f06eda38a345b548657fd7f7f83d4b46acf70724cc3f8b1dbaff8ddc61a", + "4ebbb49331f48c126de53406c9fabe490193028ad84f5a26a17516ad9564791c", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "6c7b30c15d563a11b90d0ea6b18aec5b8ca2d4d23d2420c70e164c39a71b9001", - "68b50ac31582a7ce46565f5459b8fbe03f5243aae4b91aa59ef9b0458b35e424", - "1ba655cfb279350f419e91d3940f943ca8c1b0c0e56b9766b722621e29080839", - "1c715d9474876f8f66ce409a4a33d9fd2ac04fe48e06a522ee0b2b0dbed7232e", + "3d76247b4f9bd343995f9176e38f8df22c4f57d5e719eb069cef7e92b41cb911", + "68485f06eda38a345b548657fd7f7f83d4b46acf70724cc3f8b1dbaff8ddc61a", + "4ebbb49331f48c126de53406c9fabe490193028ad84f5a26a17516ad9564791c", + "4e384b77c1ef87a9d13c03eaecfd8087f82cd7eb142fe128e175603debcdaf11", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], &[ - "56ab7bb4c1512ff1482f0396480fa279d61ab463c4739446e1950acadffa7623", - "7cf463647a99b1eaf86a69870d2b8ab4715883f65ec5266df29bdbe127eb1410", - "cb9924474486f642ef3874e21bb81866aa1c351d6f9544843cc1807f2b925032", - "d85192f68188fa0bfcb30670dedcc7aab8d94b9ecb0e4290401917bb248ea010", + "934c4292c5cc7a2bea6a76904ce06804118cbf8473fbbd947dd2c25f2716d530", + "99891a03946cb96d745ea038044ff806047a34971c7e7ec3661fe035ece2661d", + "f76cec3e22756cf1ecb0bd41485588e2fdf60ff2221cfabbcf1a9bb185408c35", + "2143c3043be1460dfe24cbcd26377ef870454a97e0e8ca51cac8fbf07957423a", ][..], ]; diff --git a/ledger/src/dummy/protocol_state.bin b/ledger/src/dummy/protocol_state.bin index 7ef96fdce..35e54c6f9 100644 Binary files a/ledger/src/dummy/protocol_state.bin and b/ledger/src/dummy/protocol_state.bin differ diff --git a/ledger/src/generators/user_command.rs b/ledger/src/generators/user_command.rs index b0edb9c5d..5ee4f820a 100644 --- a/ledger/src/generators/user_command.rs +++ b/ledger/src/generators/user_command.rs @@ -14,7 +14,7 @@ use crate::{ }, }, util, Account, AccountId, AuthRequired, BaseLedger, Mask, MyCowMut, Permissions, TokenId, - VerificationKey, ZkAppAccount, + VerificationKey, ZkAppAccount, TXN_VERSION_CURRENT, }; use super::{ @@ -113,7 +113,10 @@ fn zkapp_command_with_ledger( send: AuthRequired::Either, set_delegate: AuthRequired::Either, set_permissions: AuthRequired::Either, - set_verification_key: AuthRequired::Either, + set_verification_key: crate::SetVerificationKey { + auth: AuthRequired::Either, + txn_version: TXN_VERSION_CURRENT, + }, set_zkapp_uri: AuthRequired::Either, edit_action_state: AuthRequired::Either, set_token_symbol: AuthRequired::Either, diff --git a/ledger/src/generators/zkapp_command.rs b/ledger/src/generators/zkapp_command.rs index 312bbddd9..11536f5f8 100644 --- a/ledger/src/generators/zkapp_command.rs +++ b/ledger/src/generators/zkapp_command.rs @@ -37,7 +37,8 @@ use crate::{ zkapp_logic::{self, ZkAppCommandElt}, }, Account, AccountId, AuthRequired, BaseLedger, ControlTag, Mask, MyCowMut, Permissions, - ReceiptChainHash, TokenId, VerificationKey, VotingFor, ZkAppAccount, + ReceiptChainHash, SetVerificationKey, TokenId, VerificationKey, VotingFor, ZkAppAccount, + TXN_VERSION_CURRENT, }; // use mina_p2p_messages::v2::MinaBaseAccountUpdateCallTypeStableV1 as CallType; @@ -479,17 +480,19 @@ fn gen_account_precondition_from_account( } }; - AccountPreconditions::Full(Box::new(predicate_account)) + AccountPreconditions(predicate_account) } else { - AccountPreconditions::Full(Box::new(predicate_account)) + AccountPreconditions(predicate_account) } } else { // Nonce let Account { nonce, .. } = account; match failure { - Some(Failure::InvalidAccountPrecondition) => AccountPreconditions::Nonce(nonce.succ()), - _ => AccountPreconditions::Nonce(*nonce), + Some(Failure::InvalidAccountPrecondition) => { + AccountPreconditions::with_nonce(nonce.succ()) + } + _ => AccountPreconditions::with_nonce(*nonce), } } } @@ -1268,7 +1271,7 @@ fn gen_account_update_body_fee_payer( // f_account_precondition, |_, account| account_precondition_gen(account), // f_account_update_account_precondition, - |nonce| AccountPreconditions::Nonce(*nonce), + |nonce| AccountPreconditions::with_nonce(*nonce), ); body_components.to_fee_payer() @@ -1494,7 +1497,10 @@ pub fn gen_zkapp_command_from(params: GenZkappCommandParams) -> ZkAppCommand { perm.edit_state = AuthRequired::from(auth_tag); } NotPermitedOf::VerificationKey => { - perm.set_verification_key = AuthRequired::from(auth_tag); + perm.set_verification_key = SetVerificationKey { + auth: AuthRequired::from(auth_tag), + txn_version: TXN_VERSION_CURRENT, + } } NotPermitedOf::ZkappUri => { perm.set_zkapp_uri = AuthRequired::from(auth_tag); diff --git a/ledger/src/proofs/block.rs b/ledger/src/proofs/block.rs index c5b2c0bfb..62326a368 100644 --- a/ledger/src/proofs/block.rs +++ b/ledger/src/proofs/block.rs @@ -785,6 +785,7 @@ pub mod consensus { pub slots_per_window: CheckedLength, pub sub_windows_per_window: CheckedLength, pub slots_per_epoch: CheckedLength, + pub grace_period_slots: CheckedLength, pub grace_period_end: CheckedLength, pub slot_duration_ms: CheckedBlockTimeSpan, pub epoch_duration: CheckedBlockTimeSpan, @@ -801,7 +802,15 @@ pub mod consensus { prev_state: &v2::MinaStateProtocolStateValueStableV2, w: &mut Witness, ) -> ConsensusConstantsChecked { - let protocol_constants = &prev_state.body.constants; + let v2::MinaBaseProtocolConstantsCheckedValueStableV1 { + k, + slots_per_epoch, + slots_per_sub_window, + grace_period_slots, + delta, + genesis_state_timestamp, + } = &prev_state.body.constants; + let constraint_constants = &CONSTRAINT_CONSTANTS; let of_u64 = |n: u64| CheckedN::::from_field(n.into()); @@ -809,14 +818,14 @@ pub mod consensus { let block_window_duration_ms = of_u64(constraint_constants.block_window_duration_ms); - let k = of_u32(protocol_constants.k.as_u32()); - let delta = of_u32(protocol_constants.delta.as_u32()); - let slots_per_sub_window = of_u32(protocol_constants.slots_per_sub_window.as_u32()); + let k = of_u32(k.as_u32()); + let delta = of_u32(delta.as_u32()); + let slots_per_sub_window = of_u32(slots_per_sub_window.as_u32()); let sub_windows_per_window = of_u64(constraint_constants.sub_windows_per_window); let slots_per_window = slots_per_sub_window.const_mul(&sub_windows_per_window, w); - let slots_per_epoch = of_u32(protocol_constants.slots_per_epoch.as_u32()); + let slots_per_epoch = of_u32(slots_per_epoch.as_u32()); let slot_duration_ms = block_window_duration_ms.clone(); @@ -830,25 +839,8 @@ pub mod consensus { slot_duration_ms.const_mul(&delta_plus_one, w) }; - let num_days: u64 = 3; - assert!(num_days < 14); - - let grace_period_end = { - let slots = { - let n_days = { - let n_days_ms = of_u64(num_days * N_MILLIS_PER_DAY); - n_days_ms.div_mod(&block_window_duration_ms, w).0 - }; - n_days.min(&slots_per_epoch, w) - }; - match constraint_constants.fork.as_ref() { - None => slots, - Some(f) => { - let previous_global_slot = of_u32(f.previous_global_slot.as_u32()); - previous_global_slot.add(&slots, w) - } - } - }; + let grace_period_slots = of_u32(grace_period_slots.as_u32()); + let grace_period_end = { grace_period_slots.add(&slots_per_window, w) }; let to_length = |v: CheckedN| CheckedLength::from_field(v.to_field()); let to_timespan = |v: CheckedN| CheckedBlockTimeSpan::from_field(v.to_field()); @@ -861,6 +853,7 @@ pub mod consensus { slots_per_window: to_length(slots_per_window), sub_windows_per_window: to_length(sub_windows_per_window), slots_per_epoch: to_length(slots_per_epoch), + grace_period_slots: to_length(grace_period_slots), grace_period_end: to_length(grace_period_end), slot_duration_ms: to_timespan(slot_duration_ms), epoch_duration: to_timespan(epoch_duration), @@ -868,12 +861,22 @@ pub mod consensus { checkpoint_window_size_in_slots: CheckedLength::zero(), delta_duration: to_timespan(delta_duration), genesis_state_timestamp: { - let v = of_u64(protocol_constants.genesis_state_timestamp.as_u64()); + let v = of_u64(genesis_state_timestamp.as_u64()); CheckedBlockTime::from_field(v.to_field()) }, } } + fn check_invariants(constants: &ConsensusConstantsChecked) { + let slots_per_epoch = constants.slots_per_epoch.to_inner().as_u32(); + let slots_per_window = constants.slots_per_window.to_inner().as_u32(); + let grace_period_end = constants.grace_period_end.to_inner().as_u32(); + + let grace_period_effective_end = grace_period_end - slots_per_window; + + assert!(grace_period_effective_end < (slots_per_epoch / 3)) + } + fn create_constant( prev_state: &v2::MinaStateProtocolStateValueStableV2, w: &mut Witness, @@ -904,6 +907,8 @@ pub mod consensus { constants.checkpoint_window_slots_per_year = checkpoint_window_slots_per_year; constants.checkpoint_window_size_in_slots = checkpoint_window_size_in_slots; + check_invariants(&constants); + constants } @@ -1176,7 +1181,7 @@ pub mod consensus { pub min_window_density: CheckedLength, pub sub_window_densities: Vec>, pub last_vrf_output: Box<[bool; VRF_OUTPUT_NBITS]>, - pub curr_global_slot: GlobalSlot, + pub curr_global_slot_since_hard_fork: GlobalSlot, pub global_slot_since_genesis: CheckedSlot, pub total_currency: CheckedAmount, pub staking_epoch_data: EpochData, @@ -1216,7 +1221,7 @@ pub mod consensus { let constants = create_constant(prev_state, w); let v2::ConsensusProofOfStakeDataConsensusStateValueStableV2 { - curr_global_slot: prev_global_slot, + curr_global_slot_since_hard_fork: prev_global_slot, .. } = &prev_state.body.consensus_state; let prev_global_slot: GlobalSlot = prev_global_slot.into(); @@ -1416,7 +1421,7 @@ pub mod consensus { min_window_density, sub_window_densities, last_vrf_output: truncated_vrf_result, - curr_global_slot: next_global_slot, + curr_global_slot_since_hard_fork: next_global_slot, global_slot_since_genesis, total_currency: new_total_currency, staking_epoch_data, @@ -1438,14 +1443,14 @@ fn is_genesis_state_var( ) -> Boolean { use crate::scan_state::currency::Slot; - let curr_global_slot = &cs.curr_global_slot; + let curr_global_slot = &cs.curr_global_slot_since_hard_fork; let slot_number = Slot::from_u32(curr_global_slot.slot_number.as_u32()).to_checked::(); CheckedSlot::zero().equal(&slot_number, w) } fn is_genesis_state_var2(cs: &ConsensusState, w: &mut Witness) -> Boolean { - let curr_global_slot = &cs.curr_global_slot; + let curr_global_slot = &cs.curr_global_slot_since_hard_fork; let slot_number = &curr_global_slot.slot_number; CheckedSlot::zero().equal(slot_number, w) @@ -1692,15 +1697,6 @@ fn block_main<'a>( (new_state_hash, previous_proof_statements) } -pub struct ProverExtendBlockchainInputStableV22 { - pub chain: v2::BlockchainSnarkBlockchainStableV2, - pub next_state: v2::MinaStateProtocolStateValueStableV2, - pub block: v2::MinaStateSnarkTransitionValueStableV2, - pub ledger_proof: Option, - pub prover_state: v2::ConsensusStakeProofStableV2, - pub pending_coinbase: v2::MinaBasePendingCoinbaseWitnessStableV2, -} - struct BlockMainParams<'a> { transition: &'a v2::MinaStateSnarkTransitionValueStableV2, prev_state: &'a v2::MinaStateProtocolStateValueStableV2, diff --git a/ledger/src/proofs/constants.rs b/ledger/src/proofs/constants.rs index 7ed466adc..3d1a5ff92 100644 --- a/ledger/src/proofs/constants.rs +++ b/ledger/src/proofs/constants.rs @@ -27,34 +27,34 @@ pub struct WrapBlockProof {} pub struct StepMergeProof {} pub struct WrapMergeProof {} -pub struct StepZkappProofProof {} +pub struct StepZkappProvedProof {} pub struct StepZkappOptSignedProof {} pub struct StepZkappOptSignedOptSignedProof {} /// Using signature authorization pub struct WrapZkappProof {} /// Using proof authorization -pub struct WrapZkappProofProof {} +pub struct WrapZkappProvedProof {} pub struct WrapZkappOptSignedProof {} impl ProofConstants for StepZkappOptSignedOptSignedProof { const PRIMARY_LEN: usize = 67; - const AUX_LEN: usize = 104744; + const AUX_LEN: usize = 104914; const PREVIOUS_CHALLENGES: usize = 0; - const ROWS: usize = 18590; + const ROWS: usize = 18655; } impl ProofConstants for StepZkappOptSignedProof { const PRIMARY_LEN: usize = 67; - const AUX_LEN: usize = 71779; + const AUX_LEN: usize = 71842; const PREVIOUS_CHALLENGES: usize = 0; - const ROWS: usize = 11298; + const ROWS: usize = 11332; } -impl ProofConstants for StepZkappProofProof { +impl ProofConstants for StepZkappProvedProof { const PRIMARY_LEN: usize = 67; - const AUX_LEN: usize = 210282; + const AUX_LEN: usize = 210345; const PREVIOUS_CHALLENGES: usize = 1; - const ROWS: usize = 19980; + const ROWS: usize = 20013; } // Same values than `WrapTransactionProof` @@ -66,7 +66,7 @@ impl ProofConstants for WrapZkappProof { } // Same values than `WrapTransactionProof` -impl ProofConstants for WrapZkappProofProof { +impl ProofConstants for WrapZkappProvedProof { const PRIMARY_LEN: usize = WrapTransactionProof::PRIMARY_LEN; const AUX_LEN: usize = WrapTransactionProof::AUX_LEN; const PREVIOUS_CHALLENGES: usize = WrapTransactionProof::PREVIOUS_CHALLENGES; @@ -83,9 +83,9 @@ impl ProofConstants for WrapZkappOptSignedProof { impl ProofConstants for StepTransactionProof { const PRIMARY_LEN: usize = 67; - const AUX_LEN: usize = 94386; + const AUX_LEN: usize = 94478; const PREVIOUS_CHALLENGES: usize = 0; - const ROWS: usize = 17794; + const ROWS: usize = 17805; } impl ProofConstants for WrapTransactionProof { @@ -105,23 +105,23 @@ impl ProofConstants for WrapMergeProof { impl ProofConstants for WrapBlockProof { const PRIMARY_LEN: usize = 40; - const AUX_LEN: usize = 179248; + const AUX_LEN: usize = 179208; const PREVIOUS_CHALLENGES: usize = 2; const ROWS: usize = 14657; } impl ProofConstants for StepMergeProof { const PRIMARY_LEN: usize = 67; - const AUX_LEN: usize = 352536; + const AUX_LEN: usize = 352469; const PREVIOUS_CHALLENGES: usize = 2; const ROWS: usize = 29010; } impl ProofConstants for StepBlockProof { const PRIMARY_LEN: usize = 67; - const AUX_LEN: usize = 339034; + const AUX_LEN: usize = 338872; const PREVIOUS_CHALLENGES: usize = 2; - const ROWS: usize = 34811; + const ROWS: usize = 34794; } pub trait ForWrapData { @@ -161,7 +161,7 @@ impl ForWrapData for WrapZkappProof { } } -impl ForWrapData for WrapZkappProofProof { +impl ForWrapData for WrapZkappProvedProof { fn wrap_data() -> WrapData { WrapData { which_index: 4, diff --git a/ledger/src/proofs/data/blockchain_verifier_index.json b/ledger/src/proofs/data/blockchain_verifier_index.json index 70593a695..323c75be1 100644 --- a/ledger/src/proofs/data/blockchain_verifier_index.json +++ b/ledger/src/proofs/data/blockchain_verifier_index.json @@ -1 +1 @@ -{"domain":[0,64,0,0,0,0,0,0,14,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,124,83,5,186,208,232,138,130,164,165,225,15,70,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,63,231,190,175,104,208,52,139,137,189,211,5,198,150,228,88,73,89,113,83,156,141,179,121,176,59,37,36,112,104,135,85,30,25,66,148,64,192,214,221,169,100,14,40,86,176,237,64,248,79,192,245,249,237,125,208,40,207,61,77,56,205,53,91,46,103,102,102,102,64,145,79,107,37,221,161,208,100,112,79,167,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,25],"max_poly_size":32768,"public":40,"prev_challenges":2,"sigma_comm":[{"unshifted":[[31,190,58,198,77,78,225,2,68,128,71,166,90,111,24,136,66,26,243,107,123,81,2,25,109,79,93,26,207,47,139,26,128]],"shifted":null},{"unshifted":[[204,155,99,153,41,215,240,103,13,112,7,224,23,32,40,90,226,71,89,88,100,54,19,142,190,145,143,17,46,173,207,34,128]],"shifted":null},{"unshifted":[[235,201,97,204,126,160,53,240,170,104,36,63,60,38,24,237,228,177,169,137,3,139,124,252,42,38,17,238,97,102,251,2,128]],"shifted":null},{"unshifted":[[5,93,20,61,19,9,227,50,73,252,0,82,214,188,10,53,135,79,13,246,141,132,133,130,190,146,243,124,231,21,214,15,128]],"shifted":null},{"unshifted":[[171,45,183,138,128,103,54,100,138,65,78,246,160,249,123,144,118,166,185,154,255,125,7,31,131,67,142,207,55,159,200,32,128]],"shifted":null},{"unshifted":[[71,61,249,132,193,44,141,50,110,71,164,109,51,23,207,79,233,97,250,245,166,124,94,5,135,253,214,57,170,86,92,47,0]],"shifted":null},{"unshifted":[[85,229,31,211,3,30,30,249,143,186,110,204,23,157,242,230,151,25,20,63,111,246,38,38,196,102,116,75,6,109,33,32,0]],"shifted":null}],"coefficients_comm":[{"unshifted":[[247,18,14,239,1,132,83,83,97,135,56,147,5,156,206,85,243,85,186,143,236,231,240,63,136,131,228,207,229,67,84,49,128]],"shifted":null},{"unshifted":[[34,153,19,7,6,199,214,168,85,115,175,201,103,210,161,216,65,174,193,165,78,160,38,231,64,174,56,82,209,15,6,8,0]],"shifted":null},{"unshifted":[[15,175,236,136,170,97,30,208,237,223,219,73,191,60,57,158,53,28,128,9,31,26,247,102,96,36,135,85,115,7,224,58,0]],"shifted":null},{"unshifted":[[54,178,8,231,47,8,130,92,179,243,239,79,83,32,172,180,50,230,188,179,161,96,181,239,138,89,143,37,127,253,203,61,128]],"shifted":null},{"unshifted":[[20,214,141,97,247,1,144,224,14,109,180,5,72,104,183,164,90,26,174,0,100,150,245,166,192,44,167,197,9,22,79,54,0]],"shifted":null},{"unshifted":[[92,50,124,28,226,242,85,245,160,26,87,12,30,35,220,94,38,228,203,22,153,175,107,104,246,75,173,135,211,145,245,4,0]],"shifted":null},{"unshifted":[[33,17,84,26,219,118,17,221,114,13,217,76,118,27,53,122,254,117,93,220,233,68,54,4,83,230,97,39,112,230,50,62,0]],"shifted":null},{"unshifted":[[202,47,101,190,156,6,174,59,211,142,60,26,152,85,207,43,122,118,129,88,235,95,86,65,47,116,151,74,129,206,226,26,0]],"shifted":null},{"unshifted":[[31,82,69,3,187,250,163,127,250,61,89,118,114,234,25,29,197,134,174,43,238,18,84,24,232,97,108,187,64,250,16,10,128]],"shifted":null},{"unshifted":[[102,167,26,26,119,118,35,90,74,134,59,150,81,218,122,59,113,168,141,41,157,107,5,145,154,19,145,40,214,194,178,33,0]],"shifted":null},{"unshifted":[[54,208,187,185,17,16,53,74,43,76,71,202,247,183,18,80,74,80,92,13,181,129,3,122,20,135,195,178,165,231,99,39,0]],"shifted":null},{"unshifted":[[3,113,99,254,51,222,77,155,64,120,169,120,127,67,41,203,158,254,171,108,16,163,120,228,30,87,83,160,67,110,89,50,128]],"shifted":null},{"unshifted":[[142,206,99,144,141,72,62,179,119,136,153,249,176,23,237,186,186,80,103,250,34,158,198,178,55,138,243,36,114,254,115,29,128]],"shifted":null},{"unshifted":[[175,76,212,43,83,157,233,53,93,4,234,51,185,240,90,43,115,50,54,164,183,6,172,175,101,4,199,123,136,93,223,47,128]],"shifted":null},{"unshifted":[[57,77,70,180,224,192,255,212,214,255,81,138,132,84,195,245,202,163,99,52,87,33,179,207,21,217,84,125,136,186,41,13,128]],"shifted":null}],"generic_comm":{"unshifted":[[27,146,27,178,115,217,236,84,223,58,217,188,250,39,187,5,18,223,81,182,95,207,192,24,62,105,78,59,116,98,54,54,0]],"shifted":null},"psm_comm":{"unshifted":[[36,67,48,73,217,213,36,17,160,254,50,71,42,96,177,24,28,81,175,64,170,237,33,199,103,99,12,103,245,62,139,10,0]],"shifted":null},"complete_add_comm":{"unshifted":[[75,77,49,91,184,92,35,106,198,60,105,235,222,123,48,189,124,69,3,83,253,6,92,231,124,120,31,241,24,146,133,30,128]],"shifted":null},"mul_comm":{"unshifted":[[197,185,199,124,195,174,234,122,103,40,90,6,39,21,155,185,37,121,129,132,113,182,49,43,169,5,212,140,58,125,201,62,128]],"shifted":null},"emul_comm":{"unshifted":[[185,12,130,77,130,158,137,66,75,33,168,102,168,39,144,130,33,113,107,102,91,215,215,96,102,94,175,15,2,114,71,17,0]],"shifted":null},"endomul_scalar_comm":{"unshifted":[[221,106,167,87,181,130,220,79,247,1,142,134,8,43,197,187,89,183,212,32,202,239,94,205,78,89,18,100,155,10,195,4,0]],"shifted":null},"range_check0_comm":null,"range_check1_comm":null,"foreign_field_add_comm":null,"foreign_field_mul_comm":null,"xor_comm":null,"rot_comm":null,"shift":[[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[227,162,20,233,19,52,208,202,241,235,133,223,91,215,82,77,115,213,235,122,175,116,42,126,178,212,11,253,200,205,185,0],[198,39,53,13,180,255,55,165,1,160,226,214,148,51,139,230,18,173,50,169,70,0,110,98,18,64,216,96,129,246,124,0],[109,15,68,51,154,51,159,184,164,228,155,241,9,150,32,170,100,153,24,72,43,149,163,151,174,57,185,236,90,212,119,0],[180,9,35,189,120,230,25,200,10,123,57,192,243,241,30,72,0,85,25,210,254,241,106,31,119,212,5,69,229,199,119,0],[132,116,64,98,76,38,66,110,132,128,163,31,40,153,28,190,54,71,223,142,112,240,39,71,122,174,198,236,104,175,179,0],[161,116,1,178,74,86,126,230,188,141,137,24,182,117,6,26,111,19,135,74,167,80,93,147,237,192,111,83,164,28,56,0]],"lookup_index":null} \ No newline at end of file +{"domain":[0,64,0,0,0,0,0,0,14,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,124,83,5,186,208,232,138,130,164,165,225,15,70,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,63,231,190,175,104,208,52,139,137,189,211,5,198,150,228,88,73,89,113,83,156,141,179,121,176,59,37,36,112,104,135,85,30,25,66,148,64,192,214,221,169,100,14,40,86,176,237,64,248,79,192,245,249,237,125,208,40,207,61,77,56,205,53,91,46,103,102,102,102,64,145,79,107,37,221,161,208,100,112,79,167,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,25],"max_poly_size":32768,"public":40,"prev_challenges":2,"sigma_comm":[{"unshifted":[[31,190,58,198,77,78,225,2,68,128,71,166,90,111,24,136,66,26,243,107,123,81,2,25,109,79,93,26,207,47,139,26,128]],"shifted":null},{"unshifted":[[204,155,99,153,41,215,240,103,13,112,7,224,23,32,40,90,226,71,89,88,100,54,19,142,190,145,143,17,46,173,207,34,128]],"shifted":null},{"unshifted":[[235,201,97,204,126,160,53,240,170,104,36,63,60,38,24,237,228,177,169,137,3,139,124,252,42,38,17,238,97,102,251,2,128]],"shifted":null},{"unshifted":[[5,93,20,61,19,9,227,50,73,252,0,82,214,188,10,53,135,79,13,246,141,132,133,130,190,146,243,124,231,21,214,15,128]],"shifted":null},{"unshifted":[[171,45,183,138,128,103,54,100,138,65,78,246,160,249,123,144,118,166,185,154,255,125,7,31,131,67,142,207,55,159,200,32,128]],"shifted":null},{"unshifted":[[71,61,249,132,193,44,141,50,110,71,164,109,51,23,207,79,233,97,250,245,166,124,94,5,135,253,214,57,170,86,92,47,0]],"shifted":null},{"unshifted":[[85,229,31,211,3,30,30,249,143,186,110,204,23,157,242,230,151,25,20,63,111,246,38,38,196,102,116,75,6,109,33,32,0]],"shifted":null}],"coefficients_comm":[{"unshifted":[[254,175,4,122,184,220,22,206,88,200,233,219,44,52,167,60,79,138,26,192,130,47,196,176,202,102,120,217,129,104,231,33,0]],"shifted":null},{"unshifted":[[34,153,19,7,6,199,214,168,85,115,175,201,103,210,161,216,65,174,193,165,78,160,38,231,64,174,56,82,209,15,6,8,0]],"shifted":null},{"unshifted":[[15,175,236,136,170,97,30,208,237,223,219,73,191,60,57,158,53,28,128,9,31,26,247,102,96,36,135,85,115,7,224,58,0]],"shifted":null},{"unshifted":[[54,178,8,231,47,8,130,92,179,243,239,79,83,32,172,180,50,230,188,179,161,96,181,239,138,89,143,37,127,253,203,61,128]],"shifted":null},{"unshifted":[[20,214,141,97,247,1,144,224,14,109,180,5,72,104,183,164,90,26,174,0,100,150,245,166,192,44,167,197,9,22,79,54,0]],"shifted":null},{"unshifted":[[243,249,251,17,160,10,209,35,226,194,227,67,132,88,179,199,98,2,6,152,132,119,11,242,96,153,68,139,202,10,220,22,128]],"shifted":null},{"unshifted":[[33,17,84,26,219,118,17,221,114,13,217,76,118,27,53,122,254,117,93,220,233,68,54,4,83,230,97,39,112,230,50,62,0]],"shifted":null},{"unshifted":[[202,47,101,190,156,6,174,59,211,142,60,26,152,85,207,43,122,118,129,88,235,95,86,65,47,116,151,74,129,206,226,26,0]],"shifted":null},{"unshifted":[[31,82,69,3,187,250,163,127,250,61,89,118,114,234,25,29,197,134,174,43,238,18,84,24,232,97,108,187,64,250,16,10,128]],"shifted":null},{"unshifted":[[102,167,26,26,119,118,35,90,74,134,59,150,81,218,122,59,113,168,141,41,157,107,5,145,154,19,145,40,214,194,178,33,0]],"shifted":null},{"unshifted":[[54,208,187,185,17,16,53,74,43,76,71,202,247,183,18,80,74,80,92,13,181,129,3,122,20,135,195,178,165,231,99,39,0]],"shifted":null},{"unshifted":[[3,113,99,254,51,222,77,155,64,120,169,120,127,67,41,203,158,254,171,108,16,163,120,228,30,87,83,160,67,110,89,50,128]],"shifted":null},{"unshifted":[[142,206,99,144,141,72,62,179,119,136,153,249,176,23,237,186,186,80,103,250,34,158,198,178,55,138,243,36,114,254,115,29,128]],"shifted":null},{"unshifted":[[175,76,212,43,83,157,233,53,93,4,234,51,185,240,90,43,115,50,54,164,183,6,172,175,101,4,199,123,136,93,223,47,128]],"shifted":null},{"unshifted":[[57,77,70,180,224,192,255,212,214,255,81,138,132,84,195,245,202,163,99,52,87,33,179,207,21,217,84,125,136,186,41,13,128]],"shifted":null}],"generic_comm":{"unshifted":[[27,146,27,178,115,217,236,84,223,58,217,188,250,39,187,5,18,223,81,182,95,207,192,24,62,105,78,59,116,98,54,54,0]],"shifted":null},"psm_comm":{"unshifted":[[36,67,48,73,217,213,36,17,160,254,50,71,42,96,177,24,28,81,175,64,170,237,33,199,103,99,12,103,245,62,139,10,0]],"shifted":null},"complete_add_comm":{"unshifted":[[75,77,49,91,184,92,35,106,198,60,105,235,222,123,48,189,124,69,3,83,253,6,92,231,124,120,31,241,24,146,133,30,128]],"shifted":null},"mul_comm":{"unshifted":[[197,185,199,124,195,174,234,122,103,40,90,6,39,21,155,185,37,121,129,132,113,182,49,43,169,5,212,140,58,125,201,62,128]],"shifted":null},"emul_comm":{"unshifted":[[185,12,130,77,130,158,137,66,75,33,168,102,168,39,144,130,33,113,107,102,91,215,215,96,102,94,175,15,2,114,71,17,0]],"shifted":null},"endomul_scalar_comm":{"unshifted":[[221,106,167,87,181,130,220,79,247,1,142,134,8,43,197,187,89,183,212,32,202,239,94,205,78,89,18,100,155,10,195,4,0]],"shifted":null},"range_check0_comm":null,"range_check1_comm":null,"foreign_field_add_comm":null,"foreign_field_mul_comm":null,"xor_comm":null,"rot_comm":null,"shift":[[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[227,162,20,233,19,52,208,202,241,235,133,223,91,215,82,77,115,213,235,122,175,116,42,126,178,212,11,253,200,205,185,0],[198,39,53,13,180,255,55,165,1,160,226,214,148,51,139,230,18,173,50,169,70,0,110,98,18,64,216,96,129,246,124,0],[109,15,68,51,154,51,159,184,164,228,155,241,9,150,32,170,100,153,24,72,43,149,163,151,174,57,185,236,90,212,119,0],[180,9,35,189,120,230,25,200,10,123,57,192,243,241,30,72,0,85,25,210,254,241,106,31,119,212,5,69,229,199,119,0],[132,116,64,98,76,38,66,110,132,128,163,31,40,153,28,190,54,71,223,142,112,240,39,71,122,174,198,236,104,175,179,0],[161,116,1,178,74,86,126,230,188,141,137,24,182,117,6,26,111,19,135,74,167,80,93,147,237,192,111,83,164,28,56,0]],"lookup_index":null} \ No newline at end of file diff --git a/ledger/src/proofs/data/transaction_verifier_index.json b/ledger/src/proofs/data/transaction_verifier_index.json index 34009d3c5..9596bfe22 100644 --- a/ledger/src/proofs/data/transaction_verifier_index.json +++ b/ledger/src/proofs/data/transaction_verifier_index.json @@ -1 +1 @@ -{"domain":[0,64,0,0,0,0,0,0,14,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,124,83,5,186,208,232,138,130,164,165,225,15,70,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,63,231,190,175,104,208,52,139,137,189,211,5,198,150,228,88,73,89,113,83,156,141,179,121,176,59,37,36,112,104,135,85,30,25,66,148,64,192,214,221,169,100,14,40,86,176,237,64,248,79,192,245,249,237,125,208,40,207,61,77,56,205,53,91,46,103,102,102,102,64,145,79,107,37,221,161,208,100,112,79,167,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,25],"max_poly_size":32768,"public":40,"prev_challenges":2,"sigma_comm":[{"unshifted":[[183,147,16,233,153,35,29,179,67,34,21,88,160,138,135,233,220,111,109,199,144,26,100,18,11,92,31,28,191,3,255,58,128]],"shifted":null},{"unshifted":[[188,181,117,68,140,236,191,156,19,149,193,214,128,86,245,255,66,164,109,40,103,99,226,100,188,117,40,30,119,155,20,13,0]],"shifted":null},{"unshifted":[[237,163,216,152,16,51,137,91,66,18,174,241,80,234,123,212,24,52,20,224,41,46,174,124,105,104,69,15,29,212,102,40,0]],"shifted":null},{"unshifted":[[178,12,163,194,229,92,204,83,67,14,199,78,133,175,222,141,82,147,70,9,248,139,163,151,187,160,225,55,144,15,10,12,0]],"shifted":null},{"unshifted":[[235,152,196,58,67,84,237,140,231,228,134,253,9,64,20,35,247,44,6,198,116,254,151,49,44,241,180,161,240,254,42,52,0]],"shifted":null},{"unshifted":[[248,234,162,222,154,237,23,223,97,209,76,178,213,87,231,54,31,74,123,98,153,66,250,167,104,123,98,234,148,114,111,1,128]],"shifted":null},{"unshifted":[[154,5,0,187,231,228,255,57,242,54,101,143,21,171,58,183,169,73,33,153,244,243,54,96,30,96,187,144,182,7,59,20,128]],"shifted":null}],"coefficients_comm":[{"unshifted":[[226,83,88,206,162,18,8,224,237,176,169,58,247,41,108,166,139,161,249,147,40,71,107,73,242,21,217,167,217,222,162,41,128]],"shifted":null},{"unshifted":[[241,84,57,85,18,110,251,192,63,158,144,102,18,133,221,218,227,4,27,134,79,37,184,123,84,96,243,242,38,46,56,8,128]],"shifted":null},{"unshifted":[[39,246,229,192,203,48,121,61,213,114,216,48,219,34,123,105,98,17,253,59,63,55,247,9,110,128,252,228,74,41,113,60,128]],"shifted":null},{"unshifted":[[23,112,243,246,188,132,213,40,125,85,15,138,188,217,223,56,242,94,240,243,221,27,22,27,211,203,206,166,111,236,101,3,128]],"shifted":null},{"unshifted":[[141,51,148,248,155,142,88,20,117,74,153,136,92,25,133,97,55,163,222,21,186,128,121,234,88,107,194,231,29,5,140,44,0]],"shifted":null},{"unshifted":[[55,67,208,175,202,231,171,213,168,215,32,215,164,5,123,137,24,123,247,163,49,114,100,157,240,38,51,227,88,190,173,62,128]],"shifted":null},{"unshifted":[[235,69,81,91,68,69,190,248,190,234,143,114,196,86,185,209,71,237,40,192,238,234,139,33,215,183,164,181,128,66,188,20,0]],"shifted":null},{"unshifted":[[3,221,81,228,27,97,214,229,45,62,55,15,222,216,14,106,37,193,170,53,113,92,20,129,223,213,51,227,237,129,69,49,128]],"shifted":null},{"unshifted":[[163,162,101,115,84,146,144,103,12,52,106,3,179,210,203,251,30,168,52,203,215,72,104,139,161,7,144,239,176,42,137,49,128]],"shifted":null},{"unshifted":[[33,200,127,127,46,110,106,162,173,118,43,1,219,34,12,144,87,79,94,47,193,197,114,244,105,185,250,37,208,47,200,19,0]],"shifted":null},{"unshifted":[[95,63,10,11,6,203,22,221,242,239,19,213,79,189,224,143,60,252,87,33,18,111,143,30,128,56,222,103,146,29,209,55,128]],"shifted":null},{"unshifted":[[251,154,13,34,142,140,220,130,156,116,140,139,141,119,81,153,139,129,128,89,89,211,7,220,191,47,59,96,29,170,129,51,0]],"shifted":null},{"unshifted":[[16,25,236,117,103,213,111,193,14,239,167,102,200,183,80,51,234,177,220,206,162,123,65,61,116,133,73,72,82,19,38,51,0]],"shifted":null},{"unshifted":[[100,17,144,200,187,48,33,216,127,12,12,32,220,254,232,12,34,135,233,134,186,12,129,128,119,255,115,166,126,109,57,63,128]],"shifted":null},{"unshifted":[[109,178,72,4,95,36,196,26,85,87,197,250,193,201,95,53,0,201,116,118,116,96,53,169,197,138,26,94,26,136,215,44,0]],"shifted":null}],"generic_comm":{"unshifted":[[161,195,223,170,206,84,139,171,229,188,238,11,133,206,241,29,25,229,164,250,11,52,23,71,97,164,120,5,130,162,182,17,0]],"shifted":null},"psm_comm":{"unshifted":[[228,9,131,220,113,171,89,106,138,218,28,91,97,245,98,168,174,248,255,188,95,27,89,127,57,218,57,188,110,181,35,56,128]],"shifted":null},"complete_add_comm":{"unshifted":[[94,185,21,143,142,37,255,13,155,17,161,108,205,103,175,71,161,137,160,211,0,147,192,144,38,194,66,7,66,3,61,26,0]],"shifted":null},"mul_comm":{"unshifted":[[133,74,166,27,128,9,81,133,250,42,133,0,22,82,218,60,183,56,87,170,114,53,156,235,2,65,202,89,40,71,158,47,0]],"shifted":null},"emul_comm":{"unshifted":[[108,145,111,233,215,174,167,25,77,172,149,9,232,228,36,35,71,97,219,190,3,138,180,143,115,17,92,196,227,83,139,1,128]],"shifted":null},"endomul_scalar_comm":{"unshifted":[[132,95,45,27,219,204,37,197,173,0,93,236,201,189,63,12,221,146,140,21,122,173,197,90,136,221,28,215,79,142,229,27,0]],"shifted":null},"range_check0_comm":null,"range_check1_comm":null,"foreign_field_add_comm":null,"foreign_field_mul_comm":null,"xor_comm":null,"rot_comm":null,"shift":[[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[227,162,20,233,19,52,208,202,241,235,133,223,91,215,82,77,115,213,235,122,175,116,42,126,178,212,11,253,200,205,185,0],[198,39,53,13,180,255,55,165,1,160,226,214,148,51,139,230,18,173,50,169,70,0,110,98,18,64,216,96,129,246,124,0],[109,15,68,51,154,51,159,184,164,228,155,241,9,150,32,170,100,153,24,72,43,149,163,151,174,57,185,236,90,212,119,0],[180,9,35,189,120,230,25,200,10,123,57,192,243,241,30,72,0,85,25,210,254,241,106,31,119,212,5,69,229,199,119,0],[132,116,64,98,76,38,66,110,132,128,163,31,40,153,28,190,54,71,223,142,112,240,39,71,122,174,198,236,104,175,179,0],[161,116,1,178,74,86,126,230,188,141,137,24,182,117,6,26,111,19,135,74,167,80,93,147,237,192,111,83,164,28,56,0]],"lookup_index":null} \ No newline at end of file +{"domain":[0,64,0,0,0,0,0,0,14,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,124,83,5,186,208,232,138,130,164,165,225,15,70,34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,63,231,190,175,104,208,52,139,137,189,211,5,198,150,228,88,73,89,113,83,156,141,179,121,176,59,37,36,112,104,135,85,30,25,66,148,64,192,214,221,169,100,14,40,86,176,237,64,248,79,192,245,249,237,125,208,40,207,61,77,56,205,53,91,46,103,102,102,102,64,145,79,107,37,221,161,208,100,112,79,167,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,25],"max_poly_size":32768,"public":40,"prev_challenges":2,"sigma_comm":[{"unshifted":[[183,147,16,233,153,35,29,179,67,34,21,88,160,138,135,233,220,111,109,199,144,26,100,18,11,92,31,28,191,3,255,58,128]],"shifted":null},{"unshifted":[[188,181,117,68,140,236,191,156,19,149,193,214,128,86,245,255,66,164,109,40,103,99,226,100,188,117,40,30,119,155,20,13,0]],"shifted":null},{"unshifted":[[237,163,216,152,16,51,137,91,66,18,174,241,80,234,123,212,24,52,20,224,41,46,174,124,105,104,69,15,29,212,102,40,0]],"shifted":null},{"unshifted":[[178,12,163,194,229,92,204,83,67,14,199,78,133,175,222,141,82,147,70,9,248,139,163,151,187,160,225,55,144,15,10,12,0]],"shifted":null},{"unshifted":[[235,152,196,58,67,84,237,140,231,228,134,253,9,64,20,35,247,44,6,198,116,254,151,49,44,241,180,161,240,254,42,52,0]],"shifted":null},{"unshifted":[[248,234,162,222,154,237,23,223,97,209,76,178,213,87,231,54,31,74,123,98,153,66,250,167,104,123,98,234,148,114,111,1,128]],"shifted":null},{"unshifted":[[154,5,0,187,231,228,255,57,242,54,101,143,21,171,58,183,169,73,33,153,244,243,54,96,30,96,187,144,182,7,59,20,128]],"shifted":null}],"coefficients_comm":[{"unshifted":[[97,86,67,142,246,26,205,252,211,240,12,152,120,129,98,20,102,155,162,3,185,83,37,158,21,61,142,201,72,142,208,59,0]],"shifted":null},{"unshifted":[[65,26,150,160,134,117,234,203,201,152,52,76,108,183,40,198,47,91,61,240,126,36,7,172,95,122,161,8,81,98,3,42,128]],"shifted":null},{"unshifted":[[39,246,229,192,203,48,121,61,213,114,216,48,219,34,123,105,98,17,253,59,63,55,247,9,110,128,252,228,74,41,113,60,128]],"shifted":null},{"unshifted":[[23,112,243,246,188,132,213,40,125,85,15,138,188,217,223,56,242,94,240,243,221,27,22,27,211,203,206,166,111,236,101,3,128]],"shifted":null},{"unshifted":[[141,51,148,248,155,142,88,20,117,74,153,136,92,25,133,97,55,163,222,21,186,128,121,234,88,107,194,231,29,5,140,44,0]],"shifted":null},{"unshifted":[[197,254,225,37,205,189,174,142,9,255,36,232,235,234,115,216,175,204,255,108,115,17,123,187,221,179,135,208,220,142,208,54,0]],"shifted":null},{"unshifted":[[235,69,81,91,68,69,190,248,190,234,143,114,196,86,185,209,71,237,40,192,238,234,139,33,215,183,164,181,128,66,188,20,0]],"shifted":null},{"unshifted":[[3,221,81,228,27,97,214,229,45,62,55,15,222,216,14,106,37,193,170,53,113,92,20,129,223,213,51,227,237,129,69,49,128]],"shifted":null},{"unshifted":[[163,162,101,115,84,146,144,103,12,52,106,3,179,210,203,251,30,168,52,203,215,72,104,139,161,7,144,239,176,42,137,49,128]],"shifted":null},{"unshifted":[[33,200,127,127,46,110,106,162,173,118,43,1,219,34,12,144,87,79,94,47,193,197,114,244,105,185,250,37,208,47,200,19,0]],"shifted":null},{"unshifted":[[95,63,10,11,6,203,22,221,242,239,19,213,79,189,224,143,60,252,87,33,18,111,143,30,128,56,222,103,146,29,209,55,128]],"shifted":null},{"unshifted":[[251,154,13,34,142,140,220,130,156,116,140,139,141,119,81,153,139,129,128,89,89,211,7,220,191,47,59,96,29,170,129,51,0]],"shifted":null},{"unshifted":[[16,25,236,117,103,213,111,193,14,239,167,102,200,183,80,51,234,177,220,206,162,123,65,61,116,133,73,72,82,19,38,51,0]],"shifted":null},{"unshifted":[[100,17,144,200,187,48,33,216,127,12,12,32,220,254,232,12,34,135,233,134,186,12,129,128,119,255,115,166,126,109,57,63,128]],"shifted":null},{"unshifted":[[109,178,72,4,95,36,196,26,85,87,197,250,193,201,95,53,0,201,116,118,116,96,53,169,197,138,26,94,26,136,215,44,0]],"shifted":null}],"generic_comm":{"unshifted":[[161,195,223,170,206,84,139,171,229,188,238,11,133,206,241,29,25,229,164,250,11,52,23,71,97,164,120,5,130,162,182,17,0]],"shifted":null},"psm_comm":{"unshifted":[[228,9,131,220,113,171,89,106,138,218,28,91,97,245,98,168,174,248,255,188,95,27,89,127,57,218,57,188,110,181,35,56,128]],"shifted":null},"complete_add_comm":{"unshifted":[[94,185,21,143,142,37,255,13,155,17,161,108,205,103,175,71,161,137,160,211,0,147,192,144,38,194,66,7,66,3,61,26,0]],"shifted":null},"mul_comm":{"unshifted":[[133,74,166,27,128,9,81,133,250,42,133,0,22,82,218,60,183,56,87,170,114,53,156,235,2,65,202,89,40,71,158,47,0]],"shifted":null},"emul_comm":{"unshifted":[[108,145,111,233,215,174,167,25,77,172,149,9,232,228,36,35,71,97,219,190,3,138,180,143,115,17,92,196,227,83,139,1,128]],"shifted":null},"endomul_scalar_comm":{"unshifted":[[132,95,45,27,219,204,37,197,173,0,93,236,201,189,63,12,221,146,140,21,122,173,197,90,136,221,28,215,79,142,229,27,0]],"shifted":null},"range_check0_comm":null,"range_check1_comm":null,"foreign_field_add_comm":null,"foreign_field_mul_comm":null,"xor_comm":null,"rot_comm":null,"shift":[[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[227,162,20,233,19,52,208,202,241,235,133,223,91,215,82,77,115,213,235,122,175,116,42,126,178,212,11,253,200,205,185,0],[198,39,53,13,180,255,55,165,1,160,226,214,148,51,139,230,18,173,50,169,70,0,110,98,18,64,216,96,129,246,124,0],[109,15,68,51,154,51,159,184,164,228,155,241,9,150,32,170,100,153,24,72,43,149,163,151,174,57,185,236,90,212,119,0],[180,9,35,189,120,230,25,200,10,123,57,192,243,241,30,72,0,85,25,210,254,241,106,31,119,212,5,69,229,199,119,0],[132,116,64,98,76,38,66,110,132,128,163,31,40,153,28,190,54,71,223,142,112,240,39,71,122,174,198,236,104,175,179,0],[161,116,1,178,74,86,126,230,188,141,137,24,182,117,6,26,111,19,135,74,167,80,93,147,237,192,111,83,164,28,56,0]],"lookup_index":null} \ No newline at end of file diff --git a/ledger/src/proofs/gates.rs b/ledger/src/proofs/gates.rs index 61699eefe..c1bdbcff0 100644 --- a/ledger/src/proofs/gates.rs +++ b/ledger/src/proofs/gates.rs @@ -8,7 +8,7 @@ use once_cell::sync::Lazy; use super::{ constants::{ StepBlockProof, StepMergeProof, StepTransactionProof, StepZkappOptSignedOptSignedProof, - StepZkappOptSignedProof, StepZkappProofProof, WrapBlockProof, WrapTransactionProof, + StepZkappOptSignedProof, StepZkappProvedProof, WrapBlockProof, WrapTransactionProof, }, field::FieldWitness, transaction::{make_prover_index, InternalVars, Prover, V}, @@ -20,127 +20,126 @@ use mina_p2p_messages::binprot::{ }; struct Gates { - gates: Vec>, - wrap_gates: Vec>, - merge_gates: Vec>, - block_gates: Vec>, - block_wrap_gates: Vec>, - zkapp_step_opt_signed_opt_signed_gates: Vec>, - zkapp_step_opt_signed_gates: Vec>, - zkapp_step_proof_gates: Vec>, - internal_vars: HashMap, Option)>, - rows_rev: Vec>>, - internal_vars_wrap: HashMap, Option)>, - rows_rev_wrap: Vec>>, - merge_internal_vars: HashMap, Option)>, - merge_rows_rev: Vec>>, - block_internal_vars: HashMap, Option)>, - block_rows_rev: Vec>>, - block_wrap_internal_vars: HashMap, Option)>, - block_wrap_rows_rev: Vec>>, - zkapp_step_opt_signed_opt_signed_internal_vars: HashMap, Option)>, - zkapp_step_opt_signed_opt_signed_rows_rev: Vec>>, - zkapp_step_opt_signed_internal_vars: HashMap, Option)>, - zkapp_step_opt_signed_rows_rev: Vec>>, - zkapp_step_proof_internal_vars: HashMap, Option)>, - zkapp_step_proof_rows_rev: Vec>>, + step_tx_gates: Vec>, + wrap_tx_gates: Vec>, + step_merge_gates: Vec>, + step_block_gates: Vec>, + wrap_block_gates: Vec>, + step_opt_signed_opt_signed_gates: Vec>, + step_opt_signed_gates: Vec>, + step_proved_gates: Vec>, + step_tx_internal_vars: HashMap, Option)>, + step_tx_rows_rev: Vec>>, + wrap_tx_internal_vars: HashMap, Option)>, + wrap_tx_rows_rev: Vec>>, + step_merge_internal_vars: HashMap, Option)>, + step_merge_rows_rev: Vec>>, + step_block_internal_vars: HashMap, Option)>, + step_block_rows_rev: Vec>>, + wrap_block_internal_vars: HashMap, Option)>, + wrap_block_rows_rev: Vec>>, + step_opt_signed_opt_signed_internal_vars: HashMap, Option)>, + step_opt_signed_opt_signed_rows_rev: Vec>>, + step_opt_signed_internal_vars: HashMap, Option)>, + step_opt_signed_rows_rev: Vec>>, + step_proved_internal_vars: HashMap, Option)>, + step_proved_rows_rev: Vec>>, } fn read_gates() -> Gates { - let base_dir = Path::new(env!("CARGO_MANIFEST_DIR")); - let base_dir = base_dir.join("rampup4"); - fn read_gates_file( filepath: &impl AsRef, ) -> std::io::Result>> { + use serde_with::serde_as; + + #[serde_as] + #[derive(serde::Deserialize)] + struct GatesFile { + public_input_size: usize, + #[serde_as(as = "Vec<_>")] + gates: Vec>, + } + let file = std::fs::File::open(filepath)?; let reader = std::io::BufReader::new(file); - serde_json::from_reader(reader).map_err(Into::into) + let data: GatesFile = serde_json::from_reader(reader)?; + Ok(data.gates) + } + + fn make( + filename: &str, + ) -> ( + HashMap, Option)>, + Vec>>, + Vec>, + ) { + let base_dir = Path::new(env!("CARGO_MANIFEST_DIR")); + let base_dir = base_dir.join("berkeley_rc1"); + + let internal_vars_path = base_dir.join(format!("{}_internal_vars.bin", filename)); + let rows_rev_path = base_dir.join(format!("{}_rows_rev.bin", filename)); + let gates_path = base_dir.join(format!("{}_gates.json", filename)); + + let gates: Vec> = read_gates_file(&gates_path).unwrap(); + let (internal_vars_path, rows_rev_path) = + read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); + + (internal_vars_path, rows_rev_path, gates) } - let internal_vars_path = base_dir.join("internal_vars_rampup4.bin"); - let rows_rev_path = base_dir.join("rows_rev_rampup4.bin"); - let (internal_vars, rows_rev) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - - let internal_vars_path = base_dir.join("internal_vars_wrap_rampup4.bin"); - let rows_rev_path = base_dir.join("rows_rev_wrap_rampup4.bin"); - let (internal_vars_wrap, rows_rev_wrap) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - - let internal_vars_path = base_dir.join("merge_internal_vars.bin"); - let rows_rev_path = base_dir.join("merge_rows_rev.bin"); - let (merge_internal_vars, merge_rows_rev) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - - let internal_vars_path = base_dir.join("block_internal_vars.bin"); - let rows_rev_path = base_dir.join("block_rows_rev.bin"); - let (block_internal_vars, block_rows_rev) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - - let internal_vars_path = base_dir.join("block_wrap_internal_vars.bin"); - let rows_rev_path = base_dir.join("block_wrap_rows_rev.bin"); - let (block_wrap_internal_vars, block_wrap_rows_rev) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - - let internal_vars_path = base_dir.join("zkapp_step_internal_vars.bin"); - let rows_rev_path = base_dir.join("zkapp_step_rows_rev.bin"); - let (zkapp_step_opt_signed_opt_signed_internal_vars, zkapp_step_opt_signed_opt_signed_rows_rev) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - - let internal_vars_path = base_dir.join("zkapp_step_opt_signed_internal_vars.bin"); - let rows_rev_path = base_dir.join("zkapp_step_opt_signed_rows_rev.bin"); - let (zkapp_step_opt_signed_internal_vars, zkapp_step_opt_signed_rows_rev) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - - let gates: Vec> = - read_gates_file(&base_dir.join("gates_step_rampup4.json")).unwrap(); - let wrap_gates: Vec> = - read_gates_file(&base_dir.join("gates_wrap_rampup4.json")).unwrap(); - let merge_gates: Vec> = - read_gates_file(&base_dir.join("gates_merge_rampup4.json")).unwrap(); - - let block_gates: Vec> = - read_gates_file(&base_dir.join("block_gates.json")).unwrap(); - let block_wrap_gates: Vec> = - read_gates_file(&base_dir.join("block_wrap_gates.json")).unwrap(); - let zkapp_step_opt_signed_opt_signed_gates: Vec> = - read_gates_file(&base_dir.join("zkapp_step_gates.json")).unwrap(); - let zkapp_step_opt_signed_gates: Vec> = - read_gates_file(&base_dir.join("zkapp_step_opt_signed_gates.json")).unwrap(); - - let internal_vars_path = base_dir.join("zkapp_step_proof_internal_vars.bin"); - let rows_rev_path = base_dir.join("zkapp_step_proof_rows_rev.bin"); - let (zkapp_step_proof_internal_vars, zkapp_step_proof_rows_rev) = - read_constraints_data::(&internal_vars_path, &rows_rev_path).unwrap(); - let zkapp_step_proof_gates: Vec> = - read_gates_file(&base_dir.join("zkapp_step_proof_gates.json")).unwrap(); + let (step_tx_internal_vars, step_tx_rows_rev, step_tx_gates) = { + make("step-step-proving-key-transaction-snark-transaction-0-81cc493d6bc2538fdbee3ad60fd77758") + }; + let (wrap_tx_internal_vars, wrap_tx_rows_rev, wrap_tx_gates) = + { make("wrap-wrap-proving-key-transaction-snark-96f388cb62fd3b955368b475623e0a92") }; + let (step_merge_internal_vars, step_merge_rows_rev, step_merge_gates) = { + make("step-step-proving-key-transaction-snark-merge-1-ba1d52dfdc2dd4d2e61f6c66ff2a5b2f") + }; + let (step_block_internal_vars, step_block_rows_rev, step_block_gates) = + { make("step-step-proving-key-blockchain-snark-step-0-c6715547791ab80660cda1f715ce8c58") }; + let (wrap_block_internal_vars, wrap_block_rows_rev, wrap_block_gates) = + { make("wrap-wrap-proving-key-blockchain-snark-b18a44f63a978aec2c3f3dbb392acbfb") }; + let ( + step_opt_signed_opt_signed_internal_vars, + step_opt_signed_opt_signed_rows_rev, + step_opt_signed_opt_signed_gates, + ) = { + make("step-step-proving-key-transaction-snark-opt_signed-opt_signed-2-4a4a49c139f2fb195603ffc386c41cc6") + }; + let (step_opt_signed_internal_vars, step_opt_signed_rows_rev, step_opt_signed_gates) = { + make( + "step-step-proving-key-transaction-snark-opt_signed-3-6f4b0c362fb64d33fe3c8a3ed1351de5", + ) + }; + let (step_proved_internal_vars, step_proved_rows_rev, step_proved_gates) = { + make("step-step-proving-key-transaction-snark-proved-4-879547e44319e1b0a4bb2513c66be9f8") + }; Gates { - gates, - wrap_gates, - merge_gates, - block_gates, - internal_vars, - rows_rev, - internal_vars_wrap, - rows_rev_wrap, - merge_internal_vars, - merge_rows_rev, - block_internal_vars, - block_rows_rev, - block_wrap_gates, - block_wrap_internal_vars, - block_wrap_rows_rev, - zkapp_step_opt_signed_opt_signed_gates, - zkapp_step_opt_signed_opt_signed_internal_vars, - zkapp_step_opt_signed_opt_signed_rows_rev, - zkapp_step_opt_signed_gates, - zkapp_step_opt_signed_internal_vars, - zkapp_step_opt_signed_rows_rev, - zkapp_step_proof_gates, - zkapp_step_proof_internal_vars, - zkapp_step_proof_rows_rev, + step_tx_gates, + wrap_tx_gates, + step_merge_gates, + step_block_gates, + step_tx_internal_vars, + step_tx_rows_rev, + wrap_tx_internal_vars, + wrap_tx_rows_rev, + step_merge_internal_vars, + step_merge_rows_rev, + step_block_internal_vars, + step_block_rows_rev, + wrap_block_gates, + wrap_block_internal_vars, + wrap_block_rows_rev, + step_opt_signed_opt_signed_gates, + step_opt_signed_opt_signed_internal_vars, + step_opt_signed_opt_signed_rows_rev, + step_opt_signed_gates, + step_opt_signed_internal_vars, + step_opt_signed_rows_rev, + step_proved_gates, + step_proved_internal_vars, + step_proved_rows_rev, } } @@ -164,91 +163,89 @@ pub fn get_provers() -> Arc { /// Slow, use `get_provers` instead fn make_provers() -> Provers { let Gates { - gates, - wrap_gates, - merge_gates, - block_gates, - internal_vars, - rows_rev, - internal_vars_wrap, - rows_rev_wrap, - merge_internal_vars, - merge_rows_rev, - block_internal_vars, - block_rows_rev, - block_wrap_gates, - block_wrap_internal_vars, - block_wrap_rows_rev, - zkapp_step_opt_signed_opt_signed_gates, - zkapp_step_opt_signed_opt_signed_internal_vars, - zkapp_step_opt_signed_opt_signed_rows_rev, - zkapp_step_opt_signed_gates, - zkapp_step_opt_signed_internal_vars, - zkapp_step_opt_signed_rows_rev, - zkapp_step_proof_gates, - zkapp_step_proof_internal_vars, - zkapp_step_proof_rows_rev, + step_tx_gates, + wrap_tx_gates, + step_merge_gates, + step_block_gates, + step_tx_internal_vars, + step_tx_rows_rev, + wrap_tx_internal_vars, + wrap_tx_rows_rev, + step_merge_internal_vars, + step_merge_rows_rev, + step_block_internal_vars, + step_block_rows_rev, + wrap_block_gates, + wrap_block_internal_vars, + wrap_block_rows_rev, + step_opt_signed_opt_signed_gates, + step_opt_signed_opt_signed_internal_vars, + step_opt_signed_opt_signed_rows_rev, + step_opt_signed_gates, + step_opt_signed_internal_vars, + step_opt_signed_rows_rev, + step_proved_gates, + step_proved_internal_vars, + step_proved_rows_rev, } = read_gates(); - let tx_prover_index = make_prover_index::(gates); - let merge_prover_index = make_prover_index::(merge_gates); - let wrap_prover_index = make_prover_index::(wrap_gates); - let wrap_block_prover_index = make_prover_index::(block_wrap_gates); - let block_prover_index = make_prover_index::(block_gates); + let tx_prover_index = make_prover_index::(step_tx_gates); + let merge_prover_index = make_prover_index::(step_merge_gates); + let wrap_prover_index = make_prover_index::(wrap_tx_gates); + let wrap_block_prover_index = make_prover_index::(wrap_block_gates); + let block_prover_index = make_prover_index::(step_block_gates); let zkapp_step_opt_signed_opt_signed_prover_index = - make_prover_index::( - zkapp_step_opt_signed_opt_signed_gates, - ); + make_prover_index::(step_opt_signed_opt_signed_gates); let zkapp_step_opt_signed_prover_index = - make_prover_index::(zkapp_step_opt_signed_gates); + make_prover_index::(step_opt_signed_gates); let zkapp_step_proof_prover_index = - make_prover_index::(zkapp_step_proof_gates); + make_prover_index::(step_proved_gates); let tx_step_prover = Prover { - internal_vars, - rows_rev, + internal_vars: step_tx_internal_vars, + rows_rev: step_tx_rows_rev, index: tx_prover_index, }; let merge_step_prover = Prover { - internal_vars: merge_internal_vars, - rows_rev: merge_rows_rev, + internal_vars: step_merge_internal_vars, + rows_rev: step_merge_rows_rev, index: merge_prover_index, }; let tx_wrap_prover = Prover { - internal_vars: internal_vars_wrap, - rows_rev: rows_rev_wrap, + internal_vars: wrap_tx_internal_vars, + rows_rev: wrap_tx_rows_rev, index: wrap_prover_index, }; let block_step_prover = Prover { - internal_vars: block_internal_vars, - rows_rev: block_rows_rev, + internal_vars: step_block_internal_vars, + rows_rev: step_block_rows_rev, index: block_prover_index, }; let block_wrap_prover = Prover { - internal_vars: block_wrap_internal_vars, - rows_rev: block_wrap_rows_rev, + internal_vars: wrap_block_internal_vars, + rows_rev: wrap_block_rows_rev, index: wrap_block_prover_index, }; let zkapp_step_opt_signed_opt_signed_prover = Prover { - internal_vars: zkapp_step_opt_signed_opt_signed_internal_vars, - rows_rev: zkapp_step_opt_signed_opt_signed_rows_rev, + internal_vars: step_opt_signed_opt_signed_internal_vars, + rows_rev: step_opt_signed_opt_signed_rows_rev, index: zkapp_step_opt_signed_opt_signed_prover_index, }; let zkapp_step_opt_signed_prover = Prover { - internal_vars: zkapp_step_opt_signed_internal_vars, - rows_rev: zkapp_step_opt_signed_rows_rev, + internal_vars: step_opt_signed_internal_vars, + rows_rev: step_opt_signed_rows_rev, index: zkapp_step_opt_signed_prover_index, }; let zkapp_step_proof_prover = Prover { - internal_vars: zkapp_step_proof_internal_vars, - rows_rev: zkapp_step_proof_rows_rev, + internal_vars: step_proved_internal_vars, + rows_rev: step_proved_rows_rev, index: zkapp_step_proof_prover_index, }; diff --git a/ledger/src/proofs/numbers/nat.rs b/ledger/src/proofs/numbers/nat.rs index a45c04382..9c2d20531 100644 --- a/ledger/src/proofs/numbers/nat.rs +++ b/ledger/src/proofs/numbers/nat.rs @@ -10,6 +10,7 @@ use crate::{ }, scan_state::currency::{ BlockTime, BlockTimeSpan, Index, Length, Magnitude, MinMax, Nonce, Slot, SlotSpan, + TxnVersion, }, ToInputs, }; @@ -114,7 +115,7 @@ pub trait CheckedNat: Boolean::assert_any(&[x_gte_y, y_gte_x], w); let is_equal = field::equal(x, y, w); - let underflow = y_gte_x.and(&is_equal, w); + let underflow = y_gte_x.and(&is_equal.neg(), w); let value = w.exists(match underflow { Boolean::True => F::zero(), @@ -224,23 +225,12 @@ impl CheckedLength { } } -#[derive(Clone, Debug)] -pub struct CheckedSlot(F); -#[derive(Clone, Debug)] -pub struct CheckedSlotSpan(F); -#[derive(Clone, Debug)] -pub struct CheckedLength(F); -#[derive(Clone, Debug)] -pub struct CheckedNonce(F); -#[derive(Clone, Debug)] -pub struct CheckedIndex(F); -#[derive(Clone, Debug)] -pub struct CheckedBlockTime(F); -#[derive(Clone, Debug)] -pub struct CheckedBlockTimeSpan(F); - macro_rules! impl_nat { ($({$name:tt, $unchecked:tt}),*) => ($( + + #[derive(Clone, Debug)] + pub struct $name(F); + impl CheckedNat for $name:: { type Inner = $unchecked; fn to_field(&self) -> F { @@ -289,6 +279,7 @@ macro_rules! impl_nat { } impl_nat!( + {CheckedTxnVersion, TxnVersion}, {CheckedSlot, Slot}, {CheckedSlotSpan, SlotSpan}, {CheckedLength, Length}, diff --git a/ledger/src/proofs/prover.rs b/ledger/src/proofs/prover.rs index d38d13c02..f259e275e 100644 --- a/ledger/src/proofs/prover.rs +++ b/ledger/src/proofs/prover.rs @@ -140,7 +140,9 @@ pub fn make_padded_proof_from_p2p( // https://github.com/MinaProtocol/mina/blob/bfd1009abdbee78979ff0343cc73a3480e862f58/src/lib/pickles/verify.ml#L361C1-L364C51 while challenge_polynomial_commitments.len() < 2 { let padding = get_challenge_polynomial_commitments_padding(); - challenge_polynomial_commitments.to_mut().insert(0, padding); + challenge_polynomial_commitments + .to_mut() + .push_front(padding); } let challenge_polynomial_commitments: Vec> = challenge_polynomial_commitments diff --git a/ledger/src/proofs/public_input/protocol_state.rs b/ledger/src/proofs/public_input/protocol_state.rs index cc27211c4..547e1310b 100644 --- a/ledger/src/proofs/public_input/protocol_state.rs +++ b/ledger/src/proofs/public_input/protocol_state.rs @@ -51,7 +51,7 @@ impl ToInputs for MinaStateProtocolStateBodyValueStableV2 { sub_window_densities, last_vrf_output, total_currency, - curr_global_slot, + curr_global_slot_since_hard_fork, global_slot_since_genesis, staking_epoch_data, next_epoch_data, @@ -78,8 +78,8 @@ impl ToInputs for MinaStateProtocolStateBodyValueStableV2 { } } inputs.append_u64(total_currency.as_u64()); - inputs.append_u32(curr_global_slot.slot_number.as_u32()); - inputs.append_u32(curr_global_slot.slots_per_epoch.as_u32()); + inputs.append_u32(curr_global_slot_since_hard_fork.slot_number.as_u32()); + inputs.append_u32(curr_global_slot_since_hard_fork.slots_per_epoch.as_u32()); inputs.append_u32(global_slot_since_genesis.as_u32()); inputs.append_bool(*has_ancestor_in_same_checkpoint_window); inputs.append_bool(*supercharge_coinbase); @@ -306,6 +306,7 @@ impl ToInputs for MinaBaseProtocolConstantsCheckedValueStableV1 { slots_per_sub_window, delta, genesis_state_timestamp, + grace_period_slots: _, } = self; inputs.append_u32(k.as_u32()); @@ -343,7 +344,7 @@ impl ToInputs for ProtocolStateBody { sub_window_densities, last_vrf_output, total_currency, - curr_global_slot, + curr_global_slot_since_hard_fork, global_slot_since_genesis, staking_epoch_data, next_epoch_data, @@ -366,8 +367,8 @@ impl ToInputs for ProtocolStateBody { } inputs.append(total_currency); - inputs.append(&curr_global_slot.slot_number); - inputs.append(&curr_global_slot.slots_per_epoch); + inputs.append(&curr_global_slot_since_hard_fork.slot_number); + inputs.append(&curr_global_slot_since_hard_fork.slots_per_epoch); inputs.append(global_slot_since_genesis); inputs.append_bool(has_ancestor_in_same_checkpoint_window.as_bool()); inputs.append_bool(supercharge_coinbase.as_bool()); diff --git a/ledger/src/proofs/to_field_elements.rs b/ledger/src/proofs/to_field_elements.rs index 1b2202102..239c86460 100644 --- a/ledger/src/proofs/to_field_elements.rs +++ b/ledger/src/proofs/to_field_elements.rs @@ -520,7 +520,7 @@ impl ToFieldElements sub_window_densities, last_vrf_output, total_currency, - curr_global_slot: + curr_global_slot_since_hard_fork: v2::ConsensusGlobalSlotStableV1 { slot_number, slots_per_epoch, @@ -573,6 +573,7 @@ impl ToFieldElements for v2::MinaBaseProtocolConstantsChecke k, slots_per_epoch, slots_per_sub_window, + grace_period_slots, delta, genesis_state_timestamp, } = self; @@ -580,6 +581,7 @@ impl ToFieldElements for v2::MinaBaseProtocolConstantsChecke k.as_u32().to_field_elements(fields); slots_per_epoch.as_u32().to_field_elements(fields); slots_per_sub_window.as_u32().to_field_elements(fields); + grace_period_slots.as_u32().to_field_elements(fields); delta.as_u32().to_field_elements(fields); genesis_state_timestamp.as_u64().to_field_elements(fields); } @@ -774,17 +776,27 @@ impl ToFieldElements for crate::Timing { impl ToFieldElements for crate::Permissions { fn to_field_elements(&self, fields: &mut Vec) { - self.iter_as_bits(|bit| { - bit.to_field_elements(fields); + use crate::AuthOrVersion; + + self.iter_as_bits(|bit| match bit { + AuthOrVersion::Auth(bit) => bit.to_field_elements(fields), + AuthOrVersion::Version(version) => version.to_field_elements(fields), }); } } impl ToFieldElements for crate::AuthRequired { fn to_field_elements(&self, fields: &mut Vec) { - for bit in self.encode().to_bits() { - bit.to_field_elements(fields); - } + // In OCaml `Controller.if_` + // push values in reverse order (because of OCaml evaluation order) + // https://github.com/MinaProtocol/mina/blob/4283d70c8c5c1bd9eebb0d3e449c36fb0bf0c9af/src/lib/mina_base/permissions.ml#L174 + let crate::AuthRequiredEncoded { + constant, + signature_necessary, + signature_sufficient, + } = self.encode(); + + [signature_sufficient, signature_necessary, constant].to_field_elements(fields); } } diff --git a/ledger/src/proofs/transaction.rs b/ledger/src/proofs/transaction.rs index 945d9bc28..0d17c8d8b 100644 --- a/ledger/src/proofs/transaction.rs +++ b/ledger/src/proofs/transaction.rs @@ -32,7 +32,7 @@ use crate::{ constants::{StepTransactionProof, WrapTransactionProof}, unfinalized::AllEvals, util::sha256_sum, - wrap::WrapParams, + wrap::{self, WrapParams}, }, scan_state::{ currency::{self, Sgn}, @@ -45,7 +45,6 @@ use crate::{ Account, MyCow, ReceiptChainHash, SpongeParamsForField, TimingAsRecord, TokenId, TokenSymbol, }; -use super::field::{field, Boolean, CircuitVar, FieldWitness, ToBoolean}; use super::step::{InductiveRule, OptFlag, StepProof}; use super::{ constants::ProofConstants, @@ -56,6 +55,10 @@ use super::{ witness::Witness, wrap::WrapProof, }; +use super::{ + field::{field, Boolean, CircuitVar, FieldWitness, ToBoolean}, + step, +}; pub trait Check { fn check(&self, w: &mut Witness); @@ -1088,7 +1091,7 @@ impl Check for MinaStateProtocolStateBodyValueStableV2 { sub_window_densities, last_vrf_output: _, total_currency, - curr_global_slot, + curr_global_slot_since_hard_fork, global_slot_since_genesis, staking_epoch_data, next_epoch_data, @@ -1103,6 +1106,7 @@ impl Check for MinaStateProtocolStateBodyValueStableV2 { k, slots_per_epoch, slots_per_sub_window, + grace_period_slots, delta, genesis_state_timestamp, }, @@ -1118,7 +1122,7 @@ impl Check for MinaStateProtocolStateBodyValueStableV2 { sub_window_density.check(w); } total_currency.check(w); - curr_global_slot.check(w); + curr_global_slot_since_hard_fork.check(w); global_slot_since_genesis.check(w); staking_epoch_data.check(w); next_epoch_data.check(w); @@ -1127,6 +1131,7 @@ impl Check for MinaStateProtocolStateBodyValueStableV2 { k.check(w); slots_per_epoch.check(w); slots_per_sub_window.check(w); + grace_period_slots.check(w); delta.check(w); genesis_state_timestamp.check(w); } @@ -1348,7 +1353,7 @@ impl Check for Box { delegate: _, voting_for: _, timing, - permissions: _, + permissions, zkapp: _, } = &**self; @@ -1356,6 +1361,7 @@ impl Check for Box { balance.check(w); nonce.check(w); timing.check(w); + permissions.check(w); } } @@ -2789,16 +2795,16 @@ pub mod transaction_snark { let mut ledger = sparse_ledger.copy_content(); let tag = payload.body.tag.clone(); - let is_user_command = tag.is_user_command().to_boolean(); + let is_user_command = tag.is_user_command(); check_signature(shifted, payload, is_user_command, signer, signature, w); let _signer_pk = compress_var(signer.point(), w); - let is_payment = tag.is_payment().to_boolean(); - let is_stake_delegation = tag.is_stake_delegation().to_boolean(); - let is_fee_transfer = tag.is_fee_transfer().to_boolean(); - let is_coinbase = tag.is_coinbase().to_boolean(); + let is_payment = tag.is_payment(); + let is_stake_delegation = tag.is_stake_delegation(); + let is_fee_transfer = tag.is_fee_transfer(); + let is_coinbase = tag.is_coinbase(); let fee_token = &payload.common.fee_token; let fee_token_default = field::equal(fee_token.0, TokenId::default().0, w); @@ -3570,10 +3576,10 @@ pub mod transaction_snark { dummy_constraints(w); let shifted = create_shifted_inner_curve(w); - let tx = w.exists(tx); - let pending_coinbase_init = w.exists(tx_witness.init_stack.clone()); - let state_body = w.exists(tx_witness.protocol_state_body.clone()); - let global_slot = w.exists(tx_witness.block_global_slot.clone()); + let tx = w.exists(&tx); + let pending_coinbase_init = w.exists(&tx_witness.init_stack); + let state_body = w.exists(&tx_witness.protocol_state_body); + let global_slot = w.exists(&tx_witness.block_global_slot); let sparse_ledger: SparseLedger = (&tx_witness.first_pass_ledger).into(); @@ -3581,11 +3587,11 @@ pub mod transaction_snark { &shifted, statement_with_sok.source.first_pass_ledger, currency::Slot::from_u32(global_slot.as_u32()), - &pending_coinbase_init, + pending_coinbase_init, &statement_with_sok.source.pending_coinbase_stack, &statement_with_sok.target.pending_coinbase_stack, - &state_body, - &tx, + state_body, + tx, &sparse_ledger, w, ); @@ -3773,6 +3779,14 @@ pub fn compute_witness( prover: &Prover, w: &Witness, ) -> [Vec; COLUMNS] { + #[cfg(test)] + { + // Make sure our constants are correct + eprintln!("compute_witness {:?}", std::any::type_name::()); + assert_eq!(C::ROWS, prover.rows_rev.len() + C::PRIMARY_LEN); + assert_eq!(C::AUX_LEN, w.aux().len()); + } + if !w.ocaml_aux.is_empty() { assert_eq!(w.aux().len(), w.ocaml_aux.len()); }; @@ -3786,7 +3800,6 @@ pub fn compute_witness( }; let mut internal_values = HashMap::::with_capacity(13_000); - let public_input_size = C::PRIMARY_LEN; let num_rows = C::ROWS; @@ -3905,7 +3918,7 @@ pub(super) fn create_proof( if only_verify_constraints { let public = &computed_witness[0][0..prover_index.cs.public]; prover_index - .verify(&computed_witness, &public) + .verify(&computed_witness, public) .map_err(|e| { ProofError::ConstraintsNotSatisfied(format!("incorrect witness: {:?}", e)) })?; @@ -3981,16 +3994,16 @@ pub(super) fn generate_tx_proof( let dlog_plonk_index = { PlonkVerificationKeyEvals::from(tx_wrap_prover.index.verifier_index.as_ref().unwrap()) }; - let statement_with_sok = w.exists(statement_with_sok); + let statement_with_sok = Rc::new(w.exists(statement_with_sok)); transaction_snark::main(&statement_with_sok, tx_witness, w); let StepProof { statement: step_statement, prev_evals, proof, - } = super::step::step::( - super::step::StepParams { - app_state: Rc::new(statement_with_sok.clone()), + } = step::step::( + step::StepParams { + app_state: Rc::clone(&statement_with_sok) as _, rule: InductiveRule::empty(), for_step_datas: [], indexes: [], @@ -4014,9 +4027,9 @@ pub(super) fn generate_tx_proof( w.ocaml_aux = ocaml_aux; }; - crate::proofs::wrap::wrap::( + wrap::wrap::( WrapParams { - app_state: Rc::new(statement_with_sok), + app_state: statement_with_sok, proof: &proof, step_statement, prev_evals: &prev_evals, @@ -4090,8 +4103,7 @@ mod tests { proofs::{ block::{generate_block_proof, BlockParams}, constants::{StepBlockProof, StepMergeProof}, - gates::Provers, - gates::{get_provers, read_constraints_data}, + gates::{get_provers, Provers}, merge::{generate_merge_proof, MergeParams}, util::sha256_sum, zkapp::{generate_zkapp_proof, LedgerProof, ZkappParams}, @@ -4113,6 +4125,13 @@ mod tests { PerformJob(mina_p2p_messages::v2::SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse), } + fn panic_in_ci() { + fn is_ci() -> bool { + std::env::var("CI").is_ok() + } + assert!(!is_ci(), "missing circuit files !"); + } + fn read_binprot(mut r: R) -> T where T: binprot::BinProtRead, @@ -4135,7 +4154,8 @@ mod tests { fn read_witnesses(filename: &str) -> Result, ()> { let f = std::fs::read_to_string( std::path::Path::new(env!("CARGO_MANIFEST_DIR")) - .join("rampup4") + .join("berkeley_rc1") + .join("witnesses") .join(filename), ) .unwrap(); @@ -4145,12 +4165,61 @@ mod tests { .collect() } + #[allow(unused)] #[test] - fn test_read_constraints() { - let internal_vars_path = - Path::new(env!("CARGO_MANIFEST_DIR")).join("internal_vars_rampup4.bin"); - let rows_rev_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("rows_rev_rampup4.bin"); - read_constraints_data::(&internal_vars_path, &rows_rev_path); + fn test_convert_requests() { + use binprot::BinProtWrite; + use mina_p2p_messages::v2::*; + + return; + + fn write_binprot(spec: T, mut w: W) { + let mut buf = Vec::new(); + spec.binprot_write(&mut buf).unwrap(); + let len = (buf.len() as u64).to_le_bytes(); + w.write_all(&len).unwrap(); + w.write_all(&buf).unwrap(); + } + + let path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("berkeley_rc1") + .join("tests"); + + let entries = std::fs::read_dir(path) + .unwrap() + .map(|res| res.map(|e| e.path())) + .collect::, std::io::Error>>() + .unwrap(); + + let prover = CompressedPubKey::from_address( + "B62qpK6TcG4sWdtT3BzdbWHiK3RJMj3Zbo9mqwBos7cVsydPMCj5wZx", + ) + .unwrap(); + let fee = crate::scan_state::currency::Fee::from_u64(1_000_000); + + for filename in entries { + let bytes = std::fs::read(&filename).unwrap(); + + let single: SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single = + binprot::BinProtRead::binprot_read(&mut bytes.as_slice()).unwrap(); + let instances = + SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Instances::One(single); + + let job = SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0 { + instances, + fee: (&fee).into(), + }; + let job = + SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse(Some((job, (&prover).into()))); + let job = ExternalSnarkWorkerRequest::PerformJob(job); + + let path = Path::new("/tmp") + .join("requests") + .join(filename.file_name().unwrap()); + let mut file = std::fs::File::create(path).unwrap(); + write_binprot(job, &mut file); + file.sync_all().unwrap(); + } } fn extract_request( @@ -4237,15 +4306,58 @@ mod tests { zkapp_step_opt_signed_opt_signed_prover, zkapp_step_opt_signed_prover, zkapp_step_proof_prover, + // } = crate::proofs::gates::make_provers2(); } = &*get_provers(); - let v = &tx_wrap_prover.index.verifier_index.as_ref().unwrap(); - let v_json = serde_json::to_string(&v).unwrap(); - // std::fs::write("/tmp/tx.json", &v_json).unwrap(); - - // let linear = &v.linearization; + // use crate::proofs::caching::verifier_index_to_bytes; + // use crate::proofs::verifier_index::get_verifier_index; + // let v = &tx_wrap_prover.index.verifier_index.as_ref().unwrap(); + // let v = verifier_index_to_bytes(&v); // let new_v = get_verifier_index(crate::proofs::verifier_index::VerifierKind::Transaction); + // let new_v = verifier_index_to_bytes(&new_v); + // assert_eq!(v, new_v); + // let tx_old = new_v; + + // let v = &block_wrap_prover.index.verifier_index.as_ref().unwrap(); + // let v = verifier_index_to_bytes(&v); + // let new_v = get_verifier_index(crate::proofs::verifier_index::VerifierKind::Blockchain); + // let new_v = verifier_index_to_bytes(&new_v); + // assert_eq!(v, new_v); + // let block_old = new_v; + + eprintln!("OK"); + + // let Provers { + // tx_step_prover, + // tx_wrap_prover, + // merge_step_prover, + // block_step_prover, + // block_wrap_prover, + // zkapp_step_opt_signed_opt_signed_prover, + // zkapp_step_opt_signed_prover, + // zkapp_step_proof_prover, + // } = crate::proofs::gates::make_provers2(); + + // // let writer = std::fs::File::create("/tmp/transaction_verifier_index.json").unwrap(); + // // let value = tx_wrap_prover.index.verifier_index.as_ref().unwrap(); + // // serde_json::to_writer(writer, value).unwrap(); + + // // let writer = std::fs::File::create("/tmp/blockchain_verifier_index.json").unwrap(); + // // let value = block_wrap_prover.index.verifier_index.as_ref().unwrap(); + // // serde_json::to_writer(writer, value).unwrap(); + + // let v = &tx_wrap_prover.index.verifier_index.as_ref().unwrap(); + // let v = verifier_index_to_bytes(&v); + // let tx_is_same = v == tx_old; + + // let v = &block_wrap_prover.index.verifier_index.as_ref().unwrap(); + // let v = verifier_index_to_bytes(&v); + // let block_is_same = v == block_old; + + // dbg!(tx_is_same, block_is_same); + // eprintln!("OK2"); + // let linear2 = &new_v.linearization; // assert_eq!(linear.constant_term, linear2.constant_term); @@ -4258,16 +4370,18 @@ mod tests { } #[test] - fn test_protocol_state_body() { + fn test_regular_tx() { let Ok(data) = // std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("request_signed.bin")) - std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("rampup4").join("request_payment_0_rampup4.bin")) + // std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("rampup4").join("request_payment_0_rampup4.bin")) + std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("berkeley_rc1").join("tests").join("command-0-0.bin")) // std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("rampup4").join("request_payment_1_rampup4.bin")) // std::fs::read("/tmp/fee_transfer_1_rampup4.bin") // std::fs::read("/tmp/coinbase_1_rampup4.bin") // std::fs::read("/tmp/stake_0_rampup4.bin") else { eprintln!("request not found"); + panic_in_ci(); return; }; @@ -4284,8 +4398,7 @@ mod tests { } = &*get_provers(); let mut witnesses: Witness = Witness::new::(); - - witnesses.ocaml_aux = read_witnesses("fps_rampup4.txt").unwrap(); + // witnesses.ocaml_aux = read_witnesses("tx_fps.txt").unwrap(); let WrapProof { proof, .. } = generate_tx_proof( TransactionParams { @@ -4307,16 +4420,83 @@ mod tests { dbg!(sum); } + #[allow(unused)] + #[test] + fn test_read_requests() { + return; + + let path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("berkeley_rc1") + .join("tests"); + + let mut files = Vec::with_capacity(1000); + + for index in 0..285 { + for j in 0..2 { + let filename = format!("command-{index}-{j}.bin"); + let file_path = path.join(filename); + if file_path.exists() { + files.push(file_path); + } + } + } + + for (index, file) in files.iter().enumerate() { + use mina_p2p_messages::v2::*; + + let bytes = std::fs::read(file).unwrap(); + + let v: ExternalSnarkWorkerRequest = read_binprot(&mut bytes.as_slice()); + let ExternalSnarkWorkerRequest::PerformJob(job) = v else { + panic!() + }; + let SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse(Some((a, _prover))) = job else { + panic!() + }; + let SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Instances::One(single) = + a.instances + else { + panic!() + }; + + let (_stmt, witness) = match single { + mina_p2p_messages::v2::SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single::Transition(stmt, witness) => (stmt, witness), + mina_p2p_messages::v2::SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single::Merge(_) => todo!(), + }; + + match &witness.transaction { + MinaTransactionTransactionStableV2::Command(cmd) => match &**cmd { + mina_p2p_messages::v2::MinaBaseUserCommandStableV2::SignedCommand(_) => { + eprintln!("[{}] signed: {:?}", index, file) + } + mina_p2p_messages::v2::MinaBaseUserCommandStableV2::ZkappCommand(z) => { + eprintln!("[{}] zkapp: {:?}", index, file); + // eprintln!("zkapp {:#?}", z); + } + }, + MinaTransactionTransactionStableV2::FeeTransfer(_) => { + eprintln!("[{}] fee_transfer", index) + } + MinaTransactionTransactionStableV2::Coinbase(_) => { + eprintln!("[{}] coinbase", index) + } + } + } + } + #[test] fn test_merge_proof() { let Ok(data) = // std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("request_signed.bin")) - std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("rampup4").join("merge_0_rampup4.bin")) + // std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("rampup4").join("merge_0_rampup4.bin")) + std::fs::read(Path::new(env!("CARGO_MANIFEST_DIR")).join("berkeley_rc1").join("tests").join("merge-100-0.bin")) + // std::fs::read("/tmp/minaa/mina-works-dump/merge-100-0.bin") // std::fs::read("/tmp/fee_transfer_1_rampup4.bin") // std::fs::read("/tmp/coinbase_1_rampup4.bin") // std::fs::read("/tmp/stake_0_rampup4.bin") else { eprintln!("request not found"); + panic_in_ci(); return; }; @@ -4333,7 +4513,7 @@ mod tests { } = &*get_provers(); let mut witnesses: Witness = Witness::new::(); - witnesses.ocaml_aux = read_witnesses("fps_merge.txt").unwrap(); + // witnesses.ocaml_aux = read_witnesses("fps_merge.txt").unwrap(); let WrapProof { proof, .. } = generate_merge_proof( MergeParams { @@ -4343,32 +4523,35 @@ mod tests { step_prover: &merge_step_prover, wrap_prover: &tx_wrap_prover, only_verify_constraints: false, - expected_step_proof: Some( - "fb89b6d51ce5ed6fe7815b86ca37a7dcdc34d9891b4967692d3751dad32842f8", - ), - - ocaml_wrap_witness: Some(read_witnesses("fqs_merge.txt").unwrap()), + expected_step_proof: None, + // expected_step_proof: Some( + // "fb89b6d51ce5ed6fe7815b86ca37a7dcdc34d9891b4967692d3751dad32842f8", + // ), + ocaml_wrap_witness: None, + // ocaml_wrap_witness: Some(read_witnesses("fqs_merge.txt").unwrap()), }, &mut witnesses, ) .unwrap(); let proof_json = serde_json::to_vec(&proof).unwrap(); - let sum = sha256_sum(&proof_json); - assert_eq!( - sum, - "49eed450384e96b61debdec162884358635ab083ac09fe1c09e2a4aa4f169bf8" - ); + let _sum = dbg!(sha256_sum(&proof_json)); + // assert_eq!( + // sum, + // "49eed450384e96b61debdec162884358635ab083ac09fe1c09e2a4aa4f169bf8" + // ); } #[test] fn test_zkapp_proof_sig() { let Ok(data) = std::fs::read( Path::new(env!("CARGO_MANIFEST_DIR")) - .join("rampup4") - .join("zkapp_0_rampup4.bin"), + .join("berkeley_rc1") + .join("tests") + .join("command-260-1.bin"), ) else { eprintln!("request not found"); + panic_in_ci(); return; }; @@ -4385,6 +4568,9 @@ mod tests { zkapp_step_proof_prover, } = &*get_provers(); + dbg!(zkapp_step_opt_signed_opt_signed_prover.rows_rev.len()); + // dbg!(zkapp_step_opt_signed_opt_signed_prover.rows_rev.iter().map(|v| v.len()).collect::>()); + let LedgerProof { proof, .. } = generate_zkapp_proof(ZkappParams { statement: &statement, tx_witness: &tx_witness, @@ -4394,31 +4580,50 @@ mod tests { step_proof_prover: &zkapp_step_proof_prover, merge_step_prover: &merge_step_prover, tx_wrap_prover: &tx_wrap_prover, - opt_signed_path: Some("zkapp_opt_signed"), + opt_signed_path: None, + // opt_signed_path: Some("zkapp_opt_signed"), proved_path: None, }) .unwrap(); let proof_json = serde_json::to_vec(&proof.proof).unwrap(); - let sum = dbg!(sha256_sum(&proof_json)); + let _sum = dbg!(sha256_sum(&proof_json)); - assert_eq!( - sum, - "6e9bb6ed613cf0aa737188e0e8ddde7438211ca54c02e89aff32816c181caca9" - ); + // assert_eq!( + // sum, + // "6e9bb6ed613cf0aa737188e0e8ddde7438211ca54c02e89aff32816c181caca9" + // ); } #[test] fn test_proof_zkapp_proof() { let Ok(data) = std::fs::read( Path::new(env!("CARGO_MANIFEST_DIR")) - .join("rampup4") - .join("zkapp_10_rampup4.bin"), + .join("berkeley_rc1") + .join("tests") + .join("command-157-1.bin"), + // .join("command-144-0.bin"), + // .join("command-139-1.bin"), + // .join("command-135-0.bin"), + // .join("command-55-0.bin"), + // .join("command-43-1.bin"), + // .join("command-12-1.bin"), ) else { eprintln!("request not found"); + panic_in_ci(); return; }; + // Other zkapps using proof auth: + // [23] zkapp: "command-12-1.bin" + // [77] zkapp: "command-43-1.bin" + // [96] zkapp: "command-55-0.bin" + // [120] zkapp: "command-135-0.bin" + // [127] zkapp: "command-139-1.bin" + // [134] zkapp: "command-144-0.bin" + // [159] zkapp: "command-157-1.bin" + // [226] zkapp: "command-260-1.bin" + let (statement, tx_witness, message) = extract_request(&data); let Provers { @@ -4441,28 +4646,32 @@ mod tests { step_proof_prover: &zkapp_step_proof_prover, merge_step_prover: &merge_step_prover, tx_wrap_prover: &tx_wrap_prover, - opt_signed_path: Some("zkapp_proof"), - proved_path: Some("zkapp_proof2"), + opt_signed_path: None, + proved_path: None, + // opt_signed_path: Some("zkapp_proof"), + // proved_path: Some("zkapp_proof2"), }) .unwrap(); let proof_json = serde_json::to_vec(&proof.proof).unwrap(); - let sum = dbg!(sha256_sum(&proof_json)); + let _sum = dbg!(sha256_sum(&proof_json)); - assert_eq!( - sum, - "e2ca355ce4ed5aaf379e992c0c8c5b1c4ac1687546ceac5a5c6c9c4994002249" - ); + // assert_eq!( + // sum, + // "e2ca355ce4ed5aaf379e992c0c8c5b1c4ac1687546ceac5a5c6c9c4994002249" + // ); } #[test] fn test_block_proof() { let Ok(data) = std::fs::read( Path::new(env!("CARGO_MANIFEST_DIR")) - .join("rampup4") - .join("block_input_working.bin"), + .join("berkeley_rc1") + .join("tests") + .join("block_input-2775525-0.bin"), ) else { eprintln!("request not found"); + panic_in_ci(); return; }; @@ -4489,10 +4698,12 @@ mod tests { block_wrap_prover: &block_wrap_prover, tx_wrap_prover: &tx_wrap_prover, only_verify_constraints: false, - expected_step_proof: Some( - "a82a10e5c276dd6dc251241dcbad005201034ffff5752516a179f317dfe385f5", - ), - ocaml_wrap_witness: Some(read_witnesses("block_fqs.txt").unwrap()), + expected_step_proof: None, + ocaml_wrap_witness: None, + // expected_step_proof: Some( + // "a82a10e5c276dd6dc251241dcbad005201034ffff5752516a179f317dfe385f5", + // ), + // ocaml_wrap_witness: Some(read_witnesses("block_fqs.txt").unwrap()), }, &mut witnesses, ) @@ -4500,19 +4711,22 @@ mod tests { let proof_json = serde_json::to_vec(&proof).unwrap(); - let sum = sha256_sum(&proof_json); - assert_eq!( - sum, - "cc55eb645197fc0246c96f2d2090633af54137adc93226e1aac102098337c46e" - ); + let _sum = dbg!(sha256_sum(&proof_json)); + // assert_eq!( + // sum, + // "cc55eb645197fc0246c96f2d2090633af54137adc93226e1aac102098337c46e" + // ); } #[test] fn test_proofs() { - let base_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("rampup4"); + let base_dir = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("berkeley_rc1") + .join("tests"); if !base_dir.exists() { eprintln!("{:?} not found", base_dir); + panic_in_ci(); return; } @@ -4530,11 +4744,11 @@ mod tests { #[rustfmt::skip] let zkapp_cases = [ // zkapp proof with signature authorization - ("zkapp_0_rampup4.bin", Some("zkapp_opt_signed"), None, "6e9bb6ed613cf0aa737188e0e8ddde7438211ca54c02e89aff32816c181caca9"), + ("command-260-1.bin", None, None, "0c7cd3cdb923189a8529742f223a2aff0e826129494062c65e08eb29ef8c7b2d"), // zkapp proof with proof authorization - ("zkapp_10_rampup4.bin", Some("zkapp_proof"), Some("zkapp_proof2"), "e2ca355ce4ed5aaf379e992c0c8c5b1c4ac1687546ceac5a5c6c9c4994002249"), + ("command-157-1.bin", None, None, "35e6c960fe48bedc92c20ab613972d70c4b8423139758c442b0ddc2025bdaaba"), // zkapp with multiple account updates - ("zkapp_2_0_rampup4.bin", None, None, "03153d1c5b934e00c7102d3683f27572b6e8bfe0335817cb822d701c83415930"), + // ("zkapp_2_0_rampup4.bin", None, None, "03153d1c5b934e00c7102d3683f27572b6e8bfe0335817cb822d701c83415930"), ]; for (file, opt_signed_path, proved_path, expected_sum) in zkapp_cases { @@ -4563,7 +4777,7 @@ mod tests { // Block proof { - let data = std::fs::read(base_dir.join("block_input_working.bin")).unwrap(); + let data = std::fs::read(base_dir.join("block_input-2775525-0.bin")).unwrap(); let blockchain_input: v2::ProverExtendBlockchainInputStableV2 = read_binprot(&mut data.as_slice()); @@ -4578,31 +4792,33 @@ mod tests { block_wrap_prover: &block_wrap_prover, tx_wrap_prover: &tx_wrap_prover, only_verify_constraints: false, - expected_step_proof: Some( - "a82a10e5c276dd6dc251241dcbad005201034ffff5752516a179f317dfe385f5", - ), - ocaml_wrap_witness: Some(read_witnesses("block_fqs.txt").unwrap()), + expected_step_proof: None, + ocaml_wrap_witness: None, + // expected_step_proof: Some( + // "a82a10e5c276dd6dc251241dcbad005201034ffff5752516a179f317dfe385f5", + // ), + // ocaml_wrap_witness: Some(read_witnesses("block_fqs.txt").unwrap()), }, &mut witnesses, ) .unwrap(); let proof_json = serde_json::to_vec(&proof).unwrap(); - let sum = sha256_sum(&proof_json); - assert_eq!( - sum, - "cc55eb645197fc0246c96f2d2090633af54137adc93226e1aac102098337c46e" - ); + let _sum = sha256_sum(&proof_json); + // assert_eq!( + // sum, + // "cc55eb645197fc0246c96f2d2090633af54137adc93226e1aac102098337c46e" + // ); } // Merge proof { - let data = std::fs::read(base_dir.join("merge_0_rampup4.bin")).unwrap(); + let data = std::fs::read(base_dir.join("merge-100-0.bin")).unwrap(); let (statement, proofs, message) = extract_merge(&data); let mut witnesses: Witness = Witness::new::(); - witnesses.ocaml_aux = read_witnesses("fps_merge.txt").unwrap(); + // witnesses.ocaml_aux = read_witnesses("fps_merge.txt").unwrap(); let WrapProof { proof, .. } = generate_merge_proof( MergeParams { @@ -4612,10 +4828,12 @@ mod tests { step_prover: &merge_step_prover, wrap_prover: &tx_wrap_prover, only_verify_constraints: false, - expected_step_proof: Some( - "fb89b6d51ce5ed6fe7815b86ca37a7dcdc34d9891b4967692d3751dad32842f8", - ), - ocaml_wrap_witness: Some(read_witnesses("fqs_merge.txt").unwrap()), + expected_step_proof: None, + ocaml_wrap_witness: None, + // expected_step_proof: Some( + // "fb89b6d51ce5ed6fe7815b86ca37a7dcdc34d9891b4967692d3751dad32842f8", + // ), + // ocaml_wrap_witness: Some(read_witnesses("fqs_merge.txt").unwrap()), }, &mut witnesses, ) @@ -4623,19 +4841,19 @@ mod tests { let proof_json = serde_json::to_vec(&proof).unwrap(); - let sum = sha256_sum(&proof_json); - assert_eq!( - sum, - "49eed450384e96b61debdec162884358635ab083ac09fe1c09e2a4aa4f169bf8" - ); + let _sum = sha256_sum(&proof_json); + // assert_eq!( + // sum, + // "49eed450384e96b61debdec162884358635ab083ac09fe1c09e2a4aa4f169bf8" + // ); } // Same values than OCaml #[rustfmt::skip] let requests = [ - ("request_payment_0_rampup4.bin", "c209c2f40caf61b29af5162476748ee7865eef0bc92eb1e6a50e52fc1d391c1e"), + ("command-0-0.bin", "c209c2f40caf61b29af5162476748ee7865eef0bc92eb1e6a50e52fc1d391c1e"), // ("request_payment_1_rampup4.bin", "a5391b8ac8663a06a0a57ee6b6479e3cf4d95dfbb6d0688e439cb8c36cf187f6"), - ("coinbase_0_rampup4.bin", "a2ce1982938687ca3ba3b1994e5100090a80649aefb1f0d10f736a845dab2812"), + // ("coinbase_0_rampup4.bin", "a2ce1982938687ca3ba3b1994e5100090a80649aefb1f0d10f736a845dab2812"), // ("coinbase_1_rampup4.bin", "1120c9fe25078866e0df90fd09a41a2f5870351a01c8a7227d51a19290883efe"), // ("coinbase_2_rampup4.bin", "7875781e8ea4a7eb9035a5510cd54cfc33229867f46f97e68fbb9a7a6534ec74"), // ("coinbase_3_rampup4.bin", "12875cb8a182d550eb527e3561ad71458e1ca651ea399ee1878244c9b8f04966"), @@ -4645,7 +4863,7 @@ mod tests { // ("coinbase_7_rampup4.bin", "78fcec79bf2013d4f3d97628b316da7410af3c92a73dc26abc3ea63fbe92372a"), // ("coinbase_8_rampup4.bin", "169f1ad4739d0a3fe194a66497bcabbca8dd5584cd83d13a5addede4b5a49e9d"), // ("coinbase_9_rampup4.bin", "dfe50b656e0c0520a9678a1d34dd68af4620ea9909461b39c24bdda69504ed4b"), - ("fee_transfer_0_rampup4.bin", "58d711bcc6377037e1c6a1334a49d53789b6e9c93aa343bda2f736cfc40d90b3"), + // ("fee_transfer_0_rampup4.bin", "58d711bcc6377037e1c6a1334a49d53789b6e9c93aa343bda2f736cfc40d90b3"), // ("fee_transfer_1_rampup4.bin", "791644dc9b5f17be24cbacab83e8b1f4b2ba7218e09ec718b37f1cd280b6c467"), // ("fee_transfer_2_rampup4.bin", "ea02567ed5f116191ece0e7f6ac78a3b014079509457d03dd8d654e601404722"), // ("fee_transfer_3_rampup4.bin", "6048053909b20e57cb104d1838c3aca565462605c69ced184f1a0e31b18c9c05"), @@ -4657,7 +4875,7 @@ mod tests { // ("fee_transfer_9_rampup4.bin", "087a07eddedf5de18b2f2bd7ded3cd474d00a0030e9c13d7a5fd2433c72fc7d5"), ]; - for (file, expected_sum) in requests { + for (file, _expected_sum) in requests { let data = std::fs::read(base_dir.join(file)).unwrap(); let (statement, tx_witness, message) = extract_request(&data); @@ -4683,14 +4901,14 @@ mod tests { .unwrap(); let proof_json = serde_json::to_vec(&proof).unwrap(); - let sum = sha256_sum(&proof_json); - - if dbg!(&sum) != expected_sum { - eprintln!("Wrong proof: {:?}", file); - eprintln!("got sum: {:?}", sum); - eprintln!("expected: {:?}", expected_sum); - panic!() - } + let _sum = sha256_sum(&proof_json); + + // if dbg!(&sum) != expected_sum { + // eprintln!("Wrong proof: {:?}", file); + // eprintln!("got sum: {:?}", sum); + // eprintln!("expected: {:?}", expected_sum); + // panic!() + // } } } } diff --git a/ledger/src/proofs/util.rs b/ledger/src/proofs/util.rs index 0408abe89..9a9ffcd73 100644 --- a/ledger/src/proofs/util.rs +++ b/ledger/src/proofs/util.rs @@ -17,22 +17,33 @@ use super::{ witness::Witness, }; -pub fn extract_polynomial_commitment( - curves: &[(BigInt, BigInt)], +pub fn extract_polynomial_commitment< + 'a, + F: FieldWitness, + I: IntoIterator, +>( + curves: I, ) -> Vec> { curves - .iter() + .into_iter() .map(|curve| InnerCurve::from((curve.0.to_field::(), curve.1.to_field()))) .collect() } -pub fn extract_bulletproof( - v: &[PaddedSeq< - PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A, - N, - >], +pub fn extract_bulletproof< + 'a, + F: FieldWitness, + I: IntoIterator< + Item = &'a PaddedSeq< + PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A, + N, + >, + >, + const N: usize, +>( + v: I, ) -> Vec<[F; N]> { - v.iter() + v.into_iter() .map(|old| { array::from_fn(|j| { let prechallenge = &old[j].prechallenge.inner; @@ -417,7 +428,7 @@ pub fn to_absorption_sequence2( lookup_aggregation, lookup_table, ] - .iter() + .into_iter() .filter_map(|v| v.as_ref()), ); @@ -432,7 +443,7 @@ pub fn to_absorption_sequence2( range_check_lookup_selector, foreign_field_mul_lookup_selector, ] - .iter() + .into_iter() .filter_map(|v| v.as_ref()), ); diff --git a/ledger/src/proofs/verification.rs b/ledger/src/proofs/verification.rs index 901e5470c..f3d75b83b 100644 --- a/ledger/src/proofs/verification.rs +++ b/ledger/src/proofs/verification.rs @@ -167,14 +167,18 @@ pub fn prev_evals_from_p2p( foreign_field_mul_lookup_selector, } = evals; - let of = |(zeta, zeta_omega): &(Vec, Vec)| -> PointEvaluations> { + fn of<'a, F: FieldWitness, I: IntoIterator>( + zeta: I, + zeta_omega: I, + ) -> PointEvaluations> { PointEvaluations { - zeta: zeta.iter().map(BigInt::to_field).collect(), - zeta_omega: zeta_omega.iter().map(BigInt::to_field).collect(), + zeta: zeta.into_iter().map(BigInt::to_field).collect(), + zeta_omega: zeta_omega.into_iter().map(BigInt::to_field).collect(), } - }; + } - let of_opt = |v: &Option<(Vec, Vec)>| v.as_ref().map(of); + let of = |(zeta, zeta_omega): &(_, _)| -> PointEvaluations> { of(zeta, zeta_omega) }; + let of_opt = |v: &Option<(_, _)>| v.as_ref().map(of); ProofEvaluations { w: array::from_fn(|i| of(&w[i])), @@ -238,9 +242,8 @@ pub fn prev_evals_to_p2p( use mina_p2p_messages::pseq::PaddedSeq; - let of = |[zeta, zeta_omega]: &[Fp; 2]| -> (Vec, Vec) { - (vec![zeta.into()], vec![zeta_omega.into()]) - }; + let of = + |[zeta, zeta_omega]: &[Fp; 2]| (vec![zeta.into()].into(), vec![zeta_omega.into()].into()); let of_opt = |v: &Option<[Fp; 2]>| v.as_ref().map(of); @@ -280,16 +283,16 @@ struct LimitedDomain { impl PlonkDomain for LimitedDomain { fn vanishing_polynomial(&self, _x: F, _w: &mut super::witness::Witness) -> F { - todo!() + unimplemented!() // Unused during proof verification } fn generator(&self) -> F { - todo!() + unimplemented!() // Unused during proof verification } fn shifts(&self) -> &[F; PERMUTS] { self.shifts.shifts() } fn log2_size(&self) -> u64 { - todo!() + unimplemented!() // Unused during proof verification } } diff --git a/ledger/src/proofs/witness.rs b/ledger/src/proofs/witness.rs index 5ab048ba5..0c4f1ef21 100644 --- a/ledger/src/proofs/witness.rs +++ b/ledger/src/proofs/witness.rs @@ -81,7 +81,7 @@ impl Witness { eprintln!( "index={:?} w{:?}", - self.aux.len() + self.primary.capacity(), + start_offset + self.primary.capacity(), &self.aux[start_offset..] ); } diff --git a/ledger/src/proofs/zkapp.rs b/ledger/src/proofs/zkapp.rs index 828d6775f..d0d5c6908 100644 --- a/ledger/src/proofs/zkapp.rs +++ b/ledger/src/proofs/zkapp.rs @@ -57,8 +57,8 @@ use self::group::SegmentBasic; use super::{ constants::{ - ForWrapData, ProofConstants, StepZkappOptSignedProof, StepZkappProofProof, - WrapZkappProofProof, + ForWrapData, ProofConstants, StepZkappOptSignedProof, StepZkappProvedProof, + WrapZkappProvedProof, }, field::GroupAffine, numbers::{ @@ -904,7 +904,8 @@ fn basic_spec(s: &SegmentBasic) -> Box<[Spec]> { fn read_witnesses(path: &str) -> Vec { let f = std::fs::read_to_string( std::path::Path::new(env!("CARGO_MANIFEST_DIR")) - .join("rampup4") + .join("berkeley_rc1") + .join("witnesses") .join(path), // .join("zkapp_fps.txt"), ) @@ -1646,7 +1647,7 @@ fn of_zkapp_command_segment( of_zkapp_command_segment_exn:: } SegmentBasic::Proved => { - of_zkapp_command_segment_exn:: + of_zkapp_command_segment_exn:: } }; diff --git a/ledger/src/scan_state/conv.rs b/ledger/src/scan_state/conv.rs index e1d6b12e7..416c0fdfb 100644 --- a/ledger/src/scan_state/conv.rs +++ b/ledger/src/scan_state/conv.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use mina_hasher::Fp; use mina_p2p_messages::{ binprot, + list::List, pseq::PaddedSeq, string::CharString, v2::{ @@ -36,8 +37,7 @@ use mina_p2p_messages::{ MinaBaseStakeDelegationStableV2, MinaBaseStateBodyHashStableV1, MinaBaseTransactionStatusFailureCollectionStableV1, MinaBaseTransactionStatusFailureStableV2, MinaBaseTransactionStatusStableV2, - MinaBaseUserCommandStableV2, MinaBaseZkappAccountZkappUriStableV1, - MinaBaseZkappCommandTStableV1WireStableV1, + MinaBaseUserCommandStableV2, MinaBaseZkappCommandTStableV1WireStableV1, MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA, MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA, MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA, @@ -621,12 +621,6 @@ impl From<&Statement> for MinaStateSnarkedLedgerStateWithSokStableV2 } } -impl From<&SokDigest> for MinaBaseZkappAccountZkappUriStableV1 { - fn from(value: &SokDigest) -> Self { - Self(value.as_slice().into()) - } -} - impl From<&MinaBaseTransactionStatusStableV2> for TransactionStatus { fn from(value: &MinaBaseTransactionStatusStableV2) -> Self { match value { @@ -882,7 +876,6 @@ impl From<&zkapp_command::EpochData> for MinaBaseZkappPreconditionProtocolStateE impl From<&MinaBaseAccountUpdatePreconditionsStableV1> for zkapp_command::Preconditions { fn from(value: &MinaBaseAccountUpdatePreconditionsStableV1) -> Self { - use mina_p2p_messages::v2::MinaBaseAccountUpdateAccountPreconditionStableV1 as MAccount; use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1Amount as MAmount; use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot as MSlot; use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash as Ledger; @@ -914,63 +907,57 @@ impl From<&MinaBaseAccountUpdatePreconditionsStableV1> for zkapp_command::Precon staking_epoch_data: (&value.network.staking_epoch_data).into(), next_epoch_data: (&value.network.next_epoch_data).into(), }, - account: match &value.account { - MAccount::Full(account) => { - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Balance as MBalance; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Delegate as Delegate; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ProvedState as Proved; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash as Receipt; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2StateA as State; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1Length as MNonce; - - let account = &**account; - AccountPreconditions::Full(Box::new(zkapp_command::Account { - balance: match &account.balance { - MBalance::Check(balance) => OrIgnore::Check(ClosedInterval { - lower: Balance::from_u64(balance.lower.0.as_u64()), - upper: Balance::from_u64(balance.upper.0.as_u64()), - }), - MBalance::Ignore => OrIgnore::Ignore, - }, - nonce: match &account.nonce { - MNonce::Check(balance) => OrIgnore::Check(ClosedInterval { - lower: Nonce::from_u32(balance.lower.0.as_u32()), - upper: Nonce::from_u32(balance.upper.0.as_u32()), - }), - MNonce::Ignore => OrIgnore::Ignore, - }, - receipt_chain_hash: match &account.receipt_chain_hash { - Receipt::Check(hash) => OrIgnore::Check(hash.to_field()), - Receipt::Ignore => OrIgnore::Ignore, - }, - delegate: match &account.delegate { - Delegate::Check(delegate) => { - OrIgnore::Check(delegate.clone().into_inner().into()) - } - Delegate::Ignore => OrIgnore::Ignore, - }, - state: array_into_with(&account.state, |s| match s { - State::Check(s) => OrIgnore::Check(s.to_field()), - State::Ignore => OrIgnore::Ignore, + account: { + let account = &value.account.0; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Balance as MBalance; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Delegate as Delegate; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ProvedState as Proved; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash as Receipt; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2StateA as State; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1Length as MNonce; + + AccountPreconditions(zkapp_command::Account { + balance: match &account.balance { + MBalance::Check(balance) => OrIgnore::Check(ClosedInterval { + lower: Balance::from_u64(balance.lower.0.as_u64()), + upper: Balance::from_u64(balance.upper.0.as_u64()), }), - action_state: match &account.action_state { - State::Check(s) => OrIgnore::Check(s.to_field()), - State::Ignore => OrIgnore::Ignore, - }, - proved_state: match account.proved_state { - Proved::Check(state) => OrIgnore::Check(state), - Proved::Ignore => OrIgnore::Ignore, - }, - is_new: match account.is_new { - Proved::Check(state) => OrIgnore::Check(state), - Proved::Ignore => OrIgnore::Ignore, - }, - })) - } - MAccount::Nonce(nonce) => { - AccountPreconditions::Nonce(Nonce::from_u32(nonce.as_u32())) - } - MAccount::Accept => AccountPreconditions::Accept, + MBalance::Ignore => OrIgnore::Ignore, + }, + nonce: match &account.nonce { + MNonce::Check(balance) => OrIgnore::Check(ClosedInterval { + lower: Nonce::from_u32(balance.lower.0.as_u32()), + upper: Nonce::from_u32(balance.upper.0.as_u32()), + }), + MNonce::Ignore => OrIgnore::Ignore, + }, + receipt_chain_hash: match &account.receipt_chain_hash { + Receipt::Check(hash) => OrIgnore::Check(hash.to_field()), + Receipt::Ignore => OrIgnore::Ignore, + }, + delegate: match &account.delegate { + Delegate::Check(delegate) => { + OrIgnore::Check(delegate.clone().into_inner().into()) + } + Delegate::Ignore => OrIgnore::Ignore, + }, + state: array_into_with(&account.state, |s| match s { + State::Check(s) => OrIgnore::Check(s.to_field()), + State::Ignore => OrIgnore::Ignore, + }), + action_state: match &account.action_state { + State::Check(s) => OrIgnore::Check(s.to_field()), + State::Ignore => OrIgnore::Ignore, + }, + proved_state: match account.proved_state { + Proved::Check(state) => OrIgnore::Check(state), + Proved::Ignore => OrIgnore::Ignore, + }, + is_new: match account.is_new { + Proved::Check(state) => OrIgnore::Check(state), + Proved::Ignore => OrIgnore::Ignore, + }, + }) }, valid_while: match &value.valid_while { MSlot::Check(valid_while) => OrIgnore::Check(ClosedInterval { @@ -997,7 +984,6 @@ impl From<&zkapp_command::Preconditions> for MinaBaseAccountUpdatePreconditionsS use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1Amount as MAmount; use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot as MSlot; use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash as Ledger; - use zkapp_command::AccountPreconditions; use zkapp_command::{Numeric, OrIgnore}; Self { @@ -1032,65 +1018,61 @@ impl From<&zkapp_command::Preconditions> for MinaBaseAccountUpdatePreconditionsS staking_epoch_data: (&value.network.staking_epoch_data).into(), next_epoch_data: (&value.network.next_epoch_data).into(), }, - account: match &value.account { - AccountPreconditions::Full(account) => { - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Balance as MBalance; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Delegate as Delegate; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ProvedState as Proved; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash as Receipt; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2StateA as State; - use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1Length as MNonce; - - let account = &**account; - MAccount::Full(Box::new(MinaBaseZkappPreconditionAccountStableV2 { - balance: match &account.balance { - OrIgnore::Check(balance) => { - MBalance::Check(MinaBaseZkappPreconditionAccountStableV2BalanceA { - lower: (&balance.lower).into(), - upper: (&balance.upper).into(), - }) - } - OrIgnore::Ignore => MBalance::Ignore, - }, - nonce: match &account.nonce { - OrIgnore::Check(nonce) => MNonce::Check( - MinaBaseZkappPreconditionProtocolStateStableV1LengthA { - lower: (&nonce.lower).into(), - upper: (&nonce.upper).into(), - }, - ), - OrIgnore::Ignore => MNonce::Ignore, - }, - receipt_chain_hash: match &account.receipt_chain_hash { - OrIgnore::Check(hash) => { - Receipt::Check(MinaBaseReceiptChainHashStableV1(hash.into())) - } - OrIgnore::Ignore => Receipt::Ignore, - }, - delegate: match &account.delegate { - OrIgnore::Check(delegate) => Delegate::Check(delegate.into()), - OrIgnore::Ignore => Delegate::Ignore, - }, - state: PaddedSeq(array_into_with(&account.state, |s| match s { - OrIgnore::Check(s) => State::Check(s.into()), - OrIgnore::Ignore => State::Ignore, - })), - action_state: match &account.action_state { - OrIgnore::Check(s) => State::Check(s.into()), - OrIgnore::Ignore => State::Ignore, - }, - proved_state: match account.proved_state { - OrIgnore::Check(state) => Proved::Check(state), - OrIgnore::Ignore => Proved::Ignore, - }, - is_new: match account.is_new { - OrIgnore::Check(state) => Proved::Check(state), - OrIgnore::Ignore => Proved::Ignore, - }, - })) - } - AccountPreconditions::Nonce(nonce) => MAccount::Nonce(nonce.into()), - AccountPreconditions::Accept => MAccount::Accept, + account: { + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Balance as MBalance; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2Delegate as Delegate; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ProvedState as Proved; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash as Receipt; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionAccountStableV2StateA as State; + use mina_p2p_messages::v2::MinaBaseZkappPreconditionProtocolStateStableV1Length as MNonce; + + let account = &value.account.0; + MAccount(MinaBaseZkappPreconditionAccountStableV2 { + balance: match &account.balance { + OrIgnore::Check(balance) => { + MBalance::Check(MinaBaseZkappPreconditionAccountStableV2BalanceA { + lower: (&balance.lower).into(), + upper: (&balance.upper).into(), + }) + } + OrIgnore::Ignore => MBalance::Ignore, + }, + nonce: match &account.nonce { + OrIgnore::Check(nonce) => { + MNonce::Check(MinaBaseZkappPreconditionProtocolStateStableV1LengthA { + lower: (&nonce.lower).into(), + upper: (&nonce.upper).into(), + }) + } + OrIgnore::Ignore => MNonce::Ignore, + }, + receipt_chain_hash: match &account.receipt_chain_hash { + OrIgnore::Check(hash) => { + Receipt::Check(MinaBaseReceiptChainHashStableV1(hash.into())) + } + OrIgnore::Ignore => Receipt::Ignore, + }, + delegate: match &account.delegate { + OrIgnore::Check(delegate) => Delegate::Check(delegate.into()), + OrIgnore::Ignore => Delegate::Ignore, + }, + state: PaddedSeq(array_into_with(&account.state, |s| match s { + OrIgnore::Check(s) => State::Check(s.into()), + OrIgnore::Ignore => State::Ignore, + })), + action_state: match &account.action_state { + OrIgnore::Check(s) => State::Check(s.into()), + OrIgnore::Ignore => State::Ignore, + }, + proved_state: match account.proved_state { + OrIgnore::Check(state) => Proved::Check(state), + OrIgnore::Ignore => Proved::Ignore, + }, + is_new: match account.is_new { + OrIgnore::Check(state) => Proved::Check(state), + OrIgnore::Ignore => Proved::Ignore, + }, + }) }, valid_while: match &value.valid_while { OrIgnore::Check(valid_while) => { @@ -1116,10 +1098,9 @@ impl From<&MinaBaseAccountUpdateTStableV1> for AccountUpdate { use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1Delegate as Delegate; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1Permissions as Perm; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1Timing as Timing; - use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1TokenSymbol as Symbol; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1VerificationKey as VK; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1VotingFor as Voting; - use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1ZkappUri as Uri; + use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1ZkappUri as BString; use MinaBaseAccountUpdateUpdateStableV1AppStateA as AppState; Self { @@ -1144,12 +1125,12 @@ impl From<&MinaBaseAccountUpdateTStableV1> for AccountUpdate { Perm::Keep => SetOrKeep::Keep, }, zkapp_uri: match &value.body.update.zkapp_uri { - Uri::Set(s) => SetOrKeep::Set(s.try_into().unwrap()), - Uri::Keep => SetOrKeep::Keep, + BString::Set(s) => SetOrKeep::Set(s.try_into().unwrap()), + BString::Keep => SetOrKeep::Keep, }, token_symbol: match &value.body.update.token_symbol { - Symbol::Set(s) => SetOrKeep::Set((&s.0).try_into().unwrap()), - Symbol::Keep => SetOrKeep::Keep, + BString::Set(s) => SetOrKeep::Set(s.try_into().unwrap()), + BString::Keep => SetOrKeep::Keep, }, timing: match &value.body.update.timing { Timing::Set(timing) => SetOrKeep::Set((&**timing).into()), @@ -1211,10 +1192,10 @@ impl From<&MinaBaseAccountUpdateTStableV1> for AccountUpdate { } /// Notes: childs -impl From<&Vec> +impl From<&List> for CallForest { - fn from(value: &Vec) -> Self { + fn from(value: &List) -> Self { use ark_ff::Zero; Self( @@ -1234,10 +1215,10 @@ impl From<&Vec> } /// Notes: root -impl From<&Vec> +impl From<&List> for CallForest { - fn from(value: &Vec) -> Self { + fn from(value: &List) -> Self { use ark_ff::Zero; let values = value @@ -1250,12 +1231,13 @@ impl From<&Vec> }, stack_hash: Fp::zero(), // replaced later in `of_wire` }) - .collect(); + .collect::>(); // https://github.com/MinaProtocol/mina/blob/3fe924c80a4d01f418b69f27398f5f93eb652514/src/lib/mina_base/zkapp_command.ml#L1113-L1115 let mut call_forest = CallForest(values); - call_forest.of_wire(value); + call_forest.of_wire(&[]); + // call_forest.of_wire(value); call_forest } @@ -1290,10 +1272,9 @@ impl From<&AccountUpdate> for MinaBaseAccountUpdateTStableV1 { use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1Delegate as Delegate; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1Permissions as Perm; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1Timing as Timing; - use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1TokenSymbol as Symbol; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1VerificationKey as VK; use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1VotingFor as Voting; - use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1ZkappUri as Uri; + use mina_p2p_messages::v2::MinaBaseAccountUpdateUpdateStableV1ZkappUri as BString; use MinaBaseAccountUpdateUpdateStableV1AppStateA as AppState; Self { @@ -1318,12 +1299,12 @@ impl From<&AccountUpdate> for MinaBaseAccountUpdateTStableV1 { SetOrKeep::Keep => Perm::Keep, }, zkapp_uri: match &value.body.update.zkapp_uri { - SetOrKeep::Set(s) => Uri::Set(s.into()), - SetOrKeep::Keep => Uri::Keep, + SetOrKeep::Set(s) => BString::Set(s.into()), + SetOrKeep::Keep => BString::Keep, }, token_symbol: match &value.body.update.token_symbol { - SetOrKeep::Set(s) => Symbol::Set(MinaBaseZkappAccountZkappUriStableV1(s.into())), - SetOrKeep::Keep => Symbol::Keep, + SetOrKeep::Set(s) => BString::Set(s.into()), + SetOrKeep::Keep => BString::Keep, }, timing: match &value.body.update.timing { SetOrKeep::Set(timing) => Timing::Set(Box::new(timing.into())), @@ -1383,7 +1364,7 @@ impl From<&AccountUpdate> for MinaBaseAccountUpdateTStableV1 { /// Childs impl From<&CallForest> - for Vec + for List { fn from(value: &CallForest) -> Self { value @@ -1405,7 +1386,7 @@ impl From<&CallForest> /// Root impl From<&CallForest> - for Vec + for List { fn from(value: &CallForest) -> Self { let mut wired: Vec<_> = value @@ -1424,7 +1405,7 @@ impl From<&CallForest> .collect(); value.to_wire(&mut wired); - wired + wired.into_iter().collect() } } @@ -2262,8 +2243,8 @@ impl From<¶llel_scan::Weight> for ParallelScanWeightStableV1 { let parallel_scan::Weight { base, merge } = value; Self { - base: base.into(), - merge: merge.into(), + base: (*base).into(), + merge: (*merge).into(), } } } @@ -2414,7 +2395,7 @@ impl From<&ScanState> for TransactionSnarkScanStateStableV2 { let first = trees.remove(0); let rest = trees; - (first, rest) + (first, rest.into_iter().collect()) }, acc: acc.as_ref().map(|(proof, txns)| { ( @@ -2554,7 +2535,7 @@ impl From<&PendingCoinbase> for MinaBasePendingCoinbaseStableV2 { let addr = value.indexes.get(id).unwrap(); let index = addr.to_index(); - let index: mina_p2p_messages::number::Int64 = index.as_u64().into(); + let index: mina_p2p_messages::number::UInt64 = index.as_u64().into(); let id: MinaBasePendingCoinbaseStackIdStableV1 = id.into(); @@ -2623,7 +2604,7 @@ impl From<&PendingCoinbase> for MinaBasePendingCoinbaseStableV2 { let depth: u64 = value.depth.try_into().unwrap(); MinaBasePendingCoinbaseMerkleTreeVersionedStableV2 { - indexes, + indexes: indexes.into_iter().collect(), depth: depth.into(), tree, } diff --git a/ledger/src/scan_state/currency.rs b/ledger/src/scan_state/currency.rs index e10d1a361..c8dc7acc4 100644 --- a/ledger/src/scan_state/currency.rs +++ b/ledger/src/scan_state/currency.rs @@ -525,6 +525,6 @@ macro_rules! impl_number { } impl_number!( - 32: { Length, Slot, Nonce, Index, SlotSpan, }, + 32: { Length, Slot, Nonce, Index, SlotSpan, TxnVersion, }, 64: { Amount, Balance, Fee, BlockTime, BlockTimeSpan, N, }, ); diff --git a/ledger/src/scan_state/scan_state.rs b/ledger/src/scan_state/scan_state.rs index 224298d2d..deb59cb9c 100644 --- a/ledger/src/scan_state/scan_state.rs +++ b/ledger/src/scan_state/scan_state.rs @@ -96,7 +96,7 @@ pub mod transaction_snark { use itertools::Itertools; use mina_hasher::Fp; - use mina_p2p_messages::{binprot, v2::TransactionSnarkProofStableV2}; + use mina_p2p_messages::{binprot, string::ByteString, v2::TransactionSnarkProofStableV2}; use mina_signer::CompressedPubKey; use serde::{Deserialize, Serialize}; @@ -187,6 +187,18 @@ pub mod transaction_snark { #[derive(Clone, PartialEq, Eq, derive_more::Deref)] pub struct SokDigest(pub Vec); + impl From for ByteString { + fn from(value: SokDigest) -> Self { + value.0.into() + } + } + + impl From<&SokDigest> for ByteString { + fn from(value: &SokDigest) -> Self { + value.0.clone().into() + } + } + impl OCamlString for SokDigest { fn to_ocaml_str(&self) -> String { crate::staged_ledger::hash::to_ocaml_str(&self.0) @@ -538,7 +550,7 @@ pub mod transaction_snark { proofs: (&*value.proofs).into(), } } -} + } impl Work { pub fn statement(&self) -> Statement { @@ -833,22 +845,22 @@ impl ScanState { let state_hash = scan_state.hash( |buffer, proof| { - #[cfg(test)] - { - let a: mina_p2p_messages::v2::TransactionSnarkScanStateLedgerProofWithSokMessageStableV2 = proof.as_ref().into(); - let b: LedgerProofWithSokMessage = (&a).into(); - assert_eq!(&b, proof.as_ref()); - } + // #[cfg(test)] + // { + // let a: mina_p2p_messages::v2::TransactionSnarkScanStateLedgerProofWithSokMessageStableV2 = proof.as_ref().into(); + // let b: LedgerProofWithSokMessage = (&a).into(); + // assert_eq!(&b, proof.as_ref()); + // } proof.binprot_write(buffer).unwrap(); }, |buffer, transaction| { - #[cfg(test)] - { - let a: mina_p2p_messages::v2::TransactionSnarkScanStateTransactionWithWitnessStableV2 = transaction.as_ref().into(); - let b: TransactionWithWitness = (&a).into(); - assert_eq!(&b, transaction.as_ref()); - } + // #[cfg(test)] + // { + // let a: mina_p2p_messages::v2::TransactionSnarkScanStateTransactionWithWitnessStableV2 = transaction.as_ref().into(); + // let b: TransactionWithWitness = (&a).into(); + // assert_eq!(&b, transaction.as_ref()); + // } transaction.binprot_write(buffer).unwrap(); }, diff --git a/ledger/src/scan_state/transaction_logic.rs b/ledger/src/scan_state/transaction_logic.rs index d058ba738..0c67e91aa 100644 --- a/ledger/src/scan_state/transaction_logic.rs +++ b/ledger/src/scan_state/transaction_logic.rs @@ -27,9 +27,7 @@ use self::{ TransactionApplied, ZkappCommandApplied, }, transaction_union_payload::TransactionUnionPayload, - zkapp_command::{ - AccountPreconditions, AccountUpdate, WithHash, ZkAppCommand, ZkAppPreconditions, - }, + zkapp_command::{AccountUpdate, WithHash, ZkAppCommand, ZkAppPreconditions}, }; use super::currency::SlotSpan; @@ -80,7 +78,7 @@ pub enum TransactionFailure { AccountReceiptChainHashPreconditionUnsatisfied, AccountDelegatePreconditionUnsatisfied, AccountActionStatePreconditionUnsatisfied, - AccountAppStatePreconditionUnsatisfied(i64), + AccountAppStatePreconditionUnsatisfied(u64), AccountProvedStatePreconditionUnsatisfied, AccountIsNewPreconditionUnsatisfied, ProtocolStatePreconditionUnsatisfied, @@ -2099,7 +2097,7 @@ pub mod zkapp_command { for (i, (c, v)) in self.state.iter().zip(zkapp.app_state.iter()).enumerate() { ret.push(( - TransactionFailure::AccountAppStatePreconditionUnsatisfied(i as i64), + TransactionFailure::AccountAppStatePreconditionUnsatisfied(i as u64), c.zcheck(format!("state[{}]", i), *v), )); } @@ -2169,7 +2167,7 @@ pub mod zkapp_command { .rev() .map(|(i, (s, account_s))| { let b = (s, Fp::zero).checked_zcheck(account_s, w); - (AccountAppStatePreconditionUnsatisfied(i as i64), b) + (AccountAppStatePreconditionUnsatisfied(i as u64), b) }) .collect::>(); // We need to call rev here, in order to match OCaml order @@ -2217,18 +2215,12 @@ pub mod zkapp_command { /// https://github.com/MinaProtocol/mina/blob/2ee6e004ba8c6a0541056076aab22ea162f7eb3a/src/lib/mina_base/account_update.ml#L613 #[derive(Debug, Clone, PartialEq)] - pub enum AccountPreconditions { - Full(Box), - Nonce(Nonce), - Accept, - } + pub struct AccountPreconditions(pub Account); impl ToInputs for AccountPreconditions { /// https://github.com/MinaProtocol/mina/blob/3fe924c80a4d01f418b69f27398f5f93eb652514/src/lib/mina_base/account_update.ml#L635 /// https://github.com/MinaProtocol/mina/blob/3fe924c80a4d01f418b69f27398f5f93eb652514/src/lib/mina_base/zkapp_precondition.ml#L568 fn to_inputs(&self, inputs: &mut Inputs) { - let account = self.to_full(); - let Account { balance, nonce, @@ -2238,7 +2230,7 @@ pub mod zkapp_command { action_state, proved_state, is_new, - } = account.as_ref(); + } = &self.0; inputs.append(&(balance, ClosedInterval::min_max)); inputs.append(&(nonce, ClosedInterval::min_max)); @@ -2256,8 +2248,6 @@ pub mod zkapp_command { impl ToFieldElements for AccountPreconditions { fn to_field_elements(&self, fields: &mut Vec) { - let account = self.to_full(); - let Account { balance, nonce, @@ -2267,7 +2257,7 @@ pub mod zkapp_command { action_state, proved_state, is_new, - } = account.as_ref(); + } = &self.0; (balance, ClosedInterval::min_max).to_field_elements(fields); (nonce, ClosedInterval::min_max).to_field_elements(fields); @@ -2284,8 +2274,6 @@ pub mod zkapp_command { impl Check for AccountPreconditions { fn check(&self, w: &mut Witness) { - let account = self.to_full(); - let Account { balance, nonce, @@ -2295,7 +2283,7 @@ pub mod zkapp_command { action_state, proved_state, is_new, - } = account.as_ref(); + } = &self.0; (balance, ClosedInterval::min_max).check(w); (nonce, ClosedInterval::min_max).check(w); @@ -2311,31 +2299,30 @@ pub mod zkapp_command { } impl AccountPreconditions { - pub fn nonce(&self) -> Numeric { - match self { - Self::Full(account) => account.nonce.clone(), - Self::Nonce(nonce) => Numeric::Check(ClosedInterval { - lower: *nonce, - upper: *nonce, + pub fn with_nonce(nonce: Nonce) -> Self { + use OrIgnore::{Check, Ignore}; + AccountPreconditions(Account { + balance: Ignore, + nonce: Check(ClosedInterval { + lower: nonce, + upper: nonce, }), - Self::Accept => Numeric::Ignore, - } + receipt_chain_hash: Ignore, + delegate: Ignore, + state: std::array::from_fn(|_| EqData::Ignore), + action_state: Ignore, + proved_state: Ignore, + is_new: Ignore, + }) + } + + pub fn nonce(&self) -> Numeric { + self.0.nonce.clone() } /// https://github.com/MinaProtocol/mina/blob/3fe924c80a4d01f418b69f27398f5f93eb652514/src/lib/mina_base/account_update.ml#L635 pub fn to_full(&self) -> MyCow { - match self { - AccountPreconditions::Full(s) => MyCow::Borrow(&**s), - AccountPreconditions::Nonce(nonce) => { - let mut account = Account::accept(); - account.nonce = OrIgnore::Check(ClosedInterval { - lower: *nonce, - upper: *nonce, - }); - MyCow::Own(account) - } - AccountPreconditions::Accept => MyCow::Own(Account::accept()), - } + MyCow::Borrow(&self.0) } pub fn checked_zcheck( @@ -2592,7 +2579,7 @@ pub mod zkapp_command { app_state: _, delegate: _, verification_key: _, - permissions: _, + permissions, zkapp_uri: _, token_symbol, timing, @@ -2610,6 +2597,7 @@ pub mod zkapp_command { authorization_kind: _, } = self; + (permissions, Permissions::empty).check(w); (token_symbol, TokenSymbol::default).check(w); (timing, Timing::dummy).check(w); balance_change.check(w); @@ -2837,7 +2825,7 @@ pub mod zkapp_command { network }, - account: AccountPreconditions::Nonce(nonce), + account: AccountPreconditions::with_nonce(nonce), valid_while: Numeric::Ignore, }, use_full_commitment: true, @@ -3089,28 +3077,16 @@ pub mod zkapp_command { staking_epoch_data: EpochData::gen(), next_epoch_data: EpochData::gen(), }, - account: { - match AccountPreconditions::Accept { - AccountPreconditions::Full(_) => (), - AccountPreconditions::Nonce(_) => (), - AccountPreconditions::Accept => (), - }; - - match rng.gen_range(0..3) { - 0 => AccountPreconditions::Accept, - 1 => AccountPreconditions::Nonce(rng.gen()), - _ => AccountPreconditions::Full(Box::new(Account { - balance: OrIgnore::gen(|| ClosedInterval::gen(|| rng.gen())), - nonce: OrIgnore::gen(|| ClosedInterval::gen(|| rng.gen())), - receipt_chain_hash: OrIgnore::gen(|| Fp::rand(rng)), - delegate: OrIgnore::gen(gen_compressed), - state: std::array::from_fn(|_| OrIgnore::gen(|| Fp::rand(rng))), - action_state: OrIgnore::gen(|| Fp::rand(rng)), - proved_state: OrIgnore::gen(|| rng.gen()), - is_new: OrIgnore::gen(|| rng.gen()), - })), - } - }, + account: AccountPreconditions(Account { + balance: OrIgnore::gen(|| ClosedInterval::gen(|| rng.gen())), + nonce: OrIgnore::gen(|| ClosedInterval::gen(|| rng.gen())), + receipt_chain_hash: OrIgnore::gen(|| Fp::rand(rng)), + delegate: OrIgnore::gen(gen_compressed), + state: std::array::from_fn(|_| OrIgnore::gen(|| Fp::rand(rng))), + action_state: OrIgnore::gen(|| Fp::rand(rng)), + proved_state: OrIgnore::gen(|| rng.gen()), + is_new: OrIgnore::gen(|| rng.gen()), + }), valid_while: OrIgnore::gen(|| ClosedInterval::gen(|| rng.gen())), }, use_full_commitment: rng.gen(), @@ -5349,20 +5325,14 @@ where PerformResult::Bool(pred.zcheck(global_state.protocol_state).is_ok()) } Eff::CheckAccountPrecondition(account_update, account, new_account, local_state) => { - let local_state = match account_update.body.preconditions.account { - AccountPreconditions::Accept => local_state, - AccountPreconditions::Nonce(n) => local_state.add_check( - TransactionFailure::AccountNoncePreconditionUnsatisfied, - account.nonce == n, - ), - AccountPreconditions::Full(precondition_account) => { - let mut _local_state = local_state; - let check = |failure, b| { - _local_state = _local_state.add_check(failure, b); - }; - precondition_account.zcheck(new_account, check, account); - _local_state - } + let local_state = { + let precondition_account = &account_update.body.preconditions.account.0; + let mut _local_state = local_state; + let check = |failure, b| { + _local_state = _local_state.add_check(failure, b); + }; + precondition_account.zcheck(new_account, check, account); + _local_state }; PerformResult::LocalState(local_state) } @@ -6902,6 +6872,7 @@ pub mod transaction_union_payload { use crate::{ decompress_pk, + proofs::field::Boolean, scan_state::transaction_logic::signed_command::{PaymentPayload, StakeDelegationPayload}, }; @@ -6926,38 +6897,38 @@ pub mod transaction_union_payload { } impl Tag { - pub fn is_user_command(&self) -> bool { + pub fn is_user_command(&self) -> Boolean { match self { - Tag::Payment | Tag::StakeDelegation => true, - Tag::FeeTransfer | Tag::Coinbase => false, + Tag::Payment | Tag::StakeDelegation => Boolean::True, + Tag::FeeTransfer | Tag::Coinbase => Boolean::False, } } - pub fn is_payment(&self) -> bool { + pub fn is_payment(&self) -> Boolean { match self { - Tag::Payment => true, - Tag::FeeTransfer | Tag::Coinbase | Tag::StakeDelegation => false, + Tag::Payment => Boolean::True, + Tag::FeeTransfer | Tag::Coinbase | Tag::StakeDelegation => Boolean::False, } } - pub fn is_stake_delegation(&self) -> bool { + pub fn is_stake_delegation(&self) -> Boolean { match self { - Tag::StakeDelegation => true, - Tag::FeeTransfer | Tag::Coinbase | Tag::Payment => false, + Tag::StakeDelegation => Boolean::True, + Tag::FeeTransfer | Tag::Coinbase | Tag::Payment => Boolean::False, } } - pub fn is_fee_transfer(&self) -> bool { + pub fn is_fee_transfer(&self) -> Boolean { match self { - Tag::FeeTransfer => true, - Tag::StakeDelegation | Tag::Coinbase | Tag::Payment => false, + Tag::FeeTransfer => Boolean::True, + Tag::StakeDelegation | Tag::Coinbase | Tag::Payment => Boolean::False, } } - pub fn is_coinbase(&self) -> bool { + pub fn is_coinbase(&self) -> Boolean { match self { - Tag::Coinbase => true, - Tag::StakeDelegation | Tag::FeeTransfer | Tag::Payment => false, + Tag::Coinbase => Boolean::True, + Tag::StakeDelegation | Tag::FeeTransfer | Tag::Payment => Boolean::False, } } @@ -7641,7 +7612,7 @@ pub mod for_tests { use crate::{ gen_keypair, scan_state::parallel_scan::ceil_log2, AuthRequired, BaseLedger, Mask, - Permissions, ZkAppAccount, + Permissions, ZkAppAccount, TXN_VERSION_CURRENT, }; use super::*; @@ -7732,7 +7703,10 @@ pub mod for_tests { receive: AuthRequired::None, set_delegate: Either, set_permissions: Either, - set_verification_key: Either, + set_verification_key: crate::SetVerificationKey { + auth: Either, + txn_version: TXN_VERSION_CURRENT, + }, set_zkapp_uri: Either, edit_action_state: Either, set_token_symbol: Either, diff --git a/ledger/src/scan_state/zkapp_logic.rs b/ledger/src/scan_state/zkapp_logic.rs index 7d8830847..8e12c801f 100644 --- a/ledger/src/scan_state/zkapp_logic.rs +++ b/ledger/src/scan_state/zkapp_logic.rs @@ -19,7 +19,8 @@ use crate::{ }, }, sparse_ledger::LedgerIntf, - Account, AuthRequired, ControlTag, Mask, ReceiptChainHash, Timing, TokenId, ZkAppAccount, + Account, AuthRequired, ControlTag, Mask, ReceiptChainHash, SetVerificationKey, Timing, TokenId, + ZkAppAccount, TXN_VERSION_CURRENT, }; use super::{ @@ -749,11 +750,19 @@ where let (a, local_state) = { let verification_key = account_update.verification_key(); - let has_permission = controller_check( - proof_verifies, - signature_verifies, - a.permissions.set_verification_key, - )?; + + let SetVerificationKey { auth, txn_version } = &a.permissions.set_verification_key; + + let older_than_current_version = txn_version.lt(&TXN_VERSION_CURRENT); + let original_auth = auth; + + let auth = if older_than_current_version { + original_auth.verification_key_perm_fallback_to_signature_with_older_version() + } else { + original_auth.clone() + }; + + let has_permission = controller_check(proof_verifies, signature_verifies, auth)?; let local_state = local_state.add_check( TransactionFailure::UpdateNotPermittedVerificationKey, diff --git a/ledger/src/sparse_ledger/sparse_ledger.rs b/ledger/src/sparse_ledger/sparse_ledger.rs index d03239684..130274e19 100644 --- a/ledger/src/sparse_ledger/sparse_ledger.rs +++ b/ledger/src/sparse_ledger/sparse_ledger.rs @@ -319,7 +319,7 @@ impl From<&SparseLedger> for mina_p2p_messages::v2::MinaBaseSparseLedgerBaseStab let addr = value.indexes.get(id).unwrap(); let index = addr.to_index(); - let index: mina_p2p_messages::number::Int64 = index.as_u64().into(); + let index: mina_p2p_messages::number::UInt64 = index.as_u64().into(); let id: MinaBaseAccountIdStableV2 = id.clone().into(); @@ -381,7 +381,7 @@ impl From<&SparseLedger> for mina_p2p_messages::v2::MinaBaseSparseLedgerBaseStab let depth: u64 = value.depth.try_into().unwrap(); Self { - indexes, + indexes: indexes.into_iter().collect(), depth: depth.into(), tree, } diff --git a/ledger/src/staged_ledger/staged_ledger.rs b/ledger/src/staged_ledger/staged_ledger.rs index 1bf614837..7b512c1d9 100644 --- a/ledger/src/staged_ledger/staged_ledger.rs +++ b/ledger/src/staged_ledger/staged_ledger.rs @@ -53,16 +53,13 @@ pub struct StackStateWithInitStack { pub init_stack: Stack, } -// pub enum PreDiffError { -// CoinbaseError(&'static str), -// } - /// https://github.com/MinaProtocol/mina/blob/05c2f73d0f6e4f1341286843814ce02dcb3919e0/src/lib/staged_ledger/staged_ledger.ml#L23 -#[derive(Debug)] +#[derive(Debug, derive_more::From)] pub enum StagedLedgerError { NonZeroFeeExcess(Vec>, SpacePartition), InvalidProofs(Vec<(LedgerProof, Statement<()>, SokMessage)>, String), CouldntReachVerifier, + #[from] PreDiff(PreDiffError), InsufficientWork(String), MismatchedStatuses { @@ -70,38 +67,15 @@ pub enum StagedLedgerError { got: TransactionStatus, }, InvalidPublicKey(CompressedPubKey), + ZkAppsExceedLimit { + count: usize, + limit: usize, + }, + #[from] Unexpected(String), } -impl From for StagedLedgerError { - fn from(value: String) -> Self { - Self::Unexpected(value) - } -} - -impl From for StagedLedgerError { - fn from(value: PreDiffError) -> Self { - Self::PreDiff(value) - } -} - -// module Staged_ledger_error = struct -// type t = -// | Non_zero_fee_excess of -// Scan_state.Space_partition.t * Transaction.t With_status.t list -// | Invalid_proofs of -// ( Ledger_proof.t -// * Transaction_snark.Statement.t -// * Mina_base.Sok_message.t ) -// list -// | Couldn't_reach_verifier of Error.t -// | Pre_diff of Pre_diff_info.Error.t -// | Insufficient_work of string -// | Mismatched_statuses of -// Transaction.t With_status.t * Transaction_status.t -// | Invalid_public_key of Public_key.Compressed.t -// | Unexpected of Error.t -// [@@deriving sexp] +const ZKAPP_LIMIT_PER_BLOCK: Option = None; pub struct PreStatement { partially_applied_transaction: TransactionPartiallyApplied, @@ -1111,6 +1085,16 @@ impl StagedLedger { let (transactions, works, _commands_count, coinbases) = pre_diff_info; + if let Some(zkapp_limit) = ZKAPP_LIMIT_PER_BLOCK { + let zkapp_count = transactions.iter().filter(|t| t.data.is_zkapp()).count(); + if zkapp_count > zkapp_limit { + return Err(StagedLedgerError::ZkAppsExceedLimit { + count: zkapp_count, + limit: zkapp_limit, + }); + } + }; + let ( is_new_stack, data, @@ -2583,10 +2567,10 @@ mod tests_ocaml { let cmds_applied_count = diff.commands().len(); - let cmds = util::drop(cmds, cmds_applied_count).to_vec(); + let cmds = util::drop(cmds, cmds_applied_count); let counts_rest = &cmd_iters[1..]; - iter_cmds_acc(&cmds, counts_rest, acc, fun) + iter_cmds_acc(cmds, counts_rest, acc, fun) } } } @@ -2608,7 +2592,11 @@ mod tests_ocaml { let global_slot_since_genesis = { let since_genesis = &state.body.consensus_state.global_slot_since_genesis; - let curr = &state.body.consensus_state.curr_global_slot.slot_number; + let curr = &state + .body + .consensus_state + .curr_global_slot_since_hard_fork + .slot_number; let since_genesis: Slot = since_genesis.into(); let curr: Slot = curr.into(); @@ -2619,7 +2607,7 @@ mod tests_ocaml { }; let cs = &mut state.body.consensus_state; - cs.curr_global_slot.slot_number = (&new_global_slot).into(); + cs.curr_global_slot_since_hard_fork.slot_number = (&new_global_slot).into(); cs.global_slot_since_genesis = (&global_slot_since_genesis).into(); }; diff --git a/ledger/src/staged_ledger/validate_block.rs b/ledger/src/staged_ledger/validate_block.rs index 75f3fa9de..297fda3ab 100644 --- a/ledger/src/staged_ledger/validate_block.rs +++ b/ledger/src/staged_ledger/validate_block.rs @@ -3,8 +3,7 @@ use std::collections::{BTreeMap, VecDeque}; use itertools::Itertools; use mina_p2p_messages::binprot::BinProtWrite; use mina_p2p_messages::v2::{ - Blake2MakeStableV1, ConsensusBodyReferenceStableV1, MinaBlockBlockStableV2, - StagedLedgerDiffDiffStableV2, + ConsensusBodyReferenceStableV1, MinaBlockBlockStableV2, StagedLedgerDiffDiffStableV2, }; const BODY_TAG: u8 = 0; @@ -30,7 +29,7 @@ pub fn block_body_hash( let bytes = serialize_with_len_and_tag(body); blocks_of_data(MAX_BLOCK_SIZE, &bytes) .map(|(_, hash)| hash) - .map(|hash| Blake2MakeStableV1(hash.as_slice().into())) + .map(|hash| hash.as_slice().into()) .map(ConsensusBodyReferenceStableV1) } diff --git a/ledger/src/zkapps/intefaces.rs b/ledger/src/zkapps/intefaces.rs index d9b4df08f..f8ca334fa 100644 --- a/ledger/src/zkapps/intefaces.rs +++ b/ledger/src/zkapps/intefaces.rs @@ -7,7 +7,7 @@ use crate::proofs::field::{Boolean, FieldWitness}; use crate::proofs::to_field_elements::ToFieldElements; use crate::proofs::transaction::Check; -use crate::scan_state::currency::{self, SlotSpan}; +use crate::scan_state::currency::{self, SlotSpan, TxnVersion}; use crate::zkapps::zkapp_logic; use crate::scan_state::transaction_logic::zkapp_command::{ @@ -373,6 +373,19 @@ pub trait ControllerInterface { single_data: &Self::SingleData, w: &mut Self::W, ) -> Self::Bool; + + fn verification_key_perm_fallback_to_signature_with_older_version( + auth: &AuthRequired, + w: &mut Self::W, + ) -> AuthRequired; +} + +pub trait TxnVersionInterface { + type W: WitnessGenerator; + type Bool: BoolInterface; + + fn equal_to_current(version: TxnVersion, w: &mut Self::W) -> Self::Bool; + fn older_than_current(version: TxnVersion, w: &mut Self::W) -> Self::Bool; } pub trait BoolInterface @@ -617,6 +630,7 @@ where Bool = Self::Bool, SingleData = Self::SingleData, >; + type TxnVersion: TxnVersionInterface; type SetOrKeep: SetOrKeepInterface; type GlobalSlotSpan: GlobalSlotSpanInterface< W = Self::WitnessGenerator, diff --git a/ledger/src/zkapps/snark.rs b/ledger/src/zkapps/snark.rs index 4de645c39..247e626c1 100644 --- a/ledger/src/zkapps/snark.rs +++ b/ledger/src/zkapps/snark.rs @@ -23,7 +23,7 @@ use crate::{ zkapp::{GlobalStateForProof, LedgerWithHash, WithStackHash, ZkappSingleData}, }, scan_state::{ - currency::{Amount, SlotSpan}, + currency::{Amount, SlotSpan, TxnVersion}, transaction_logic::{ local_state::{StackFrame, StackFrameChecked, StackFrameCheckedFrame, WithLazyHash}, zkapp_command::{ @@ -38,7 +38,7 @@ use crate::{ sparse_ledger::SparseLedger, zkapps::zkapp_logic, Account, AccountId, AuthRequired, AuthRequiredEncoded, Inputs, MyCow, ReceiptChainHash, - ToInputs, TokenId, VerificationKey, ZkAppAccount, + ToInputs, TokenId, VerificationKey, ZkAppAccount, TXN_VERSION_CURRENT, }; use super::intefaces::{ @@ -48,8 +48,8 @@ use super::intefaces::{ GlobalSlotSinceGenesisInterface, GlobalSlotSpanInterface, GlobalStateInterface, IndexInterface, LedgerInterface, LocalStateInterface, Opt, ReceiptChainHashInterface, SetOrKeepInterface, SignedAmountBranchParam, SignedAmountInterface, StackFrameInterface, StackFrameMakeParams, - StackInterface, TokenIdInterface, TransactionCommitmentInterface, VerificationKeyHashInterface, - WitnessGenerator, ZkappApplication, ZkappHandler, + StackInterface, TokenIdInterface, TransactionCommitmentInterface, TxnVersionInterface, + VerificationKeyHashInterface, WitnessGenerator, ZkappApplication, ZkappHandler, }; pub struct ZkappSnark; @@ -77,6 +77,7 @@ impl ZkappApplication for ZkappSnark { type VerificationKeyHash = SnarkVerificationKeyHash; type SingleData = ZkappSingleData; type Controller = SnarkController; + type TxnVersion = SnarkTxnVersion; type SetOrKeep = SnarkSetOrKeep; type GlobalSlotSpan = SnarkGlobalSlotSpan; type Actions = SnarkActions; @@ -908,7 +909,7 @@ impl Check for AccountUnhashed { delegate: _, voting_for: _, timing, - permissions: _, + permissions, zkapp, } = &*self.0; @@ -916,6 +917,7 @@ impl Check for AccountUnhashed { balance.check(w); nonce.check(w); timing.check(w); + permissions.check(w); ( FlaggedOption::from(zkapp.as_ref()), crate::ZkAppAccount::default, @@ -1161,6 +1163,7 @@ pub type SnarkBalance = CheckedBalance; pub struct SnarkTransactionCommitment; pub struct SnarkVerificationKeyHash; pub struct SnarkController; +pub struct SnarkTxnVersion; pub struct SnarkSetOrKeep; pub struct SnarkGlobalSlotSpan; pub struct SnarkActions; @@ -1323,6 +1326,24 @@ fn eval_proof(auth: &AuthRequired, w: &mut Witness) -> SnarkBool { signature_necessary.neg().and(&impossible.neg(), w) } +fn verification_key_perm_fallback_to_signature_with_older_version( + auth: &AuthRequired, + w: &mut Witness, +) -> AuthRequired { + let AuthRequiredEncoded { + signature_sufficient, + .. + } = encode_auth(auth); + + let on_true = SnarkBranch::make(w, |_| AuthRequired::Signature); + let on_false = SnarkBranch::make(w, |_| auth.clone()); + + w.on_if( + signature_sufficient.neg(), + BranchParam { on_true, on_false }, + ) +} + impl ControllerInterface for SnarkController { type W = Witness; type Bool = SnarkBool; @@ -1342,6 +1363,30 @@ impl ControllerInterface for SnarkController { Signature | NoneGiven => eval_no_proof(auth, signature_verifies, w), } } + + fn verification_key_perm_fallback_to_signature_with_older_version( + auth: &AuthRequired, + w: &mut Self::W, + ) -> AuthRequired { + verification_key_perm_fallback_to_signature_with_older_version(auth, w) + } +} + +impl TxnVersionInterface for SnarkTxnVersion { + type W = Witness; + type Bool = SnarkBool; + + fn equal_to_current(version: TxnVersion, w: &mut Self::W) -> Self::Bool { + let current = TXN_VERSION_CURRENT.to_checked(); + let version = version.to_checked(); + version.equal(¤t, w).var() + } + + fn older_than_current(version: TxnVersion, w: &mut Self::W) -> Self::Bool { + let current = TXN_VERSION_CURRENT.to_checked(); + let version = version.to_checked(); + version.less_than(¤t, w).var() + } } impl SetOrKeepInterface for SnarkSetOrKeep { diff --git a/ledger/src/zkapps/zkapp_logic.rs b/ledger/src/zkapps/zkapp_logic.rs index de0133236..5f99fc0b6 100644 --- a/ledger/src/zkapps/zkapp_logic.rs +++ b/ledger/src/zkapps/zkapp_logic.rs @@ -2,7 +2,6 @@ use mina_hasher::Fp; use mina_signer::CompressedPubKey; use crate::scan_state::transaction_logic::zkapp_command::{Actions, SetOrKeep}; -use crate::Permissions; use crate::{ proofs::transaction::transaction_snark::CONSTRAINT_CONSTANTS, scan_state::{ @@ -13,8 +12,9 @@ use crate::{ }, }, zkapps::intefaces::*, - AuthRequired, AuthRequiredEncoded, MyCow, TokenId, VerificationKey, + AuthRequired, MyCow, TokenId, VerificationKey, }; +use crate::{Permissions, SetVerificationKey}; use crate::proofs::{ field::{Boolean, ToBoolean}, @@ -83,25 +83,7 @@ fn pop_call_stack( (stack_frame, call_stack) } -// We don't use `AuthRequired::to_field_elements`, because in OCaml `Controller.if_` -// push values in reverse order (because of OCaml evaluation order) -// https://github.com/MinaProtocol/mina/blob/4283d70c8c5c1bd9eebb0d3e449c36fb0bf0c9af/src/lib/mina_base/permissions.ml#L174 -fn controller_exists( - auth: AuthRequired, - w: &mut Z::WitnessGenerator, -) -> AuthRequired { - let AuthRequiredEncoded { - constant, - signature_necessary, - signature_sufficient, - } = auth.encode(); - - w.exists_no_check([signature_sufficient, signature_necessary, constant]); - auth -} - // Different order than in `Permissions::iter_as_bits` -// Here we use `Iterator::rev()` fn permissions_exists( perms: Permissions, w: &mut Z::WitnessGenerator, @@ -113,7 +95,11 @@ fn permissions_exists( receive, set_delegate, set_permissions, - set_verification_key, + set_verification_key: + SetVerificationKey { + auth: set_verification_key_auth, + txn_version, + }, set_zkapp_uri, edit_action_state, set_token_symbol, @@ -122,25 +108,34 @@ fn permissions_exists( set_timing, } = &perms; + use crate::AuthOrVersion; + for auth in [ - edit_state, - access, - send, - receive, - set_delegate, - set_permissions, - set_verification_key, - set_zkapp_uri, - edit_action_state, - set_token_symbol, - increment_nonce, - set_voting_for, - set_timing, + AuthOrVersion::Auth(edit_state), + AuthOrVersion::Auth(send), + AuthOrVersion::Auth(receive), + AuthOrVersion::Auth(set_delegate), + AuthOrVersion::Auth(set_permissions), + AuthOrVersion::Auth(set_verification_key_auth), + AuthOrVersion::Version(*txn_version), + AuthOrVersion::Auth(set_zkapp_uri), + AuthOrVersion::Auth(edit_action_state), + AuthOrVersion::Auth(set_token_symbol), + AuthOrVersion::Auth(increment_nonce), + AuthOrVersion::Auth(set_voting_for), + AuthOrVersion::Auth(set_timing), + AuthOrVersion::Auth(access), ] .into_iter() - .rev() { - controller_exists::(*auth, w); + match auth { + AuthOrVersion::Auth(auth) => { + w.exists_no_check(*auth); + } + AuthOrVersion::Version(version) => { + w.exists_no_check(version); + } + } } perms } @@ -765,13 +760,11 @@ where let is_receiver = actual_balance_change.is_non_neg(); let _local_state = { - let controller = controller_exists::( - match is_receiver.as_boolean() { - Boolean::True => a.get().permissions.receive, - Boolean::False => a.get().permissions.send, - }, - w, - ); + let controller = { + let on_true = Z::Branch::make(w, |_| a.get().permissions.receive); + let on_false = Z::Branch::make(w, |_| a.get().permissions.send); + w.on_if(is_receiver, BranchParam { on_true, on_false }) + }; let has_permission = Z::Controller::check( proof_verifies, signature_verifies, @@ -893,15 +886,29 @@ where // Set verification key. let (_a, _local_state) = { let verification_key = &account_update.body().update.verification_key; + let has_permission = { - let set_verification_key = &a.get().permissions.set_verification_key; - Z::Controller::check( - proof_verifies, - signature_verifies, - set_verification_key, - &single_data, - w, - ) + let SetVerificationKey { auth, txn_version } = + &a.get().permissions.set_verification_key; + + let older_than_current_version = Z::TxnVersion::older_than_current(*txn_version, w); + let original_auth = auth; + + let auth = { + let on_true = Z::Branch::make(w, |w| { + Z::Controller::verification_key_perm_fallback_to_signature_with_older_version( + original_auth, + w, + ) + }); + let on_false = Z::Branch::make(w, |_| original_auth.clone()); + w.on_if( + older_than_current_version, + BranchParam { on_true, on_false }, + ) + }; + + Z::Controller::check(proof_verifies, signature_verifies, &auth, &single_data, w) }; Z::LocalState::add_check( local_state, diff --git a/mina-p2p-messages/Cargo.toml b/mina-p2p-messages/Cargo.toml index cefadc2c5..e8c948f78 100644 --- a/mina-p2p-messages/Cargo.toml +++ b/mina-p2p-messages/Cargo.toml @@ -26,6 +26,7 @@ mina-poseidon = { workspace = true, optional = true } o1-utils = { workspace = true, optional = true } ark-ff = { version = "0.3.0", features = [ "parallel", "asm" ], optional = true } +rsexp = "0.2.3" [target.'cfg(fuzzing)'.dev-dependencies] fuzzcheck = "0.12.1" diff --git a/mina-p2p-messages/default-v2.toml b/mina-p2p-messages/default-v2.toml index 331f23b7b..6dd886709 100644 --- a/mina-p2p-messages/default-v2.toml +++ b/mina-p2p-messages/default-v2.toml @@ -8,7 +8,7 @@ use binprot_derive::{BinProtRead, BinProtWrite}; use derive_more::Deref; use serde::{Deserialize, Serialize}; _blank_!(); -use crate::pseq::PaddedSeq; +use crate::{array::ArrayN16, list::List, pseq::PaddedSeq}; _blank_!(); use super::manual::*; _blank_!(); @@ -75,15 +75,15 @@ rust_id = 'bool' args_num = 'None' [base_types.int] -rust_id = 'crate::number::Int64' +rust_id = 'crate::number::UInt64' args_num = 'None' [base_types.int32] -rust_id = 'crate::number::Int32' +rust_id = 'crate::number::UInt32' args_num = 'None' [base_types.int64] -rust_id = 'crate::number::Int64' +rust_id = 'crate::number::UInt64' args_num = 'None' [base_types.char] @@ -91,7 +91,15 @@ rust_id = 'crate::char::Char' args_num = 'None' [base_types.list] -rust_id = 'Vec' +rust_id = 'List' +args_num = 'Single' + +[base_types."Bounded_types.String.t"] +rust_id = 'crate::string::ByteString' +args_num = 'None' + +[base_types."Bounded_types.Array.t"] +rust_id = 'ArrayN16' args_num = 'Single' [ocaml_mod_mapping] diff --git a/mina-p2p-messages/shapes/berkeley-1551e2faaa.txt.xz b/mina-p2p-messages/shapes/berkeley-1551e2faaa.txt.xz new file mode 100644 index 000000000..65c9b88d4 Binary files /dev/null and b/mina-p2p-messages/shapes/berkeley-1551e2faaa.txt.xz differ diff --git a/mina-p2p-messages/src/array.rs b/mina-p2p-messages/src/array.rs new file mode 100644 index 000000000..b23ae3856 --- /dev/null +++ b/mina-p2p-messages/src/array.rs @@ -0,0 +1,131 @@ +use std::ops::Deref; + +use binprot::{BinProtRead, BinProtWrite, Nat0}; +use serde::{Deserialize, Serialize}; + +/// Mina array bounded to specific length. Note that the length is only checked +/// when performing binprot operations. +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, derive_more::From, derive_more::Into)] +pub struct ArrayN(Vec); + +impl AsRef<[T]> for ArrayN { + fn as_ref(&self) -> &[T] { + self.0.as_ref() + } +} + +impl Deref for ArrayN { + type Target = [T]; + + fn deref(&self) -> &Self::Target { + self.0.as_ref() + } +} + +impl IntoIterator for ArrayN { + type Item = T; + + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<'a, T, const N: u64> IntoIterator for &'a ArrayN { + type Item = &'a T; + + type IntoIter = <&'a Vec as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + (&self.0).into_iter() + } +} + + +impl FromIterator for ArrayN { + fn from_iter>(iter: I) -> Self { + ArrayN::<_, N>(Vec::from_iter(iter)) + } +} + +impl ArrayN { + pub fn to_inner(self) -> Vec { + self.0 + } + + pub fn inner(&self) -> &Vec { + &self.0 + } + + pub fn inner_mut(&mut self) -> &mut Vec { + &mut self.0 + } + + pub fn iter(&self) -> std::slice::Iter<'_, T> { + self.0.iter() + } +} + +impl BinProtRead for ArrayN +where + T: BinProtRead, +{ + fn binprot_read(r: &mut R) -> Result { + let Nat0(len) = Nat0::binprot_read(r)?; + if len > N { + return Err(MinaArrayNTooLong::::new(len).into()); + } + let mut v: Vec = Vec::with_capacity(len as usize); + for _i in 0..len { + let item = T::binprot_read(r)?; + v.push(item) + } + Ok(ArrayN(v)) + } +} + +impl BinProtWrite for ArrayN +where + T: BinProtWrite, +{ + fn binprot_write(&self, w: &mut W) -> std::io::Result<()> { + let len = self.0.len() as u64; + if len > N { + return Err(MinaArrayNTooLong::::new(len).into()); + } + Nat0(len).binprot_write(w)?; + for v in self.0.iter() { + v.binprot_write(w)? + } + Ok(()) + } +} + +#[derive(Debug, thiserror::Error)] +#[error("String length `{0}` is greater than maximum `{N}`")] +pub struct MinaArrayNTooLong(u64); + +impl MinaArrayNTooLong { + fn new(actual: u64) -> Self { + MinaArrayNTooLong(actual) + } +} + +impl From> for std::io::Error { + fn from(value: MinaArrayNTooLong) -> Self { + std::io::Error::new(std::io::ErrorKind::InvalidData, Box::new(value)) + } +} + +impl From> for binprot::Error { + fn from(value: MinaArrayNTooLong) -> Self { + binprot::Error::CustomError(Box::new(value)) + } +} + +/// Mina array limited to 16 elements. +pub type ArrayN16 = ArrayN; + +/// Mina array limited to 4000 elements. +pub type ArrayN4000 = ArrayN; diff --git a/mina-p2p-messages/src/core.rs b/mina-p2p-messages/src/core.rs index fd4a50515..44a4d1e46 100644 --- a/mina-p2p-messages/src/core.rs +++ b/mina-p2p-messages/src/core.rs @@ -2,27 +2,67 @@ use std::net::IpAddr; use binprot_derive::{BinProtRead, BinProtWrite}; use serde::{Deserialize, Serialize}; - -use crate::versioned::Versioned; +use crate::{ + string::{ByteString, CharString}, + versioned::Versioned, +}; ///! Types from Janestreet's Core library. -/// Core.Error type. -/// -/// TODO properly implement payloads. -#[derive(Clone, Debug, Serialize, Deserialize, BinProtRead, BinProtWrite, PartialEq, Eq)] -pub enum Info { - CouldNotConstruct(super::string::CharString), // of Sexp.t - String(super::string::CharString), // of string - Exn, // of Binable_exn.V1.t - Sexp, // of Sexp.t - TagSexp, // of string * Sexp.t * Source_code_position.V1.t option - TagT, // of string * t - TagArg, // of string * Sexp.t * t - OfList, // of int option * t list - WithBacktrace, // of t * string (* backtrace *) +/// This type corresponds to `Bounded_types.Wrapped_error` OCaml type, but the +/// structure is different. It only refrects the data that is passed over the +/// wire (stringified sexp representation of the error) +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, derive_more::Display)] +#[serde(into = "SexpString", try_from = "SexpString")] +#[display(fmt = "{}", "String::from_utf8_lossy(&_0.to_bytes())")] +pub struct Info(rsexp::Sexp); + +impl Info { + pub fn from_str(msg: &str) -> Self { + Info(rsexp::atom(msg.as_bytes())) + } +} + +#[derive(Debug, thiserror::Error)] +#[error("error parsing info sexp: {0:?}")] +pub struct InfoFromSexpError(rsexp::Error); + +impl binprot::BinProtRead for Info { + fn binprot_read(r: &mut R) -> Result { + let sexp = ByteString::binprot_read(r)?; + let parsed = rsexp::from_slice(&sexp) + .map_err(|e| binprot::Error::CustomError(Box::new(InfoFromSexpError(e))))?; + Ok(Info(parsed)) + } +} + +impl binprot::BinProtWrite for Info { + fn binprot_write(&self, w: &mut W) -> std::io::Result<()> { + ByteString::from(self.0.to_bytes()).binprot_write(w) + } +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(transparent)] +pub struct SexpString(CharString); + +impl From for SexpString { + fn from(value: Info) -> Self { + SexpString(CharString::from(value.0.to_bytes())) + } +} + +impl TryFrom for Info { + type Error = InfoFromSexpError; + + fn try_from(value: SexpString) -> Result { + let parsed = rsexp::from_slice(&value.0) + .map_err(|e| InfoFromSexpError(e))?; + Ok(Info(parsed)) + } } +/// Represents error processing an RPC request. pub type Error = Info; // TODO @@ -54,3 +94,37 @@ impl binprot::BinProtWrite for InetAddrV1 { self.0.to_string().binprot_write(w) } } + +#[cfg(test)] +mod test { + use binprot::{BinProtWrite, BinProtRead}; + + use super::Info; + + fn info_to_bytes(info: &Info) -> Vec { + let mut bytes = Vec::new(); + info.binprot_write(&mut bytes).unwrap(); + bytes + } + + fn bytes_to_info(mut bytes: &[u8]) -> Info { + let info = Info::binprot_read(&mut bytes).unwrap(); + assert!(bytes.len() == 0); + info + } + + #[test] + fn sexp_binprot() { + use rsexp::*; + + let info = Info(atom(b"atom")); + let bytes = info_to_bytes(&info); + assert_eq!(&bytes, b"\x04atom"); + assert_eq!(info, bytes_to_info(&bytes)); + + let info = Info(atom(b"atom atom")); + let bytes = info_to_bytes(&info); + assert_eq!(&bytes, b"\x0b\"atom atom\""); + assert_eq!(info, bytes_to_info(&bytes)); + } +} diff --git a/mina-p2p-messages/src/hash_input.rs b/mina-p2p-messages/src/hash_input.rs index 460607350..f59c04abf 100644 --- a/mina-p2p-messages/src/hash_input.rs +++ b/mina-p2p-messages/src/hash_input.rs @@ -7,10 +7,7 @@ use mina_hasher::Fp; use o1_utils::FieldHelpers; use crate::{ - b58::Base58CheckOfBinProt, - bigint::BigInt, - number::{Int32, Int64, UInt32, UInt64}, - pseq::PaddedSeq, + b58::Base58CheckOfBinProt, bigint::BigInt, list::List, number::{Int32, Int64, UInt32, UInt64}, pseq::PaddedSeq, string::ByteString }; pub trait ToInput { @@ -53,6 +50,12 @@ impl ToInput for UInt64 { } } +impl ToInput for ByteString { + fn to_input(&self, inputs: &mut Inputs) { + inputs.append_bytes(self.as_ref()) + } +} + impl ToInput for Vec where D: Deref, @@ -63,6 +66,16 @@ where } } +impl ToInput for List +where + D: Deref, + T: ToInput, +{ + fn to_input(&self, inputs: &mut Inputs) { + self.deref().into_iter().for_each(|v| v.to_input(inputs)); + } +} + impl ToInput for (T, T) where T: ToInput, diff --git a/mina-p2p-messages/src/lib.rs b/mina-p2p-messages/src/lib.rs index 2d64cd296..aac4182f3 100644 --- a/mina-p2p-messages/src/lib.rs +++ b/mina-p2p-messages/src/lib.rs @@ -12,6 +12,8 @@ pub mod phantom; pub mod rpc; pub mod rpc_kernel; pub mod string; +pub mod list; +pub mod array; pub mod utils; #[macro_use] pub mod versioned; diff --git a/mina-p2p-messages/src/list.rs b/mina-p2p-messages/src/list.rs new file mode 100644 index 000000000..0162109b1 --- /dev/null +++ b/mina-p2p-messages/src/list.rs @@ -0,0 +1,104 @@ +use std::{collections::LinkedList, ops::{Deref, DerefMut}}; + +use binprot::{BinProtRead, BinProtWrite, Nat0}; + +pub type Backend = LinkedList; + +/// Represents OCaml list type. +#[derive( + Clone, + Debug, + Default, + PartialEq, + Eq, + PartialOrd, + Ord, + serde::Serialize, + serde::Deserialize, + derive_more::From, + derive_more::Into, +)] +pub struct List(Backend); + +impl List { + pub fn new() -> Self { + List(Backend::new()) + } + + pub fn iter(&self) -> <&Backend as IntoIterator>::IntoIter { + (self).into_iter() + } + + pub fn push_front(&mut self, element: T) { + self.0.push_front(element) + } +} + +impl Deref for List { + type Target = Backend; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for List { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl IntoIterator for List { + type Item = T; + + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +impl<'a, T> IntoIterator for &'a List { + type Item = &'a T; + + type IntoIter = <&'a Backend as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + (&self.0).into_iter() + } +} + +impl FromIterator for List { + fn from_iter>(iter: I) -> Self { + List(Backend::from_iter(iter)) + } +} + +impl BinProtRead for List +where + T: BinProtRead, +{ + fn binprot_read(r: &mut R) -> Result { + let Nat0(len) = Nat0::binprot_read(r)?; + let mut v: Backend = Backend::new(); + for _i in 0..len { + let item = T::binprot_read(r)?; + v.push_back(item) + } + Ok(List(v)) + } +} + +impl BinProtWrite for List +where + T: BinProtWrite, +{ + fn binprot_write(&self, w: &mut W) -> std::io::Result<()> { + let len = self.0.len() as u64; + Nat0(len).binprot_write(w)?; + for v in self.0.iter() { + v.binprot_write(w)? + } + Ok(()) + } +} diff --git a/mina-p2p-messages/src/number.rs b/mina-p2p-messages/src/number.rs index 7b8384220..4b5302de0 100644 --- a/mina-p2p-messages/src/number.rs +++ b/mina-p2p-messages/src/number.rs @@ -68,6 +68,18 @@ impl From<&u64> for Number { } } +impl From<&u32> for Number { + fn from(value: &u32) -> Self { + Self(*value) + } +} + +impl From<&u64> for Number { + fn from(value: &u64) -> Self { + Self(*value) + } +} + impl Serialize for Number where T: Serialize + Display, diff --git a/mina-p2p-messages/src/rpc.rs b/mina-p2p-messages/src/rpc.rs index 8d9f92478..c0a6cc55a 100644 --- a/mina-p2p-messages/src/rpc.rs +++ b/mina-p2p-messages/src/rpc.rs @@ -18,6 +18,7 @@ use crate::{v1, v2}; macro_rules! mina_rpc { ($name:ident, $tag:literal, $version:literal, $query:ty, $response:ty $(,)?) => { + #[derive(Debug)] pub struct $name; impl crate::rpc_kernel::RpcMethod for $name { const NAME: &'static str = $tag; @@ -93,7 +94,7 @@ mina_rpc!( mina_rpc!( AnswerSyncLedgerQueryV2, "answer_sync_ledger_query", - 2, + 3, (LedgerHashV1, v2::MinaLedgerSyncLedgerQueryStableV1), RpcResult ); diff --git a/mina-p2p-messages/src/rpc_kernel.rs b/mina-p2p-messages/src/rpc_kernel.rs index 990f46fa8..dde21c081 100644 --- a/mina-p2p-messages/src/rpc_kernel.rs +++ b/mina-p2p-messages/src/rpc_kernel.rs @@ -63,6 +63,12 @@ where #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, derive_more::From)] pub struct NeedsLength(pub T); +impl NeedsLength { + pub fn into_inner(self) -> T { + self.0 + } +} + impl BinProtRead for NeedsLength where T: BinProtRead, @@ -297,7 +303,7 @@ where R: Read, { ResponsePayload::::binprot_read(r) - .map(|v| Result::from(v).map(|NeedsLength(v)| v)) + .map(|v| Result::from(v).map(NeedsLength::into_inner)) } } @@ -353,7 +359,7 @@ where R: Read, { if let Message::Response(response) = Message::::binprot_read(r)? { - Ok(Result::from(response.data).map(|v| v.0)) + Ok(Result::from(response.data).map(NeedsLength::into_inner)) } else { Err(RpcDebuggerReaderError::ExpectResponse) } diff --git a/mina-p2p-messages/src/string.rs b/mina-p2p-messages/src/string.rs index 26390761d..aafacd2c7 100644 --- a/mina-p2p-messages/src/string.rs +++ b/mina-p2p-messages/src/string.rs @@ -1,6 +1,8 @@ use binprot::Nat0; use serde::{de::Visitor, Deserialize, Serialize}; +const MINA_STRING_MAX_LENGTH: usize = 100_000_000; + /// String of bytes. #[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord)] pub struct ByteString(Vec); @@ -109,8 +111,11 @@ impl binprot::BinProtRead for ByteString { where Self: Sized, { - let len = Nat0::binprot_read(r)?; - let mut buf: Vec = vec![0u8; len.0 as usize]; + let len = Nat0::binprot_read(r)?.0 as usize; + if len > MINA_STRING_MAX_LENGTH { + return Err(MinaStringTooLong::as_binprot_err(len)); + } + let mut buf: Vec = vec![0u8; len]; r.read_exact(&mut buf)?; Ok(Self(buf)) } @@ -118,6 +123,9 @@ impl binprot::BinProtRead for ByteString { impl binprot::BinProtWrite for ByteString { fn binprot_write(&self, w: &mut W) -> std::io::Result<()> { + if self.0.len() > MINA_STRING_MAX_LENGTH { + return Err(MinaStringTooLong::as_io_err(self.0.len())); + } let _ = Nat0(self.0.len() as u64).binprot_write(w)?; let _ = w.write_all(&self.0)?; Ok(()) @@ -235,8 +243,11 @@ impl binprot::BinProtRead for CharString { where Self: Sized, { - let len = Nat0::binprot_read(r)?; - let mut buf: Vec = vec![0u8; len.0 as usize]; + let len = Nat0::binprot_read(r)?.0 as usize; + if len > MINA_STRING_MAX_LENGTH { + return Err(MinaStringTooLong::as_binprot_err(len)); + } + let mut buf: Vec = vec![0u8; len]; r.read_exact(&mut buf)?; Ok(Self(buf)) } @@ -244,8 +255,100 @@ impl binprot::BinProtRead for CharString { impl binprot::BinProtWrite for CharString { fn binprot_write(&self, w: &mut W) -> std::io::Result<()> { + if self.0.len() > MINA_STRING_MAX_LENGTH { + return Err(MinaStringTooLong::as_io_err(self.0.len())); + } let _ = Nat0(self.0.len() as u64).binprot_write(w)?; let _ = w.write_all(&self.0)?; Ok(()) } } + +#[derive(Debug, thiserror::Error)] +#[error("String length `{actual}` is greater than maximum `{max}`")] +pub struct MinaStringTooLong { + max: usize, + actual: usize, +} + +impl MinaStringTooLong { + fn boxed(actual: usize) -> Box { + Box::new(MinaStringTooLong { + max: MINA_STRING_MAX_LENGTH, + actual, + }) + } + + fn as_io_err(actual: usize) -> std::io::Error { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + MinaStringTooLong::boxed(actual), + ) + } + + fn as_binprot_err(actual: usize) -> binprot::Error { + binprot::Error::CustomError(MinaStringTooLong::boxed(actual)) + } +} + +#[cfg(test)] +mod tests { + use std::io::Cursor; + + use binprot::{BinProtRead, BinProtWrite, Nat0}; + + use crate::string::CharString; + + use super::{ByteString, MINA_STRING_MAX_LENGTH}; + + #[test] + fn bounded_string_binprot_write() { + let bs = ByteString::from(vec![0; MINA_STRING_MAX_LENGTH]); + let mut out = Vec::new(); + let res = bs.binprot_write(&mut out); + assert!(res.is_ok()); + + let bs = CharString::from(vec![0; MINA_STRING_MAX_LENGTH]); + let mut out = Vec::new(); + let res = bs.binprot_write(&mut out); + assert!(res.is_ok()); + + let bs = ByteString::from(vec![0; MINA_STRING_MAX_LENGTH + 1]); + let mut out = Vec::new(); + let res = bs.binprot_write(&mut out); + assert!(res.is_err()); + + let bs = CharString::from(vec![0; MINA_STRING_MAX_LENGTH + 1]); + let mut out = Vec::new(); + let res = bs.binprot_write(&mut out); + assert!(res.is_err()); + } + + #[test] + fn bounded_string_binprot_read() { + fn input(len: usize) -> Cursor> { + let mut input = Vec::new(); + // prepare input + Nat0(len as u64).binprot_write(&mut input).unwrap(); + vec![0; len].binprot_write(&mut input).unwrap(); + Cursor::new(input) + } + + let mut inp = input(MINA_STRING_MAX_LENGTH); + let res = ByteString::binprot_read(&mut inp); + assert!(res.is_ok()); + + let mut inp = input(MINA_STRING_MAX_LENGTH); + let res = CharString::binprot_read(&mut inp); + assert!(res.is_ok()); + + let mut inp = input(MINA_STRING_MAX_LENGTH + 1); + let res = ByteString::binprot_read(&mut inp); + assert!(res.is_err()); + + let mut inp = input(MINA_STRING_MAX_LENGTH + 1); + let res = CharString::binprot_read(&mut inp); + assert!(res.is_err()); + + } +} diff --git a/mina-p2p-messages/src/v2/generated.rs b/mina-p2p-messages/src/v2/generated.rs index 7988cbaaa..571d44d6d 100644 --- a/mina-p2p-messages/src/v2/generated.rs +++ b/mina-p2p-messages/src/v2/generated.rs @@ -2,14 +2,15 @@ use binprot_derive::{BinProtRead, BinProtWrite}; use derive_more::Deref; use serde::{Deserialize, Serialize}; -use crate::pseq::PaddedSeq; +use crate::{array::ArrayN16, list::List, pseq::PaddedSeq}; use super::manual::*; + /// **OCaml name**: `Mina_block__Block.Stable.V2` /// -/// Gid: `1086` -/// Location: [src/lib/mina_block/block.ml:8:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_block/block.ml#L8) +/// Gid: `1102` +/// Location: [src/lib/mina_block/block.ml:8:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_block/block.ml#L8) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBlockBlockStableV2 { pub header: MinaBlockHeaderStableV2, @@ -18,25 +19,25 @@ pub struct MinaBlockBlockStableV2 { /// **OCaml name**: `Network_pool__Transaction_pool.Diff_versioned.Stable.V2` /// -/// Gid: `1106` -/// Location: [src/lib/network_pool/transaction_pool.ml:47:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/network_pool/transaction_pool.ml#L47) +/// Gid: `1122` +/// Location: [src/lib/network_pool/transaction_pool.ml:47:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/network_pool/transaction_pool.ml#L47) /// /// /// Gid: `167` -/// Location: [src/std_internal.ml:131:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L131) +/// Location: [src/std_internal.ml:131:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L131) /// Args: MinaBaseUserCommandStableV2 /// /// /// Gid: `50` -/// Location: [src/list0.ml:6:0](https://github.com/MinaProtocol/mina/blob/14047c5551/src/list0.ml#L6) +/// Location: [src/list0.ml:6:0](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/list0.ml#L6) /// Args: MinaBaseUserCommandStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct NetworkPoolTransactionPoolDiffVersionedStableV2(pub Vec); +pub struct NetworkPoolTransactionPoolDiffVersionedStableV2(pub List); /// **OCaml name**: `Network_pool__Snark_pool.Diff_versioned.Stable.V2` /// -/// Gid: `1110` -/// Location: [src/lib/network_pool/snark_pool.ml:547:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/network_pool/snark_pool.ml#L547) +/// Gid: `1126` +/// Location: [src/lib/network_pool/snark_pool.ml:542:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/network_pool/snark_pool.ml#L542) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum NetworkPoolSnarkPoolDiffVersionedStableV2 { AddSolvedWork( @@ -50,34 +51,34 @@ pub enum NetworkPoolSnarkPoolDiffVersionedStableV2 { /// **OCaml name**: `Mina_base__Sparse_ledger_base.Stable.V2` /// -/// Gid: `873` -/// Location: [src/lib/mina_base/sparse_ledger_base.ml:8:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/sparse_ledger_base.ml#L8) +/// Gid: `882` +/// Location: [src/lib/mina_base/sparse_ledger_base.ml:8:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/sparse_ledger_base.ml#L8) /// /// -/// Gid: `652` -/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:38:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/sparse_ledger_lib/sparse_ledger.ml#L38) +/// Gid: `661` +/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:38:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/sparse_ledger_lib/sparse_ledger.ml#L38) /// Args: LedgerHash , MinaBaseAccountIdStableV2 , MinaBaseAccountBinableArgStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseSparseLedgerBaseStableV2 { - pub indexes: Vec<(MinaBaseAccountIdStableV2, crate::number::Int64)>, - pub depth: crate::number::Int64, + pub indexes: List<(MinaBaseAccountIdStableV2, crate::number::UInt64)>, + pub depth: crate::number::UInt64, pub tree: MinaBaseSparseLedgerBaseStableV2Tree, } /// **OCaml name**: `Mina_base__Account.Binable_arg.Stable.V2` /// -/// Gid: `771` -/// Location: [src/lib/mina_base/account.ml:264:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account.ml#L264) +/// Gid: `780` +/// Location: [src/lib/mina_base/account.ml:265:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account.ml#L265) /// /// -/// Gid: `769` -/// Location: [src/lib/mina_base/account.ml:209:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account.ml#L209) -/// Args: NonZeroCurvePoint , TokenIdKeyHash , MinaBaseZkappAccountZkappUriStableV1 , CurrencyBalanceStableV1 , UnsignedExtendedUInt32StableV1 , MinaBaseReceiptChainHashStableV1 , Option < NonZeroCurvePoint > , StateHash , MinaBaseAccountTimingStableV2 , MinaBasePermissionsStableV2 , Option < MinaBaseZkappAccountStableV2 > +/// Gid: `778` +/// Location: [src/lib/mina_base/account.ml:210:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account.ml#L210) +/// Args: NonZeroCurvePoint , TokenIdKeyHash , crate :: string :: ByteString , CurrencyBalanceStableV1 , UnsignedExtendedUInt32StableV1 , MinaBaseReceiptChainHashStableV1 , Option < NonZeroCurvePoint > , StateHash , MinaBaseAccountTimingStableV2 , MinaBasePermissionsStableV2 , Option < MinaBaseZkappAccountStableV2 > #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountBinableArgStableV2 { pub public_key: NonZeroCurvePoint, pub token_id: TokenIdKeyHash, - pub token_symbol: MinaBaseZkappAccountZkappUriStableV1, + pub token_symbol: crate::string::ByteString, pub balance: CurrencyBalanceStableV1, pub nonce: UnsignedExtendedUInt32StableV1, pub receipt_chain_hash: MinaBaseReceiptChainHashStableV1, @@ -90,52 +91,52 @@ pub struct MinaBaseAccountBinableArgStableV2 { /// **OCaml name**: `Network_peer__Peer.Stable.V1` /// -/// Gid: `881` -/// Location: [src/lib/network_peer/peer.ml:28:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/network_peer/peer.ml#L28) +/// Gid: `890` +/// Location: [src/lib/network_peer/peer.ml:56:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/network_peer/peer.ml#L56) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct NetworkPeerPeerStableV1 { pub host: crate::string::ByteString, - pub libp2p_port: crate::number::Int64, + pub libp2p_port: crate::number::UInt64, pub peer_id: NetworkPeerPeerIdStableV1, } /// **OCaml name**: `Transaction_snark_scan_state.Stable.V2` /// -/// Gid: `1084` -/// Location: [src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml:160:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml#L160) +/// Gid: `1058` +/// Location: [src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml:160:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml#L160) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkScanStateStableV2 { pub scan_state: TransactionSnarkScanStateStableV2ScanState, pub previous_incomplete_zkapp_updates: ( - Vec, + List, TransactionSnarkScanStateStableV2PreviousIncompleteZkappUpdates1, ), } /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Stable.V2` /// -/// Gid: `865` -/// Location: [src/lib/mina_base/pending_coinbase.ml:1281:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L1281) +/// Gid: `874` +/// Location: [src/lib/mina_base/pending_coinbase.ml:1281:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L1281) /// /// -/// Gid: `864` -/// Location: [src/lib/mina_base/pending_coinbase.ml:1269:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L1269) +/// Gid: `873` +/// Location: [src/lib/mina_base/pending_coinbase.ml:1269:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L1269) /// Args: MinaBasePendingCoinbaseMerkleTreeVersionedStableV2 , MinaBasePendingCoinbaseStackIdStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePendingCoinbaseStableV2 { pub tree: MinaBasePendingCoinbaseMerkleTreeVersionedStableV2, - pub pos_list: Vec, + pub pos_list: List, pub new_pos: MinaBasePendingCoinbaseStackIdStableV1, } /// **OCaml name**: `Mina_state__Protocol_state.Make_str.Value.Stable.V2` /// -/// Gid: `990` -/// Location: [src/lib/mina_state/protocol_state.ml:203:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/protocol_state.ml#L203) +/// Gid: `1004` +/// Location: [src/lib/mina_state/protocol_state.ml:203:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/protocol_state.ml#L203) /// /// -/// Gid: `986` -/// Location: [src/lib/mina_state/protocol_state.ml:38:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/protocol_state.ml#L38) +/// Gid: `1000` +/// Location: [src/lib/mina_state/protocol_state.ml:38:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/protocol_state.ml#L38) /// Args: StateHash , MinaStateProtocolStateBodyValueStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateProtocolStateValueStableV2 { @@ -145,12 +146,12 @@ pub struct MinaStateProtocolStateValueStableV2 { /// **OCaml name**: `Mina_ledger__Sync_ledger.Query.Stable.V1` /// -/// Gid: `926` -/// Location: [src/lib/mina_ledger/sync_ledger.ml:83:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_ledger/sync_ledger.ml#L83) +/// Gid: `940` +/// Location: [src/lib/mina_ledger/sync_ledger.ml:83:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_ledger/sync_ledger.ml#L83) /// /// -/// Gid: `915` -/// Location: [src/lib/syncable_ledger/syncable_ledger.ml:17:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/syncable_ledger/syncable_ledger.ml#L17) +/// Gid: `927` +/// Location: [src/lib/syncable_ledger/syncable_ledger.ml:17:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/syncable_ledger/syncable_ledger.ml#L17) /// Args: MerkleAddressBinableArgStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaLedgerSyncLedgerQueryStableV1 { @@ -161,38 +162,38 @@ pub enum MinaLedgerSyncLedgerQueryStableV1 { /// **OCaml name**: `Mina_ledger__Sync_ledger.Answer.Stable.V2` /// -/// Gid: `925` -/// Location: [src/lib/mina_ledger/sync_ledger.ml:58:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_ledger/sync_ledger.ml#L58) +/// Gid: `939` +/// Location: [src/lib/mina_ledger/sync_ledger.ml:58:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_ledger/sync_ledger.ml#L58) /// /// -/// Gid: `916` -/// Location: [src/lib/syncable_ledger/syncable_ledger.ml:35:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/syncable_ledger/syncable_ledger.ml#L35) +/// Gid: `928` +/// Location: [src/lib/syncable_ledger/syncable_ledger.ml:35:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/syncable_ledger/syncable_ledger.ml#L35) /// Args: LedgerHash , MinaBaseAccountBinableArgStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaLedgerSyncLedgerAnswerStableV2 { ChildHashesAre(LedgerHash, LedgerHash), - ContentsAre(Vec), - NumAccounts(crate::number::Int64, LedgerHash), + ContentsAre(List), + NumAccounts(crate::number::UInt64, LedgerHash), } /// **OCaml name**: `Consensus__Proof_of_stake.Make_str.Data.Consensus_state.Value.Stable.V2` /// -/// Gid: `970` -/// Location: [src/lib/consensus/proof_of_stake.ml:1800:12](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/proof_of_stake.ml#L1800) +/// Gid: `984` +/// Location: [src/lib/consensus/proof_of_stake.ml:1768:12](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/proof_of_stake.ml#L1768) /// /// -/// Gid: `969` -/// Location: [src/lib/consensus/proof_of_stake.ml:1755:12](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/proof_of_stake.ml#L1755) +/// Gid: `983` +/// Location: [src/lib/consensus/proof_of_stake.ml:1723:12](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/proof_of_stake.ml#L1723) /// Args: UnsignedExtendedUInt32StableV1 , ConsensusVrfOutputTruncatedStableV1 , CurrencyAmountStableV1 , ConsensusGlobalSlotStableV1 , MinaNumbersGlobalSlotSinceGenesisMStableV1 , ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1 , ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1 , bool , NonZeroCurvePoint #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct ConsensusProofOfStakeDataConsensusStateValueStableV2 { pub blockchain_length: UnsignedExtendedUInt32StableV1, pub epoch_count: UnsignedExtendedUInt32StableV1, pub min_window_density: UnsignedExtendedUInt32StableV1, - pub sub_window_densities: Vec, + pub sub_window_densities: List, pub last_vrf_output: ConsensusVrfOutputTruncatedStableV1, pub total_currency: CurrencyAmountStableV1, - pub curr_global_slot: ConsensusGlobalSlotStableV1, + pub curr_global_slot_since_hard_fork: ConsensusGlobalSlotStableV1, pub global_slot_since_genesis: MinaNumbersGlobalSlotSinceGenesisMStableV1, pub staking_epoch_data: ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1, pub next_epoch_data: ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1, @@ -205,8 +206,8 @@ pub struct ConsensusProofOfStakeDataConsensusStateValueStableV2 { /// **OCaml name**: `Sync_status.T.Stable.V1` /// -/// Gid: `1142` -/// Location: [src/lib/sync_status/sync_status.ml:54:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/sync_status/sync_status.ml#L54) +/// Gid: `1158` +/// Location: [src/lib/sync_status/sync_status.ml:55:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/sync_status/sync_status.ml#L55) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] #[polymorphic_variant] pub enum SyncStatusTStableV1 { @@ -226,8 +227,8 @@ pub enum SyncStatusTStableV1 { /// **OCaml name**: `Trust_system__Peer_status.Stable.V1` /// -/// Gid: `913` -/// Location: [src/lib/trust_system/peer_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/trust_system/peer_status.ml#L6) +/// Gid: `925` +/// Location: [src/lib/trust_system/peer_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/trust_system/peer_status.ml#L6) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TrustSystemPeerStatusStableV1 { pub trust: crate::number::Float64, @@ -236,8 +237,8 @@ pub struct TrustSystemPeerStatusStableV1 { /// **OCaml name**: `Blockchain_snark__Blockchain.Stable.V2` /// -/// Gid: `1043` -/// Location: [src/lib/blockchain_snark/blockchain.ml:8:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/blockchain_snark/blockchain.ml#L8) +/// Gid: `1069` +/// Location: [src/lib/blockchain_snark/blockchain.ml:8:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/blockchain_snark/blockchain.ml#L8) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct BlockchainSnarkBlockchainStableV2 { pub state: MinaStateProtocolStateValueStableV2, @@ -246,8 +247,8 @@ pub struct BlockchainSnarkBlockchainStableV2 { /// **OCaml name**: `Transaction_witness.Stable.V2` /// -/// Gid: `995` -/// Location: [src/lib/transaction_witness/transaction_witness.ml:54:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_witness/transaction_witness.ml#L54) +/// Gid: `1009` +/// Location: [src/lib/transaction_witness/transaction_witness.ml:54:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_witness/transaction_witness.ml#L54) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionWitnessStableV2 { pub transaction: MinaTransactionTransactionStableV2, @@ -261,8 +262,8 @@ pub struct TransactionWitnessStableV2 { /// **OCaml name**: `Prover.Extend_blockchain_input.Stable.V2` /// -/// Gid: `1263` -/// Location: [src/lib/prover/prover.ml:16:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/prover/prover.ml#L16) +/// Gid: `1280` +/// Location: [src/lib/prover/prover.ml:16:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/prover/prover.ml#L16) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct ProverExtendBlockchainInputStableV2 { pub chain: BlockchainSnarkBlockchainStableV2, @@ -275,17 +276,17 @@ pub struct ProverExtendBlockchainInputStableV2 { /// **OCaml name**: `Snark_worker.Worker.Rpcs_versioned.Get_work.V2.T.response` /// -/// Gid: `1119` -/// Location: [src/lib/snark_worker/snark_worker.ml:29:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/snark_worker/snark_worker.ml#L29) +/// Gid: `1135` +/// Location: [src/lib/snark_worker/snark_worker.ml:29:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/snark_worker/snark_worker.ml#L29) /// /// /// Gid: `169` -/// Location: [src/std_internal.ml:137:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L137) +/// Location: [src/std_internal.ml:137:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L137) /// Args: (SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0 , NonZeroCurvePoint ,) /// /// /// Gid: `60` -/// Location: [src/option.ml:4:0](https://github.com/MinaProtocol/mina/blob/14047c5551/src/option.ml#L4) +/// Location: [src/option.ml:4:0](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/option.ml#L4) /// Args: (SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0 , NonZeroCurvePoint ,) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse( @@ -297,12 +298,12 @@ pub struct SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponse( /// **OCaml name**: `Snark_worker.Worker.Rpcs_versioned.Submit_work.V2.T.query` /// -/// Gid: `1120` -/// Location: [src/lib/snark_worker/snark_worker.ml:59:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/snark_worker/snark_worker.ml#L59) +/// Gid: `1136` +/// Location: [src/lib/snark_worker/snark_worker.ml:59:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/snark_worker/snark_worker.ml#L59) /// /// -/// Gid: `1066` -/// Location: [src/lib/snark_work_lib/work.ml:90:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/snark_work_lib/work.ml#L90) +/// Gid: `1040` +/// Location: [src/lib/snark_work_lib/work.ml:90:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/snark_work_lib/work.ml#L90) /// Args: SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0 , LedgerProofProdStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct SnarkWorkerWorkerRpcsVersionedSubmitWorkV2TQuery { @@ -312,19 +313,10 @@ pub struct SnarkWorkerWorkerRpcsVersionedSubmitWorkV2TQuery { pub prover: NonZeroCurvePoint, } -/// **OCaml name**: `Mina_base__Zkapp_account.Zkapp_uri.Stable.V1` -/// -/// Gid: `73` -/// Location: [src/string.ml:14:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/string.ml#L14) -#[derive( - Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref, Default, -)] -pub struct MinaBaseZkappAccountZkappUriStableV1(pub crate::string::ByteString); - /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.statement.fp` /// -/// Gid: `458` -/// Location: [src/lib/pickles_types/shifted_value.ml:98:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_types/shifted_value.ml#L98) +/// Gid: `461` +/// Location: [src/lib/pickles_types/shifted_value.ml:98:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_types/shifted_value.ml#L98) /// Args: crate :: bigint :: BigInt #[derive(Clone, Debug, PartialEq, BinProtRead, BinProtWrite)] pub enum PicklesProofProofsVerified2ReprStableV2StatementFp { @@ -333,8 +325,8 @@ pub enum PicklesProofProofsVerified2ReprStableV2StatementFp { /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.statement.proof_state.deferred_values.plonk.feature_flags` /// -/// Gid: `461` -/// Location: [src/lib/pickles_types/plonk_types.ml:194:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_types/plonk_types.ml#L194) +/// Gid: `464` +/// Location: [src/lib/pickles_types/plonk_types.ml:194:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_types/plonk_types.ml#L194) /// Args: bool #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2StatementProofStateDeferredValuesPlonkFeatureFlags @@ -351,50 +343,130 @@ pub struct PicklesProofProofsVerified2ReprStableV2StatementProofStateDeferredVal /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.prev_evals.evals.evals` /// -/// Gid: `462` -/// Location: [src/lib/pickles_types/plonk_types.ml:363:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_types/plonk_types.ml#L363) -/// Args: (Vec < crate :: bigint :: BigInt > , Vec < crate :: bigint :: BigInt > ,) +/// Gid: `465` +/// Location: [src/lib/pickles_types/plonk_types.ml:363:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_types/plonk_types.ml#L363) +/// Args: (ArrayN16 < crate :: bigint :: BigInt > , ArrayN16 < crate :: bigint :: BigInt > ,) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2PrevEvalsEvalsEvals { - pub w: PaddedSeq<(Vec, Vec), 15>, - pub coefficients: PaddedSeq<(Vec, Vec), 15>, - pub z: (Vec, Vec), - pub s: PaddedSeq<(Vec, Vec), 6>, - pub generic_selector: (Vec, Vec), - pub poseidon_selector: (Vec, Vec), - pub complete_add_selector: (Vec, Vec), - pub mul_selector: (Vec, Vec), - pub emul_selector: (Vec, Vec), - pub endomul_scalar_selector: (Vec, Vec), - pub range_check0_selector: Option<(Vec, Vec)>, - pub range_check1_selector: Option<(Vec, Vec)>, - pub foreign_field_add_selector: - Option<(Vec, Vec)>, - pub foreign_field_mul_selector: - Option<(Vec, Vec)>, - pub xor_selector: Option<(Vec, Vec)>, - pub rot_selector: Option<(Vec, Vec)>, - pub lookup_aggregation: Option<(Vec, Vec)>, - pub lookup_table: Option<(Vec, Vec)>, - pub lookup_sorted: - PaddedSeq, Vec)>, 5>, - pub runtime_lookup_table: Option<(Vec, Vec)>, - pub runtime_lookup_table_selector: - Option<(Vec, Vec)>, - pub xor_lookup_selector: Option<(Vec, Vec)>, - pub lookup_gate_lookup_selector: - Option<(Vec, Vec)>, - pub range_check_lookup_selector: - Option<(Vec, Vec)>, - pub foreign_field_mul_lookup_selector: - Option<(Vec, Vec)>, + pub w: PaddedSeq< + ( + ArrayN16, + ArrayN16, + ), + 15, + >, + pub coefficients: PaddedSeq< + ( + ArrayN16, + ArrayN16, + ), + 15, + >, + pub z: ( + ArrayN16, + ArrayN16, + ), + pub s: PaddedSeq< + ( + ArrayN16, + ArrayN16, + ), + 6, + >, + pub generic_selector: ( + ArrayN16, + ArrayN16, + ), + pub poseidon_selector: ( + ArrayN16, + ArrayN16, + ), + pub complete_add_selector: ( + ArrayN16, + ArrayN16, + ), + pub mul_selector: ( + ArrayN16, + ArrayN16, + ), + pub emul_selector: ( + ArrayN16, + ArrayN16, + ), + pub endomul_scalar_selector: ( + ArrayN16, + ArrayN16, + ), + pub range_check0_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub range_check1_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub foreign_field_add_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub foreign_field_mul_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub xor_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub rot_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub lookup_aggregation: Option<( + ArrayN16, + ArrayN16, + )>, + pub lookup_table: Option<( + ArrayN16, + ArrayN16, + )>, + pub lookup_sorted: PaddedSeq< + Option<( + ArrayN16, + ArrayN16, + )>, + 5, + >, + pub runtime_lookup_table: Option<( + ArrayN16, + ArrayN16, + )>, + pub runtime_lookup_table_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub xor_lookup_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub lookup_gate_lookup_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub range_check_lookup_selector: Option<( + ArrayN16, + ArrayN16, + )>, + pub foreign_field_mul_lookup_selector: Option<( + ArrayN16, + ArrayN16, + )>, } /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.prev_evals.evals` /// -/// Gid: `463` -/// Location: [src/lib/pickles_types/plonk_types.ml:1057:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_types/plonk_types.ml#L1057) -/// Args: (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) , (Vec < crate :: bigint :: BigInt > , Vec < crate :: bigint :: BigInt > ,) +/// Gid: `466` +/// Location: [src/lib/pickles_types/plonk_types.ml:1057:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_types/plonk_types.ml#L1057) +/// Args: (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) , (ArrayN16 < crate :: bigint :: BigInt > , ArrayN16 < crate :: bigint :: BigInt > ,) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2PrevEvalsEvals { pub public_input: (crate::bigint::BigInt, crate::bigint::BigInt), @@ -403,9 +475,9 @@ pub struct PicklesProofProofsVerified2ReprStableV2PrevEvalsEvals { /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.prev_evals` /// -/// Gid: `464` -/// Location: [src/lib/pickles_types/plonk_types.ml:1092:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_types/plonk_types.ml#L1092) -/// Args: crate :: bigint :: BigInt , Vec < crate :: bigint :: BigInt > +/// Gid: `467` +/// Location: [src/lib/pickles_types/plonk_types.ml:1092:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_types/plonk_types.ml#L1092) +/// Args: crate :: bigint :: BigInt , ArrayN16 < crate :: bigint :: BigInt > #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2PrevEvals { pub evals: PicklesProofProofsVerified2ReprStableV2PrevEvalsEvals, @@ -414,12 +486,12 @@ pub struct PicklesProofProofsVerified2ReprStableV2PrevEvals { /// Derived name: `Pickles__Wrap_wire_proof.Stable.V1.bulletproof` /// -/// Gid: `465` -/// Location: [src/lib/pickles_types/plonk_types.ml:1141:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_types/plonk_types.ml#L1141) +/// Gid: `468` +/// Location: [src/lib/pickles_types/plonk_types.ml:1141:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_types/plonk_types.ml#L1141) /// Args: (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) , crate :: bigint :: BigInt #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesWrapWireProofStableV1Bulletproof { - pub lr: Vec<( + pub lr: ArrayN16<( (crate::bigint::BigInt, crate::bigint::BigInt), (crate::bigint::BigInt, crate::bigint::BigInt), )>, @@ -431,8 +503,8 @@ pub struct PicklesWrapWireProofStableV1Bulletproof { /// Derived name: `Mina_base__Verification_key_wire.Stable.V1.wrap_index` /// -/// Gid: `473` -/// Location: [src/lib/pickles_types/plonk_verification_key_evals.ml:7:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_types/plonk_verification_key_evals.ml#L7) +/// Gid: `476` +/// Location: [src/lib/pickles_types/plonk_verification_key_evals.ml:7:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_types/plonk_verification_key_evals.ml#L7) /// Args: (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseVerificationKeyWireStableV1WrapIndex { @@ -448,25 +520,18 @@ pub struct MinaBaseVerificationKeyWireStableV1WrapIndex { /// Derived name: `Pickles__Reduced_messages_for_next_proof_over_same_field.Wrap.Challenges_vector.Stable.V2.a.challenge` /// -/// Gid: `480` -/// Location: [src/lib/crypto/kimchi_backend/common/scalar_challenge.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/crypto/kimchi_backend/common/scalar_challenge.ml#L6) +/// Gid: `482` +/// Location: [src/lib/crypto/kimchi_backend/common/scalar_challenge.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/crypto/kimchi_backend/common/scalar_challenge.ml#L6) /// Args: PaddedSeq < LimbVectorConstantHex64StableV1 , 2 > #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2AChallenge { pub inner: PaddedSeq, } -/// **OCaml name**: `Blake2.Make.Stable.V1` -/// -/// Gid: `502` -/// Location: [src/binable0.ml:120:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/binable0.ml#L120) -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct Blake2MakeStableV1(pub crate::string::ByteString); - /// Derived name: `Snark_worker.Worker.Rpcs_versioned.Submit_work.V2.T.query.metrics` /// -/// Gid: `505` -/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/one_or_two/one_or_two.ml#L7) +/// Gid: `508` +/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/one_or_two/one_or_two.ml#L7) /// Args: (crate :: number :: Float64 , SnarkWorkerWorkerRpcsVersionedSubmitWorkV2TQueryMetricsA1 ,) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] #[polymorphic_variant] @@ -495,8 +560,8 @@ pub enum SnarkWorkerWorkerRpcsVersionedSubmitWorkV2TQueryMetrics { /// Derived name: `Transaction_snark_work.T.Stable.V2.proofs` /// -/// Gid: `505` -/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/one_or_two/one_or_two.ml#L7) +/// Gid: `508` +/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/one_or_two/one_or_two.ml#L7) /// Args: LedgerProofProdStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] #[polymorphic_variant] @@ -509,8 +574,8 @@ pub enum TransactionSnarkWorkTStableV2Proofs { /// Derived name: `Snark_worker.Worker.Rpcs_versioned.Get_work.V2.T.response.a.0.instances` /// -/// Gid: `505` -/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/one_or_two/one_or_two.ml#L7) +/// Gid: `508` +/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/one_or_two/one_or_two.ml#L7) /// Args: SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] #[polymorphic_variant] @@ -528,8 +593,8 @@ pub enum SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Instances { /// **OCaml name**: `Pickles_base__Proofs_verified.Stable.V1` /// -/// Gid: `511` -/// Location: [src/lib/pickles_base/proofs_verified.ml:8:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_base/proofs_verified.ml#L8) +/// Gid: `514` +/// Location: [src/lib/pickles_base/proofs_verified.ml:8:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_base/proofs_verified.ml#L8) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum PicklesBaseProofsVerifiedStableV1 { N0, @@ -539,34 +604,34 @@ pub enum PicklesBaseProofsVerifiedStableV1 { /// **OCaml name**: `Limb_vector__Constant.Hex64.Stable.V1` /// -/// Gid: `520` -/// Location: [src/lib/pickles/limb_vector/constant.ml:60:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/limb_vector/constant.ml#L60) +/// Gid: `523` +/// Location: [src/lib/pickles/limb_vector/constant.ml:60:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/limb_vector/constant.ml#L60) /// /// /// Gid: `125` -/// Location: [src/int64.ml:6:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int64.ml#L6) +/// Location: [src/int64.ml:6:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/int64.ml#L6) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct LimbVectorConstantHex64StableV1(pub crate::number::Int64); +pub struct LimbVectorConstantHex64StableV1(pub crate::number::UInt64); /// **OCaml name**: `Composition_types__Branch_data.Make_str.Domain_log2.Stable.V1` /// -/// Gid: `521` -/// Location: [src/lib/pickles/composition_types/branch_data.ml:24:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/branch_data.ml#L24) +/// Gid: `524` +/// Location: [src/lib/pickles/composition_types/branch_data.ml:24:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/branch_data.ml#L24) /// /// /// Gid: `161` -/// Location: [src/std_internal.ml:113:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L113) +/// Location: [src/std_internal.ml:113:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L113) /// /// /// Gid: `89` -/// Location: [src/char.ml:8:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/char.ml#L8) +/// Location: [src/char.ml:8:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/char.ml#L8) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct CompositionTypesBranchDataDomainLog2StableV1(pub crate::char::Char); /// **OCaml name**: `Composition_types__Branch_data.Make_str.Stable.V1` /// -/// Gid: `522` -/// Location: [src/lib/pickles/composition_types/branch_data.ml:51:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/branch_data.ml#L51) +/// Gid: `525` +/// Location: [src/lib/pickles/composition_types/branch_data.ml:51:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/branch_data.ml#L51) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct CompositionTypesBranchDataStableV1 { pub proofs_verified: PicklesBaseProofsVerifiedStableV1, @@ -575,8 +640,8 @@ pub struct CompositionTypesBranchDataStableV1 { /// Derived name: `Pickles__Reduced_messages_for_next_proof_over_same_field.Wrap.Challenges_vector.Stable.V2.a` /// -/// Gid: `523` -/// Location: [src/lib/pickles/composition_types/bulletproof_challenge.ml:4:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/bulletproof_challenge.ml#L4) +/// Gid: `526` +/// Location: [src/lib/pickles/composition_types/bulletproof_challenge.ml:4:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/bulletproof_challenge.ml#L4) /// Args: PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2AChallenge #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A { @@ -586,8 +651,8 @@ pub struct PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorSt /// **OCaml name**: `Composition_types__Digest.Constant.Stable.V1` /// -/// Gid: `524` -/// Location: [src/lib/pickles/composition_types/digest.ml:13:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/digest.ml#L13) +/// Gid: `527` +/// Location: [src/lib/pickles/composition_types/digest.ml:13:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/digest.ml#L13) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct CompositionTypesDigestConstantStableV1( pub PaddedSeq, @@ -595,8 +660,8 @@ pub struct CompositionTypesDigestConstantStableV1( /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.statement.proof_state.deferred_values.plonk` /// -/// Gid: `525` -/// Location: [src/lib/pickles/composition_types/composition_types.ml:45:14](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/composition_types.ml#L45) +/// Gid: `528` +/// Location: [src/lib/pickles/composition_types/composition_types.ml:45:14](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/composition_types.ml#L45) /// Args: PaddedSeq < LimbVectorConstantHex64StableV1 , 2 > , PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2AChallenge , bool #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2StatementProofStateDeferredValuesPlonk { @@ -614,8 +679,8 @@ pub struct PicklesProofProofsVerified2ReprStableV2StatementProofStateDeferredVal /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.statement.proof_state.deferred_values` /// -/// Gid: `527` -/// Location: [src/lib/pickles/composition_types/composition_types.ml:275:12](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/composition_types.ml#L275) +/// Gid: `530` +/// Location: [src/lib/pickles/composition_types/composition_types.ml:275:12](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/composition_types.ml#L275) /// Args: PaddedSeq < LimbVectorConstantHex64StableV1 , 2 > , PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2AChallenge , PicklesProofProofsVerified2ReprStableV2StatementFp , bool , PaddedSeq < PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A , 16 > , CompositionTypesBranchDataStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2StatementProofStateDeferredValues { @@ -627,8 +692,8 @@ pub struct PicklesProofProofsVerified2ReprStableV2StatementProofStateDeferredVal /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.messages_for_next_wrap_proof` /// -/// Gid: `528` -/// Location: [src/lib/pickles/composition_types/composition_types.ml:397:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/composition_types.ml#L397) +/// Gid: `531` +/// Location: [src/lib/pickles/composition_types/composition_types.ml:397:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/composition_types.ml#L397) /// Args: (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) , PaddedSeq < PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2 , 2 > #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2MessagesForNextWrapProof { @@ -639,8 +704,8 @@ pub struct PicklesProofProofsVerified2ReprStableV2MessagesForNextWrapProof { /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.statement.proof_state` /// -/// Gid: `530` -/// Location: [src/lib/pickles/composition_types/composition_types.ml:466:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/composition_types.ml#L466) +/// Gid: `533` +/// Location: [src/lib/pickles/composition_types/composition_types.ml:466:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/composition_types.ml#L466) /// Args: PaddedSeq < LimbVectorConstantHex64StableV1 , 2 > , PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2AChallenge , PicklesProofProofsVerified2ReprStableV2StatementFp , bool , PicklesProofProofsVerified2ReprStableV2MessagesForNextWrapProof , CompositionTypesDigestConstantStableV1 , PaddedSeq < PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A , 16 > , CompositionTypesBranchDataStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2StatementProofState { @@ -652,8 +717,8 @@ pub struct PicklesProofProofsVerified2ReprStableV2StatementProofState { /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.statement` /// -/// Gid: `532` -/// Location: [src/lib/pickles/composition_types/composition_types.ml:714:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/composition_types/composition_types.ml#L714) +/// Gid: `535` +/// Location: [src/lib/pickles/composition_types/composition_types.ml:714:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/composition_types/composition_types.ml#L714) /// Args: PaddedSeq < LimbVectorConstantHex64StableV1 , 2 > , PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2AChallenge , PicklesProofProofsVerified2ReprStableV2StatementFp , bool , PicklesProofProofsVerified2ReprStableV2MessagesForNextWrapProof , CompositionTypesDigestConstantStableV1 , PicklesProofProofsVerified2ReprStableV2MessagesForNextStepProof , PaddedSeq < PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A , 16 > , CompositionTypesBranchDataStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2Statement { @@ -664,8 +729,8 @@ pub struct PicklesProofProofsVerified2ReprStableV2Statement { /// **OCaml name**: `Pickles__Wrap_wire_proof.Commitments.Stable.V1` /// -/// Gid: `534` -/// Location: [src/lib/pickles/wrap_wire_proof.ml:17:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/wrap_wire_proof.ml#L17) +/// Gid: `537` +/// Location: [src/lib/pickles/wrap_wire_proof.ml:17:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/wrap_wire_proof.ml#L17) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesWrapWireProofCommitmentsStableV1 { pub w_comm: PaddedSeq<(crate::bigint::BigInt, crate::bigint::BigInt), 15>, @@ -675,8 +740,8 @@ pub struct PicklesWrapWireProofCommitmentsStableV1 { /// **OCaml name**: `Pickles__Wrap_wire_proof.Evaluations.Stable.V1` /// -/// Gid: `535` -/// Location: [src/lib/pickles/wrap_wire_proof.ml:55:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/wrap_wire_proof.ml#L55) +/// Gid: `538` +/// Location: [src/lib/pickles/wrap_wire_proof.ml:55:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/wrap_wire_proof.ml#L55) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesWrapWireProofEvaluationsStableV1 { pub w: PaddedSeq<(crate::bigint::BigInt, crate::bigint::BigInt), 15>, @@ -693,8 +758,8 @@ pub struct PicklesWrapWireProofEvaluationsStableV1 { /// **OCaml name**: `Pickles__Wrap_wire_proof.Stable.V1` /// -/// Gid: `536` -/// Location: [src/lib/pickles/wrap_wire_proof.ml:175:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/wrap_wire_proof.ml#L175) +/// Gid: `539` +/// Location: [src/lib/pickles/wrap_wire_proof.ml:175:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/wrap_wire_proof.ml#L175) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesWrapWireProofStableV1 { pub commitments: PicklesWrapWireProofCommitmentsStableV1, @@ -705,26 +770,26 @@ pub struct PicklesWrapWireProofStableV1 { /// Derived name: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2.messages_for_next_step_proof` /// -/// Gid: `539` -/// Location: [src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml:16:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml#L16) -/// Args: () , Vec < (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) > , Vec < PaddedSeq < PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A , 16 > > +/// Gid: `542` +/// Location: [src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml:16:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml#L16) +/// Args: () , List < (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) > , List < PaddedSeq < PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A , 16 > > #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2MessagesForNextStepProof { pub app_state: (), - pub challenge_polynomial_commitments: Vec<(crate::bigint::BigInt, crate::bigint::BigInt)>, - pub old_bulletproof_challenges: Vec< + pub challenge_polynomial_commitments: List<(crate::bigint::BigInt, crate::bigint::BigInt)>, + pub old_bulletproof_challenges: List< PaddedSeq, >, } /// **OCaml name**: `Pickles__Reduced_messages_for_next_proof_over_same_field.Wrap.Challenges_vector.Stable.V2` /// -/// Gid: `540` -/// Location: [src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml:57:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml#L57) +/// Gid: `543` +/// Location: [src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml:57:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/reduced_messages_for_next_proof_over_same_field.ml#L57) /// /// -/// Gid: `486` -/// Location: [src/lib/crypto/kimchi_backend/pasta/basic/kimchi_pasta_basic.ml:32:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/crypto/kimchi_backend/pasta/basic/kimchi_pasta_basic.ml#L32) +/// Gid: `488` +/// Location: [src/lib/crypto/kimchi_backend/pasta/basic/kimchi_pasta_basic.ml:32:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/crypto/kimchi_backend/pasta/basic/kimchi_pasta_basic.ml#L32) /// Args: PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2A #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorStableV2( @@ -733,12 +798,12 @@ pub struct PicklesReducedMessagesForNextProofOverSameFieldWrapChallengesVectorSt /// **OCaml name**: `Mina_base__Verification_key_wire.Stable.V1` /// -/// Gid: `541` -/// Location: [src/lib/pickles/side_loaded_verification_key.ml:170:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/side_loaded_verification_key.ml#L170) +/// Gid: `544` +/// Location: [src/lib/pickles/side_loaded_verification_key.ml:170:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/side_loaded_verification_key.ml#L170) /// /// -/// Gid: `516` -/// Location: [src/lib/pickles_base/side_loaded_verification_key.ml:132:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles_base/side_loaded_verification_key.ml#L132) +/// Gid: `519` +/// Location: [src/lib/pickles_base/side_loaded_verification_key.ml:130:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles_base/side_loaded_verification_key.ml#L130) /// Args: (crate :: bigint :: BigInt , crate :: bigint :: BigInt ,) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseVerificationKeyWireStableV1 { @@ -749,12 +814,12 @@ pub struct MinaBaseVerificationKeyWireStableV1 { /// **OCaml name**: `Pickles__Proof.Proofs_verified_2.Repr.Stable.V2` /// -/// Gid: `544` -/// Location: [src/lib/pickles/proof.ml:342:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/proof.ml#L342) +/// Gid: `547` +/// Location: [src/lib/pickles/proof.ml:342:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/proof.ml#L342) /// /// -/// Gid: `543` -/// Location: [src/lib/pickles/proof.ml:47:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/proof.ml#L47) +/// Gid: `546` +/// Location: [src/lib/pickles/proof.ml:47:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/proof.ml#L47) /// Args: PicklesProofProofsVerified2ReprStableV2MessagesForNextWrapProof , PicklesProofProofsVerified2ReprStableV2MessagesForNextStepProof #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerified2ReprStableV2 { @@ -765,12 +830,12 @@ pub struct PicklesProofProofsVerified2ReprStableV2 { /// **OCaml name**: `Pickles__Proof.Proofs_verified_max.Stable.V2` /// -/// Gid: `545` -/// Location: [src/lib/pickles/proof.ml:411:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/proof.ml#L411) +/// Gid: `548` +/// Location: [src/lib/pickles/proof.ml:411:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/proof.ml#L411) /// /// -/// Gid: `543` -/// Location: [src/lib/pickles/proof.ml:47:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/pickles/proof.ml#L47) +/// Gid: `546` +/// Location: [src/lib/pickles/proof.ml:47:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/pickles/proof.ml#L47) /// Args: PicklesProofProofsVerified2ReprStableV2MessagesForNextWrapProof , PicklesProofProofsVerified2ReprStableV2MessagesForNextStepProof #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct PicklesProofProofsVerifiedMaxStableV2 { @@ -781,12 +846,12 @@ pub struct PicklesProofProofsVerifiedMaxStableV2 { /// **OCaml name**: `Non_zero_curve_point.Uncompressed.Stable.V1` /// -/// Gid: `555` -/// Location: [src/lib/non_zero_curve_point/non_zero_curve_point.ml:46:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/non_zero_curve_point/non_zero_curve_point.ml#L46) +/// Gid: `558` +/// Location: [src/lib/non_zero_curve_point/non_zero_curve_point.ml:46:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/non_zero_curve_point/non_zero_curve_point.ml#L46) /// /// -/// Gid: `549` -/// Location: [src/lib/non_zero_curve_point/compressed_poly.ml:13:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/non_zero_curve_point/compressed_poly.ml#L13) +/// Gid: `552` +/// Location: [src/lib/non_zero_curve_point/compressed_poly.ml:13:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/non_zero_curve_point/compressed_poly.ml#L13) /// Args: crate :: bigint :: BigInt , bool #[derive( Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, BinProtRead, BinProtWrite, @@ -798,37 +863,48 @@ pub struct NonZeroCurvePointUncompressedStableV1 { /// **OCaml name**: `Signature_lib__Private_key.Stable.V1` /// -/// Gid: `567` -/// Location: [src/lib/signature_lib/private_key.ml:11:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/signature_lib/private_key.ml#L11) +/// Gid: `570` +/// Location: [src/lib/signature_lib/private_key.ml:11:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/signature_lib/private_key.ml#L11) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct SignatureLibPrivateKeyStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Unsigned_extended.UInt64.Int64_for_version_tags.Stable.V1` /// -/// Gid: `573` -/// Location: [src/lib/unsigned_extended/unsigned_extended.ml:81:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/unsigned_extended/unsigned_extended.ml#L81) +/// Gid: `576` +/// Location: [src/lib/unsigned_extended/unsigned_extended.ml:81:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/unsigned_extended/unsigned_extended.ml#L81) /// /// /// Gid: `125` -/// Location: [src/int64.ml:6:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int64.ml#L6) +/// Location: [src/int64.ml:6:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/int64.ml#L6) #[derive(Clone, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct UnsignedExtendedUInt64Int64ForVersionTagsStableV1(pub crate::number::UInt64); /// **OCaml name**: `Unsigned_extended.UInt32.Stable.V1` /// -/// Gid: `577` -/// Location: [src/lib/unsigned_extended/unsigned_extended.ml:156:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/unsigned_extended/unsigned_extended.ml#L156) +/// Gid: `580` +/// Location: [src/lib/unsigned_extended/unsigned_extended.ml:156:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/unsigned_extended/unsigned_extended.ml#L156) /// /// /// Gid: `119` -/// Location: [src/int32.ml:6:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int32.ml#L6) +/// Location: [src/int32.ml:6:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/int32.ml#L6) #[derive(Clone, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref, Default)] pub struct UnsignedExtendedUInt32StableV1(pub crate::number::UInt32); +/// **OCaml name**: `Protocol_version.Make_str.Stable.V2` +/// +/// Gid: `584` +/// Location: [src/lib/protocol_version/protocol_version.ml:18:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/protocol_version/protocol_version.ml#L18) +#[derive(Clone, Debug, PartialEq, BinProtRead, BinProtWrite)] +pub struct ProtocolVersionStableV2 { + pub transaction: crate::number::UInt64, + pub network: crate::number::UInt64, + pub patch: crate::number::UInt64, +} + /// **OCaml name**: `Mina_numbers__Nat.Make32.Stable.V1` /// -/// Gid: `581` -/// Location: [src/lib/mina_numbers/nat.ml:260:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_numbers/nat.ml#L260) +/// Gid: `585` +/// Location: [src/lib/mina_numbers/nat.ml:260:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_numbers/nat.ml#L260) #[derive( Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref, Default, )] @@ -836,8 +912,8 @@ pub struct MinaNumbersNatMake32StableV1(pub UnsignedExtendedUInt32StableV1); /// **OCaml name**: `Mina_numbers__Global_slot_span.Make_str.Stable.V1` /// -/// Gid: `599` -/// Location: [src/lib/mina_numbers/global_slot_span.ml:22:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_numbers/global_slot_span.ml#L22) +/// Gid: `608` +/// Location: [src/lib/mina_numbers/global_slot_span.ml:22:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_numbers/global_slot_span.ml#L22) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaNumbersGlobalSlotSpanStableV1 { GlobalSlotSpan(UnsignedExtendedUInt32StableV1), @@ -845,8 +921,8 @@ pub enum MinaNumbersGlobalSlotSpanStableV1 { /// **OCaml name**: `Mina_numbers__Global_slot_since_genesis.Make_str.M.Stable.V1` /// -/// Gid: `605` -/// Location: [src/lib/mina_numbers/global_slot_since_genesis.ml:27:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_numbers/global_slot_since_genesis.ml#L27) +/// Gid: `614` +/// Location: [src/lib/mina_numbers/global_slot_since_genesis.ml:27:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_numbers/global_slot_since_genesis.ml#L27) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaNumbersGlobalSlotSinceGenesisMStableV1 { SinceGenesis(UnsignedExtendedUInt32StableV1), @@ -854,8 +930,8 @@ pub enum MinaNumbersGlobalSlotSinceGenesisMStableV1 { /// **OCaml name**: `Mina_numbers__Global_slot_since_hard_fork.Make_str.M.Stable.V1` /// -/// Gid: `611` -/// Location: [src/lib/mina_numbers/global_slot_since_hard_fork.ml:27:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_numbers/global_slot_since_hard_fork.ml#L27) +/// Gid: `620` +/// Location: [src/lib/mina_numbers/global_slot_since_hard_fork.ml:27:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_numbers/global_slot_since_hard_fork.ml#L27) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaNumbersGlobalSlotSinceHardForkMStableV1 { SinceHardFork(UnsignedExtendedUInt32StableV1), @@ -863,8 +939,8 @@ pub enum MinaNumbersGlobalSlotSinceHardForkMStableV1 { /// **OCaml name**: `Sgn.Stable.V1` /// -/// Gid: `627` -/// Location: [src/lib/sgn/sgn.ml:9:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/sgn/sgn.ml#L9) +/// Gid: `636` +/// Location: [src/lib/sgn/sgn.ml:9:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/sgn/sgn.ml#L9) #[derive(Clone, Debug, PartialEq, BinProtRead, BinProtWrite)] pub enum SgnStableV1 { Pos, @@ -873,8 +949,8 @@ pub enum SgnStableV1 { /// Derived name: `Mina_state__Blockchain_state.Value.Stable.V2.signed_amount` /// -/// Gid: `628` -/// Location: [src/lib/currency/signed_poly.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/currency/signed_poly.ml#L6) +/// Gid: `637` +/// Location: [src/lib/currency/signed_poly.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/currency/signed_poly.ml#L6) /// Args: CurrencyAmountStableV1 , SgnStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateBlockchainStateValueStableV2SignedAmount { @@ -884,29 +960,29 @@ pub struct MinaStateBlockchainStateValueStableV2SignedAmount { /// **OCaml name**: `Currency.Make_str.Fee.Stable.V1` /// -/// Gid: `629` -/// Location: [src/lib/currency/currency.ml:945:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/currency/currency.ml#L945) +/// Gid: `638` +/// Location: [src/lib/currency/currency.ml:947:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/currency/currency.ml#L947) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct CurrencyFeeStableV1(pub UnsignedExtendedUInt64Int64ForVersionTagsStableV1); /// **OCaml name**: `Currency.Make_str.Amount.Make_str.Stable.V1` /// -/// Gid: `632` -/// Location: [src/lib/currency/currency.ml:1092:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/currency/currency.ml#L1092) +/// Gid: `641` +/// Location: [src/lib/currency/currency.ml:1094:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/currency/currency.ml#L1094) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct CurrencyAmountStableV1(pub UnsignedExtendedUInt64Int64ForVersionTagsStableV1); /// **OCaml name**: `Currency.Make_str.Balance.Stable.V1` /// -/// Gid: `635` -/// Location: [src/lib/currency/currency.ml:1136:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/currency/currency.ml#L1136) +/// Gid: `644` +/// Location: [src/lib/currency/currency.ml:1138:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/currency/currency.ml#L1138) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct CurrencyBalanceStableV1(pub CurrencyAmountStableV1); /// **OCaml name**: `Data_hash_lib__State_hash.Stable.V1` /// -/// Gid: `642` -/// Location: [src/lib/data_hash_lib/state_hash.ml:44:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/data_hash_lib/state_hash.ml#L44) +/// Gid: `651` +/// Location: [src/lib/data_hash_lib/state_hash.ml:44:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/data_hash_lib/state_hash.ml#L44) #[derive( Clone, Debug, @@ -924,8 +1000,8 @@ pub struct DataHashLibStateHashStableV1(pub crate::bigint::BigInt); /// Derived name: `Mina_base__Sparse_ledger_base.Stable.V2.tree` /// -/// Gid: `651` -/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/sparse_ledger_lib/sparse_ledger.ml#L9) +/// Gid: `660` +/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/sparse_ledger_lib/sparse_ledger.ml#L9) /// Args: LedgerHash , MinaBaseAccountBinableArgStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseSparseLedgerBaseStableV2Tree { @@ -940,8 +1016,8 @@ pub enum MinaBaseSparseLedgerBaseStableV2Tree { /// Derived name: `Mina_base__Pending_coinbase.Make_str.Merkle_tree_versioned.Stable.V2.tree` /// -/// Gid: `651` -/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/sparse_ledger_lib/sparse_ledger.ml#L9) +/// Gid: `660` +/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/sparse_ledger_lib/sparse_ledger.ml#L9) /// Args: PendingCoinbaseHash , MinaBasePendingCoinbaseStackVersionedStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree { @@ -956,33 +1032,33 @@ pub enum MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree { /// **OCaml name**: `Block_time.Make_str.Time.Stable.V1` /// -/// Gid: `653` -/// Location: [src/lib/block_time/block_time.ml:22:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/block_time/block_time.ml#L22) +/// Gid: `662` +/// Location: [src/lib/block_time/block_time.ml:22:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/block_time/block_time.ml#L22) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct BlockTimeTimeStableV1(pub UnsignedExtendedUInt64Int64ForVersionTagsStableV1); /// **OCaml name**: `Mina_base__Account_id.Make_str.Digest.Stable.V1` /// -/// Gid: `655` -/// Location: [src/lib/mina_base/account_id.ml:64:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_id.ml#L64) +/// Gid: `664` +/// Location: [src/lib/mina_base/account_id.ml:64:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_id.ml#L64) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseAccountIdDigestStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Account_id.Make_str.Stable.V2` /// -/// Gid: `660` -/// Location: [src/lib/mina_base/account_id.ml:151:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_id.ml#L151) +/// Gid: `669` +/// Location: [src/lib/mina_base/account_id.ml:151:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_id.ml#L151) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountIdStableV2(pub NonZeroCurvePoint, pub MinaBaseAccountIdDigestStableV1); /// **OCaml name**: `Mina_base__Account_timing.Stable.V2` /// -/// Gid: `666` -/// Location: [src/lib/mina_base/account_timing.ml:39:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_timing.ml#L39) +/// Gid: `675` +/// Location: [src/lib/mina_base/account_timing.ml:39:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_timing.ml#L39) /// /// -/// Gid: `665` -/// Location: [src/lib/mina_base/account_timing.ml:22:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_timing.ml#L22) +/// Gid: `674` +/// Location: [src/lib/mina_base/account_timing.ml:22:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_timing.ml#L22) /// Args: MinaNumbersGlobalSlotSinceGenesisMStableV1 , MinaNumbersGlobalSlotSpanStableV1 , CurrencyBalanceStableV1 , CurrencyAmountStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountTimingStableV2 { @@ -998,20 +1074,20 @@ pub enum MinaBaseAccountTimingStableV2 { /// **OCaml name**: `Mina_base__Signature.Stable.V1` /// -/// Gid: `670` -/// Location: [src/lib/mina_base/signature.ml:23:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signature.ml#L23) +/// Gid: `679` +/// Location: [src/lib/mina_base/signature.ml:23:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signature.ml#L23) /// /// -/// Gid: `667` -/// Location: [src/lib/mina_base/signature.ml:12:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signature.ml#L12) +/// Gid: `676` +/// Location: [src/lib/mina_base/signature.ml:12:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signature.ml#L12) /// Args: crate :: bigint :: BigInt , crate :: bigint :: BigInt #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseSignatureStableV1(pub crate::bigint::BigInt, pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Control.Stable.V2` /// -/// Gid: `674` -/// Location: [src/lib/mina_base/control.ml:11:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/control.ml#L11) +/// Gid: `683` +/// Location: [src/lib/mina_base/control.ml:11:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/control.ml#L11) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseControlStableV2 { Proof(Box), @@ -1021,19 +1097,19 @@ pub enum MinaBaseControlStableV2 { /// **OCaml name**: `Mina_base__Token_id.Stable.V2` /// -/// Gid: `678` -/// Location: [src/lib/mina_base/token_id.ml:8:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/token_id.ml#L8) +/// Gid: `687` +/// Location: [src/lib/mina_base/token_id.ml:8:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/token_id.ml#L8) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseTokenIdStableV2(pub MinaBaseAccountIdDigestStableV1); /// **OCaml name**: `Mina_base__Payment_payload.Stable.V2` /// -/// Gid: `688` -/// Location: [src/lib/mina_base/payment_payload.ml:39:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/payment_payload.ml#L39) +/// Gid: `697` +/// Location: [src/lib/mina_base/payment_payload.ml:39:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/payment_payload.ml#L39) /// /// -/// Gid: `684` -/// Location: [src/lib/mina_base/payment_payload.ml:14:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/payment_payload.ml#L14) +/// Gid: `693` +/// Location: [src/lib/mina_base/payment_payload.ml:14:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/payment_payload.ml#L14) /// Args: NonZeroCurvePoint , CurrencyAmountStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePaymentPayloadStableV2 { @@ -1043,8 +1119,8 @@ pub struct MinaBasePaymentPayloadStableV2 { /// **OCaml name**: `Mina_base__Ledger_hash0.Stable.V1` /// -/// Gid: `694` -/// Location: [src/lib/mina_base/ledger_hash0.ml:17:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/ledger_hash0.ml#L17) +/// Gid: `703` +/// Location: [src/lib/mina_base/ledger_hash0.ml:17:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/ledger_hash0.ml#L17) #[derive( Clone, Debug, @@ -1062,8 +1138,8 @@ pub struct MinaBaseLedgerHash0StableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Permissions.Auth_required.Stable.V2` /// -/// Gid: `697` -/// Location: [src/lib/mina_base/permissions.ml:53:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/permissions.ml#L53) +/// Gid: `706` +/// Location: [src/lib/mina_base/permissions.ml:53:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/permissions.ml#L53) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBasePermissionsAuthRequiredStableV2 { None, @@ -1075,13 +1151,13 @@ pub enum MinaBasePermissionsAuthRequiredStableV2 { /// **OCaml name**: `Mina_base__Permissions.Stable.V2` /// -/// Gid: `699` -/// Location: [src/lib/mina_base/permissions.ml:381:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/permissions.ml#L381) +/// Gid: `708` +/// Location: [src/lib/mina_base/permissions.ml:399:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/permissions.ml#L399) /// /// -/// Gid: `698` -/// Location: [src/lib/mina_base/permissions.ml:345:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/permissions.ml#L345) -/// Args: MinaBasePermissionsAuthRequiredStableV2 +/// Gid: `707` +/// Location: [src/lib/mina_base/permissions.ml:357:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/permissions.ml#L357) +/// Args: MinaBasePermissionsAuthRequiredStableV2 , UnsignedExtendedUInt32StableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePermissionsStableV2 { pub edit_state: MinaBasePermissionsAuthRequiredStableV2, @@ -1090,7 +1166,10 @@ pub struct MinaBasePermissionsStableV2 { pub receive: MinaBasePermissionsAuthRequiredStableV2, pub set_delegate: MinaBasePermissionsAuthRequiredStableV2, pub set_permissions: MinaBasePermissionsAuthRequiredStableV2, - pub set_verification_key: MinaBasePermissionsAuthRequiredStableV2, + pub set_verification_key: ( + MinaBasePermissionsAuthRequiredStableV2, + UnsignedExtendedUInt32StableV1, + ), pub set_zkapp_uri: MinaBasePermissionsAuthRequiredStableV2, pub edit_action_state: MinaBasePermissionsAuthRequiredStableV2, pub set_token_symbol: MinaBasePermissionsAuthRequiredStableV2, @@ -1101,8 +1180,8 @@ pub struct MinaBasePermissionsStableV2 { /// **OCaml name**: `Mina_base__Stake_delegation.Stable.V2` /// -/// Gid: `703` -/// Location: [src/lib/mina_base/stake_delegation.ml:11:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/stake_delegation.ml#L11) +/// Gid: `712` +/// Location: [src/lib/mina_base/stake_delegation.ml:11:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/stake_delegation.ml#L11) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseStakeDelegationStableV2 { SetDelegate { new_delegate: NonZeroCurvePoint }, @@ -1110,8 +1189,8 @@ pub enum MinaBaseStakeDelegationStableV2 { /// **OCaml name**: `Mina_base__Transaction_status.Failure.Stable.V2` /// -/// Gid: `709` -/// Location: [src/lib/mina_base/transaction_status.ml:9:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/transaction_status.ml#L9) +/// Gid: `718` +/// Location: [src/lib/mina_base/transaction_status.ml:9:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/transaction_status.ml#L9) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseTransactionStatusFailureStableV2 { Predicate, @@ -1150,7 +1229,7 @@ pub enum MinaBaseTransactionStatusFailureStableV2 { AccountReceiptChainHashPreconditionUnsatisfied, AccountDelegatePreconditionUnsatisfied, AccountActionStatePreconditionUnsatisfied, - AccountAppStatePreconditionUnsatisfied(crate::number::Int64), + AccountAppStatePreconditionUnsatisfied(crate::number::UInt64), AccountProvedStatePreconditionUnsatisfied, AccountIsNewPreconditionUnsatisfied, ProtocolStatePreconditionUnsatisfied, @@ -1163,27 +1242,27 @@ pub enum MinaBaseTransactionStatusFailureStableV2 { /// **OCaml name**: `Mina_base__Transaction_status.Failure.Collection.Stable.V1` /// -/// Gid: `711` -/// Location: [src/lib/mina_base/transaction_status.ml:77:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/transaction_status.ml#L77) +/// Gid: `720` +/// Location: [src/lib/mina_base/transaction_status.ml:77:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/transaction_status.ml#L77) /// /// /// Gid: `167` -/// Location: [src/std_internal.ml:131:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L131) -/// Args: Vec < MinaBaseTransactionStatusFailureStableV2 > +/// Location: [src/std_internal.ml:131:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L131) +/// Args: List < MinaBaseTransactionStatusFailureStableV2 > /// /// /// Gid: `50` -/// Location: [src/list0.ml:6:0](https://github.com/MinaProtocol/mina/blob/14047c5551/src/list0.ml#L6) -/// Args: Vec < MinaBaseTransactionStatusFailureStableV2 > +/// Location: [src/list0.ml:6:0](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/list0.ml#L6) +/// Args: List < MinaBaseTransactionStatusFailureStableV2 > #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseTransactionStatusFailureCollectionStableV1( - pub Vec>, + pub List>, ); /// **OCaml name**: `Mina_base__Transaction_status.Stable.V2` /// -/// Gid: `712` -/// Location: [src/lib/mina_base/transaction_status.ml:476:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/transaction_status.ml#L476) +/// Gid: `721` +/// Location: [src/lib/mina_base/transaction_status.ml:476:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/transaction_status.ml#L476) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseTransactionStatusStableV2 { Applied, @@ -1192,12 +1271,12 @@ pub enum MinaBaseTransactionStatusStableV2 { /// **OCaml name**: `Mina_base__Signed_command_payload.Common.Stable.V2` /// -/// Gid: `717` -/// Location: [src/lib/mina_base/signed_command_payload.ml:76:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signed_command_payload.ml#L76) +/// Gid: `726` +/// Location: [src/lib/mina_base/signed_command_payload.ml:76:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signed_command_payload.ml#L76) /// /// -/// Gid: `713` -/// Location: [src/lib/mina_base/signed_command_payload.ml:41:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signed_command_payload.ml#L41) +/// Gid: `722` +/// Location: [src/lib/mina_base/signed_command_payload.ml:41:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signed_command_payload.ml#L41) /// Args: CurrencyFeeStableV1 , NonZeroCurvePoint , UnsignedExtendedUInt32StableV1 , MinaNumbersGlobalSlotSinceGenesisMStableV1 , MinaBaseSignedCommandMemoStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseSignedCommandPayloadCommonStableV2 { @@ -1210,8 +1289,8 @@ pub struct MinaBaseSignedCommandPayloadCommonStableV2 { /// **OCaml name**: `Mina_base__Signed_command_payload.Body.Stable.V2` /// -/// Gid: `721` -/// Location: [src/lib/mina_base/signed_command_payload.ml:189:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signed_command_payload.ml#L189) +/// Gid: `730` +/// Location: [src/lib/mina_base/signed_command_payload.ml:189:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signed_command_payload.ml#L189) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseSignedCommandPayloadBodyStableV2 { Payment(MinaBasePaymentPayloadStableV2), @@ -1220,12 +1299,12 @@ pub enum MinaBaseSignedCommandPayloadBodyStableV2 { /// **OCaml name**: `Mina_base__Signed_command_payload.Stable.V2` /// -/// Gid: `728` -/// Location: [src/lib/mina_base/signed_command_payload.ml:267:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signed_command_payload.ml#L267) +/// Gid: `737` +/// Location: [src/lib/mina_base/signed_command_payload.ml:267:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signed_command_payload.ml#L267) /// /// -/// Gid: `725` -/// Location: [src/lib/mina_base/signed_command_payload.ml:249:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signed_command_payload.ml#L249) +/// Gid: `734` +/// Location: [src/lib/mina_base/signed_command_payload.ml:249:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signed_command_payload.ml#L249) /// Args: MinaBaseSignedCommandPayloadCommonStableV2 , MinaBaseSignedCommandPayloadBodyStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseSignedCommandPayloadStableV2 { @@ -1235,12 +1314,12 @@ pub struct MinaBaseSignedCommandPayloadStableV2 { /// **OCaml name**: `Mina_base__Signed_command.Make_str.Stable.V2` /// -/// Gid: `735` -/// Location: [src/lib/mina_base/signed_command.ml:52:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signed_command.ml#L52) +/// Gid: `744` +/// Location: [src/lib/mina_base/signed_command.ml:52:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signed_command.ml#L52) /// /// -/// Gid: `732` -/// Location: [src/lib/mina_base/signed_command.ml:27:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/signed_command.ml#L27) +/// Gid: `741` +/// Location: [src/lib/mina_base/signed_command.ml:27:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/signed_command.ml#L27) /// Args: MinaBaseSignedCommandPayloadStableV2 , NonZeroCurvePoint , Signature #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseSignedCommandStableV2 { @@ -1251,22 +1330,22 @@ pub struct MinaBaseSignedCommandStableV2 { /// **OCaml name**: `Mina_base__Receipt.Chain_hash.Stable.V1` /// -/// Gid: `746` -/// Location: [src/lib/mina_base/receipt.ml:31:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/receipt.ml#L31) +/// Gid: `755` +/// Location: [src/lib/mina_base/receipt.ml:31:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/receipt.ml#L31) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseReceiptChainHashStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__State_body_hash.Stable.V1` /// -/// Gid: `751` -/// Location: [src/lib/mina_base/state_body_hash.ml:19:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/state_body_hash.ml#L19) +/// Gid: `760` +/// Location: [src/lib/mina_base/state_body_hash.ml:19:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/state_body_hash.ml#L19) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseStateBodyHashStableV1(pub crate::bigint::BigInt); /// Derived name: `Mina_base__Account_update.Update.Stable.V1.timing` /// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) +/// Gid: `766` +/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L100) /// Args: MinaBaseAccountUpdateUpdateTimingInfoStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateUpdateStableV1Timing { @@ -1276,8 +1355,8 @@ pub enum MinaBaseAccountUpdateUpdateStableV1Timing { /// Derived name: `Mina_base__Account_update.Update.Stable.V1.permissions` /// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) +/// Gid: `766` +/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L100) /// Args: MinaBasePermissionsStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateUpdateStableV1Permissions { @@ -1287,8 +1366,8 @@ pub enum MinaBaseAccountUpdateUpdateStableV1Permissions { /// Derived name: `Mina_base__Account_update.Update.Stable.V1.verification_key` /// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) +/// Gid: `766` +/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L100) /// Args: MinaBaseVerificationKeyWireStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateUpdateStableV1VerificationKey { @@ -1296,21 +1375,10 @@ pub enum MinaBaseAccountUpdateUpdateStableV1VerificationKey { Keep, } -/// Derived name: `Mina_base__Account_update.Update.Stable.V1.token_symbol` -/// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) -/// Args: MinaBaseZkappAccountZkappUriStableV1 -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] -pub enum MinaBaseAccountUpdateUpdateStableV1TokenSymbol { - Set(MinaBaseZkappAccountZkappUriStableV1), - Keep, -} - /// Derived name: `Mina_base__Account_update.Update.Stable.V1.delegate` /// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) +/// Gid: `766` +/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L100) /// Args: NonZeroCurvePoint #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateUpdateStableV1Delegate { @@ -1320,8 +1388,8 @@ pub enum MinaBaseAccountUpdateUpdateStableV1Delegate { /// Derived name: `Mina_base__Account_update.Update.Stable.V1.voting_for` /// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) +/// Gid: `766` +/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L100) /// Args: StateHash #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateUpdateStableV1VotingFor { @@ -1331,8 +1399,8 @@ pub enum MinaBaseAccountUpdateUpdateStableV1VotingFor { /// Derived name: `Mina_base__Account_update.Update.Stable.V1.app_state.a` /// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) +/// Gid: `766` +/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L100) /// Args: crate :: bigint :: BigInt #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateUpdateStableV1AppStateA { @@ -1342,8 +1410,8 @@ pub enum MinaBaseAccountUpdateUpdateStableV1AppStateA { /// Derived name: `Mina_base__Account_update.Update.Stable.V1.zkapp_uri` /// -/// Gid: `757` -/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L100) +/// Gid: `766` +/// Location: [src/lib/mina_base/zkapp_basic.ml:100:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L100) /// Args: crate :: string :: ByteString #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateUpdateStableV1ZkappUri { @@ -1353,8 +1421,8 @@ pub enum MinaBaseAccountUpdateUpdateStableV1ZkappUri { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Epoch_data.Stable.V1.epoch_seed` /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: EpochSeed #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed { @@ -1364,8 +1432,8 @@ pub enum MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1.snarked_ledger_hash` /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: LedgerHash #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash { @@ -1375,8 +1443,8 @@ pub enum MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash { /// Derived name: `Mina_base__Zkapp_precondition.Account.Stable.V2.receipt_chain_hash` /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: MinaBaseReceiptChainHashStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash { @@ -1386,8 +1454,8 @@ pub enum MinaBaseZkappPreconditionAccountStableV2ReceiptChainHash { /// Derived name: `Mina_base__Zkapp_precondition.Account.Stable.V2.delegate` /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: NonZeroCurvePoint #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionAccountStableV2Delegate { @@ -1397,8 +1465,8 @@ pub enum MinaBaseZkappPreconditionAccountStableV2Delegate { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Epoch_data.Stable.V1.start_checkpoint` /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: StateHash #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint { @@ -1408,8 +1476,8 @@ pub enum MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint /// Derived name: `Mina_base__Zkapp_precondition.Account.Stable.V2.proved_state` /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: bool #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionAccountStableV2ProvedState { @@ -1419,8 +1487,8 @@ pub enum MinaBaseZkappPreconditionAccountStableV2ProvedState { /// Derived name: `Mina_base__Zkapp_precondition.Account.Stable.V2.state.a` /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: crate :: bigint :: BigInt #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionAccountStableV2StateA { @@ -1430,12 +1498,12 @@ pub enum MinaBaseZkappPreconditionAccountStableV2StateA { /// **OCaml name**: `Mina_base__Zkapp_state.Value.Stable.V1` /// -/// Gid: `761` -/// Location: [src/lib/mina_base/zkapp_state.ml:46:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_state.ml#L46) +/// Gid: `770` +/// Location: [src/lib/mina_base/zkapp_state.ml:46:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_state.ml#L46) /// /// -/// Gid: `760` -/// Location: [src/lib/mina_base/zkapp_state.ml:17:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_state.ml#L17) +/// Gid: `769` +/// Location: [src/lib/mina_base/zkapp_state.ml:17:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_state.ml#L17) /// Args: crate :: bigint :: BigInt #[derive( Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref, Default, @@ -1444,13 +1512,13 @@ pub struct MinaBaseZkappStateValueStableV1(pub PaddedSeq , MinaNumbersNatMake32StableV1 , crate :: bigint :: BigInt , MinaNumbersGlobalSlotSinceGenesisMStableV1 , bool , MinaBaseZkappAccountZkappUriStableV1 +/// Gid: `771` +/// Location: [src/lib/mina_base/zkapp_account.ml:194:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_account.ml#L194) +/// Args: MinaBaseZkappStateValueStableV1 , Option < MinaBaseVerificationKeyWireStableV1 > , MinaNumbersNatMake32StableV1 , crate :: bigint :: BigInt , MinaNumbersGlobalSlotSinceGenesisMStableV1 , bool , crate :: string :: ByteString #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappAccountStableV2 { pub app_state: MinaBaseZkappStateValueStableV1, @@ -1459,28 +1527,28 @@ pub struct MinaBaseZkappAccountStableV2 { pub action_state: PaddedSeq, pub last_action_slot: MinaNumbersGlobalSlotSinceGenesisMStableV1, pub proved_state: bool, - pub zkapp_uri: MinaBaseZkappAccountZkappUriStableV1, + pub zkapp_uri: crate::string::ByteString, } /// **OCaml name**: `Mina_base__Account.Index.Stable.V1` /// -/// Gid: `764` -/// Location: [src/lib/mina_base/account.ml:18:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account.ml#L18) +/// Gid: `773` +/// Location: [src/lib/mina_base/account.ml:18:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account.ml#L18) /// /// /// Gid: `163` -/// Location: [src/std_internal.ml:119:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L119) +/// Location: [src/std_internal.ml:119:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L119) /// /// /// Gid: `113` -/// Location: [src/int.ml:19:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int.ml#L19) +/// Location: [src/int.ml:19:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/int.ml#L19) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct MinaBaseAccountIndexStableV1(pub crate::number::Int64); +pub struct MinaBaseAccountIndexStableV1(pub crate::number::UInt64); /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Epoch_data.Stable.V1.epoch_ledger` /// -/// Gid: `772` -/// Location: [src/lib/mina_base/epoch_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/epoch_ledger.ml#L9) +/// Gid: `781` +/// Location: [src/lib/mina_base/epoch_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/epoch_ledger.ml#L9) /// Args: MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash , MinaBaseZkappPreconditionProtocolStateStableV1Amount #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger { @@ -1490,12 +1558,12 @@ pub struct MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger { /// **OCaml name**: `Mina_base__Epoch_ledger.Value.Stable.V1` /// -/// Gid: `773` -/// Location: [src/lib/mina_base/epoch_ledger.ml:23:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/epoch_ledger.ml#L23) +/// Gid: `782` +/// Location: [src/lib/mina_base/epoch_ledger.ml:23:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/epoch_ledger.ml#L23) /// /// -/// Gid: `772` -/// Location: [src/lib/mina_base/epoch_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/epoch_ledger.ml#L9) +/// Gid: `781` +/// Location: [src/lib/mina_base/epoch_ledger.ml:9:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/epoch_ledger.ml#L9) /// Args: LedgerHash , CurrencyAmountStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseEpochLedgerValueStableV1 { @@ -1505,15 +1573,15 @@ pub struct MinaBaseEpochLedgerValueStableV1 { /// **OCaml name**: `Mina_base__Epoch_seed.Stable.V1` /// -/// Gid: `776` -/// Location: [src/lib/mina_base/epoch_seed.ml:14:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/epoch_seed.ml#L14) +/// Gid: `785` +/// Location: [src/lib/mina_base/epoch_seed.ml:14:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/epoch_seed.ml#L14) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseEpochSeedStableV1(pub crate::bigint::BigInt); /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1.amount.a` /// -/// Gid: `781` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L23) +/// Gid: `790` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L23) /// Args: CurrencyAmountStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionProtocolStateStableV1AmountA { @@ -1523,8 +1591,8 @@ pub struct MinaBaseZkappPreconditionProtocolStateStableV1AmountA { /// Derived name: `Mina_base__Zkapp_precondition.Account.Stable.V2.balance.a` /// -/// Gid: `781` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L23) +/// Gid: `790` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L23) /// Args: CurrencyBalanceStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionAccountStableV2BalanceA { @@ -1534,8 +1602,8 @@ pub struct MinaBaseZkappPreconditionAccountStableV2BalanceA { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1.global_slot.a` /// -/// Gid: `781` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L23) +/// Gid: `790` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L23) /// Args: MinaNumbersGlobalSlotSinceGenesisMStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA { @@ -1545,8 +1613,8 @@ pub struct MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1.length.a` /// -/// Gid: `781` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L23) +/// Gid: `790` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:23:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L23) /// Args: UnsignedExtendedUInt32StableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionProtocolStateStableV1LengthA { @@ -1556,13 +1624,13 @@ pub struct MinaBaseZkappPreconditionProtocolStateStableV1LengthA { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1.amount` /// -/// Gid: `782` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L165) +/// Gid: `791` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L165) /// Args: CurrencyAmountStableV1 /// /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: MinaBaseZkappPreconditionProtocolStateStableV1AmountA #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionProtocolStateStableV1Amount { @@ -1572,13 +1640,13 @@ pub enum MinaBaseZkappPreconditionProtocolStateStableV1Amount { /// Derived name: `Mina_base__Zkapp_precondition.Account.Stable.V2.balance` /// -/// Gid: `782` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L165) +/// Gid: `791` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L165) /// Args: CurrencyBalanceStableV1 /// /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: MinaBaseZkappPreconditionAccountStableV2BalanceA #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionAccountStableV2Balance { @@ -1588,13 +1656,13 @@ pub enum MinaBaseZkappPreconditionAccountStableV2Balance { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1.global_slot` /// -/// Gid: `782` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L165) +/// Gid: `791` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L165) /// Args: MinaNumbersGlobalSlotSinceGenesisMStableV1 /// /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlotA #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot { @@ -1604,13 +1672,13 @@ pub enum MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot { /// Derived name: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1.length` /// -/// Gid: `782` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L165) +/// Gid: `791` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:165:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L165) /// Args: UnsignedExtendedUInt32StableV1 /// /// -/// Gid: `758` -/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_basic.ml#L232) +/// Gid: `767` +/// Location: [src/lib/mina_base/zkapp_basic.ml:232:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_basic.ml#L232) /// Args: MinaBaseZkappPreconditionProtocolStateStableV1LengthA #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseZkappPreconditionProtocolStateStableV1Length { @@ -1620,8 +1688,8 @@ pub enum MinaBaseZkappPreconditionProtocolStateStableV1Length { /// **OCaml name**: `Mina_base__Zkapp_precondition.Account.Stable.V2` /// -/// Gid: `783` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:465:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L465) +/// Gid: `792` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:465:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L465) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionAccountStableV2 { pub balance: MinaBaseZkappPreconditionAccountStableV2Balance, @@ -1636,12 +1704,12 @@ pub struct MinaBaseZkappPreconditionAccountStableV2 { /// **OCaml name**: `Mina_base__Zkapp_precondition.Protocol_state.Epoch_data.Stable.V1` /// -/// Gid: `784` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:779:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L779) +/// Gid: `793` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:792:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L792) /// /// -/// Gid: `779` -/// Location: [src/lib/mina_base/epoch_data.ml:8:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/epoch_data.ml#L8) +/// Gid: `788` +/// Location: [src/lib/mina_base/epoch_data.ml:8:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/epoch_data.ml#L8) /// Args: MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochLedger , MinaBaseZkappPreconditionProtocolStateEpochDataStableV1EpochSeed , MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint , MinaBaseZkappPreconditionProtocolStateEpochDataStableV1StartCheckpoint , MinaBaseZkappPreconditionProtocolStateStableV1Length #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionProtocolStateEpochDataStableV1 { @@ -1654,12 +1722,12 @@ pub struct MinaBaseZkappPreconditionProtocolStateEpochDataStableV1 { /// **OCaml name**: `Mina_base__Zkapp_precondition.Protocol_state.Stable.V1` /// -/// Gid: `786` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:954:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L954) +/// Gid: `795` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:967:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L967) /// /// -/// Gid: `785` -/// Location: [src/lib/mina_base/zkapp_precondition.ml:910:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_precondition.ml#L910) +/// Gid: `794` +/// Location: [src/lib/mina_base/zkapp_precondition.ml:923:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_precondition.ml#L923) /// Args: MinaBaseZkappPreconditionProtocolStateStableV1SnarkedLedgerHash , MinaBaseZkappPreconditionProtocolStateStableV1Length , MinaBaseZkappPreconditionProtocolStateStableV1GlobalSlot , MinaBaseZkappPreconditionProtocolStateStableV1Amount , MinaBaseZkappPreconditionProtocolStateEpochDataStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappPreconditionProtocolStateStableV1 { @@ -1674,8 +1742,8 @@ pub struct MinaBaseZkappPreconditionProtocolStateStableV1 { /// **OCaml name**: `Mina_base__Account_update.Authorization_kind.Stable.V1` /// -/// Gid: `794` -/// Location: [src/lib/mina_base/account_update.ml:28:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L28) +/// Gid: `803` +/// Location: [src/lib/mina_base/account_update.ml:28:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L28) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateAuthorizationKindStableV1 { Signature, @@ -1685,8 +1753,8 @@ pub enum MinaBaseAccountUpdateAuthorizationKindStableV1 { /// **OCaml name**: `Mina_base__Account_update.May_use_token.Stable.V1` /// -/// Gid: `795` -/// Location: [src/lib/mina_base/account_update.ml:161:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L161) +/// Gid: `804` +/// Location: [src/lib/mina_base/account_update.ml:161:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L161) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBaseAccountUpdateMayUseTokenStableV1 { No, @@ -1696,8 +1764,8 @@ pub enum MinaBaseAccountUpdateMayUseTokenStableV1 { /// **OCaml name**: `Mina_base__Account_update.Update.Timing_info.Stable.V1` /// -/// Gid: `796` -/// Location: [src/lib/mina_base/account_update.ml:532:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L532) +/// Gid: `805` +/// Location: [src/lib/mina_base/account_update.ml:532:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L532) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountUpdateUpdateTimingInfoStableV1 { pub initial_minimum_balance: CurrencyBalanceStableV1, @@ -1709,8 +1777,8 @@ pub struct MinaBaseAccountUpdateUpdateTimingInfoStableV1 { /// **OCaml name**: `Mina_base__Account_update.Update.Stable.V1` /// -/// Gid: `797` -/// Location: [src/lib/mina_base/account_update.ml:692:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L692) +/// Gid: `806` +/// Location: [src/lib/mina_base/account_update.ml:692:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L692) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountUpdateUpdateStableV1 { pub app_state: PaddedSeq, @@ -1718,26 +1786,24 @@ pub struct MinaBaseAccountUpdateUpdateStableV1 { pub verification_key: MinaBaseAccountUpdateUpdateStableV1VerificationKey, pub permissions: MinaBaseAccountUpdateUpdateStableV1Permissions, pub zkapp_uri: MinaBaseAccountUpdateUpdateStableV1ZkappUri, - pub token_symbol: MinaBaseAccountUpdateUpdateStableV1TokenSymbol, + pub token_symbol: MinaBaseAccountUpdateUpdateStableV1ZkappUri, pub timing: MinaBaseAccountUpdateUpdateStableV1Timing, pub voting_for: MinaBaseAccountUpdateUpdateStableV1VotingFor, } /// **OCaml name**: `Mina_base__Account_update.Account_precondition.Stable.V1` /// -/// Gid: `798` -/// Location: [src/lib/mina_base/account_update.ml:958:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L958) -#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] -pub enum MinaBaseAccountUpdateAccountPreconditionStableV1 { - Full(Box), - Nonce(UnsignedExtendedUInt32StableV1), - Accept, -} +/// Gid: `807` +/// Location: [src/lib/mina_base/account_update.ml:958:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L958) +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] +pub struct MinaBaseAccountUpdateAccountPreconditionStableV1( + pub MinaBaseZkappPreconditionAccountStableV2, +); /// **OCaml name**: `Mina_base__Account_update.Preconditions.Stable.V1` /// -/// Gid: `799` -/// Location: [src/lib/mina_base/account_update.ml:1067:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L1067) +/// Gid: `808` +/// Location: [src/lib/mina_base/account_update.ml:1029:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L1029) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountUpdatePreconditionsStableV1 { pub network: MinaBaseZkappPreconditionProtocolStateStableV1, @@ -1747,25 +1813,25 @@ pub struct MinaBaseAccountUpdatePreconditionsStableV1 { /// **OCaml name**: `Mina_base__Account_update.Body.Events'.Stable.V1` /// -/// Gid: `800` -/// Location: [src/lib/mina_base/account_update.ml:1155:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L1155) +/// Gid: `809` +/// Location: [src/lib/mina_base/account_update.ml:1116:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L1116) /// /// /// Gid: `167` -/// Location: [src/std_internal.ml:131:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L131) -/// Args: Vec < crate :: bigint :: BigInt > +/// Location: [src/std_internal.ml:131:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L131) +/// Args: ArrayN16 < crate :: bigint :: BigInt > /// /// /// Gid: `50` -/// Location: [src/list0.ml:6:0](https://github.com/MinaProtocol/mina/blob/14047c5551/src/list0.ml#L6) -/// Args: Vec < crate :: bigint :: BigInt > +/// Location: [src/list0.ml:6:0](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/list0.ml#L6) +/// Args: ArrayN16 < crate :: bigint :: BigInt > #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct MinaBaseAccountUpdateBodyEventsStableV1(pub Vec>); +pub struct MinaBaseAccountUpdateBodyEventsStableV1(pub List>); /// **OCaml name**: `Mina_base__Account_update.Body.Stable.V1` /// -/// Gid: `803` -/// Location: [src/lib/mina_base/account_update.ml:1252:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L1252) +/// Gid: `812` +/// Location: [src/lib/mina_base/account_update.ml:1216:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L1216) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountUpdateBodyStableV1 { pub public_key: NonZeroCurvePoint, @@ -1785,8 +1851,8 @@ pub struct MinaBaseAccountUpdateBodyStableV1 { /// **OCaml name**: `Mina_base__Account_update.Body.Fee_payer.Stable.V1` /// -/// Gid: `804` -/// Location: [src/lib/mina_base/account_update.ml:1358:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L1358) +/// Gid: `813` +/// Location: [src/lib/mina_base/account_update.ml:1322:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L1322) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountUpdateBodyFeePayerStableV1 { pub public_key: NonZeroCurvePoint, @@ -1797,8 +1863,8 @@ pub struct MinaBaseAccountUpdateBodyFeePayerStableV1 { /// **OCaml name**: `Mina_base__Account_update.T.Stable.V1` /// -/// Gid: `807` -/// Location: [src/lib/mina_base/account_update.ml:1728:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L1728) +/// Gid: `816` +/// Location: [src/lib/mina_base/account_update.ml:1694:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L1694) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountUpdateTStableV1 { pub body: MinaBaseAccountUpdateBodyStableV1, @@ -1807,8 +1873,8 @@ pub struct MinaBaseAccountUpdateTStableV1 { /// **OCaml name**: `Mina_base__Account_update.Fee_payer.Stable.V1` /// -/// Gid: `808` -/// Location: [src/lib/mina_base/account_update.ml:1772:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/account_update.ml#L1772) +/// Gid: `817` +/// Location: [src/lib/mina_base/account_update.ml:1738:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/account_update.ml#L1738) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseAccountUpdateFeePayerStableV1 { pub body: MinaBaseAccountUpdateBodyFeePayerStableV1, @@ -1817,8 +1883,8 @@ pub struct MinaBaseAccountUpdateFeePayerStableV1 { /// Derived name: `Mina_base__Zkapp_command.T.Stable.V1.Wire.Stable.V1.account_updates.a.a.calls.a` /// -/// Gid: `809` -/// Location: [src/lib/mina_base/with_stack_hash.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/with_stack_hash.ml#L6) +/// Gid: `818` +/// Location: [src/lib/mina_base/with_stack_hash.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/with_stack_hash.ml#L6) /// Args: Box < MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA > , () #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA { @@ -1828,8 +1894,8 @@ pub struct MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAACallsA { /// Derived name: `Mina_base__Zkapp_command.T.Stable.V1.Wire.Stable.V1.account_updates.a` /// -/// Gid: `809` -/// Location: [src/lib/mina_base/with_stack_hash.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/with_stack_hash.ml#L6) +/// Gid: `818` +/// Location: [src/lib/mina_base/with_stack_hash.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/with_stack_hash.ml#L6) /// Args: MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA , () #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA { @@ -1839,8 +1905,8 @@ pub struct MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesA { /// Derived name: `Mina_transaction_logic.Transaction_applied.Coinbase_applied.Stable.V2.coinbase` /// -/// Gid: `810` -/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/with_status.ml#L6) +/// Gid: `819` +/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/with_status.ml#L6) /// Args: MinaBaseCoinbaseStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2Coinbase { @@ -1850,8 +1916,8 @@ pub struct MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2Coinbase /// Derived name: `Mina_transaction_logic.Transaction_applied.Fee_transfer_applied.Stable.V2.fee_transfer` /// -/// Gid: `810` -/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/with_status.ml#L6) +/// Gid: `819` +/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/with_status.ml#L6) /// Args: MinaBaseFeeTransferStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2FeeTransfer { @@ -1861,8 +1927,8 @@ pub struct MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2FeeTr /// Derived name: `Mina_transaction_logic.Transaction_applied.Signed_command_applied.Common.Stable.V2.user_command` /// -/// Gid: `810` -/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/with_status.ml#L6) +/// Gid: `819` +/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/with_status.ml#L6) /// Args: MinaBaseSignedCommandStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStableV2UserCommand { @@ -1872,8 +1938,8 @@ pub struct MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStabl /// Derived name: `Staged_ledger_diff__Diff.Make_str.Pre_diff_with_at_most_two_coinbase.Stable.V2.b` /// -/// Gid: `810` -/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/with_status.ml#L6) +/// Gid: `819` +/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/with_status.ml#L6) /// Args: MinaBaseUserCommandStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B { @@ -1883,8 +1949,8 @@ pub struct StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B { /// Derived name: `Mina_transaction_logic.Transaction_applied.Zkapp_command_applied.Stable.V1.command` /// -/// Gid: `810` -/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/with_status.ml#L6) +/// Gid: `819` +/// Location: [src/lib/mina_base/with_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/with_status.ml#L6) /// Args: MinaBaseZkappCommandTStableV1WireStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1Command { @@ -1894,35 +1960,35 @@ pub struct MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1Comm /// Derived name: `Mina_base__Zkapp_command.T.Stable.V1.Wire.Stable.V1.account_updates.a.a` /// -/// Gid: `811` -/// Location: [src/lib/mina_base/zkapp_command.ml:11:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_command.ml#L11) +/// Gid: `820` +/// Location: [src/lib/mina_base/zkapp_command.ml:11:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_command.ml#L11) /// Args: MinaBaseAccountUpdateTStableV1 , () , () #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappCommandTStableV1WireStableV1AccountUpdatesAA { pub account_update: MinaBaseAccountUpdateTStableV1, pub account_update_digest: (), - pub calls: Vec, + pub calls: List, } /// **OCaml name**: `Mina_base__Zkapp_command.T.Stable.V1.Wire.Stable.V1` /// -/// Gid: `820` -/// Location: [src/lib/mina_base/zkapp_command.ml:684:12](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/zkapp_command.ml#L684) +/// Gid: `829` +/// Location: [src/lib/mina_base/zkapp_command.ml:684:12](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/zkapp_command.ml#L684) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseZkappCommandTStableV1WireStableV1 { pub fee_payer: MinaBaseAccountUpdateFeePayerStableV1, - pub account_updates: Vec, + pub account_updates: List, pub memo: MinaBaseSignedCommandMemoStableV1, } /// **OCaml name**: `Mina_base__User_command.Stable.V2` /// -/// Gid: `830` -/// Location: [src/lib/mina_base/user_command.ml:79:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/user_command.ml#L79) +/// Gid: `839` +/// Location: [src/lib/mina_base/user_command.ml:79:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/user_command.ml#L79) /// /// -/// Gid: `828` -/// Location: [src/lib/mina_base/user_command.ml:7:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/user_command.ml#L7) +/// Gid: `837` +/// Location: [src/lib/mina_base/user_command.ml:7:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/user_command.ml#L7) /// Args: MinaBaseSignedCommandStableV2 , MinaBaseZkappCommandTStableV1WireStableV1 #[derive( Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, derive_more::From, @@ -1934,8 +2000,8 @@ pub enum MinaBaseUserCommandStableV2 { /// **OCaml name**: `Mina_base__Fee_transfer.Make_str.Single.Stable.V2` /// -/// Gid: `834` -/// Location: [src/lib/mina_base/fee_transfer.ml:19:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/fee_transfer.ml#L19) +/// Gid: `843` +/// Location: [src/lib/mina_base/fee_transfer.ml:19:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/fee_transfer.ml#L19) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseFeeTransferSingleStableV2 { pub receiver_pk: NonZeroCurvePoint, @@ -1945,12 +2011,12 @@ pub struct MinaBaseFeeTransferSingleStableV2 { /// **OCaml name**: `Mina_base__Fee_transfer.Make_str.Stable.V2` /// -/// Gid: `835` -/// Location: [src/lib/mina_base/fee_transfer.ml:69:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/fee_transfer.ml#L69) +/// Gid: `844` +/// Location: [src/lib/mina_base/fee_transfer.ml:69:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/fee_transfer.ml#L69) /// /// -/// Gid: `505` -/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/one_or_two/one_or_two.ml#L7) +/// Gid: `508` +/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/one_or_two/one_or_two.ml#L7) /// Args: MinaBaseFeeTransferSingleStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] #[polymorphic_variant] @@ -1968,8 +2034,8 @@ pub enum MinaBaseFeeTransferStableV2 { /// **OCaml name**: `Mina_base__Coinbase_fee_transfer.Make_str.Stable.V1` /// -/// Gid: `836` -/// Location: [src/lib/mina_base/coinbase_fee_transfer.ml:15:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/coinbase_fee_transfer.ml#L15) +/// Gid: `845` +/// Location: [src/lib/mina_base/coinbase_fee_transfer.ml:15:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/coinbase_fee_transfer.ml#L15) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseCoinbaseFeeTransferStableV1 { pub receiver_pk: NonZeroCurvePoint, @@ -1978,8 +2044,8 @@ pub struct MinaBaseCoinbaseFeeTransferStableV1 { /// **OCaml name**: `Mina_base__Coinbase.Make_str.Stable.V1` /// -/// Gid: `837` -/// Location: [src/lib/mina_base/coinbase.ml:17:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/coinbase.ml#L17) +/// Gid: `846` +/// Location: [src/lib/mina_base/coinbase.ml:17:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/coinbase.ml#L17) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseCoinbaseStableV1 { pub receiver: NonZeroCurvePoint, @@ -1989,41 +2055,41 @@ pub struct MinaBaseCoinbaseStableV1 { /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Stack_id.Stable.V1` /// -/// Gid: `839` -/// Location: [src/lib/mina_base/pending_coinbase.ml:106:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L106) +/// Gid: `848` +/// Location: [src/lib/mina_base/pending_coinbase.ml:106:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L106) /// /// /// Gid: `163` -/// Location: [src/std_internal.ml:119:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L119) +/// Location: [src/std_internal.ml:119:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L119) /// /// /// Gid: `113` -/// Location: [src/int.ml:19:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int.ml#L19) +/// Location: [src/int.ml:19:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/int.ml#L19) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct MinaBasePendingCoinbaseStackIdStableV1(pub crate::number::Int64); +pub struct MinaBasePendingCoinbaseStackIdStableV1(pub crate::number::UInt64); /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Coinbase_stack.Stable.V1` /// -/// Gid: `842` -/// Location: [src/lib/mina_base/pending_coinbase.ml:159:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L159) +/// Gid: `851` +/// Location: [src/lib/mina_base/pending_coinbase.ml:159:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L159) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBasePendingCoinbaseCoinbaseStackStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Stack_hash.Stable.V1` /// -/// Gid: `847` -/// Location: [src/lib/mina_base/pending_coinbase.ml:219:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L219) +/// Gid: `856` +/// Location: [src/lib/mina_base/pending_coinbase.ml:219:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L219) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBasePendingCoinbaseStackHashStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.State_stack.Stable.V1` /// -/// Gid: `851` -/// Location: [src/lib/mina_base/pending_coinbase.ml:255:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L255) +/// Gid: `860` +/// Location: [src/lib/mina_base/pending_coinbase.ml:255:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L255) /// /// -/// Gid: `850` -/// Location: [src/lib/mina_base/pending_coinbase.ml:245:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L245) +/// Gid: `859` +/// Location: [src/lib/mina_base/pending_coinbase.ml:245:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L245) /// Args: CoinbaseStackHash #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePendingCoinbaseStateStackStableV1 { @@ -2033,15 +2099,15 @@ pub struct MinaBasePendingCoinbaseStateStackStableV1 { /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Hash_builder.Stable.V1` /// -/// Gid: `854` -/// Location: [src/lib/mina_base/pending_coinbase.ml:373:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L373) +/// Gid: `863` +/// Location: [src/lib/mina_base/pending_coinbase.ml:373:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L373) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBasePendingCoinbaseHashBuilderStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Update.Action.Stable.V1` /// -/// Gid: `857` -/// Location: [src/lib/mina_base/pending_coinbase.ml:407:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L407) +/// Gid: `866` +/// Location: [src/lib/mina_base/pending_coinbase.ml:407:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L407) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaBasePendingCoinbaseUpdateActionStableV1 { UpdateNone, @@ -2052,12 +2118,12 @@ pub enum MinaBasePendingCoinbaseUpdateActionStableV1 { /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Update.Stable.V1` /// -/// Gid: `859` -/// Location: [src/lib/mina_base/pending_coinbase.ml:473:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L473) +/// Gid: `868` +/// Location: [src/lib/mina_base/pending_coinbase.ml:473:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L473) /// /// -/// Gid: `858` -/// Location: [src/lib/mina_base/pending_coinbase.ml:463:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L463) +/// Gid: `867` +/// Location: [src/lib/mina_base/pending_coinbase.ml:463:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L463) /// Args: MinaBasePendingCoinbaseUpdateActionStableV1 , CurrencyAmountStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePendingCoinbaseUpdateStableV1 { @@ -2067,12 +2133,12 @@ pub struct MinaBasePendingCoinbaseUpdateStableV1 { /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Stack_versioned.Stable.V1` /// -/// Gid: `861` -/// Location: [src/lib/mina_base/pending_coinbase.ml:522:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L522) +/// Gid: `870` +/// Location: [src/lib/mina_base/pending_coinbase.ml:522:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L522) /// /// -/// Gid: `860` -/// Location: [src/lib/mina_base/pending_coinbase.ml:511:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L511) +/// Gid: `869` +/// Location: [src/lib/mina_base/pending_coinbase.ml:511:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L511) /// Args: CoinbaseStackData , MinaBasePendingCoinbaseStateStackStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePendingCoinbaseStackVersionedStableV1 { @@ -2082,8 +2148,8 @@ pub struct MinaBasePendingCoinbaseStackVersionedStableV1 { /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Hash_versioned.Stable.V1` /// -/// Gid: `862` -/// Location: [src/lib/mina_base/pending_coinbase.ml:535:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L535) +/// Gid: `871` +/// Location: [src/lib/mina_base/pending_coinbase.ml:535:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L535) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBasePendingCoinbaseHashVersionedStableV1( pub MinaBasePendingCoinbaseHashBuilderStableV1, @@ -2091,54 +2157,41 @@ pub struct MinaBasePendingCoinbaseHashVersionedStableV1( /// **OCaml name**: `Mina_base__Pending_coinbase.Make_str.Merkle_tree_versioned.Stable.V2` /// -/// Gid: `863` -/// Location: [src/lib/mina_base/pending_coinbase.ml:547:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase.ml#L547) +/// Gid: `872` +/// Location: [src/lib/mina_base/pending_coinbase.ml:547:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase.ml#L547) /// /// -/// Gid: `652` -/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:38:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/sparse_ledger_lib/sparse_ledger.ml#L38) +/// Gid: `661` +/// Location: [src/lib/sparse_ledger_lib/sparse_ledger.ml:38:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/sparse_ledger_lib/sparse_ledger.ml#L38) /// Args: PendingCoinbaseHash , MinaBasePendingCoinbaseStackIdStableV1 , MinaBasePendingCoinbaseStackVersionedStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePendingCoinbaseMerkleTreeVersionedStableV2 { - pub indexes: Vec<(MinaBasePendingCoinbaseStackIdStableV1, crate::number::Int64)>, - pub depth: crate::number::Int64, + pub indexes: List<( + MinaBasePendingCoinbaseStackIdStableV1, + crate::number::UInt64, + )>, + pub depth: crate::number::UInt64, pub tree: MinaBasePendingCoinbaseMerkleTreeVersionedStableV2Tree, } /// **OCaml name**: `Mina_base__Staged_ledger_hash.Make_str.Aux_hash.Stable.V1` /// -/// Gid: `866` -/// Location: [src/lib/mina_base/staged_ledger_hash.ml:27:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/staged_ledger_hash.ml#L27) -/// -/// -/// Gid: `170` -/// Location: [src/std_internal.ml:140:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L140) -/// -/// -/// Gid: `83` -/// Location: [src/string.ml:44:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/string.ml#L44) +/// Gid: `875` +/// Location: [src/lib/mina_base/staged_ledger_hash.ml:27:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/staged_ledger_hash.ml#L27) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseStagedLedgerHashAuxHashStableV1(pub crate::string::ByteString); /// **OCaml name**: `Mina_base__Staged_ledger_hash.Make_str.Pending_coinbase_aux.Stable.V1` /// -/// Gid: `867` -/// Location: [src/lib/mina_base/staged_ledger_hash.ml:110:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/staged_ledger_hash.ml#L110) -/// -/// -/// Gid: `170` -/// Location: [src/std_internal.ml:140:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L140) -/// -/// -/// Gid: `83` -/// Location: [src/string.ml:44:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/string.ml#L44) +/// Gid: `876` +/// Location: [src/lib/mina_base/staged_ledger_hash.ml:111:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/staged_ledger_hash.ml#L111) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseStagedLedgerHashPendingCoinbaseAuxStableV1(pub crate::string::ByteString); /// **OCaml name**: `Mina_base__Staged_ledger_hash.Make_str.Non_snark.Stable.V1` /// -/// Gid: `868` -/// Location: [src/lib/mina_base/staged_ledger_hash.ml:152:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/staged_ledger_hash.ml#L152) +/// Gid: `877` +/// Location: [src/lib/mina_base/staged_ledger_hash.ml:154:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/staged_ledger_hash.ml#L154) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseStagedLedgerHashNonSnarkStableV1 { pub ledger_hash: LedgerHash, @@ -2148,12 +2201,12 @@ pub struct MinaBaseStagedLedgerHashNonSnarkStableV1 { /// **OCaml name**: `Mina_base__Staged_ledger_hash.Make_str.Stable.V1` /// -/// Gid: `870` -/// Location: [src/lib/mina_base/staged_ledger_hash.ml:259:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/staged_ledger_hash.ml#L259) +/// Gid: `879` +/// Location: [src/lib/mina_base/staged_ledger_hash.ml:261:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/staged_ledger_hash.ml#L261) /// /// -/// Gid: `869` -/// Location: [src/lib/mina_base/staged_ledger_hash.ml:241:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/staged_ledger_hash.ml#L241) +/// Gid: `878` +/// Location: [src/lib/mina_base/staged_ledger_hash.ml:243:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/staged_ledger_hash.ml#L243) /// Args: MinaBaseStagedLedgerHashNonSnarkStableV1 , PendingCoinbaseHash #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseStagedLedgerHashStableV1 { @@ -2163,15 +2216,15 @@ pub struct MinaBaseStagedLedgerHashStableV1 { /// **OCaml name**: `Mina_base__Stack_frame.Make_str.Stable.V1` /// -/// Gid: `872` -/// Location: [src/lib/mina_base/stack_frame.ml:64:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/stack_frame.ml#L64) +/// Gid: `881` +/// Location: [src/lib/mina_base/stack_frame.ml:64:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/stack_frame.ml#L64) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseStackFrameStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Sok_message.Make_str.Stable.V1` /// -/// Gid: `874` -/// Location: [src/lib/mina_base/sok_message.ml:14:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/sok_message.ml#L14) +/// Gid: `883` +/// Location: [src/lib/mina_base/sok_message.ml:14:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/sok_message.ml#L14) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseSokMessageStableV1 { pub fee: CurrencyFeeStableV1, @@ -2180,33 +2233,34 @@ pub struct MinaBaseSokMessageStableV1 { /// **OCaml name**: `Mina_base__Protocol_constants_checked.Value.Stable.V1` /// -/// Gid: `875` -/// Location: [src/lib/mina_base/protocol_constants_checked.ml:22:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/protocol_constants_checked.ml#L22) +/// Gid: `884` +/// Location: [src/lib/mina_base/protocol_constants_checked.ml:22:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/protocol_constants_checked.ml#L22) /// /// -/// Gid: `648` -/// Location: [src/lib/genesis_constants/genesis_constants.ml:242:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/genesis_constants/genesis_constants.ml#L242) +/// Gid: `657` +/// Location: [src/lib/genesis_constants/genesis_constants.ml:240:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/genesis_constants/genesis_constants.ml#L240) /// Args: UnsignedExtendedUInt32StableV1 , UnsignedExtendedUInt32StableV1 , BlockTimeTimeStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseProtocolConstantsCheckedValueStableV1 { pub k: UnsignedExtendedUInt32StableV1, pub slots_per_epoch: UnsignedExtendedUInt32StableV1, pub slots_per_sub_window: UnsignedExtendedUInt32StableV1, + pub grace_period_slots: UnsignedExtendedUInt32StableV1, pub delta: UnsignedExtendedUInt32StableV1, pub genesis_state_timestamp: BlockTimeTimeStableV1, } /// **OCaml name**: `Mina_base__Proof.Stable.V2` /// -/// Gid: `876` -/// Location: [src/lib/mina_base/proof.ml:12:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/proof.ml#L12) +/// Gid: `885` +/// Location: [src/lib/mina_base/proof.ml:12:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/proof.ml#L12) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseProofStableV2(pub PicklesProofProofsVerified2ReprStableV2); /// **OCaml name**: `Mina_base__Pending_coinbase_witness.Stable.V2` /// -/// Gid: `877` -/// Location: [src/lib/mina_base/pending_coinbase_witness.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/pending_coinbase_witness.ml#L6) +/// Gid: `886` +/// Location: [src/lib/mina_base/pending_coinbase_witness.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/pending_coinbase_witness.ml#L6) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBasePendingCoinbaseWitnessStableV2 { pub pending_coinbases: MinaBasePendingCoinbaseStableV2, @@ -2215,15 +2269,15 @@ pub struct MinaBasePendingCoinbaseWitnessStableV2 { /// **OCaml name**: `Mina_base__Call_stack_digest.Make_str.Stable.V1` /// -/// Gid: `878` -/// Location: [src/lib/mina_base/call_stack_digest.ml:12:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/call_stack_digest.ml#L12) +/// Gid: `887` +/// Location: [src/lib/mina_base/call_stack_digest.ml:12:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/call_stack_digest.ml#L12) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaBaseCallStackDigestStableV1(pub crate::bigint::BigInt); /// **OCaml name**: `Mina_base__Fee_with_prover.Stable.V1` /// -/// Gid: `879` -/// Location: [src/lib/mina_base/fee_with_prover.ml:7:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/fee_with_prover.ml#L7) +/// Gid: `888` +/// Location: [src/lib/mina_base/fee_with_prover.ml:7:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/fee_with_prover.ml#L7) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBaseFeeWithProverStableV1 { pub fee: CurrencyFeeStableV1, @@ -2232,27 +2286,19 @@ pub struct MinaBaseFeeWithProverStableV1 { /// **OCaml name**: `Network_peer__Peer.Id.Stable.V1` /// -/// Gid: `880` -/// Location: [src/lib/network_peer/peer.ml:10:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/network_peer/peer.ml#L10) -/// -/// -/// Gid: `170` -/// Location: [src/std_internal.ml:140:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L140) -/// -/// -/// Gid: `83` -/// Location: [src/string.ml:44:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/string.ml#L44) +/// Gid: `889` +/// Location: [src/lib/network_peer/peer.ml:10:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/network_peer/peer.ml#L10) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct NetworkPeerPeerIdStableV1(pub crate::string::ByteString); /// **OCaml name**: `Mina_transaction__Transaction.Stable.V2` /// -/// Gid: `887` -/// Location: [src/lib/transaction/transaction.ml:46:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction/transaction.ml#L46) +/// Gid: `896` +/// Location: [src/lib/transaction/transaction.ml:46:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction/transaction.ml#L46) /// /// -/// Gid: `885` -/// Location: [src/lib/transaction/transaction.ml:8:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction/transaction.ml#L8) +/// Gid: `894` +/// Location: [src/lib/transaction/transaction.ml:8:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction/transaction.ml#L8) /// Args: MinaBaseUserCommandStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaTransactionTransactionStableV2 { @@ -2263,12 +2309,12 @@ pub enum MinaTransactionTransactionStableV2 { /// **OCaml name**: `Mina_transaction_logic__Zkapp_command_logic.Local_state.Value.Stable.V1` /// -/// Gid: `895` -/// Location: [src/lib/transaction_logic/zkapp_command_logic.ml:255:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/zkapp_command_logic.ml#L255) +/// Gid: `906` +/// Location: [src/lib/transaction_logic/zkapp_command_logic.ml:255:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/zkapp_command_logic.ml#L255) /// /// -/// Gid: `894` -/// Location: [src/lib/transaction_logic/zkapp_command_logic.ml:196:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/zkapp_command_logic.ml#L196) +/// Gid: `905` +/// Location: [src/lib/transaction_logic/zkapp_command_logic.ml:196:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/zkapp_command_logic.ml#L196) /// Args: MinaBaseStackFrameStableV1 , MinaBaseCallStackDigestStableV1 , SignedAmount , LedgerHash , bool , crate :: bigint :: BigInt , UnsignedExtendedUInt32StableV1 , MinaBaseTransactionStatusFailureCollectionStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 { @@ -2287,8 +2333,8 @@ pub struct MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 { /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Signed_command_applied.Common.Stable.V2` /// -/// Gid: `897` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:17:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L17) +/// Gid: `908` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:17:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L17) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStableV2 { pub user_command: @@ -2297,12 +2343,12 @@ pub struct MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStabl /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Signed_command_applied.Body.Stable.V2` /// -/// Gid: `898` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:31:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L31) +/// Gid: `909` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:31:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L31) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaTransactionLogicTransactionAppliedSignedCommandAppliedBodyStableV2 { Payment { - new_accounts: Vec, + new_accounts: List, }, StakeDelegation { previous_delegate: Option, @@ -2312,8 +2358,8 @@ pub enum MinaTransactionLogicTransactionAppliedSignedCommandAppliedBodyStableV2 /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Signed_command_applied.Stable.V2` /// -/// Gid: `899` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:46:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L46) +/// Gid: `910` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:46:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L46) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedSignedCommandAppliedStableV2 { pub common: MinaTransactionLogicTransactionAppliedSignedCommandAppliedCommonStableV2, @@ -2322,22 +2368,22 @@ pub struct MinaTransactionLogicTransactionAppliedSignedCommandAppliedStableV2 { /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Zkapp_command_applied.Stable.V1` /// -/// Gid: `900` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:65:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L65) +/// Gid: `911` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:65:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L65) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1 { - pub accounts: Vec<( + pub accounts: List<( MinaBaseAccountIdStableV2, Option, )>, pub command: MinaTransactionLogicTransactionAppliedZkappCommandAppliedStableV1Command, - pub new_accounts: Vec, + pub new_accounts: List, } /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Command_applied.Stable.V2` /// -/// Gid: `901` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:82:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L82) +/// Gid: `912` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:82:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L82) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaTransactionLogicTransactionAppliedCommandAppliedStableV2 { SignedCommand(MinaTransactionLogicTransactionAppliedSignedCommandAppliedStableV2), @@ -2346,30 +2392,30 @@ pub enum MinaTransactionLogicTransactionAppliedCommandAppliedStableV2 { /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Fee_transfer_applied.Stable.V2` /// -/// Gid: `902` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:96:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L96) +/// Gid: `913` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:96:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L96) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2 { pub fee_transfer: MinaTransactionLogicTransactionAppliedFeeTransferAppliedStableV2FeeTransfer, - pub new_accounts: Vec, + pub new_accounts: List, pub burned_tokens: CurrencyAmountStableV1, } /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Coinbase_applied.Stable.V2` /// -/// Gid: `903` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:112:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L112) +/// Gid: `914` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:112:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L112) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2 { pub coinbase: MinaTransactionLogicTransactionAppliedCoinbaseAppliedStableV2Coinbase, - pub new_accounts: Vec, + pub new_accounts: List, pub burned_tokens: CurrencyAmountStableV1, } /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Varying.Stable.V2` /// -/// Gid: `904` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:128:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L128) +/// Gid: `915` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:128:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L128) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaTransactionLogicTransactionAppliedVaryingStableV2 { Command(MinaTransactionLogicTransactionAppliedCommandAppliedStableV2), @@ -2379,8 +2425,8 @@ pub enum MinaTransactionLogicTransactionAppliedVaryingStableV2 { /// **OCaml name**: `Mina_transaction_logic.Transaction_applied.Stable.V2` /// -/// Gid: `905` -/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:142:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_logic/mina_transaction_logic.ml#L142) +/// Gid: `916` +/// Location: [src/lib/transaction_logic/mina_transaction_logic.ml:142:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_logic/mina_transaction_logic.ml#L142) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaTransactionLogicTransactionAppliedStableV2 { pub previous_hash: LedgerHash, @@ -2389,15 +2435,18 @@ pub struct MinaTransactionLogicTransactionAppliedStableV2 { /// **OCaml name**: `Merkle_address.Binable_arg.Stable.V1` /// -/// Gid: `906` -/// Location: [src/lib/merkle_address/merkle_address.ml:48:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/merkle_address/merkle_address.ml#L48) +/// Gid: `917` +/// Location: [src/lib/merkle_address/merkle_address.ml:48:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/merkle_address/merkle_address.ml#L48) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] -pub struct MerkleAddressBinableArgStableV1(pub crate::number::Int64, pub crate::string::ByteString); +pub struct MerkleAddressBinableArgStableV1( + pub crate::number::UInt64, + pub crate::string::ByteString, +); /// **OCaml name**: `Trust_system__Banned_status.Stable.V1` /// -/// Gid: `912` -/// Location: [src/lib/trust_system/banned_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/trust_system/banned_status.ml#L6) +/// Gid: `924` +/// Location: [src/lib/trust_system/banned_status.ml:6:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/trust_system/banned_status.ml#L6) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum TrustSystemBannedStatusStableV1 { Unbanned, @@ -2406,23 +2455,15 @@ pub enum TrustSystemBannedStatusStableV1 { /// **OCaml name**: `Consensus_vrf.Output.Truncated.Stable.V1` /// -/// Gid: `927` -/// Location: [src/lib/consensus/vrf/consensus_vrf.ml:168:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/vrf/consensus_vrf.ml#L168) -/// -/// -/// Gid: `170` -/// Location: [src/std_internal.ml:140:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L140) -/// -/// -/// Gid: `83` -/// Location: [src/string.ml:44:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/string.ml#L44) +/// Gid: `941` +/// Location: [src/lib/consensus/vrf/consensus_vrf.ml:168:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/vrf/consensus_vrf.ml#L168) #[derive(Clone, Debug, PartialEq, BinProtRead, BinProtWrite, Deref)] pub struct ConsensusVrfOutputTruncatedStableV1(pub crate::string::ByteString); /// **OCaml name**: `Consensus__Stake_proof.Stable.V2` /// -/// Gid: `937` -/// Location: [src/lib/consensus/stake_proof.ml:10:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/stake_proof.ml#L10) +/// Gid: `951` +/// Location: [src/lib/consensus/stake_proof.ml:10:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/stake_proof.ml#L10) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct ConsensusStakeProofStableV2 { pub delegator: MinaBaseAccountIndexStableV1, @@ -2435,19 +2476,19 @@ pub struct ConsensusStakeProofStableV2 { /// **OCaml name**: `Consensus__Body_reference.Stable.V1` /// -/// Gid: `945` -/// Location: [src/lib/consensus/body_reference.ml:17:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/body_reference.ml#L17) +/// Gid: `959` +/// Location: [src/lib/consensus/body_reference.ml:17:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/body_reference.ml#L17) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct ConsensusBodyReferenceStableV1(pub Blake2MakeStableV1); +pub struct ConsensusBodyReferenceStableV1(pub crate::string::ByteString); /// **OCaml name**: `Consensus__Global_slot.Make_str.Stable.V1` /// -/// Gid: `952` -/// Location: [src/lib/consensus/global_slot.ml:33:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/global_slot.ml#L33) +/// Gid: `966` +/// Location: [src/lib/consensus/global_slot.ml:33:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/global_slot.ml#L33) /// /// -/// Gid: `951` -/// Location: [src/lib/consensus/global_slot.ml:22:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/global_slot.ml#L22) +/// Gid: `965` +/// Location: [src/lib/consensus/global_slot.ml:22:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/global_slot.ml#L22) /// Args: MinaNumbersGlobalSlotSinceHardForkMStableV1 , UnsignedExtendedUInt32StableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct ConsensusGlobalSlotStableV1 { @@ -2457,12 +2498,12 @@ pub struct ConsensusGlobalSlotStableV1 { /// **OCaml name**: `Consensus__Proof_of_stake.Make_str.Data.Epoch_data.Staking_value_versioned.Value.Stable.V1` /// -/// Gid: `967` -/// Location: [src/lib/consensus/proof_of_stake.ml:1099:14](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/proof_of_stake.ml#L1099) +/// Gid: `981` +/// Location: [src/lib/consensus/proof_of_stake.ml:1072:14](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/proof_of_stake.ml#L1072) /// /// -/// Gid: `779` -/// Location: [src/lib/mina_base/epoch_data.ml:8:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/epoch_data.ml#L8) +/// Gid: `788` +/// Location: [src/lib/mina_base/epoch_data.ml:8:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/epoch_data.ml#L8) /// Args: MinaBaseEpochLedgerValueStableV1 , EpochSeed , StateHash , StateHash , UnsignedExtendedUInt32StableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1 { @@ -2475,12 +2516,12 @@ pub struct ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1 /// **OCaml name**: `Consensus__Proof_of_stake.Make_str.Data.Epoch_data.Next_value_versioned.Value.Stable.V1` /// -/// Gid: `968` -/// Location: [src/lib/consensus/proof_of_stake.ml:1124:14](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/consensus/proof_of_stake.ml#L1124) +/// Gid: `982` +/// Location: [src/lib/consensus/proof_of_stake.ml:1097:14](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/consensus/proof_of_stake.ml#L1097) /// /// -/// Gid: `779` -/// Location: [src/lib/mina_base/epoch_data.ml:8:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_base/epoch_data.ml#L8) +/// Gid: `788` +/// Location: [src/lib/mina_base/epoch_data.ml:8:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_base/epoch_data.ml#L8) /// Args: MinaBaseEpochLedgerValueStableV1 , EpochSeed , StateHash , StateHash , UnsignedExtendedUInt32StableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1 { @@ -2493,8 +2534,8 @@ pub struct ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1 { /// Derived name: `Mina_state__Blockchain_state.Value.Stable.V2.ledger_proof_statement.source` /// -/// Gid: `971` -/// Location: [src/lib/mina_state/registers.ml:8:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/registers.ml#L8) +/// Gid: `985` +/// Location: [src/lib/mina_state/registers.ml:8:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/registers.ml#L8) /// Args: LedgerHash , MinaBasePendingCoinbaseStackVersionedStableV1 , MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateBlockchainStateValueStableV2LedgerProofStatementSource { @@ -2506,8 +2547,8 @@ pub struct MinaStateBlockchainStateValueStableV2LedgerProofStatementSource { /// **OCaml name**: `Mina_state__Snarked_ledger_state.Make_str.Pending_coinbase_stack_state.Init_stack.Stable.V1` /// -/// Gid: `972` -/// Location: [src/lib/mina_state/snarked_ledger_state.ml:38:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/snarked_ledger_state.ml#L38) +/// Gid: `986` +/// Location: [src/lib/mina_state/snarked_ledger_state.ml:38:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/snarked_ledger_state.ml#L38) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum MinaStateSnarkedLedgerStatePendingCoinbaseStackStateInitStackStableV1 { Base(MinaBasePendingCoinbaseStackVersionedStableV1), @@ -2516,8 +2557,8 @@ pub enum MinaStateSnarkedLedgerStatePendingCoinbaseStackStateInitStackStableV1 { /// Derived name: `Mina_state__Blockchain_state.Value.Stable.V2.ledger_proof_statement` /// -/// Gid: `977` -/// Location: [src/lib/mina_state/snarked_ledger_state.ml:107:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/snarked_ledger_state.ml#L107) +/// Gid: `991` +/// Location: [src/lib/mina_state/snarked_ledger_state.ml:107:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/snarked_ledger_state.ml#L107) /// Args: LedgerHash , MinaStateBlockchainStateValueStableV2SignedAmount , MinaBasePendingCoinbaseStackVersionedStableV1 , MinaBaseFeeExcessStableV1 , () , MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateBlockchainStateValueStableV2LedgerProofStatement { @@ -2532,8 +2573,8 @@ pub struct MinaStateBlockchainStateValueStableV2LedgerProofStatement { /// **OCaml name**: `Mina_state__Snarked_ledger_state.Make_str.Stable.V2` /// -/// Gid: `978` -/// Location: [src/lib/mina_state/snarked_ledger_state.ml:191:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/snarked_ledger_state.ml#L191) +/// Gid: `992` +/// Location: [src/lib/mina_state/snarked_ledger_state.ml:191:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/snarked_ledger_state.ml#L191) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct MinaStateSnarkedLedgerStateStableV2( pub MinaStateBlockchainStateValueStableV2LedgerProofStatement, @@ -2541,13 +2582,13 @@ pub struct MinaStateSnarkedLedgerStateStableV2( /// **OCaml name**: `Mina_state__Snarked_ledger_state.Make_str.With_sok.Stable.V2` /// -/// Gid: `979` -/// Location: [src/lib/mina_state/snarked_ledger_state.ml:345:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/snarked_ledger_state.ml#L345) +/// Gid: `993` +/// Location: [src/lib/mina_state/snarked_ledger_state.ml:345:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/snarked_ledger_state.ml#L345) /// /// -/// Gid: `977` -/// Location: [src/lib/mina_state/snarked_ledger_state.ml:107:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/snarked_ledger_state.ml#L107) -/// Args: LedgerHash , MinaStateBlockchainStateValueStableV2SignedAmount , MinaBasePendingCoinbaseStackVersionedStableV1 , MinaBaseFeeExcessStableV1 , MinaBaseZkappAccountZkappUriStableV1 , MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 +/// Gid: `991` +/// Location: [src/lib/mina_state/snarked_ledger_state.ml:107:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/snarked_ledger_state.ml#L107) +/// Args: LedgerHash , MinaStateBlockchainStateValueStableV2SignedAmount , MinaBasePendingCoinbaseStackVersionedStableV1 , MinaBaseFeeExcessStableV1 , crate :: string :: ByteString , MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateSnarkedLedgerStateWithSokStableV2 { pub source: MinaStateBlockchainStateValueStableV2LedgerProofStatementSource, @@ -2556,17 +2597,17 @@ pub struct MinaStateSnarkedLedgerStateWithSokStableV2 { pub connecting_ledger_right: LedgerHash, pub supply_increase: MinaStateBlockchainStateValueStableV2SignedAmount, pub fee_excess: MinaBaseFeeExcessStableV1, - pub sok_digest: MinaBaseZkappAccountZkappUriStableV1, + pub sok_digest: crate::string::ByteString, } /// **OCaml name**: `Mina_state__Blockchain_state.Value.Stable.V2` /// -/// Gid: `983` -/// Location: [src/lib/mina_state/blockchain_state.ml:68:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/blockchain_state.ml#L68) +/// Gid: `997` +/// Location: [src/lib/mina_state/blockchain_state.ml:68:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/blockchain_state.ml#L68) /// /// -/// Gid: `982` -/// Location: [src/lib/mina_state/blockchain_state.ml:10:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/blockchain_state.ml#L10) +/// Gid: `996` +/// Location: [src/lib/mina_state/blockchain_state.ml:10:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/blockchain_state.ml#L10) /// Args: MinaBaseStagedLedgerHashStableV1 , LedgerHash , MinaTransactionLogicZkappCommandLogicLocalStateValueStableV1 , BlockTimeTimeStableV1 , ConsensusBodyReferenceStableV1 , MinaStateBlockchainStateValueStableV2SignedAmount , MinaBasePendingCoinbaseStackVersionedStableV1 , MinaBaseFeeExcessStableV1 , () #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateBlockchainStateValueStableV2 { @@ -2579,12 +2620,12 @@ pub struct MinaStateBlockchainStateValueStableV2 { /// **OCaml name**: `Mina_state__Snark_transition.Value.Stable.V2` /// -/// Gid: `985` -/// Location: [src/lib/mina_state/snark_transition.ml:25:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/snark_transition.ml#L25) +/// Gid: `999` +/// Location: [src/lib/mina_state/snark_transition.ml:25:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/snark_transition.ml#L25) /// /// -/// Gid: `984` -/// Location: [src/lib/mina_state/snark_transition.ml:8:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/snark_transition.ml#L8) +/// Gid: `998` +/// Location: [src/lib/mina_state/snark_transition.ml:8:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/snark_transition.ml#L8) /// Args: MinaStateBlockchainStateValueStableV2 , MinaNumbersGlobalSlotSinceHardForkMStableV1 , MinaBasePendingCoinbaseUpdateStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateSnarkTransitionValueStableV2 { @@ -2595,12 +2636,12 @@ pub struct MinaStateSnarkTransitionValueStableV2 { /// **OCaml name**: `Mina_state__Protocol_state.Make_str.Body.Value.Stable.V2` /// -/// Gid: `989` -/// Location: [src/lib/mina_state/protocol_state.ml:82:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/protocol_state.ml#L82) +/// Gid: `1003` +/// Location: [src/lib/mina_state/protocol_state.ml:82:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/protocol_state.ml#L82) /// /// -/// Gid: `987` -/// Location: [src/lib/mina_state/protocol_state.ml:62:10](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_state/protocol_state.ml#L62) +/// Gid: `1001` +/// Location: [src/lib/mina_state/protocol_state.ml:62:10](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_state/protocol_state.ml#L62) /// Args: StateHash , MinaStateBlockchainStateValueStableV2 , ConsensusProofOfStakeDataConsensusStateValueStableV2 , MinaBaseProtocolConstantsCheckedValueStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaStateProtocolStateBodyValueStableV2 { @@ -2612,15 +2653,15 @@ pub struct MinaStateProtocolStateBodyValueStableV2 { /// **OCaml name**: `Transaction_snark.Make_str.Proof.Stable.V2` /// -/// Gid: `997` -/// Location: [src/lib/transaction_snark/transaction_snark.ml:67:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_snark/transaction_snark.ml#L67) +/// Gid: `1011` +/// Location: [src/lib/transaction_snark/transaction_snark.ml:69:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_snark/transaction_snark.ml#L69) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct TransactionSnarkProofStableV2(pub PicklesProofProofsVerified2ReprStableV2); /// **OCaml name**: `Transaction_snark.Make_str.Stable.V2` /// -/// Gid: `998` -/// Location: [src/lib/transaction_snark/transaction_snark.ml:78:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_snark/transaction_snark.ml#L78) +/// Gid: `1012` +/// Location: [src/lib/transaction_snark/transaction_snark.ml:80:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_snark/transaction_snark.ml#L80) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkStableV2 { pub statement: MinaStateSnarkedLedgerStateWithSokStableV2, @@ -2629,19 +2670,19 @@ pub struct TransactionSnarkStableV2 { /// **OCaml name**: `Ledger_proof.Prod.Stable.V2` /// -/// Gid: `1000` -/// Location: [src/lib/ledger_proof/ledger_proof.ml:10:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/ledger_proof/ledger_proof.ml#L10) +/// Gid: `1014` +/// Location: [src/lib/ledger_proof/ledger_proof.ml:10:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/ledger_proof/ledger_proof.ml#L10) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct LedgerProofProdStableV2(pub TransactionSnarkStableV2); /// **OCaml name**: `Transaction_snark_work.Statement.Stable.V2` /// -/// Gid: `1002` -/// Location: [src/lib/transaction_snark_work/transaction_snark_work.ml:23:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_snark_work/transaction_snark_work.ml#L23) +/// Gid: `1016` +/// Location: [src/lib/transaction_snark_work/transaction_snark_work.ml:23:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_snark_work/transaction_snark_work.ml#L23) /// /// -/// Gid: `505` -/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/one_or_two/one_or_two.ml#L7) +/// Gid: `508` +/// Location: [src/lib/one_or_two/one_or_two.ml:7:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/one_or_two/one_or_two.ml#L7) /// Args: MinaStateSnarkedLedgerStateStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] #[polymorphic_variant] @@ -2659,8 +2700,8 @@ pub enum TransactionSnarkWorkStatementStableV2 { /// **OCaml name**: `Transaction_snark_work.T.Stable.V2` /// -/// Gid: `1010` -/// Location: [src/lib/transaction_snark_work/transaction_snark_work.ml:84:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_snark_work/transaction_snark_work.ml#L84) +/// Gid: `1024` +/// Location: [src/lib/transaction_snark_work/transaction_snark_work.ml:83:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_snark_work/transaction_snark_work.ml#L83) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkWorkTStableV2 { pub fee: CurrencyFeeStableV1, @@ -2670,8 +2711,8 @@ pub struct TransactionSnarkWorkTStableV2 { /// Derived name: `Staged_ledger_diff__Diff.Make_str.Pre_diff_with_at_most_two_coinbase.Stable.V2.coinbase` /// -/// Gid: `1011` -/// Location: [src/lib/staged_ledger_diff/diff.ml:28:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L28) +/// Gid: `1025` +/// Location: [src/lib/staged_ledger_diff/diff.ml:28:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L28) /// Args: StagedLedgerDiffDiffFtStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase { @@ -2687,8 +2728,8 @@ pub enum StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase { /// Derived name: `Staged_ledger_diff__Diff.Make_str.Pre_diff_with_at_most_one_coinbase.Stable.V2.coinbase` /// -/// Gid: `1012` -/// Location: [src/lib/staged_ledger_diff/diff.ml:64:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L64) +/// Gid: `1026` +/// Location: [src/lib/staged_ledger_diff/diff.ml:64:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L64) /// Args: StagedLedgerDiffDiffFtStableV1 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase { @@ -2698,49 +2739,49 @@ pub enum StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase { /// **OCaml name**: `Staged_ledger_diff__Diff.Make_str.Ft.Stable.V1` /// -/// Gid: `1013` -/// Location: [src/lib/staged_ledger_diff/diff.ml:88:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L88) +/// Gid: `1027` +/// Location: [src/lib/staged_ledger_diff/diff.ml:88:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L88) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] pub struct StagedLedgerDiffDiffFtStableV1(pub MinaBaseCoinbaseFeeTransferStableV1); /// **OCaml name**: `Staged_ledger_diff__Diff.Make_str.Pre_diff_with_at_most_two_coinbase.Stable.V2` /// -/// Gid: `1016` -/// Location: [src/lib/staged_ledger_diff/diff.ml:168:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L168) +/// Gid: `1030` +/// Location: [src/lib/staged_ledger_diff/diff.ml:168:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L168) /// /// -/// Gid: `1014` -/// Location: [src/lib/staged_ledger_diff/diff.ml:104:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L104) +/// Gid: `1028` +/// Location: [src/lib/staged_ledger_diff/diff.ml:104:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L104) /// Args: TransactionSnarkWorkTStableV2 , StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2 { - pub completed_works: Vec, - pub commands: Vec, + pub completed_works: List, + pub commands: List, pub coinbase: StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2Coinbase, - pub internal_command_statuses: Vec, + pub internal_command_statuses: List, } /// **OCaml name**: `Staged_ledger_diff__Diff.Make_str.Pre_diff_with_at_most_one_coinbase.Stable.V2` /// -/// Gid: `1017` -/// Location: [src/lib/staged_ledger_diff/diff.ml:187:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L187) +/// Gid: `1031` +/// Location: [src/lib/staged_ledger_diff/diff.ml:187:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L187) /// /// -/// Gid: `1015` -/// Location: [src/lib/staged_ledger_diff/diff.ml:136:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L136) +/// Gid: `1029` +/// Location: [src/lib/staged_ledger_diff/diff.ml:136:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L136) /// Args: TransactionSnarkWorkTStableV2 , StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2B #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2 { - pub completed_works: Vec, - pub commands: Vec, + pub completed_works: List, + pub commands: List, pub coinbase: StagedLedgerDiffDiffPreDiffWithAtMostOneCoinbaseStableV2Coinbase, - pub internal_command_statuses: Vec, + pub internal_command_statuses: List, } /// **OCaml name**: `Staged_ledger_diff__Diff.Make_str.Diff.Stable.V2` /// -/// Gid: `1018` -/// Location: [src/lib/staged_ledger_diff/diff.ml:206:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L206) +/// Gid: `1032` +/// Location: [src/lib/staged_ledger_diff/diff.ml:206:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L206) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct StagedLedgerDiffDiffDiffStableV2( pub StagedLedgerDiffDiffPreDiffWithAtMostTwoCoinbaseStableV2, @@ -2749,8 +2790,8 @@ pub struct StagedLedgerDiffDiffDiffStableV2( /// **OCaml name**: `Staged_ledger_diff__Diff.Make_str.Stable.V2` /// -/// Gid: `1019` -/// Location: [src/lib/staged_ledger_diff/diff.ml:223:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/diff.ml#L223) +/// Gid: `1033` +/// Location: [src/lib/staged_ledger_diff/diff.ml:223:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/diff.ml#L223) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct StagedLedgerDiffDiffStableV2 { pub diff: StagedLedgerDiffDiffDiffStableV2, @@ -2758,28 +2799,17 @@ pub struct StagedLedgerDiffDiffStableV2 { /// **OCaml name**: `Staged_ledger_diff__Body.Make_str.Stable.V1` /// -/// Gid: `1020` -/// Location: [src/lib/staged_ledger_diff/body.ml:18:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/staged_ledger_diff/body.ml#L18) +/// Gid: `1034` +/// Location: [src/lib/staged_ledger_diff/body.ml:18:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/staged_ledger_diff/body.ml#L18) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct StagedLedgerDiffBodyStableV1 { pub staged_ledger_diff: StagedLedgerDiffDiffStableV2, } -/// **OCaml name**: `Protocol_version.Make_str.Stable.V1` -/// -/// Gid: `1062` -/// Location: [src/lib/protocol_version/protocol_version.ml:14:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/protocol_version/protocol_version.ml#L14) -#[derive(Clone, Debug, PartialEq, BinProtRead, BinProtWrite)] -pub struct ProtocolVersionStableV1 { - pub major: crate::number::Int64, - pub minor: crate::number::Int64, - pub patch: crate::number::Int64, -} - /// Derived name: `Snark_worker.Worker.Rpcs_versioned.Get_work.V2.T.response.a.0.single` /// -/// Gid: `1064` -/// Location: [src/lib/snark_work_lib/work.ml:12:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/snark_work_lib/work.ml#L12) +/// Gid: `1038` +/// Location: [src/lib/snark_work_lib/work.ml:12:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/snark_work_lib/work.ml#L12) /// Args: TransactionWitnessStableV2 , LedgerProofProdStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single { @@ -2798,8 +2828,8 @@ pub enum SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single { /// Derived name: `Snark_worker.Worker.Rpcs_versioned.Get_work.V2.T.response.a.0` /// -/// Gid: `1065` -/// Location: [src/lib/snark_work_lib/work.ml:61:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/snark_work_lib/work.ml#L61) +/// Gid: `1039` +/// Location: [src/lib/snark_work_lib/work.ml:61:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/snark_work_lib/work.ml#L61) /// Args: SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0 { @@ -2809,23 +2839,23 @@ pub struct SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0 { /// **OCaml name**: `Parallel_scan.Sequence_number.Stable.V1` /// -/// Gid: `1067` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:22:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L22) +/// Gid: `1041` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:22:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L22) /// /// /// Gid: `163` -/// Location: [src/std_internal.ml:119:2](https://github.com/MinaProtocol/mina/blob/14047c5551/src/std_internal.ml#L119) +/// Location: [src/std_internal.ml:119:2](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/std_internal.ml#L119) /// /// /// Gid: `113` -/// Location: [src/int.ml:19:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/int.ml#L19) +/// Location: [src/int.ml:19:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/int.ml#L19) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite, Deref)] -pub struct ParallelScanSequenceNumberStableV1(pub crate::number::Int64); +pub struct ParallelScanSequenceNumberStableV1(pub crate::number::UInt64); /// **OCaml name**: `Parallel_scan.Job_status.Stable.V1` /// -/// Gid: `1068` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:35:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L35) +/// Gid: `1042` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:35:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L35) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum ParallelScanJobStatusStableV1 { Todo, @@ -2834,18 +2864,18 @@ pub enum ParallelScanJobStatusStableV1 { /// **OCaml name**: `Parallel_scan.Weight.Stable.V1` /// -/// Gid: `1069` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:53:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L53) +/// Gid: `1043` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:53:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L53) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct ParallelScanWeightStableV1 { - pub base: crate::number::Int64, - pub merge: crate::number::Int64, + pub base: crate::number::UInt64, + pub merge: crate::number::UInt64, } /// Derived name: `Transaction_snark_scan_state.Stable.V2.scan_state.trees.a.base_t.1.Full` /// -/// Gid: `1070` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:68:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L68) +/// Gid: `1044` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:68:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L68) /// Args: TransactionSnarkScanStateTransactionWithWitnessStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkScanStateStableV2ScanStateTreesABaseT1Full { @@ -2856,8 +2886,8 @@ pub struct TransactionSnarkScanStateStableV2ScanStateTreesABaseT1Full { /// Derived name: `Transaction_snark_scan_state.Stable.V2.scan_state.trees.a.base_t.1` /// -/// Gid: `1071` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:84:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L84) +/// Gid: `1045` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:84:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L84) /// Args: TransactionSnarkScanStateTransactionWithWitnessStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum TransactionSnarkScanStateStableV2ScanStateTreesABaseT1 { @@ -2867,8 +2897,8 @@ pub enum TransactionSnarkScanStateStableV2ScanStateTreesABaseT1 { /// Derived name: `Transaction_snark_scan_state.Stable.V2.scan_state.trees.a.merge_t.1.Full` /// -/// Gid: `1073` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:112:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L112) +/// Gid: `1047` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:112:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L112) /// Args: TransactionSnarkScanStateLedgerProofWithSokMessageStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1Full { @@ -2880,8 +2910,8 @@ pub struct TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1Full { /// Derived name: `Transaction_snark_scan_state.Stable.V2.scan_state.trees.a.merge_t.1` /// -/// Gid: `1074` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:130:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L130) +/// Gid: `1048` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:130:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L130) /// Args: TransactionSnarkScanStateLedgerProofWithSokMessageStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub enum TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1 { @@ -2892,28 +2922,28 @@ pub enum TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1 { /// Derived name: `Transaction_snark_scan_state.Stable.V2.scan_state` /// -/// Gid: `1081` -/// Location: [src/lib/parallel_scan/parallel_scan.ml:803:8](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/parallel_scan/parallel_scan.ml#L803) +/// Gid: `1055` +/// Location: [src/lib/parallel_scan/parallel_scan.ml:803:8](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/parallel_scan/parallel_scan.ml#L803) /// Args: TransactionSnarkScanStateLedgerProofWithSokMessageStableV2 , TransactionSnarkScanStateTransactionWithWitnessStableV2 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkScanStateStableV2ScanState { pub trees: ( TransactionSnarkScanStateStableV2ScanStateTreesA, - Vec, + List, ), pub acc: Option<( TransactionSnarkScanStateLedgerProofWithSokMessageStableV2, - Vec, + List, )>, - pub curr_job_seq_no: crate::number::Int64, - pub max_base_jobs: crate::number::Int64, - pub delay: crate::number::Int64, + pub curr_job_seq_no: crate::number::UInt64, + pub max_base_jobs: crate::number::UInt64, + pub delay: crate::number::UInt64, } /// **OCaml name**: `Transaction_snark_scan_state.Transaction_with_witness.Stable.V2` /// -/// Gid: `1082` -/// Location: [src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml:40:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml#L40) +/// Gid: `1056` +/// Location: [src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml:40:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml#L40) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkScanStateTransactionWithWitnessStableV2 { pub transaction_with_info: MinaTransactionLogicTransactionAppliedStableV2, @@ -2927,8 +2957,8 @@ pub struct TransactionSnarkScanStateTransactionWithWitnessStableV2 { /// **OCaml name**: `Transaction_snark_scan_state.Ledger_proof_with_sok_message.Stable.V2` /// -/// Gid: `1083` -/// Location: [src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml:65:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml#L65) +/// Gid: `1057` +/// Location: [src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml:65:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/transaction_snark_scan_state/transaction_snark_scan_state.ml#L65) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct TransactionSnarkScanStateLedgerProofWithSokMessageStableV2( pub LedgerProofProdStableV2, @@ -2937,21 +2967,21 @@ pub struct TransactionSnarkScanStateLedgerProofWithSokMessageStableV2( /// **OCaml name**: `Mina_block__Header.Make_str.Stable.V2` /// -/// Gid: `1085` -/// Location: [src/lib/mina_block/header.ml:21:6](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/mina_block/header.ml#L21) +/// Gid: `1101` +/// Location: [src/lib/mina_block/header.ml:21:6](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/mina_block/header.ml#L21) #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct MinaBlockHeaderStableV2 { pub protocol_state: MinaStateProtocolStateValueStableV2, pub protocol_state_proof: MinaBaseProofStableV2, - pub delta_block_chain_proof: (StateHash, Vec), - pub current_protocol_version: ProtocolVersionStableV1, - pub proposed_protocol_version_opt: Option, + pub delta_block_chain_proof: (StateHash, List), + pub current_protocol_version: ProtocolVersionStableV2, + pub proposed_protocol_version_opt: Option, } /// Derived name: `Network_pool__Snark_pool.Diff_versioned.Stable.V2.Add_solved_work.1` /// -/// Gid: `1105` -/// Location: [src/lib/network_pool/priced_proof.ml:9:4](https://github.com/MinaProtocol/mina/blob/14047c5551/src/lib/network_pool/priced_proof.ml#L9) +/// Gid: `1121` +/// Location: [src/lib/network_pool/priced_proof.ml:9:4](https://github.com/MinaProtocol/mina/blob/1551e2faaa/src/lib/network_pool/priced_proof.ml#L9) /// Args: TransactionSnarkWorkTStableV2Proofs #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, BinProtRead, BinProtWrite)] pub struct NetworkPoolSnarkPoolDiffVersionedStableV2AddSolvedWork1 { diff --git a/mina-p2p-messages/src/v2/hashing.rs b/mina-p2p-messages/src/v2/hashing.rs index 4ecffd63d..9c2c8c1ca 100644 --- a/mina-p2p-messages/src/v2/hashing.rs +++ b/mina-p2p-messages/src/v2/hashing.rs @@ -458,15 +458,22 @@ impl ToInput for MinaBaseProtocolConstantsCheckedValueStableV1 { k, slots_per_epoch, slots_per_sub_window, + grace_period_slots: _, delta, genesis_state_timestamp, } = self; - k.to_input(inputs); - delta.to_input(inputs); - slots_per_epoch.to_input(inputs); - slots_per_sub_window.to_input(inputs); - genesis_state_timestamp.to_input(inputs); + to_input_fields!( + inputs, + k, + delta, + slots_per_epoch, + slots_per_sub_window, + // TODO: 2.0.0berkeley_rc1 doesn't include this, but + // that is a bug that will be fixed later. + // grace_period_slots, + genesis_state_timestamp + ); } } @@ -500,7 +507,7 @@ impl ToInput for ConsensusProofOfStakeDataConsensusStateValueStableV2 { sub_window_densities, last_vrf_output, total_currency, - curr_global_slot, + curr_global_slot_since_hard_fork, global_slot_since_genesis, staking_epoch_data, next_epoch_data, @@ -518,7 +525,7 @@ impl ToInput for ConsensusProofOfStakeDataConsensusStateValueStableV2 { sub_window_densities, last_vrf_output, total_currency, - curr_global_slot, + curr_global_slot_since_hard_fork, global_slot_since_genesis, has_ancestor_in_same_checkpoint_window, supercharge_coinbase, diff --git a/mina-p2p-messages/src/v2/hashing/account.rs b/mina-p2p-messages/src/v2/hashing/account.rs index d463ac077..76d0b8141 100644 --- a/mina-p2p-messages/src/v2/hashing/account.rs +++ b/mina-p2p-messages/src/v2/hashing/account.rs @@ -11,12 +11,12 @@ use crate::{ MinaBaseAccountBinableArgStableV2, MinaBaseAccountTimingStableV2, MinaBasePermissionsAuthRequiredStableV2, MinaBasePermissionsStableV2, MinaBaseVerificationKeyWireStableV1, MinaBaseVerificationKeyWireStableV1WrapIndex, - MinaBaseZkappAccountStableV2, MinaBaseZkappAccountZkappUriStableV1, + MinaBaseZkappAccountStableV2, MinaNumbersGlobalSlotSinceGenesisMStableV1, PicklesBaseProofsVerifiedStableV1, }, }; -use super::{hash_noinputs, hash_with_kimchi}; +use super::hash_noinputs; impl ToInput for MinaBaseAccountBinableArgStableV2 { fn to_input(&self, inputs: &mut Inputs) { @@ -93,21 +93,20 @@ impl ToInput for MinaBasePermissionsStableV2 { } = self; to_input_fields!( inputs, - vec![ edit_state, access, send, receive, set_delegate, set_permissions, - set_verification_key, + set_verification_key.0, + set_verification_key.1, set_zkapp_uri, edit_action_state, set_token_symbol, increment_nonce, set_voting_for, set_timing - ] ); } } @@ -168,15 +167,6 @@ impl Default for MinaBaseZkappAccountStableV2 { } } -impl ToInput for MinaBaseZkappAccountZkappUriStableV1 { - fn to_input(&self, inputs: &mut Inputs) { - let mut inputs1 = Inputs::new(); - inputs1.append_bytes(self.as_ref()); - inputs1.append_bool(true); - inputs.append_field(hash_with_kimchi("MinaZkappUri", &inputs1.to_fields())); - } -} - impl ToInput for MinaBasePermissionsAuthRequiredStableV2 { fn to_input(&self, inputs: &mut Inputs) { use MinaBasePermissionsAuthRequiredStableV2::*; diff --git a/mina-p2p-messages/src/v2/manual.rs b/mina-p2p-messages/src/v2/manual.rs index 5b40b89ce..5d7ccc9d9 100644 --- a/mina-p2p-messages/src/v2/manual.rs +++ b/mina-p2p-messages/src/v2/manual.rs @@ -17,7 +17,7 @@ use super::{ MinaBaseStateBodyHashStableV1, NonZeroCurvePointUncompressedStableV1, ParallelScanWeightStableV1, PicklesProofProofsVerified2ReprStableV2, PicklesProofProofsVerified2ReprStableV2StatementFp, PicklesProofProofsVerifiedMaxStableV2, - ProtocolVersionStableV1, SgnStableV1, TransactionSnarkScanStateStableV2ScanStateTreesABaseT1, + ProtocolVersionStableV2, SgnStableV1, TransactionSnarkScanStateStableV2ScanStateTreesABaseT1, TransactionSnarkScanStateStableV2ScanStateTreesAMergeT1, }; @@ -531,14 +531,14 @@ impl<'de> Deserialize<'de> for ConsensusVrfOutputTruncatedStableV1 { mod serde_protocol_ver { #[derive(serde::Serialize, serde::Deserialize)] - pub struct ProtocolVersionStableV1 { - pub major: crate::number::Int64, - pub minor: crate::number::Int64, - pub patch: crate::number::Int64, + pub struct ProtocolVersionStableV2 { + pub transaction: crate::number::UInt64, + pub network: crate::number::UInt64, + pub patch: crate::number::UInt64, } } -impl<'de> Deserialize<'de> for ProtocolVersionStableV1 { +impl<'de> Deserialize<'de> for ProtocolVersionStableV2 { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, @@ -549,44 +549,44 @@ impl<'de> Deserialize<'de> for ProtocolVersionStableV1 { let err = || serde::de::Error::custom(format!("incorrect protocol version '{}'", s)); let parse_number = - |s: Option<&str>| s.and_then(|s| s.parse::().ok()).ok_or_else(err); + |s: Option<&str>| s.and_then(|s| s.parse::().ok()).ok_or_else(err); let mut versions = s.split('.'); - let major = parse_number(versions.next())?.into(); - let minor = parse_number(versions.next())?.into(); + let transaction = parse_number(versions.next())?.into(); + let network = parse_number(versions.next())?.into(); let patch = parse_number(versions.next())?.into(); if versions.next().is_some() { - return Err(err()); // We expect the format "major.minor.patch" + return Err(err()); // We expect the format "transaction.network.patch" } Ok(Self { - major, - minor, + transaction, + network, patch, }) } else { - serde_protocol_ver::ProtocolVersionStableV1::deserialize(deserializer).map(|s| Self { - major: s.major, - minor: s.minor, + serde_protocol_ver::ProtocolVersionStableV2::deserialize(deserializer).map(|s| Self { + transaction: s.transaction, + network: s.network, patch: s.patch, }) } } } -impl Serialize for ProtocolVersionStableV1 { +impl Serialize for ProtocolVersionStableV2 { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer, { if serializer.is_human_readable() { - let s = format!("{}.{}.{}", *self.major, *self.minor, *self.patch); + let s = format!("{}.{}.{}", *self.transaction, *self.network, *self.patch); s.serialize(serializer) } else { - let s = serde_protocol_ver::ProtocolVersionStableV1 { - major: self.major, - minor: self.minor, + let s = serde_protocol_ver::ProtocolVersionStableV2 { + transaction: self.transaction, + network: self.network, patch: self.patch, }; s.serialize(serializer) @@ -605,7 +605,7 @@ pub enum MerkleTreeNode { impl ConsensusProofOfStakeDataConsensusStateValueStableV2 { pub fn global_slot(&self) -> u32 { - match &self.curr_global_slot.slot_number { + match &self.curr_global_slot_since_hard_fork.slot_number { super::MinaNumbersGlobalSlotSinceHardForkMStableV1::SinceHardFork(s) => s.as_u32(), } } diff --git a/node/Cargo.toml b/node/Cargo.toml index 01416ee3b..977cb2ea6 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "node" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/node/invariants/Cargo.toml b/node/invariants/Cargo.toml index c2a9286ef..4a2bc9b5a 100644 --- a/node/invariants/Cargo.toml +++ b/node/invariants/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmina-node-invariants" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/node/native/Cargo.toml b/node/native/Cargo.toml index 7f98d5264..6ecef871a 100644 --- a/node/native/Cargo.toml +++ b/node/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmina-node-native" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/node/src/action.rs b/node/src/action.rs index 290cdb39b..d482813d3 100644 --- a/node/src/action.rs +++ b/node/src/action.rs @@ -49,18 +49,6 @@ pub struct CheckTimeoutsAction {} impl redux::EnablingCondition for CheckTimeoutsAction {} -macro_rules! impl_into_global_action { - ($selector:ident : $($action:ty),* $(,)?) => { - $( - impl From<$action> for crate::Action { - fn from(value: $action) -> Self { - Self::$selector(value.into()) - } - } - )* - }; -} - #[cfg(feature = "replay")] impl redux::EnablingCondition for Action { fn is_enabled(&self, _: &crate::State) -> bool { diff --git a/node/src/action_kind.rs b/node/src/action_kind.rs index 130a6f3aa..c0998c426 100644 --- a/node/src/action_kind.rs +++ b/node/src/action_kind.rs @@ -14,150 +14,36 @@ use num_enum::TryFromPrimitive; use serde::{Deserialize, Serialize}; -use crate::block_producer::vrf_evaluator::{ - BlockProducerVrfEvaluatorAction, BlockProducerVrfEvaluatorEpochDataUpdateAction, - BlockProducerVrfEvaluatorEvaluateVrfAction, BlockProducerVrfEvaluatorEvaluationSuccessAction, - BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction, - BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction, -}; -use crate::block_producer::{ - BlockProducerAction, BlockProducerBestTipUpdateAction, BlockProducerBlockInjectAction, - BlockProducerBlockInjectedAction, BlockProducerBlockProducedAction, - BlockProducerBlockUnprovenBuildAction, BlockProducerStagedLedgerDiffCreateInitAction, - BlockProducerStagedLedgerDiffCreatePendingAction, - BlockProducerStagedLedgerDiffCreateSuccessAction, BlockProducerWonSlotAction, - BlockProducerWonSlotDiscardAction, BlockProducerWonSlotProduceInitAction, - BlockProducerWonSlotSearchAction, BlockProducerWonSlotWaitAction, -}; +use crate::block_producer::vrf_evaluator::BlockProducerVrfEvaluatorAction; +use crate::block_producer::BlockProducerAction; use crate::consensus::ConsensusAction; -use crate::event_source::{ - EventSourceAction, EventSourceNewEventAction, EventSourceProcessEventsAction, - EventSourceWaitForEventsAction, EventSourceWaitTimeoutAction, -}; +use crate::event_source::EventSourceAction; use crate::external_snark_worker::ExternalSnarkWorkerAction; use crate::p2p::channels::best_tip::P2pChannelsBestTipAction; use crate::p2p::channels::rpc::P2pChannelsRpcAction; use crate::p2p::channels::snark::P2pChannelsSnarkAction; use crate::p2p::channels::snark_job_commitment::P2pChannelsSnarkJobCommitmentAction; use crate::p2p::channels::{P2pChannelsAction, P2pChannelsMessageReceivedAction}; -use crate::p2p::connection::incoming::{ - P2pConnectionIncomingAction, P2pConnectionIncomingAnswerReadyAction, - P2pConnectionIncomingAnswerSdpCreateErrorAction, - P2pConnectionIncomingAnswerSdpCreatePendingAction, - P2pConnectionIncomingAnswerSdpCreateSuccessAction, - P2pConnectionIncomingAnswerSendSuccessAction, P2pConnectionIncomingErrorAction, - P2pConnectionIncomingFinalizeErrorAction, P2pConnectionIncomingFinalizePendingAction, - P2pConnectionIncomingFinalizeSuccessAction, P2pConnectionIncomingInitAction, - P2pConnectionIncomingLibp2pReceivedAction, P2pConnectionIncomingSuccessAction, - P2pConnectionIncomingTimeoutAction, -}; -use crate::p2p::connection::outgoing::{ - P2pConnectionOutgoingAction, P2pConnectionOutgoingAnswerRecvErrorAction, - P2pConnectionOutgoingAnswerRecvPendingAction, P2pConnectionOutgoingAnswerRecvSuccessAction, - P2pConnectionOutgoingErrorAction, P2pConnectionOutgoingFinalizeErrorAction, - P2pConnectionOutgoingFinalizePendingAction, P2pConnectionOutgoingFinalizeSuccessAction, - P2pConnectionOutgoingInitAction, P2pConnectionOutgoingOfferReadyAction, - P2pConnectionOutgoingOfferSdpCreateErrorAction, - P2pConnectionOutgoingOfferSdpCreatePendingAction, - P2pConnectionOutgoingOfferSdpCreateSuccessAction, P2pConnectionOutgoingOfferSendSuccessAction, - P2pConnectionOutgoingRandomInitAction, P2pConnectionOutgoingReconnectAction, - P2pConnectionOutgoingSuccessAction, P2pConnectionOutgoingTimeoutAction, -}; +use crate::p2p::connection::incoming::P2pConnectionIncomingAction; +use crate::p2p::connection::outgoing::P2pConnectionOutgoingAction; use crate::p2p::connection::P2pConnectionAction; -use crate::p2p::disconnection::{ - P2pDisconnectionAction, P2pDisconnectionFinishAction, P2pDisconnectionInitAction, -}; -use crate::p2p::discovery::{ - P2pDiscoveryAction, P2pDiscoveryInitAction, P2pDiscoveryKademliaAddRouteAction, - P2pDiscoveryKademliaBootstrapAction, P2pDiscoveryKademliaFailureAction, - P2pDiscoveryKademliaInitAction, P2pDiscoveryKademliaSuccessAction, P2pDiscoverySuccessAction, -}; -use crate::p2p::listen::{ - P2pListenAction, P2pListenClosedAction, P2pListenErrorAction, P2pListenExpiredAction, - P2pListenNewAction, -}; -use crate::p2p::peer::{P2pPeerAction, P2pPeerBestTipUpdateAction, P2pPeerReadyAction}; +use crate::p2p::disconnection::P2pDisconnectionAction; +use crate::p2p::discovery::P2pDiscoveryAction; +use crate::p2p::listen::P2pListenAction; +use crate::p2p::peer::P2pPeerAction; use crate::p2p::P2pAction; -use crate::rpc::{ - RpcAction, RpcActionStatsGetAction, RpcFinishAction, RpcGlobalStateGetAction, - RpcHealthCheckAction, RpcP2pConnectionIncomingErrorAction, RpcP2pConnectionIncomingInitAction, - RpcP2pConnectionIncomingPendingAction, RpcP2pConnectionIncomingRespondAction, - RpcP2pConnectionIncomingSuccessAction, RpcP2pConnectionOutgoingErrorAction, - RpcP2pConnectionOutgoingInitAction, RpcP2pConnectionOutgoingPendingAction, - RpcP2pConnectionOutgoingSuccessAction, RpcPeersGetAction, RpcReadinessCheckAction, - RpcScanStateSummaryGetAction, RpcSnarkPoolAvailableJobsGetAction, RpcSnarkPoolJobGetAction, - RpcSnarkerConfigGetAction, RpcSnarkerJobCommitAction, RpcSnarkerJobSpecAction, - RpcSnarkersWorkersGetAction, RpcSyncStatsGetAction, -}; +use crate::rpc::RpcAction; use crate::snark::block_verify::SnarkBlockVerifyAction; use crate::snark::work_verify::SnarkWorkVerifyAction; use crate::snark::SnarkAction; use crate::snark_pool::candidate::SnarkPoolCandidateAction; use crate::snark_pool::SnarkPoolAction; -use crate::transition_frontier::sync::ledger::snarked::{ - TransitionFrontierSyncLedgerSnarkedAction, - TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction, - TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction, - TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction, - TransitionFrontierSyncLedgerSnarkedPeersQueryAction, - TransitionFrontierSyncLedgerSnarkedPendingAction, - TransitionFrontierSyncLedgerSnarkedSuccessAction, -}; -use crate::transition_frontier::sync::ledger::staged::{ - TransitionFrontierSyncLedgerStagedAction, - TransitionFrontierSyncLedgerStagedPartsFetchPendingAction, - TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction, - TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction, - TransitionFrontierSyncLedgerStagedPartsPeerValidAction, - TransitionFrontierSyncLedgerStagedReconstructEmptyAction, - TransitionFrontierSyncLedgerStagedReconstructErrorAction, - TransitionFrontierSyncLedgerStagedReconstructInitAction, - TransitionFrontierSyncLedgerStagedReconstructPendingAction, - TransitionFrontierSyncLedgerStagedReconstructSuccessAction, - TransitionFrontierSyncLedgerStagedSuccessAction, -}; -use crate::transition_frontier::sync::ledger::{ - TransitionFrontierSyncLedgerAction, TransitionFrontierSyncLedgerInitAction, - TransitionFrontierSyncLedgerSuccessAction, -}; -use crate::transition_frontier::sync::{ - TransitionFrontierSyncAction, TransitionFrontierSyncBestTipUpdateAction, - TransitionFrontierSyncBlocksFetchSuccessAction, - TransitionFrontierSyncBlocksNextApplyInitAction, - TransitionFrontierSyncBlocksNextApplyPendingAction, - TransitionFrontierSyncBlocksNextApplySuccessAction, - TransitionFrontierSyncBlocksPeerQueryErrorAction, - TransitionFrontierSyncBlocksPeerQueryInitAction, - TransitionFrontierSyncBlocksPeerQueryPendingAction, - TransitionFrontierSyncBlocksPeerQueryRetryAction, - TransitionFrontierSyncBlocksPeerQuerySuccessAction, - TransitionFrontierSyncBlocksPeersQueryAction, TransitionFrontierSyncBlocksPendingAction, - TransitionFrontierSyncBlocksSuccessAction, TransitionFrontierSyncInitAction, - TransitionFrontierSyncLedgerNextEpochPendingAction, - TransitionFrontierSyncLedgerNextEpochSuccessAction, - TransitionFrontierSyncLedgerRootPendingAction, TransitionFrontierSyncLedgerRootSuccessAction, - TransitionFrontierSyncLedgerStakingPendingAction, - TransitionFrontierSyncLedgerStakingSuccessAction, -}; +use crate::transition_frontier::sync::ledger::snarked::TransitionFrontierSyncLedgerSnarkedAction; +use crate::transition_frontier::sync::ledger::staged::TransitionFrontierSyncLedgerStagedAction; +use crate::transition_frontier::sync::ledger::TransitionFrontierSyncLedgerAction; +use crate::transition_frontier::sync::TransitionFrontierSyncAction; use crate::transition_frontier::{TransitionFrontierAction, TransitionFrontierSyncedAction}; -use crate::watched_accounts::{ - WatchedAccountsAction, WatchedAccountsAddAction, WatchedAccountsBlockLedgerQueryInitAction, - WatchedAccountsBlockLedgerQueryPendingAction, WatchedAccountsBlockLedgerQuerySuccessAction, - WatchedAccountsBlockTransactionsIncludedAction, - WatchedAccountsLedgerInitialStateGetErrorAction, - WatchedAccountsLedgerInitialStateGetInitAction, - WatchedAccountsLedgerInitialStateGetPendingAction, - WatchedAccountsLedgerInitialStateGetRetryAction, - WatchedAccountsLedgerInitialStateGetSuccessAction, -}; +use crate::watched_accounts::WatchedAccountsAction; use crate::{Action, ActionKindGet, CheckTimeoutsAction}; /// Unified kind enum for all action types @@ -175,16 +61,16 @@ pub enum ActionKind { BlockProducerStagedLedgerDiffCreateInit, BlockProducerStagedLedgerDiffCreatePending, BlockProducerStagedLedgerDiffCreateSuccess, - BlockProducerVrfEvaluatorEpochDataUpdate, - BlockProducerVrfEvaluatorEvaluateVrf, - BlockProducerVrfEvaluatorEvaluationSuccess, - BlockProducerVrfEvaluatorUpdateProducerAndDelegates, - BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccess, BlockProducerWonSlot, BlockProducerWonSlotDiscard, BlockProducerWonSlotProduceInit, BlockProducerWonSlotSearch, BlockProducerWonSlotWait, + BlockProducerVrfEvaluatorEpochDataUpdate, + BlockProducerVrfEvaluatorEvaluateVrf, + BlockProducerVrfEvaluatorEvaluationSuccess, + BlockProducerVrfEvaluatorUpdateProducerAndDelegates, + BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccess, CheckTimeouts, ConsensusBestTipUpdate, ConsensusBlockChainProofUpdate, @@ -312,7 +198,7 @@ pub enum ActionKind { RpcSnarkerConfigGet, RpcSnarkerJobCommit, RpcSnarkerJobSpec, - RpcSnarkersWorkersGet, + RpcSnarkerWorkersGet, RpcSyncStatsGet, SnarkBlockVerifyError, SnarkBlockVerifyFinish, @@ -357,11 +243,14 @@ pub enum ActionKind { TransitionFrontierSyncBlocksPending, TransitionFrontierSyncBlocksSuccess, TransitionFrontierSyncInit, - TransitionFrontierSyncLedgerInit, TransitionFrontierSyncLedgerNextEpochPending, TransitionFrontierSyncLedgerNextEpochSuccess, TransitionFrontierSyncLedgerRootPending, TransitionFrontierSyncLedgerRootSuccess, + TransitionFrontierSyncLedgerStakingPending, + TransitionFrontierSyncLedgerStakingSuccess, + TransitionFrontierSyncLedgerInit, + TransitionFrontierSyncLedgerSuccess, TransitionFrontierSyncLedgerSnarkedChildAccountsReceived, TransitionFrontierSyncLedgerSnarkedChildHashesReceived, TransitionFrontierSyncLedgerSnarkedPeerQueryError, @@ -386,20 +275,17 @@ pub enum ActionKind { TransitionFrontierSyncLedgerStagedReconstructPending, TransitionFrontierSyncLedgerStagedReconstructSuccess, TransitionFrontierSyncLedgerStagedSuccess, - TransitionFrontierSyncLedgerStakingPending, - TransitionFrontierSyncLedgerStakingSuccess, - TransitionFrontierSyncLedgerSuccess, TransitionFrontierSynced, WatchedAccountsAdd, WatchedAccountsBlockLedgerQueryInit, WatchedAccountsBlockLedgerQueryPending, WatchedAccountsBlockLedgerQuerySuccess, - WatchedAccountsBlockTransactionsIncluded, WatchedAccountsLedgerInitialStateGetError, WatchedAccountsLedgerInitialStateGetInit, WatchedAccountsLedgerInitialStateGetPending, WatchedAccountsLedgerInitialStateGetRetry, WatchedAccountsLedgerInitialStateGetSuccess, + WatchedAccountsTransactionsIncludedInBlock, } impl ActionKind { @@ -439,10 +325,10 @@ impl ActionKindGet for CheckTimeoutsAction { impl ActionKindGet for EventSourceAction { fn kind(&self) -> ActionKind { match self { - Self::ProcessEvents(a) => a.kind(), - Self::NewEvent(a) => a.kind(), - Self::WaitForEvents(a) => a.kind(), - Self::WaitTimeout(a) => a.kind(), + Self::ProcessEvents => ActionKind::EventSourceProcessEvents, + Self::NewEvent { .. } => ActionKind::EventSourceNewEvent, + Self::WaitForEvents => ActionKind::EventSourceWaitForEvents, + Self::WaitTimeout => ActionKind::EventSourceWaitTimeout, } } } @@ -535,19 +421,23 @@ impl ActionKindGet for BlockProducerAction { fn kind(&self) -> ActionKind { match self { Self::VrfEvaluator(a) => a.kind(), - Self::BestTipUpdate(a) => a.kind(), - Self::WonSlotSearch(a) => a.kind(), - Self::WonSlot(a) => a.kind(), - Self::WonSlotDiscard(a) => a.kind(), - Self::WonSlotWait(a) => a.kind(), - Self::WonSlotProduceInit(a) => a.kind(), - Self::StagedLedgerDiffCreateInit(a) => a.kind(), - Self::StagedLedgerDiffCreatePending(a) => a.kind(), - Self::StagedLedgerDiffCreateSuccess(a) => a.kind(), - Self::BlockUnprovenBuild(a) => a.kind(), - Self::BlockProduced(a) => a.kind(), - Self::BlockInject(a) => a.kind(), - Self::BlockInjected(a) => a.kind(), + Self::BestTipUpdate { .. } => ActionKind::BlockProducerBestTipUpdate, + Self::WonSlotSearch => ActionKind::BlockProducerWonSlotSearch, + Self::WonSlot { .. } => ActionKind::BlockProducerWonSlot, + Self::WonSlotDiscard { .. } => ActionKind::BlockProducerWonSlotDiscard, + Self::WonSlotWait => ActionKind::BlockProducerWonSlotWait, + Self::WonSlotProduceInit => ActionKind::BlockProducerWonSlotProduceInit, + Self::StagedLedgerDiffCreateInit => ActionKind::BlockProducerStagedLedgerDiffCreateInit, + Self::StagedLedgerDiffCreatePending => { + ActionKind::BlockProducerStagedLedgerDiffCreatePending + } + Self::StagedLedgerDiffCreateSuccess { .. } => { + ActionKind::BlockProducerStagedLedgerDiffCreateSuccess + } + Self::BlockUnprovenBuild => ActionKind::BlockProducerBlockUnprovenBuild, + Self::BlockProduced => ActionKind::BlockProducerBlockProduced, + Self::BlockInject => ActionKind::BlockProducerBlockInject, + Self::BlockInjected => ActionKind::BlockProducerBlockInjected, } } } @@ -555,29 +445,39 @@ impl ActionKindGet for BlockProducerAction { impl ActionKindGet for RpcAction { fn kind(&self) -> ActionKind { match self { - Self::GlobalStateGet(a) => a.kind(), - Self::ActionStatsGet(a) => a.kind(), - Self::SyncStatsGet(a) => a.kind(), - Self::PeersGet(a) => a.kind(), - Self::P2pConnectionOutgoingInit(a) => a.kind(), - Self::P2pConnectionOutgoingPending(a) => a.kind(), - Self::P2pConnectionOutgoingError(a) => a.kind(), - Self::P2pConnectionOutgoingSuccess(a) => a.kind(), - Self::P2pConnectionIncomingInit(a) => a.kind(), - Self::P2pConnectionIncomingPending(a) => a.kind(), - Self::P2pConnectionIncomingRespond(a) => a.kind(), - Self::P2pConnectionIncomingError(a) => a.kind(), - Self::P2pConnectionIncomingSuccess(a) => a.kind(), - Self::ScanStateSummaryGet(a) => a.kind(), - Self::SnarkPoolAvailableJobsGet(a) => a.kind(), - Self::SnarkPoolJobGet(a) => a.kind(), - Self::SnarkerConfigGet(a) => a.kind(), - Self::SnarkerJobCommit(a) => a.kind(), - Self::SnarkerJobSpec(a) => a.kind(), - Self::SnarkerWorkersGet(a) => a.kind(), - Self::HealthCheck(a) => a.kind(), - Self::ReadinessCheck(a) => a.kind(), - Self::Finish(a) => a.kind(), + Self::GlobalStateGet { .. } => ActionKind::RpcGlobalStateGet, + Self::ActionStatsGet { .. } => ActionKind::RpcActionStatsGet, + Self::SyncStatsGet { .. } => ActionKind::RpcSyncStatsGet, + Self::PeersGet { .. } => ActionKind::RpcPeersGet, + Self::P2pConnectionOutgoingInit { .. } => ActionKind::RpcP2pConnectionOutgoingInit, + Self::P2pConnectionOutgoingPending { .. } => { + ActionKind::RpcP2pConnectionOutgoingPending + } + Self::P2pConnectionOutgoingError { .. } => ActionKind::RpcP2pConnectionOutgoingError, + Self::P2pConnectionOutgoingSuccess { .. } => { + ActionKind::RpcP2pConnectionOutgoingSuccess + } + Self::P2pConnectionIncomingInit { .. } => ActionKind::RpcP2pConnectionIncomingInit, + Self::P2pConnectionIncomingPending { .. } => { + ActionKind::RpcP2pConnectionIncomingPending + } + Self::P2pConnectionIncomingRespond { .. } => { + ActionKind::RpcP2pConnectionIncomingRespond + } + Self::P2pConnectionIncomingError { .. } => ActionKind::RpcP2pConnectionIncomingError, + Self::P2pConnectionIncomingSuccess { .. } => { + ActionKind::RpcP2pConnectionIncomingSuccess + } + Self::ScanStateSummaryGet { .. } => ActionKind::RpcScanStateSummaryGet, + Self::SnarkPoolAvailableJobsGet { .. } => ActionKind::RpcSnarkPoolAvailableJobsGet, + Self::SnarkPoolJobGet { .. } => ActionKind::RpcSnarkPoolJobGet, + Self::SnarkerConfigGet { .. } => ActionKind::RpcSnarkerConfigGet, + Self::SnarkerJobCommit { .. } => ActionKind::RpcSnarkerJobCommit, + Self::SnarkerJobSpec { .. } => ActionKind::RpcSnarkerJobSpec, + Self::SnarkerWorkersGet { .. } => ActionKind::RpcSnarkerWorkersGet, + Self::HealthCheck { .. } => ActionKind::RpcHealthCheck, + Self::ReadinessCheck { .. } => ActionKind::RpcReadinessCheck, + Self::Finish { .. } => ActionKind::RpcFinish, } } } @@ -585,51 +485,43 @@ impl ActionKindGet for RpcAction { impl ActionKindGet for WatchedAccountsAction { fn kind(&self) -> ActionKind { match self { - Self::Add(a) => a.kind(), - Self::LedgerInitialStateGetInit(a) => a.kind(), - Self::LedgerInitialStateGetPending(a) => a.kind(), - Self::LedgerInitialStateGetError(a) => a.kind(), - Self::LedgerInitialStateGetRetry(a) => a.kind(), - Self::LedgerInitialStateGetSuccess(a) => a.kind(), - Self::TransactionsIncludedInBlock(a) => a.kind(), - Self::BlockLedgerQueryInit(a) => a.kind(), - Self::BlockLedgerQueryPending(a) => a.kind(), - Self::BlockLedgerQuerySuccess(a) => a.kind(), + Self::Add { .. } => ActionKind::WatchedAccountsAdd, + Self::LedgerInitialStateGetInit { .. } => { + ActionKind::WatchedAccountsLedgerInitialStateGetInit + } + Self::LedgerInitialStateGetPending { .. } => { + ActionKind::WatchedAccountsLedgerInitialStateGetPending + } + Self::LedgerInitialStateGetError { .. } => { + ActionKind::WatchedAccountsLedgerInitialStateGetError + } + Self::LedgerInitialStateGetRetry { .. } => { + ActionKind::WatchedAccountsLedgerInitialStateGetRetry + } + Self::LedgerInitialStateGetSuccess { .. } => { + ActionKind::WatchedAccountsLedgerInitialStateGetSuccess + } + Self::TransactionsIncludedInBlock { .. } => { + ActionKind::WatchedAccountsTransactionsIncludedInBlock + } + Self::BlockLedgerQueryInit { .. } => ActionKind::WatchedAccountsBlockLedgerQueryInit, + Self::BlockLedgerQueryPending { .. } => { + ActionKind::WatchedAccountsBlockLedgerQueryPending + } + Self::BlockLedgerQuerySuccess { .. } => { + ActionKind::WatchedAccountsBlockLedgerQuerySuccess + } } } } -impl ActionKindGet for EventSourceProcessEventsAction { - fn kind(&self) -> ActionKind { - ActionKind::EventSourceProcessEvents - } -} - -impl ActionKindGet for EventSourceNewEventAction { - fn kind(&self) -> ActionKind { - ActionKind::EventSourceNewEvent - } -} - -impl ActionKindGet for EventSourceWaitForEventsAction { - fn kind(&self) -> ActionKind { - ActionKind::EventSourceWaitForEvents - } -} - -impl ActionKindGet for EventSourceWaitTimeoutAction { - fn kind(&self) -> ActionKind { - ActionKind::EventSourceWaitTimeout - } -} - impl ActionKindGet for P2pListenAction { fn kind(&self) -> ActionKind { match self { - Self::New(a) => a.kind(), - Self::Expired(a) => a.kind(), - Self::Error(a) => a.kind(), - Self::Closed(a) => a.kind(), + Self::New { .. } => ActionKind::P2pListenNew, + Self::Expired { .. } => ActionKind::P2pListenExpired, + Self::Error { .. } => ActionKind::P2pListenError, + Self::Closed { .. } => ActionKind::P2pListenClosed, } } } @@ -646,8 +538,8 @@ impl ActionKindGet for P2pConnectionAction { impl ActionKindGet for P2pDisconnectionAction { fn kind(&self) -> ActionKind { match self { - Self::Init(a) => a.kind(), - Self::Finish(a) => a.kind(), + Self::Init { .. } => ActionKind::P2pDisconnectionInit, + Self::Finish { .. } => ActionKind::P2pDisconnectionFinish, } } } @@ -655,13 +547,13 @@ impl ActionKindGet for P2pDisconnectionAction { impl ActionKindGet for P2pDiscoveryAction { fn kind(&self) -> ActionKind { match self { - Self::Init(a) => a.kind(), - Self::Success(a) => a.kind(), - Self::KademliaBootstrap(a) => a.kind(), - Self::KademliaInit(a) => a.kind(), - Self::KademliaAddRoute(a) => a.kind(), - Self::KademliaSuccess(a) => a.kind(), - Self::KademliaFailure(a) => a.kind(), + Self::Init { .. } => ActionKind::P2pDiscoveryInit, + Self::Success { .. } => ActionKind::P2pDiscoverySuccess, + Self::KademliaBootstrap => ActionKind::P2pDiscoveryKademliaBootstrap, + Self::KademliaInit => ActionKind::P2pDiscoveryKademliaInit, + Self::KademliaAddRoute { .. } => ActionKind::P2pDiscoveryKademliaAddRoute, + Self::KademliaSuccess { .. } => ActionKind::P2pDiscoveryKademliaSuccess, + Self::KademliaFailure { .. } => ActionKind::P2pDiscoveryKademliaFailure, } } } @@ -681,8 +573,8 @@ impl ActionKindGet for P2pChannelsAction { impl ActionKindGet for P2pPeerAction { fn kind(&self) -> ActionKind { match self { - Self::Ready(a) => a.kind(), - Self::BestTipUpdate(a) => a.kind(), + Self::Ready { .. } => ActionKind::P2pPeerReady, + Self::BestTipUpdate { .. } => ActionKind::P2pPeerBestTipUpdate, } } } @@ -714,27 +606,45 @@ impl ActionKindGet for SnarkWorkVerifyAction { impl ActionKindGet for TransitionFrontierSyncAction { fn kind(&self) -> ActionKind { match self { - Self::Init(a) => a.kind(), - Self::BestTipUpdate(a) => a.kind(), - Self::LedgerStakingPending(a) => a.kind(), - Self::LedgerStakingSuccess(a) => a.kind(), - Self::LedgerNextEpochPending(a) => a.kind(), - Self::LedgerNextEpochSuccess(a) => a.kind(), - Self::LedgerRootPending(a) => a.kind(), - Self::LedgerRootSuccess(a) => a.kind(), - Self::BlocksPending(a) => a.kind(), - Self::BlocksPeersQuery(a) => a.kind(), - Self::BlocksPeerQueryInit(a) => a.kind(), - Self::BlocksPeerQueryRetry(a) => a.kind(), - Self::BlocksPeerQueryPending(a) => a.kind(), - Self::BlocksPeerQueryError(a) => a.kind(), - Self::BlocksPeerQuerySuccess(a) => a.kind(), - Self::BlocksFetchSuccess(a) => a.kind(), - Self::BlocksNextApplyInit(a) => a.kind(), - Self::BlocksNextApplyPending(a) => a.kind(), - Self::BlocksNextApplySuccess(a) => a.kind(), - Self::BlocksSuccess(a) => a.kind(), Self::Ledger(a) => a.kind(), + Self::Init { .. } => ActionKind::TransitionFrontierSyncInit, + Self::BestTipUpdate { .. } => ActionKind::TransitionFrontierSyncBestTipUpdate, + Self::LedgerStakingPending => ActionKind::TransitionFrontierSyncLedgerStakingPending, + Self::LedgerStakingSuccess => ActionKind::TransitionFrontierSyncLedgerStakingSuccess, + Self::LedgerNextEpochPending => { + ActionKind::TransitionFrontierSyncLedgerNextEpochPending + } + Self::LedgerNextEpochSuccess => { + ActionKind::TransitionFrontierSyncLedgerNextEpochSuccess + } + Self::LedgerRootPending => ActionKind::TransitionFrontierSyncLedgerRootPending, + Self::LedgerRootSuccess => ActionKind::TransitionFrontierSyncLedgerRootSuccess, + Self::BlocksPending => ActionKind::TransitionFrontierSyncBlocksPending, + Self::BlocksPeersQuery => ActionKind::TransitionFrontierSyncBlocksPeersQuery, + Self::BlocksPeerQueryInit { .. } => { + ActionKind::TransitionFrontierSyncBlocksPeerQueryInit + } + Self::BlocksPeerQueryRetry { .. } => { + ActionKind::TransitionFrontierSyncBlocksPeerQueryRetry + } + Self::BlocksPeerQueryPending { .. } => { + ActionKind::TransitionFrontierSyncBlocksPeerQueryPending + } + Self::BlocksPeerQueryError { .. } => { + ActionKind::TransitionFrontierSyncBlocksPeerQueryError + } + Self::BlocksPeerQuerySuccess { .. } => { + ActionKind::TransitionFrontierSyncBlocksPeerQuerySuccess + } + Self::BlocksFetchSuccess { .. } => ActionKind::TransitionFrontierSyncBlocksFetchSuccess, + Self::BlocksNextApplyInit => ActionKind::TransitionFrontierSyncBlocksNextApplyInit, + Self::BlocksNextApplyPending { .. } => { + ActionKind::TransitionFrontierSyncBlocksNextApplyPending + } + Self::BlocksNextApplySuccess { .. } => { + ActionKind::TransitionFrontierSyncBlocksNextApplySuccess + } + Self::BlocksSuccess => ActionKind::TransitionFrontierSyncBlocksSuccess, } } } @@ -765,1027 +675,231 @@ impl ActionKindGet for SnarkPoolCandidateAction { impl ActionKindGet for BlockProducerVrfEvaluatorAction { fn kind(&self) -> ActionKind { match self { - Self::EpochDataUpdate(a) => a.kind(), - Self::EvaluateVrf(a) => a.kind(), - Self::EvaluationSuccess(a) => a.kind(), - Self::UpdateProducerAndDelegates(a) => a.kind(), - Self::UpdateProducerAndDelegatesSuccess(a) => a.kind(), + Self::EpochDataUpdate { .. } => ActionKind::BlockProducerVrfEvaluatorEpochDataUpdate, + Self::EvaluateVrf { .. } => ActionKind::BlockProducerVrfEvaluatorEvaluateVrf, + Self::EvaluationSuccess { .. } => { + ActionKind::BlockProducerVrfEvaluatorEvaluationSuccess + } + Self::UpdateProducerAndDelegates { .. } => { + ActionKind::BlockProducerVrfEvaluatorUpdateProducerAndDelegates + } + Self::UpdateProducerAndDelegatesSuccess { .. } => { + ActionKind::BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccess + } } } } -impl ActionKindGet for BlockProducerBestTipUpdateAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerBestTipUpdate - } -} - -impl ActionKindGet for BlockProducerWonSlotSearchAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerWonSlotSearch - } -} - -impl ActionKindGet for BlockProducerWonSlotAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerWonSlot - } -} - -impl ActionKindGet for BlockProducerWonSlotDiscardAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerWonSlotDiscard - } -} - -impl ActionKindGet for BlockProducerWonSlotWaitAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerWonSlotWait - } -} - -impl ActionKindGet for BlockProducerWonSlotProduceInitAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerWonSlotProduceInit - } -} - -impl ActionKindGet for BlockProducerStagedLedgerDiffCreateInitAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerStagedLedgerDiffCreateInit - } -} - -impl ActionKindGet for BlockProducerStagedLedgerDiffCreatePendingAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerStagedLedgerDiffCreatePending - } -} - -impl ActionKindGet for BlockProducerStagedLedgerDiffCreateSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerStagedLedgerDiffCreateSuccess - } -} - -impl ActionKindGet for BlockProducerBlockUnprovenBuildAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerBlockUnprovenBuild - } -} - -impl ActionKindGet for BlockProducerBlockProducedAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerBlockProduced - } -} - -impl ActionKindGet for BlockProducerBlockInjectAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerBlockInject - } -} - -impl ActionKindGet for BlockProducerBlockInjectedAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerBlockInjected - } -} - -impl ActionKindGet for RpcGlobalStateGetAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcGlobalStateGet - } -} - -impl ActionKindGet for RpcActionStatsGetAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcActionStatsGet - } -} - -impl ActionKindGet for RpcSyncStatsGetAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcSyncStatsGet - } -} - -impl ActionKindGet for RpcPeersGetAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcPeersGet - } -} - -impl ActionKindGet for RpcP2pConnectionOutgoingInitAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionOutgoingInit - } -} - -impl ActionKindGet for RpcP2pConnectionOutgoingPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionOutgoingPending - } -} - -impl ActionKindGet for RpcP2pConnectionOutgoingErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionOutgoingError - } -} - -impl ActionKindGet for RpcP2pConnectionOutgoingSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionOutgoingSuccess - } -} - -impl ActionKindGet for RpcP2pConnectionIncomingInitAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionIncomingInit - } -} - -impl ActionKindGet for RpcP2pConnectionIncomingPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionIncomingPending - } -} - -impl ActionKindGet for RpcP2pConnectionIncomingRespondAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionIncomingRespond - } -} - -impl ActionKindGet for RpcP2pConnectionIncomingErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionIncomingError - } -} - -impl ActionKindGet for RpcP2pConnectionIncomingSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcP2pConnectionIncomingSuccess - } -} - -impl ActionKindGet for RpcScanStateSummaryGetAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcScanStateSummaryGet - } -} - -impl ActionKindGet for RpcSnarkPoolAvailableJobsGetAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcSnarkPoolAvailableJobsGet - } -} - -impl ActionKindGet for RpcSnarkPoolJobGetAction { - fn kind(&self) -> ActionKind { - ActionKind::RpcSnarkPoolJobGet - } -} - -impl ActionKindGet for RpcSnarkerConfigGetAction { +impl ActionKindGet for P2pConnectionOutgoingAction { fn kind(&self) -> ActionKind { - ActionKind::RpcSnarkerConfigGet + match self { + Self::RandomInit => ActionKind::P2pConnectionOutgoingRandomInit, + Self::Init { .. } => ActionKind::P2pConnectionOutgoingInit, + Self::Reconnect { .. } => ActionKind::P2pConnectionOutgoingReconnect, + Self::OfferSdpCreatePending { .. } => { + ActionKind::P2pConnectionOutgoingOfferSdpCreatePending + } + Self::OfferSdpCreateError { .. } => { + ActionKind::P2pConnectionOutgoingOfferSdpCreateError + } + Self::OfferSdpCreateSuccess { .. } => { + ActionKind::P2pConnectionOutgoingOfferSdpCreateSuccess + } + Self::OfferReady { .. } => ActionKind::P2pConnectionOutgoingOfferReady, + Self::OfferSendSuccess { .. } => ActionKind::P2pConnectionOutgoingOfferSendSuccess, + Self::AnswerRecvPending { .. } => ActionKind::P2pConnectionOutgoingAnswerRecvPending, + Self::AnswerRecvError { .. } => ActionKind::P2pConnectionOutgoingAnswerRecvError, + Self::AnswerRecvSuccess { .. } => ActionKind::P2pConnectionOutgoingAnswerRecvSuccess, + Self::FinalizePending { .. } => ActionKind::P2pConnectionOutgoingFinalizePending, + Self::FinalizeError { .. } => ActionKind::P2pConnectionOutgoingFinalizeError, + Self::FinalizeSuccess { .. } => ActionKind::P2pConnectionOutgoingFinalizeSuccess, + Self::Timeout { .. } => ActionKind::P2pConnectionOutgoingTimeout, + Self::Error { .. } => ActionKind::P2pConnectionOutgoingError, + Self::Success { .. } => ActionKind::P2pConnectionOutgoingSuccess, + } } } -impl ActionKindGet for RpcSnarkerJobCommitAction { +impl ActionKindGet for P2pConnectionIncomingAction { fn kind(&self) -> ActionKind { - ActionKind::RpcSnarkerJobCommit + match self { + Self::Init { .. } => ActionKind::P2pConnectionIncomingInit, + Self::AnswerSdpCreatePending { .. } => { + ActionKind::P2pConnectionIncomingAnswerSdpCreatePending + } + Self::AnswerSdpCreateError { .. } => { + ActionKind::P2pConnectionIncomingAnswerSdpCreateError + } + Self::AnswerSdpCreateSuccess { .. } => { + ActionKind::P2pConnectionIncomingAnswerSdpCreateSuccess + } + Self::AnswerReady { .. } => ActionKind::P2pConnectionIncomingAnswerReady, + Self::AnswerSendSuccess { .. } => ActionKind::P2pConnectionIncomingAnswerSendSuccess, + Self::FinalizePending { .. } => ActionKind::P2pConnectionIncomingFinalizePending, + Self::FinalizeError { .. } => ActionKind::P2pConnectionIncomingFinalizeError, + Self::FinalizeSuccess { .. } => ActionKind::P2pConnectionIncomingFinalizeSuccess, + Self::Timeout { .. } => ActionKind::P2pConnectionIncomingTimeout, + Self::Error { .. } => ActionKind::P2pConnectionIncomingError, + Self::Success { .. } => ActionKind::P2pConnectionIncomingSuccess, + Self::Libp2pReceived { .. } => ActionKind::P2pConnectionIncomingLibp2pReceived, + } } } -impl ActionKindGet for RpcSnarkerJobSpecAction { +impl ActionKindGet for P2pChannelsMessageReceivedAction { fn kind(&self) -> ActionKind { - ActionKind::RpcSnarkerJobSpec + ActionKind::P2pChannelsMessageReceived } } -impl ActionKindGet for RpcSnarkersWorkersGetAction { +impl ActionKindGet for P2pChannelsBestTipAction { fn kind(&self) -> ActionKind { - ActionKind::RpcSnarkersWorkersGet + match self { + Self::Init { .. } => ActionKind::P2pChannelsBestTipInit, + Self::Pending { .. } => ActionKind::P2pChannelsBestTipPending, + Self::Ready { .. } => ActionKind::P2pChannelsBestTipReady, + Self::RequestSend { .. } => ActionKind::P2pChannelsBestTipRequestSend, + Self::Received { .. } => ActionKind::P2pChannelsBestTipReceived, + Self::RequestReceived { .. } => ActionKind::P2pChannelsBestTipRequestReceived, + Self::ResponseSend { .. } => ActionKind::P2pChannelsBestTipResponseSend, + } } } -impl ActionKindGet for RpcHealthCheckAction { +impl ActionKindGet for P2pChannelsSnarkAction { fn kind(&self) -> ActionKind { - ActionKind::RpcHealthCheck + match self { + Self::Init { .. } => ActionKind::P2pChannelsSnarkInit, + Self::Pending { .. } => ActionKind::P2pChannelsSnarkPending, + Self::Ready { .. } => ActionKind::P2pChannelsSnarkReady, + Self::RequestSend { .. } => ActionKind::P2pChannelsSnarkRequestSend, + Self::PromiseReceived { .. } => ActionKind::P2pChannelsSnarkPromiseReceived, + Self::Received { .. } => ActionKind::P2pChannelsSnarkReceived, + Self::RequestReceived { .. } => ActionKind::P2pChannelsSnarkRequestReceived, + Self::ResponseSend { .. } => ActionKind::P2pChannelsSnarkResponseSend, + Self::Libp2pReceived { .. } => ActionKind::P2pChannelsSnarkLibp2pReceived, + Self::Libp2pBroadcast { .. } => ActionKind::P2pChannelsSnarkLibp2pBroadcast, + } } } -impl ActionKindGet for RpcReadinessCheckAction { +impl ActionKindGet for P2pChannelsSnarkJobCommitmentAction { fn kind(&self) -> ActionKind { - ActionKind::RpcReadinessCheck + match self { + Self::Init { .. } => ActionKind::P2pChannelsSnarkJobCommitmentInit, + Self::Pending { .. } => ActionKind::P2pChannelsSnarkJobCommitmentPending, + Self::Ready { .. } => ActionKind::P2pChannelsSnarkJobCommitmentReady, + Self::RequestSend { .. } => ActionKind::P2pChannelsSnarkJobCommitmentRequestSend, + Self::PromiseReceived { .. } => { + ActionKind::P2pChannelsSnarkJobCommitmentPromiseReceived + } + Self::Received { .. } => ActionKind::P2pChannelsSnarkJobCommitmentReceived, + Self::RequestReceived { .. } => { + ActionKind::P2pChannelsSnarkJobCommitmentRequestReceived + } + Self::ResponseSend { .. } => ActionKind::P2pChannelsSnarkJobCommitmentResponseSend, + } } } -impl ActionKindGet for RpcFinishAction { +impl ActionKindGet for P2pChannelsRpcAction { fn kind(&self) -> ActionKind { - ActionKind::RpcFinish + match self { + Self::Init { .. } => ActionKind::P2pChannelsRpcInit, + Self::Pending { .. } => ActionKind::P2pChannelsRpcPending, + Self::Ready { .. } => ActionKind::P2pChannelsRpcReady, + Self::RequestSend { .. } => ActionKind::P2pChannelsRpcRequestSend, + Self::Timeout { .. } => ActionKind::P2pChannelsRpcTimeout, + Self::ResponseReceived { .. } => ActionKind::P2pChannelsRpcResponseReceived, + Self::RequestReceived { .. } => ActionKind::P2pChannelsRpcRequestReceived, + Self::ResponseSend { .. } => ActionKind::P2pChannelsRpcResponseSend, + } } } -impl ActionKindGet for WatchedAccountsAddAction { +impl ActionKindGet for TransitionFrontierSyncLedgerAction { fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsAdd + match self { + Self::Snarked(a) => a.kind(), + Self::Staged(a) => a.kind(), + Self::Init => ActionKind::TransitionFrontierSyncLedgerInit, + Self::Success => ActionKind::TransitionFrontierSyncLedgerSuccess, + } } } -impl ActionKindGet for WatchedAccountsLedgerInitialStateGetInitAction { +impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedAction { fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsLedgerInitialStateGetInit + match self { + Self::Pending => ActionKind::TransitionFrontierSyncLedgerSnarkedPending, + Self::PeersQuery => ActionKind::TransitionFrontierSyncLedgerSnarkedPeersQuery, + Self::PeerQueryInit { .. } => { + ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryInit + } + Self::PeerQueryPending { .. } => { + ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryPending + } + Self::PeerQueryRetry { .. } => { + ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryRetry + } + Self::PeerQueryError { .. } => { + ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryError + } + Self::PeerQuerySuccess { .. } => { + ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQuerySuccess + } + Self::ChildHashesReceived { .. } => { + ActionKind::TransitionFrontierSyncLedgerSnarkedChildHashesReceived + } + Self::ChildAccountsReceived { .. } => { + ActionKind::TransitionFrontierSyncLedgerSnarkedChildAccountsReceived + } + Self::Success => ActionKind::TransitionFrontierSyncLedgerSnarkedSuccess, + } } } -impl ActionKindGet for WatchedAccountsLedgerInitialStateGetPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsLedgerInitialStateGetPending - } -} - -impl ActionKindGet for WatchedAccountsLedgerInitialStateGetErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsLedgerInitialStateGetError - } -} - -impl ActionKindGet for WatchedAccountsLedgerInitialStateGetRetryAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsLedgerInitialStateGetRetry - } -} - -impl ActionKindGet for WatchedAccountsLedgerInitialStateGetSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsLedgerInitialStateGetSuccess - } -} - -impl ActionKindGet for WatchedAccountsBlockTransactionsIncludedAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsBlockTransactionsIncluded - } -} - -impl ActionKindGet for WatchedAccountsBlockLedgerQueryInitAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsBlockLedgerQueryInit - } -} - -impl ActionKindGet for WatchedAccountsBlockLedgerQueryPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsBlockLedgerQueryPending - } -} - -impl ActionKindGet for WatchedAccountsBlockLedgerQuerySuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::WatchedAccountsBlockLedgerQuerySuccess - } -} - -impl ActionKindGet for P2pListenNewAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pListenNew - } -} - -impl ActionKindGet for P2pListenExpiredAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pListenExpired - } -} - -impl ActionKindGet for P2pListenErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pListenError - } -} - -impl ActionKindGet for P2pListenClosedAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pListenClosed - } -} - -impl ActionKindGet for P2pConnectionOutgoingAction { - fn kind(&self) -> ActionKind { - match self { - Self::RandomInit(a) => a.kind(), - Self::Init(a) => a.kind(), - Self::Reconnect(a) => a.kind(), - Self::OfferSdpCreatePending(a) => a.kind(), - Self::OfferSdpCreateError(a) => a.kind(), - Self::OfferSdpCreateSuccess(a) => a.kind(), - Self::OfferReady(a) => a.kind(), - Self::OfferSendSuccess(a) => a.kind(), - Self::AnswerRecvPending(a) => a.kind(), - Self::AnswerRecvError(a) => a.kind(), - Self::AnswerRecvSuccess(a) => a.kind(), - Self::FinalizePending(a) => a.kind(), - Self::FinalizeError(a) => a.kind(), - Self::FinalizeSuccess(a) => a.kind(), - Self::Timeout(a) => a.kind(), - Self::Error(a) => a.kind(), - Self::Success(a) => a.kind(), - } - } -} - -impl ActionKindGet for P2pConnectionIncomingAction { - fn kind(&self) -> ActionKind { - match self { - Self::Init(a) => a.kind(), - Self::AnswerSdpCreatePending(a) => a.kind(), - Self::AnswerSdpCreateError(a) => a.kind(), - Self::AnswerSdpCreateSuccess(a) => a.kind(), - Self::AnswerReady(a) => a.kind(), - Self::AnswerSendSuccess(a) => a.kind(), - Self::FinalizePending(a) => a.kind(), - Self::FinalizeError(a) => a.kind(), - Self::FinalizeSuccess(a) => a.kind(), - Self::Timeout(a) => a.kind(), - Self::Error(a) => a.kind(), - Self::Success(a) => a.kind(), - Self::Libp2pReceived(a) => a.kind(), - } - } -} - -impl ActionKindGet for P2pDisconnectionInitAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDisconnectionInit - } -} - -impl ActionKindGet for P2pDisconnectionFinishAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDisconnectionFinish - } -} - -impl ActionKindGet for P2pDiscoveryInitAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDiscoveryInit - } -} - -impl ActionKindGet for P2pDiscoverySuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDiscoverySuccess - } -} - -impl ActionKindGet for P2pDiscoveryKademliaBootstrapAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDiscoveryKademliaBootstrap - } -} - -impl ActionKindGet for P2pDiscoveryKademliaInitAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDiscoveryKademliaInit - } -} - -impl ActionKindGet for P2pDiscoveryKademliaAddRouteAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDiscoveryKademliaAddRoute - } -} - -impl ActionKindGet for P2pDiscoveryKademliaSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDiscoveryKademliaSuccess - } -} - -impl ActionKindGet for P2pDiscoveryKademliaFailureAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pDiscoveryKademliaFailure - } -} - -impl ActionKindGet for P2pChannelsMessageReceivedAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pChannelsMessageReceived - } -} - -impl ActionKindGet for P2pChannelsBestTipAction { - fn kind(&self) -> ActionKind { - match self { - Self::Init { .. } => ActionKind::P2pChannelsBestTipInit, - Self::Pending { .. } => ActionKind::P2pChannelsBestTipPending, - Self::Ready { .. } => ActionKind::P2pChannelsBestTipReady, - Self::RequestSend { .. } => ActionKind::P2pChannelsBestTipRequestSend, - Self::Received { .. } => ActionKind::P2pChannelsBestTipReceived, - Self::RequestReceived { .. } => ActionKind::P2pChannelsBestTipRequestReceived, - Self::ResponseSend { .. } => ActionKind::P2pChannelsBestTipResponseSend, - } - } -} - -impl ActionKindGet for P2pChannelsSnarkAction { - fn kind(&self) -> ActionKind { - match self { - Self::Init { .. } => ActionKind::P2pChannelsSnarkInit, - Self::Pending { .. } => ActionKind::P2pChannelsSnarkPending, - Self::Ready { .. } => ActionKind::P2pChannelsSnarkReady, - Self::RequestSend { .. } => ActionKind::P2pChannelsSnarkRequestSend, - Self::PromiseReceived { .. } => ActionKind::P2pChannelsSnarkPromiseReceived, - Self::Received { .. } => ActionKind::P2pChannelsSnarkReceived, - Self::RequestReceived { .. } => ActionKind::P2pChannelsSnarkRequestReceived, - Self::ResponseSend { .. } => ActionKind::P2pChannelsSnarkResponseSend, - Self::Libp2pReceived { .. } => ActionKind::P2pChannelsSnarkLibp2pReceived, - Self::Libp2pBroadcast { .. } => ActionKind::P2pChannelsSnarkLibp2pBroadcast, - } - } -} - -impl ActionKindGet for P2pChannelsSnarkJobCommitmentAction { +impl ActionKindGet for TransitionFrontierSyncLedgerStagedAction { fn kind(&self) -> ActionKind { match self { - Self::Init { .. } => ActionKind::P2pChannelsSnarkJobCommitmentInit, - Self::Pending { .. } => ActionKind::P2pChannelsSnarkJobCommitmentPending, - Self::Ready { .. } => ActionKind::P2pChannelsSnarkJobCommitmentReady, - Self::RequestSend { .. } => ActionKind::P2pChannelsSnarkJobCommitmentRequestSend, - Self::PromiseReceived { .. } => { - ActionKind::P2pChannelsSnarkJobCommitmentPromiseReceived + Self::PartsFetchPending => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsFetchPending } - Self::Received { .. } => ActionKind::P2pChannelsSnarkJobCommitmentReceived, - Self::RequestReceived { .. } => { - ActionKind::P2pChannelsSnarkJobCommitmentRequestReceived + Self::PartsPeerFetchInit => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchInit } - Self::ResponseSend { .. } => ActionKind::P2pChannelsSnarkJobCommitmentResponseSend, - } - } -} - -impl ActionKindGet for P2pChannelsRpcAction { - fn kind(&self) -> ActionKind { - match self { - Self::Init { .. } => ActionKind::P2pChannelsRpcInit, - Self::Pending { .. } => ActionKind::P2pChannelsRpcPending, - Self::Ready { .. } => ActionKind::P2pChannelsRpcReady, - Self::RequestSend { .. } => ActionKind::P2pChannelsRpcRequestSend, - Self::Timeout { .. } => ActionKind::P2pChannelsRpcTimeout, - Self::ResponseReceived { .. } => ActionKind::P2pChannelsRpcResponseReceived, - Self::RequestReceived { .. } => ActionKind::P2pChannelsRpcRequestReceived, - Self::ResponseSend { .. } => ActionKind::P2pChannelsRpcResponseSend, + Self::PartsPeerFetchPending { .. } => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchPending + } + Self::PartsPeerFetchError { .. } => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchError + } + Self::PartsPeerFetchSuccess { .. } => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccess + } + Self::PartsPeerInvalid { .. } => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerInvalid + } + Self::PartsPeerValid { .. } => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerValid + } + Self::PartsFetchSuccess { .. } => { + ActionKind::TransitionFrontierSyncLedgerStagedPartsFetchSuccess + } + Self::ReconstructEmpty => { + ActionKind::TransitionFrontierSyncLedgerStagedReconstructEmpty + } + Self::ReconstructInit => ActionKind::TransitionFrontierSyncLedgerStagedReconstructInit, + Self::ReconstructPending => { + ActionKind::TransitionFrontierSyncLedgerStagedReconstructPending + } + Self::ReconstructError { .. } => { + ActionKind::TransitionFrontierSyncLedgerStagedReconstructError + } + Self::ReconstructSuccess => { + ActionKind::TransitionFrontierSyncLedgerStagedReconstructSuccess + } + Self::Success => ActionKind::TransitionFrontierSyncLedgerStagedSuccess, } } } - -impl ActionKindGet for P2pPeerReadyAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pPeerReady - } -} - -impl ActionKindGet for P2pPeerBestTipUpdateAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pPeerBestTipUpdate - } -} - -impl ActionKindGet for TransitionFrontierSyncInitAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncInit - } -} - -impl ActionKindGet for TransitionFrontierSyncBestTipUpdateAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBestTipUpdate - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStakingPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStakingPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStakingSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStakingSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerNextEpochPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerNextEpochPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerNextEpochSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerNextEpochSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerRootPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerRootPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerRootSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerRootSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksPending - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksPeersQueryAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksPeersQuery - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksPeerQueryInitAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksPeerQueryInit - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksPeerQueryRetryAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksPeerQueryRetry - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksPeerQueryPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksPeerQueryPending - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksPeerQueryErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksPeerQueryError - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksPeerQuerySuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksPeerQuerySuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksFetchSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksFetchSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksNextApplyInitAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksNextApplyInit - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksNextApplyPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksNextApplyPending - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksNextApplySuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksNextApplySuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncBlocksSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncBlocksSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerAction { - fn kind(&self) -> ActionKind { - match self { - Self::Init(a) => a.kind(), - Self::Snarked(a) => a.kind(), - Self::Staged(a) => a.kind(), - Self::Success(a) => a.kind(), - } - } -} - -impl ActionKindGet for BlockProducerVrfEvaluatorEpochDataUpdateAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerVrfEvaluatorEpochDataUpdate - } -} - -impl ActionKindGet for BlockProducerVrfEvaluatorEvaluateVrfAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerVrfEvaluatorEvaluateVrf - } -} - -impl ActionKindGet for BlockProducerVrfEvaluatorEvaluationSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerVrfEvaluatorEvaluationSuccess - } -} - -impl ActionKindGet for BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerVrfEvaluatorUpdateProducerAndDelegates - } -} - -impl ActionKindGet for BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccess - } -} - -impl ActionKindGet for P2pConnectionOutgoingRandomInitAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingRandomInit - } -} - -impl ActionKindGet for P2pConnectionOutgoingInitAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingInit - } -} - -impl ActionKindGet for P2pConnectionOutgoingReconnectAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingReconnect - } -} - -impl ActionKindGet for P2pConnectionOutgoingOfferSdpCreatePendingAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingOfferSdpCreatePending - } -} - -impl ActionKindGet for P2pConnectionOutgoingOfferSdpCreateErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingOfferSdpCreateError - } -} - -impl ActionKindGet for P2pConnectionOutgoingOfferSdpCreateSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingOfferSdpCreateSuccess - } -} - -impl ActionKindGet for P2pConnectionOutgoingOfferReadyAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingOfferReady - } -} - -impl ActionKindGet for P2pConnectionOutgoingOfferSendSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingOfferSendSuccess - } -} - -impl ActionKindGet for P2pConnectionOutgoingAnswerRecvPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingAnswerRecvPending - } -} - -impl ActionKindGet for P2pConnectionOutgoingAnswerRecvErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingAnswerRecvError - } -} - -impl ActionKindGet for P2pConnectionOutgoingAnswerRecvSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingAnswerRecvSuccess - } -} - -impl ActionKindGet for P2pConnectionOutgoingFinalizePendingAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingFinalizePending - } -} - -impl ActionKindGet for P2pConnectionOutgoingFinalizeErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingFinalizeError - } -} - -impl ActionKindGet for P2pConnectionOutgoingFinalizeSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingFinalizeSuccess - } -} - -impl ActionKindGet for P2pConnectionOutgoingTimeoutAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingTimeout - } -} - -impl ActionKindGet for P2pConnectionOutgoingErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingError - } -} - -impl ActionKindGet for P2pConnectionOutgoingSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionOutgoingSuccess - } -} - -impl ActionKindGet for P2pConnectionIncomingInitAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingInit - } -} - -impl ActionKindGet for P2pConnectionIncomingAnswerSdpCreatePendingAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingAnswerSdpCreatePending - } -} - -impl ActionKindGet for P2pConnectionIncomingAnswerSdpCreateErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingAnswerSdpCreateError - } -} - -impl ActionKindGet for P2pConnectionIncomingAnswerSdpCreateSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingAnswerSdpCreateSuccess - } -} - -impl ActionKindGet for P2pConnectionIncomingAnswerReadyAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingAnswerReady - } -} - -impl ActionKindGet for P2pConnectionIncomingAnswerSendSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingAnswerSendSuccess - } -} - -impl ActionKindGet for P2pConnectionIncomingFinalizePendingAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingFinalizePending - } -} - -impl ActionKindGet for P2pConnectionIncomingFinalizeErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingFinalizeError - } -} - -impl ActionKindGet for P2pConnectionIncomingFinalizeSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingFinalizeSuccess - } -} - -impl ActionKindGet for P2pConnectionIncomingTimeoutAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingTimeout - } -} - -impl ActionKindGet for P2pConnectionIncomingErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingError - } -} - -impl ActionKindGet for P2pConnectionIncomingSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingSuccess - } -} - -impl ActionKindGet for P2pConnectionIncomingLibp2pReceivedAction { - fn kind(&self) -> ActionKind { - ActionKind::P2pConnectionIncomingLibp2pReceived - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerInitAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerInit - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedAction { - fn kind(&self) -> ActionKind { - match self { - Self::Pending(a) => a.kind(), - Self::PeersQuery(a) => a.kind(), - Self::PeerQueryInit(a) => a.kind(), - Self::PeerQueryPending(a) => a.kind(), - Self::PeerQueryRetry(a) => a.kind(), - Self::PeerQueryError(a) => a.kind(), - Self::PeerQuerySuccess(a) => a.kind(), - Self::ChildHashesReceived(a) => a.kind(), - Self::ChildAccountsReceived(a) => a.kind(), - Self::Success(a) => a.kind(), - } - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedAction { - fn kind(&self) -> ActionKind { - match self { - Self::PartsFetchPending(a) => a.kind(), - Self::PartsPeerFetchInit(a) => a.kind(), - Self::PartsPeerFetchPending(a) => a.kind(), - Self::PartsPeerFetchError(a) => a.kind(), - Self::PartsPeerFetchSuccess(a) => a.kind(), - Self::PartsPeerInvalid(a) => a.kind(), - Self::PartsPeerValid(a) => a.kind(), - Self::PartsFetchSuccess(a) => a.kind(), - Self::ReconstructEmpty(a) => a.kind(), - Self::ReconstructInit(a) => a.kind(), - Self::ReconstructPending(a) => a.kind(), - Self::ReconstructError(a) => a.kind(), - Self::ReconstructSuccess(a) => a.kind(), - Self::Success(a) => a.kind(), - } - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedPeersQueryAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedPeersQuery - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryInit - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryRetry - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQueryError - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedPeerQuerySuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedChildHashesReceived - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedChildAccountsReceived - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerSnarkedSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerSnarkedSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsFetchPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsFetchPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchInit - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchError - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerInvalid - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsPeerValidAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsPeerValid - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedPartsFetchSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedReconstructEmptyAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedReconstructEmpty - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedReconstructInitAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedReconstructInit - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedReconstructPendingAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedReconstructPending - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedReconstructErrorAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedReconstructError - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedReconstructSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedReconstructSuccess - } -} - -impl ActionKindGet for TransitionFrontierSyncLedgerStagedSuccessAction { - fn kind(&self) -> ActionKind { - ActionKind::TransitionFrontierSyncLedgerStagedSuccess - } -} diff --git a/node/src/block_producer/block_producer_actions.rs b/node/src/block_producer/block_producer_actions.rs index e654ef199..5407f098d 100644 --- a/node/src/block_producer/block_producer_actions.rs +++ b/node/src/block_producer/block_producer_actions.rs @@ -11,228 +11,116 @@ use super::{BlockProducerCurrentState, BlockProducerWonSlot, BlockProducerWonSlo pub type BlockProducerActionWithMeta = redux::ActionWithMeta; pub type BlockProducerActionWithMetaRef<'a> = redux::ActionWithMeta<&'a BlockProducerAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub enum BlockProducerAction { VrfEvaluator(BlockProducerVrfEvaluatorAction), - BestTipUpdate(BlockProducerBestTipUpdateAction), - WonSlotSearch(BlockProducerWonSlotSearchAction), - WonSlot(BlockProducerWonSlotAction), - WonSlotDiscard(BlockProducerWonSlotDiscardAction), - WonSlotWait(BlockProducerWonSlotWaitAction), - WonSlotProduceInit(BlockProducerWonSlotProduceInitAction), - StagedLedgerDiffCreateInit(BlockProducerStagedLedgerDiffCreateInitAction), - StagedLedgerDiffCreatePending(BlockProducerStagedLedgerDiffCreatePendingAction), - StagedLedgerDiffCreateSuccess(BlockProducerStagedLedgerDiffCreateSuccessAction), - BlockUnprovenBuild(BlockProducerBlockUnprovenBuildAction), - BlockProduced(BlockProducerBlockProducedAction), - BlockInject(BlockProducerBlockInjectAction), - BlockInjected(BlockProducerBlockInjectedAction), -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerBestTipUpdateAction { - pub best_tip: ArcBlockWithHash, -} - -impl redux::EnablingCondition for BlockProducerBestTipUpdateAction { - fn is_enabled(&self, _state: &crate::State) -> bool { - true - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerWonSlotSearchAction {} - -impl redux::EnablingCondition for BlockProducerWonSlotSearchAction { + BestTipUpdate { + best_tip: ArcBlockWithHash, + }, + WonSlotSearch, + WonSlot { + won_slot: BlockProducerWonSlot, + }, + WonSlotDiscard { + reason: BlockProducerWonSlotDiscardReason, + }, + WonSlotWait, + WonSlotProduceInit, + StagedLedgerDiffCreateInit, + StagedLedgerDiffCreatePending, + StagedLedgerDiffCreateSuccess { + diff: StagedLedgerDiffDiffStableV2, + diff_hash: ConsensusBodyReferenceStableV1, + staged_ledger_hash: MinaBaseStagedLedgerHashStableV1, + emitted_ledger_proof: Option, + }, + BlockUnprovenBuild, + BlockProduced, + BlockInject, + BlockInjected, +} + +impl redux::EnablingCondition for BlockProducerAction { fn is_enabled(&self, state: &crate::State) -> bool { - state - .block_producer - .with(None, |this| { - if !this.current.won_slot_should_search() { - return None; - } - let best_tip = state.transition_frontier.best_tip()?; - let cur_global_slot = state.cur_global_slot()?; - let next = this.vrf_evaluator.next_won_slot(cur_global_slot, best_tip); - Some(next.is_some()) - }) - .is_some_and(|v| v) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerWonSlotAction { - pub won_slot: BlockProducerWonSlot, -} - -impl redux::EnablingCondition for BlockProducerWonSlotAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - let Some(best_tip) = state.transition_frontier.best_tip() else { - return false; - }; - - this.current.won_slot_should_search() - && self.won_slot.global_slot() >= state.cur_global_slot().unwrap() - && &self.won_slot > best_tip - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerWonSlotWaitAction {} - -impl redux::EnablingCondition for BlockProducerWonSlotWaitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - this.current.won_slot_should_wait(state.time()) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerWonSlotProduceInitAction {} - -impl redux::EnablingCondition for BlockProducerWonSlotProduceInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - this.current.won_slot_should_produce(state.time()) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerStagedLedgerDiffCreateInitAction {} - -impl redux::EnablingCondition for BlockProducerStagedLedgerDiffCreateInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.current, - BlockProducerCurrentState::WonSlotProduceInit { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerStagedLedgerDiffCreatePendingAction {} - -impl redux::EnablingCondition for BlockProducerStagedLedgerDiffCreatePendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.current, - BlockProducerCurrentState::WonSlotProduceInit { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerStagedLedgerDiffCreateSuccessAction { - pub diff: StagedLedgerDiffDiffStableV2, - pub diff_hash: ConsensusBodyReferenceStableV1, - pub staged_ledger_hash: MinaBaseStagedLedgerHashStableV1, - pub emitted_ledger_proof: Option, -} - -impl redux::EnablingCondition for BlockProducerStagedLedgerDiffCreateSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.current, - BlockProducerCurrentState::StagedLedgerDiffCreatePending { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerBlockUnprovenBuildAction {} - -impl redux::EnablingCondition for BlockProducerBlockUnprovenBuildAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.current, - BlockProducerCurrentState::StagedLedgerDiffCreateSuccess { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerBlockProducedAction {} - -impl redux::EnablingCondition for BlockProducerBlockProducedAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.current, - BlockProducerCurrentState::BlockUnprovenBuilt { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerBlockInjectAction {} - -impl redux::EnablingCondition for BlockProducerBlockInjectAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!(this.current, BlockProducerCurrentState::Produced { .. }) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerBlockInjectedAction {} - -impl redux::EnablingCondition for BlockProducerBlockInjectedAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!(this.current, BlockProducerCurrentState::Produced { .. }) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerWonSlotDiscardAction { - pub reason: BlockProducerWonSlotDiscardReason, -} - -impl redux::EnablingCondition for BlockProducerWonSlotDiscardAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let reason = state.block_producer.with(None, |bp| { - let best_tip = state.transition_frontier.best_tip()?; - bp.current.won_slot_should_discard(best_tip) - }); - Some(&self.reason) == reason.as_ref() - } -} - -macro_rules! impl_into_global_action { - ($a:ty) => { - impl From<$a> for crate::Action { - fn from(value: $a) -> Self { - Self::BlockProducer(value.into()) + match self { + BlockProducerAction::VrfEvaluator(a) => a.is_enabled(state), + BlockProducerAction::BestTipUpdate { .. } => true, + BlockProducerAction::WonSlotSearch => state + .block_producer + .with(None, |this| { + if !this.current.won_slot_should_search() { + return None; + } + let best_tip = state.transition_frontier.best_tip()?; + let cur_global_slot = state.cur_global_slot()?; + let next = this.vrf_evaluator.next_won_slot(cur_global_slot, best_tip); + Some(next.is_some()) + }) + .is_some_and(|v| v), + BlockProducerAction::WonSlot { won_slot } => state.block_producer.with(false, |this| { + let Some(best_tip) = state.transition_frontier.best_tip() else { + return false; + }; + + this.current.won_slot_should_search() + && won_slot.global_slot() >= state.cur_global_slot().unwrap() + && won_slot > best_tip + }), + BlockProducerAction::WonSlotWait => state.block_producer.with(false, |this| { + this.current.won_slot_should_wait(state.time()) + }), + BlockProducerAction::WonSlotProduceInit => state.block_producer.with(false, |this| { + this.current.won_slot_should_produce(state.time()) + }), + BlockProducerAction::StagedLedgerDiffCreateInit => { + state.block_producer.with(false, |this| { + matches!( + this.current, + BlockProducerCurrentState::WonSlotProduceInit { .. } + ) + }) + } + BlockProducerAction::StagedLedgerDiffCreatePending => { + state.block_producer.with(false, |this| { + matches!( + this.current, + BlockProducerCurrentState::WonSlotProduceInit { .. } + ) + }) + } + BlockProducerAction::StagedLedgerDiffCreateSuccess { .. } => { + state.block_producer.with(false, |this| { + matches!( + this.current, + BlockProducerCurrentState::StagedLedgerDiffCreatePending { .. } + ) + }) + } + BlockProducerAction::BlockUnprovenBuild => state.block_producer.with(false, |this| { + matches!( + this.current, + BlockProducerCurrentState::StagedLedgerDiffCreateSuccess { .. } + ) + }), + BlockProducerAction::BlockProduced => state.block_producer.with(false, |this| { + matches!( + this.current, + BlockProducerCurrentState::BlockUnprovenBuilt { .. } + ) + }), + BlockProducerAction::BlockInject => state.block_producer.with(false, |this| { + matches!(this.current, BlockProducerCurrentState::Produced { .. }) + }), + BlockProducerAction::BlockInjected => state.block_producer.with(false, |this| { + matches!(this.current, BlockProducerCurrentState::Produced { .. }) + }), + BlockProducerAction::WonSlotDiscard { reason } => { + let current_reason = state.block_producer.with(None, |bp| { + let best_tip = state.transition_frontier.best_tip()?; + bp.current.won_slot_should_discard(best_tip) + }); + Some(reason) == current_reason.as_ref() } } - }; + } } - -impl_into_global_action!(BlockProducerBestTipUpdateAction); -impl_into_global_action!(BlockProducerWonSlotSearchAction); -impl_into_global_action!(BlockProducerWonSlotAction); -impl_into_global_action!(BlockProducerWonSlotDiscardAction); -impl_into_global_action!(BlockProducerWonSlotWaitAction); -impl_into_global_action!(BlockProducerWonSlotProduceInitAction); -impl_into_global_action!(BlockProducerStagedLedgerDiffCreateInitAction); -impl_into_global_action!(BlockProducerStagedLedgerDiffCreatePendingAction); -impl_into_global_action!(BlockProducerStagedLedgerDiffCreateSuccessAction); -impl_into_global_action!(BlockProducerBlockUnprovenBuildAction); -impl_into_global_action!(BlockProducerBlockProducedAction); -impl_into_global_action!(BlockProducerBlockInjectAction); -impl_into_global_action!(BlockProducerBlockInjectedAction); diff --git a/node/src/block_producer/block_producer_config.rs b/node/src/block_producer/block_producer_config.rs index e762bc4de..0aaaa75d7 100644 --- a/node/src/block_producer/block_producer_config.rs +++ b/node/src/block_producer/block_producer_config.rs @@ -1,11 +1,11 @@ -use mina_p2p_messages::v2::{NonZeroCurvePoint, ProtocolVersionStableV1}; +use mina_p2p_messages::v2::{NonZeroCurvePoint, ProtocolVersionStableV2}; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct BlockProducerConfig { pub pub_key: NonZeroCurvePoint, pub custom_coinbase_receiver: Option, - pub proposed_protocol_version: Option, + pub proposed_protocol_version: Option, } impl BlockProducerConfig { diff --git a/node/src/block_producer/block_producer_effects.rs b/node/src/block_producer/block_producer_effects.rs index ac4c3ab18..713f42f5d 100644 --- a/node/src/block_producer/block_producer_effects.rs +++ b/node/src/block_producer/block_producer_effects.rs @@ -1,21 +1,8 @@ -use redux::ActionMeta; - -use crate::transition_frontier::sync::TransitionFrontierSyncBestTipUpdateAction; +use crate::transition_frontier::sync::TransitionFrontierSyncAction; use crate::Store; -use super::vrf_evaluator::{ - BlockProducerVrfEvaluatorAction, BlockProducerVrfEvaluatorEpochDataUpdateAction, -}; -use super::{ - BlockProducerAction, BlockProducerActionWithMeta, BlockProducerBestTipUpdateAction, - BlockProducerBlockInjectAction, BlockProducerBlockInjectedAction, - BlockProducerBlockProducedAction, BlockProducerBlockUnprovenBuildAction, BlockProducerService, - BlockProducerStagedLedgerDiffCreateInitAction, - BlockProducerStagedLedgerDiffCreatePendingAction, - BlockProducerStagedLedgerDiffCreateSuccessAction, BlockProducerWonSlotAction, - BlockProducerWonSlotDiscardAction, BlockProducerWonSlotProduceInitAction, - BlockProducerWonSlotSearchAction, BlockProducerWonSlotWaitAction, -}; +use super::vrf_evaluator::BlockProducerVrfEvaluatorAction; +use super::{BlockProducerAction, BlockProducerActionWithMeta}; pub fn block_producer_effects( store: &mut Store, @@ -24,214 +11,141 @@ pub fn block_producer_effects( let (action, meta) = action.split(); match action { - BlockProducerAction::VrfEvaluator(action) => match action { - BlockProducerVrfEvaluatorAction::EpochDataUpdate(action) => { - action.effects(&meta, store); - } - BlockProducerVrfEvaluatorAction::EvaluateVrf(action) => { - action.effects(&meta, store); - } - BlockProducerVrfEvaluatorAction::EvaluationSuccess(action) => { - let has_won_slot = - matches!(action.vrf_output, vrf::VrfEvaluationOutput::SlotWon(_)); - action.effects(&meta, store); - if has_won_slot { - store.dispatch(BlockProducerWonSlotSearchAction {}); + BlockProducerAction::VrfEvaluator(ref a) => { + // TODO: does the order matter? can this clone be avoided? + a.clone().effects(&meta, store); + match a { + BlockProducerVrfEvaluatorAction::EvaluationSuccess { vrf_output, .. } => { + let has_won_slot = matches!(vrf_output, vrf::VrfEvaluationOutput::SlotWon(_)); + if has_won_slot { + store.dispatch(BlockProducerAction::WonSlotSearch); + } } + _ => {} } - BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates(action) => { - action.effects(&meta, store); + } + BlockProducerAction::BestTipUpdate { best_tip } => { + let best_tip_staking_ledger = best_tip.staking_epoch_ledger_hash(); + let protocol_state = &best_tip.block.header.protocol_state.body; + + let vrf_evaluator_current_epoch_ledger = store + .state() + .block_producer + .vrf_evaluator() + .and_then(|vrf_evaluator| { + vrf_evaluator + .current_epoch_data + .as_ref() + .map(|epoch_data| &epoch_data.ledger) + }); + + if vrf_evaluator_current_epoch_ledger != Some(best_tip_staking_ledger) { + store.dispatch(BlockProducerVrfEvaluatorAction::EpochDataUpdate { + new_epoch_number: protocol_state.consensus_state.epoch_count.as_u32(), + epoch_data: protocol_state.consensus_state.staking_epoch_data.clone(), + next_epoch_data: protocol_state.consensus_state.next_epoch_data.clone(), + }); } - BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess(action) => { - action.effects(&meta, store); + + if let Some(reason) = store + .state() + .block_producer + .with(None, |bp| bp.current.won_slot_should_discard(&best_tip)) + { + store.dispatch(BlockProducerAction::WonSlotDiscard { reason }); } - }, - BlockProducerAction::BestTipUpdate(action) => { - action.effects(&meta, store); - } - BlockProducerAction::WonSlotSearch(action) => { - action.effects(&meta, store); - } - BlockProducerAction::WonSlot(action) => { - action.effects(&meta, store); - } - BlockProducerAction::WonSlotWait(_) => {} - BlockProducerAction::WonSlotDiscard(action) => { - action.effects(&meta, store); } - BlockProducerAction::WonSlotProduceInit(action) => { - action.effects(&meta, store); - } - BlockProducerAction::StagedLedgerDiffCreateInit(action) => { - action.effects(&meta, store); - } - BlockProducerAction::StagedLedgerDiffCreatePending(_) => {} - BlockProducerAction::StagedLedgerDiffCreateSuccess(action) => { - action.effects(&meta, store); - } - BlockProducerAction::BlockUnprovenBuild(action) => { - action.effects(&meta, store); - } - BlockProducerAction::BlockProduced(action) => { - action.effects(&meta, store); - } - BlockProducerAction::BlockInject(action) => { - action.effects(&meta, store); + BlockProducerAction::WonSlotSearch => { + if let Some(won_slot) = store.state().block_producer.with(None, |bp| { + let best_tip = store.state().transition_frontier.best_tip()?; + let cur_global_slot = store.state().cur_global_slot()?; + bp.vrf_evaluator.next_won_slot(cur_global_slot, best_tip) + }) { + store.dispatch(BlockProducerAction::WonSlot { won_slot }); + } } - BlockProducerAction::BlockInjected(action) => { - action.effects(&meta, store); + BlockProducerAction::WonSlot { .. } => { + if !store.dispatch(BlockProducerAction::WonSlotWait) { + store.dispatch(BlockProducerAction::WonSlotProduceInit); + } } - } -} - -impl BlockProducerBestTipUpdateAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let best_tip_staking_ledger = self.best_tip.staking_epoch_ledger_hash(); - let protocol_state = &self.best_tip.block.header.protocol_state.body; - - let vrf_evaluator_current_epoch_ledger = store - .state() - .block_producer - .vrf_evaluator() - .and_then(|vrf_evaluator| { - vrf_evaluator - .current_epoch_data - .as_ref() - .map(|epoch_data| &epoch_data.ledger) + BlockProducerAction::WonSlotProduceInit => { + store.dispatch(BlockProducerAction::StagedLedgerDiffCreateInit); + } + BlockProducerAction::StagedLedgerDiffCreateInit => { + let state = store.state.get(); + let Some((won_slot, pred_block, coinbase_receiver)) = None.or_else(|| { + let pred_block = state.block_producer.current_parent_chain()?.last()?; + let won_slot = state.block_producer.current_won_slot()?; + let coinbase_receiver = state.block_producer.config()?.coinbase_receiver(); + Some((won_slot, pred_block, coinbase_receiver)) + }) else { + return; + }; + + let completed_snarks = state + .snark_pool + .completed_snarks_iter() + .map(|snark| (snark.job_id(), snark.clone())) + .collect(); + // TODO(binier) + let supercharge_coinbase = false; + + // TODO(binier): error handling + let output = store + .service + .staged_ledger_diff_create( + pred_block, + won_slot, + coinbase_receiver, + completed_snarks, + supercharge_coinbase, + ) + .unwrap(); + + store.dispatch(BlockProducerAction::StagedLedgerDiffCreatePending); + store.dispatch(BlockProducerAction::StagedLedgerDiffCreateSuccess { + diff: output.diff, + diff_hash: output.diff_hash, + staged_ledger_hash: output.staged_ledger_hash, + emitted_ledger_proof: output.emitted_ledger_proof, }); - - if vrf_evaluator_current_epoch_ledger != Some(best_tip_staking_ledger) { - store.dispatch(BlockProducerVrfEvaluatorEpochDataUpdateAction { - new_epoch_number: protocol_state.consensus_state.epoch_count.as_u32(), - epoch_data: protocol_state.consensus_state.staking_epoch_data.clone(), - next_epoch_data: protocol_state.consensus_state.next_epoch_data.clone(), - }); - } - - if let Some(reason) = store.state().block_producer.with(None, |bp| { - bp.current.won_slot_should_discard(&self.best_tip) - }) { - store.dispatch(BlockProducerWonSlotDiscardAction { reason }); } - } -} - -impl BlockProducerWonSlotSearchAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - if let Some(won_slot) = store.state().block_producer.with(None, |bp| { - let best_tip = store.state().transition_frontier.best_tip()?; - let cur_global_slot = store.state().cur_global_slot()?; - bp.vrf_evaluator.next_won_slot(cur_global_slot, best_tip) - }) { - store.dispatch(BlockProducerWonSlotAction { won_slot }); + BlockProducerAction::StagedLedgerDiffCreateSuccess { .. } => { + store.dispatch(BlockProducerAction::BlockUnprovenBuild); + } + BlockProducerAction::BlockUnprovenBuild => { + store.dispatch(BlockProducerAction::BlockProduced); + } + BlockProducerAction::BlockProduced => { + store.dispatch(BlockProducerAction::BlockInject); + } + BlockProducerAction::BlockInject => { + let Some((best_tip, root_block, blocks_inbetween)) = None.or_else(|| { + let (best_tip, chain) = store.state().block_producer.produced_block_with_chain()?; + let mut iter = chain.iter(); + let root_block = iter.next()?; + let blocks_inbetween = iter.map(|b| b.hash().clone()).collect(); + Some((best_tip.clone(), root_block.clone(), blocks_inbetween)) + }) else { + return; + }; + + if store.dispatch(TransitionFrontierSyncAction::BestTipUpdate { + best_tip, + root_block, + blocks_inbetween, + }) { + store.dispatch(BlockProducerAction::BlockInjected); + } } - } -} - -impl BlockProducerWonSlotAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - if !store.dispatch(BlockProducerWonSlotWaitAction {}) { - store.dispatch(BlockProducerWonSlotProduceInitAction {}); + BlockProducerAction::BlockInjected => { + store.dispatch(BlockProducerAction::WonSlotSearch); } - } -} - -impl BlockProducerWonSlotProduceInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(BlockProducerStagedLedgerDiffCreateInitAction {}); - } -} - -impl BlockProducerStagedLedgerDiffCreateInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let state = store.state.get(); - let Some((won_slot, pred_block, coinbase_receiver)) = None.or_else(|| { - let pred_block = state.block_producer.current_parent_chain()?.last()?; - let won_slot = state.block_producer.current_won_slot()?; - let coinbase_receiver = state.block_producer.config()?.coinbase_receiver(); - Some((won_slot, pred_block, coinbase_receiver)) - }) else { - return; - }; - - let completed_snarks = state - .snark_pool - .completed_snarks_iter() - .map(|snark| (snark.job_id(), snark.clone())) - .collect(); - // TODO(binier) - let supercharge_coinbase = false; - - // TODO(binier): error handling - let output = store - .service - .staged_ledger_diff_create( - pred_block, - won_slot, - coinbase_receiver, - completed_snarks, - supercharge_coinbase, - ) - .unwrap(); - - store.dispatch(BlockProducerStagedLedgerDiffCreatePendingAction {}); - store.dispatch(BlockProducerStagedLedgerDiffCreateSuccessAction { - diff: output.diff, - diff_hash: output.diff_hash, - staged_ledger_hash: output.staged_ledger_hash, - emitted_ledger_proof: output.emitted_ledger_proof, - }); - } -} - -impl BlockProducerStagedLedgerDiffCreateSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(BlockProducerBlockUnprovenBuildAction {}); - } -} - -impl BlockProducerBlockUnprovenBuildAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(BlockProducerBlockProducedAction {}); - } -} - -impl BlockProducerBlockProducedAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(BlockProducerBlockInjectAction {}); - } -} - -impl BlockProducerBlockInjectAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let Some((best_tip, root_block, blocks_inbetween)) = None.or_else(|| { - let (best_tip, chain) = store.state().block_producer.produced_block_with_chain()?; - let mut iter = chain.iter(); - let root_block = iter.next()?; - let blocks_inbetween = iter.map(|b| b.hash().clone()).collect(); - Some((best_tip.clone(), root_block.clone(), blocks_inbetween)) - }) else { - return; - }; - - if store.dispatch(TransitionFrontierSyncBestTipUpdateAction { - best_tip, - root_block, - blocks_inbetween, - }) { - store.dispatch(BlockProducerBlockInjectedAction {}); + BlockProducerAction::WonSlotDiscard { .. } => { + store.dispatch(BlockProducerAction::WonSlotSearch); } - } -} - -impl BlockProducerBlockInjectedAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(BlockProducerWonSlotSearchAction {}); - } -} - -impl BlockProducerWonSlotDiscardAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(BlockProducerWonSlotSearchAction {}); + BlockProducerAction::StagedLedgerDiffCreatePending => {} + BlockProducerAction::WonSlotWait => {} } } diff --git a/node/src/block_producer/block_producer_reducer.rs b/node/src/block_producer/block_producer_reducer.rs index 9b8d70504..a91fb00f4 100644 --- a/node/src/block_producer/block_producer_reducer.rs +++ b/node/src/block_producer/block_producer_reducer.rs @@ -5,8 +5,7 @@ use ledger::{ scan_state::currency::{Amount, Signed}, }; use mina_p2p_messages::{ - bigint::BigInt, - v2::{ + bigint::BigInt, list::List, v2::{ ConsensusGlobalSlotStableV1, ConsensusProofOfStakeDataConsensusStateValueStableV2, ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1, ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1, @@ -16,7 +15,7 @@ use mina_p2p_messages::{ MinaStateBlockchainStateValueStableV2LedgerProofStatement, MinaStateProtocolStateBodyValueStableV2, MinaStateProtocolStateValueStableV2, StagedLedgerDiffBodyStableV1, StateBodyHash, StateHash, UnsignedExtendedUInt32StableV1, - }, + } }; use openmina_core::block::{ArcBlockWithHash, BlockWithHash}; @@ -46,41 +45,40 @@ impl BlockProducerEnabled { BlockProducerAction::VrfEvaluator(action) => { self.vrf_evaluator.reducer(meta.with_action(action)) } - BlockProducerAction::BestTipUpdate(action) => { - self.vrf_evaluator.current_best_tip_slot = action - .best_tip + BlockProducerAction::BestTipUpdate { best_tip } => { + self.vrf_evaluator.current_best_tip_slot = best_tip .block .header .protocol_state .body .consensus_state - .curr_global_slot + .curr_global_slot_since_hard_fork .slot_number .as_u32(); // set the genesis timestamp on the first best tip update // TODO: move/remove once we can generate the genesis block if self.vrf_evaluator.genesis_timestamp == redux::Timestamp::ZERO { - self.vrf_evaluator.genesis_timestamp = action.best_tip.genesis_timestamp(); + self.vrf_evaluator.genesis_timestamp = best_tip.genesis_timestamp(); } } - BlockProducerAction::WonSlotSearch(_) => {} - BlockProducerAction::WonSlot(action) => { + BlockProducerAction::WonSlotSearch => {} + BlockProducerAction::WonSlot { won_slot } => { self.current = BlockProducerCurrentState::WonSlot { time: meta.time(), - won_slot: action.won_slot.clone(), + won_slot: won_slot.clone(), }; } - BlockProducerAction::WonSlotDiscard(action) => { + BlockProducerAction::WonSlotDiscard { reason } => { if let Some(won_slot) = self.current.won_slot() { self.current = BlockProducerCurrentState::WonSlotDiscarded { time: meta.time(), won_slot: won_slot.clone(), - reason: action.reason.clone(), + reason: reason.clone(), }; } } - BlockProducerAction::WonSlotWait(_) => { + BlockProducerAction::WonSlotWait => { if let Some(won_slot) = self.current.won_slot() { self.current = BlockProducerCurrentState::WonSlotWait { time: meta.time(), @@ -88,7 +86,7 @@ impl BlockProducerEnabled { }; } } - BlockProducerAction::WonSlotProduceInit(_) => { + BlockProducerAction::WonSlotProduceInit => { if let Some(won_slot) = self.current.won_slot() { let Some(chain) = best_chain.last().map(|best_tip| { if best_tip.global_slot() == won_slot.global_slot() { @@ -108,8 +106,8 @@ impl BlockProducerEnabled { }; } } - BlockProducerAction::StagedLedgerDiffCreateInit(_) => {} - BlockProducerAction::StagedLedgerDiffCreatePending(_) => { + BlockProducerAction::StagedLedgerDiffCreateInit => {} + BlockProducerAction::StagedLedgerDiffCreatePending => { let BlockProducerCurrentState::WonSlotProduceInit { won_slot, chain, .. } = &mut self.current @@ -123,7 +121,12 @@ impl BlockProducerEnabled { transactions: (), }; } - BlockProducerAction::StagedLedgerDiffCreateSuccess(action) => { + BlockProducerAction::StagedLedgerDiffCreateSuccess { + diff, + diff_hash, + staged_ledger_hash, + emitted_ledger_proof, + } => { let BlockProducerCurrentState::StagedLedgerDiffCreatePending { won_slot, chain, @@ -136,13 +139,13 @@ impl BlockProducerEnabled { time: meta.time(), won_slot: won_slot.clone(), chain: std::mem::take(chain), - diff: action.diff.clone(), - diff_hash: action.diff_hash.clone(), - staged_ledger_hash: action.staged_ledger_hash.clone(), - emitted_ledger_proof: action.emitted_ledger_proof.clone(), + diff: diff.clone(), + diff_hash: diff_hash.clone(), + staged_ledger_hash: staged_ledger_hash.clone(), + emitted_ledger_proof: emitted_ledger_proof.clone(), }; } - BlockProducerAction::BlockUnprovenBuild(_) => { + BlockProducerAction::BlockUnprovenBuild => { let BlockProducerCurrentState::StagedLedgerDiffCreateSuccess { won_slot, chain, @@ -166,14 +169,14 @@ impl BlockProducerEnabled { let genesis_ledger_hash = &pred_blockchain_state.genesis_ledger_hash; let block_timestamp = won_slot.timestamp(); - let pred_global_slot = pred_consensus_state.curr_global_slot.clone(); - let curr_global_slot = won_slot.global_slot.clone(); + let pred_global_slot = pred_consensus_state.curr_global_slot_since_hard_fork.clone(); + let curr_global_slot_since_hard_fork = won_slot.global_slot.clone(); let global_slot_since_genesis = won_slot.global_slot_since_genesis(pred_block.global_slot_diff()); let (pred_epoch, _) = to_epoch_and_slot(&pred_global_slot); - let (next_epoch, next_slot) = to_epoch_and_slot(&curr_global_slot); + let (next_epoch, next_slot) = to_epoch_and_slot(&curr_global_slot_since_hard_fork); let has_ancestor_in_same_checkpoint_window = - in_same_checkpoint_window(&pred_global_slot, &curr_global_slot); + in_same_checkpoint_window(&pred_global_slot, &curr_global_slot_since_hard_fork); let block_stake_winner = won_slot.delegator.0.clone(); let vrf_truncated_output = won_slot.vrf_output.clone(); @@ -264,7 +267,7 @@ impl BlockProducerEnabled { let pred_global_sub_window = global_sub_window(&pred_global_slot, pred_block.constants()); let next_global_sub_window = - global_sub_window(&curr_global_slot, pred_block.constants()); + global_sub_window(&curr_global_slot_since_hard_fork, pred_block.constants()); let pred_relative_sub_window = relative_sub_window(pred_global_sub_window); let next_relative_sub_window = relative_sub_window(next_global_sub_window); @@ -299,7 +302,7 @@ impl BlockProducerEnabled { let grace_period_end = grace_period_end(pred_block.constants()); let min_window_density = if is_same_global_sub_window - || curr_global_slot.slot_number.as_u32() < grace_period_end + || curr_global_slot_since_hard_fork.slot_number.as_u32() < grace_period_end { pred_consensus_state.min_window_density.clone() } else { @@ -347,7 +350,7 @@ impl BlockProducerEnabled { sub_window_densities, last_vrf_output: vrf_truncated_output, total_currency: (&total_currency).into(), - curr_global_slot, + curr_global_slot_since_hard_fork, global_slot_since_genesis, staking_epoch_data, next_epoch_data, @@ -385,7 +388,7 @@ impl BlockProducerEnabled { // TODO(binier): test let chain_proof_len = pred_block.constants().delta.as_u32() as usize; let delta_block_chain_proof = match chain_proof_len { - 0 => (hash.clone(), Vec::new()), + 0 => (hash.clone(), List::new()), chain_proof_len => { let mut iter = chain.iter().rev().take(chain_proof_len).rev(); let first_hash = iter @@ -395,7 +398,7 @@ impl BlockProducerEnabled { .map(|b| b.header().protocol_state.body.hash()) .chain(std::iter::once(body_hash)) .map(StateBodyHash::from) - .collect::>(); + .collect(); (first_hash, body_hashes) } }; @@ -426,7 +429,7 @@ impl BlockProducerEnabled { }, } } - BlockProducerAction::BlockProduced(_) => { + BlockProducerAction::BlockProduced => { if let BlockProducerCurrentState::BlockUnprovenBuilt { won_slot, chain, @@ -442,8 +445,8 @@ impl BlockProducerEnabled { }; } } - BlockProducerAction::BlockInject(_) => {} - BlockProducerAction::BlockInjected(_) => { + BlockProducerAction::BlockInject => {} + BlockProducerAction::BlockInjected => { if let BlockProducerCurrentState::Produced { won_slot, chain, diff --git a/node/src/block_producer/mod.rs b/node/src/block_producer/mod.rs index a6204b6b8..36e377c91 100644 --- a/node/src/block_producer/mod.rs +++ b/node/src/block_producer/mod.rs @@ -13,7 +13,7 @@ mod block_producer_actions; pub use block_producer_actions::*; mod block_producer_reducer; -pub use block_producer_reducer::*; + mod block_producer_effects; pub use block_producer_effects::*; diff --git a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_actions.rs b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_actions.rs index c090f03d1..408761054 100644 --- a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_actions.rs +++ b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_actions.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use crate::account::AccountPublicKey; -use crate::block_producer::{vrf_evaluator::BlockProducerVrfEvaluatorStatus, BlockProducerAction}; +use crate::block_producer::vrf_evaluator::BlockProducerVrfEvaluatorStatus; use mina_p2p_messages::v2::{ ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1, ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1, LedgerHash, @@ -16,119 +16,80 @@ pub type BlockProducerVrfEvaluatorActionWithMeta = pub type BlockProducerVrfEvaluatorActionWithMetaRef<'a> = redux::ActionWithMeta<&'a BlockProducerVrfEvaluatorAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] -pub enum BlockProducerVrfEvaluatorAction { - EpochDataUpdate(BlockProducerVrfEvaluatorEpochDataUpdateAction), - EvaluateVrf(BlockProducerVrfEvaluatorEvaluateVrfAction), - EvaluationSuccess(BlockProducerVrfEvaluatorEvaluationSuccessAction), - UpdateProducerAndDelegates(BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction), - UpdateProducerAndDelegatesSuccess( - BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction, - ), -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction { - pub current_epoch_ledger_hash: LedgerHash, - pub next_epoch_ledger_hash: LedgerHash, - pub producer: AccountPublicKey, -} - -impl redux::EnablingCondition - for BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.vrf_evaluator.status, - BlockProducerVrfEvaluatorStatus::EpochChanged { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction { - pub current_epoch_producer_and_delegators: Arc, - pub next_epoch_producer_and_delegators: Arc, - pub staking_ledger_hash: LedgerHash, -} - -impl redux::EnablingCondition - for BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.vrf_evaluator.status, - BlockProducerVrfEvaluatorStatus::DataPending { .. } - ) && this - .vrf_evaluator - .current_epoch_data - .as_ref() - .is_some_and(|epoch_data| epoch_data.ledger == self.staking_ledger_hash) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerVrfEvaluatorEvaluateVrfAction { - pub vrf_input: VrfEvaluatorInput, -} - -impl redux::EnablingCondition for BlockProducerVrfEvaluatorEvaluateVrfAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - matches!( - this.vrf_evaluator.status, - BlockProducerVrfEvaluatorStatus::SlotsReceived { .. } - | BlockProducerVrfEvaluatorStatus::DataSuccess { .. } - ) - }) - } -} - #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerVrfEvaluatorEvaluationSuccessAction { - pub vrf_output: VrfEvaluationOutput, - pub staking_ledger_hash: LedgerHash, +pub enum BlockProducerVrfEvaluatorAction { + EpochDataUpdate { + new_epoch_number: u32, + epoch_data: ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1, + next_epoch_data: ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1, + }, + EvaluateVrf { + vrf_input: VrfEvaluatorInput, + }, + EvaluationSuccess { + vrf_output: VrfEvaluationOutput, + staking_ledger_hash: LedgerHash, + }, + UpdateProducerAndDelegates { + current_epoch_ledger_hash: LedgerHash, + next_epoch_ledger_hash: LedgerHash, + producer: AccountPublicKey, + }, + UpdateProducerAndDelegatesSuccess { + current_epoch_producer_and_delegators: Arc, + next_epoch_producer_and_delegators: Arc, + staking_ledger_hash: LedgerHash, + }, } -impl redux::EnablingCondition for BlockProducerVrfEvaluatorEvaluationSuccessAction { +impl redux::EnablingCondition for BlockProducerVrfEvaluatorAction { fn is_enabled(&self, state: &crate::State) -> bool { - state.block_producer.with(false, |this| { - this.vrf_evaluator - .status - .matches_requsted_slot(self.vrf_output.global_slot(), &self.staking_ledger_hash) - }) + match self { + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates { .. } => { + state.block_producer.with(false, |this| { + matches!( + this.vrf_evaluator.status, + BlockProducerVrfEvaluatorStatus::EpochChanged { .. } + ) + }) + } + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess { + staking_ledger_hash, + .. + } => state.block_producer.with(false, |this| { + matches!( + this.vrf_evaluator.status, + BlockProducerVrfEvaluatorStatus::DataPending { .. } + ) && this + .vrf_evaluator + .current_epoch_data + .as_ref() + .is_some_and(|epoch_data| &epoch_data.ledger == staking_ledger_hash) + }), + BlockProducerVrfEvaluatorAction::EvaluateVrf { .. } => { + state.block_producer.with(false, |this| { + matches!( + this.vrf_evaluator.status, + BlockProducerVrfEvaluatorStatus::SlotsReceived { .. } + | BlockProducerVrfEvaluatorStatus::DataSuccess { .. } + ) + }) + } + BlockProducerVrfEvaluatorAction::EvaluationSuccess { + vrf_output, + staking_ledger_hash, + } => state.block_producer.with(false, |this| { + this.vrf_evaluator + .status + .matches_requested_slot(vrf_output.global_slot(), staking_ledger_hash) + }), + BlockProducerVrfEvaluatorAction::EpochDataUpdate { .. } => true, + } } } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct BlockProducerVrfEvaluatorEpochDataUpdateAction { - pub new_epoch_number: u32, - pub epoch_data: ConsensusProofOfStakeDataEpochDataStakingValueVersionedValueStableV1, - pub next_epoch_data: ConsensusProofOfStakeDataEpochDataNextValueVersionedValueStableV1, -} - -impl redux::EnablingCondition for BlockProducerVrfEvaluatorEpochDataUpdateAction { - fn is_enabled(&self, _: &crate::State) -> bool { - true +impl From for crate::Action { + fn from(value: BlockProducerVrfEvaluatorAction) -> Self { + Self::BlockProducer(crate::BlockProducerAction::VrfEvaluator(value.into())) } } - -macro_rules! impl_into_global_action { - ($a:ty) => { - impl From<$a> for crate::Action { - fn from(value: $a) -> Self { - Self::BlockProducer(BlockProducerAction::VrfEvaluator(value.into())) - } - } - }; -} - -impl_into_global_action!(BlockProducerVrfEvaluatorEpochDataUpdateAction); -impl_into_global_action!(BlockProducerVrfEvaluatorEvaluateVrfAction); -impl_into_global_action!(BlockProducerVrfEvaluatorEvaluationSuccessAction); -impl_into_global_action!(BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction); -impl_into_global_action!(BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction); diff --git a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_effects.rs b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_effects.rs index 0794aded9..9e5577c12 100644 --- a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_effects.rs +++ b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_effects.rs @@ -4,115 +4,115 @@ use crate::block_producer::vrf_evaluator::VrfEvaluatorInput; use crate::Service; use crate::Store; -use super::BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction; -use super::BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction; -use super::{ - BlockProducerVrfEvaluatorEpochDataUpdateAction, BlockProducerVrfEvaluatorEvaluateVrfAction, - BlockProducerVrfEvaluatorEvaluationSuccessAction, -}; +use super::BlockProducerVrfEvaluatorAction; -impl BlockProducerVrfEvaluatorEpochDataUpdateAction { +impl BlockProducerVrfEvaluatorAction { pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let vrf_evaluator_state_with_config = - store.state().block_producer.vrf_evaluator_with_config(); - if let Some((_, config)) = vrf_evaluator_state_with_config { - store.dispatch(BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction { - current_epoch_ledger_hash: self.epoch_data.ledger.hash, - next_epoch_ledger_hash: self.next_epoch_data.ledger.hash, - producer: config.pub_key.clone().into(), - }); - } - } -} - -impl BlockProducerVrfEvaluatorEvaluateVrfAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.service.evaluate(self.vrf_input); - } -} - -impl BlockProducerVrfEvaluatorEvaluationSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let Some((next_slot, current_epoch, current_epoch_data, next_epoch_data)) = - store.state().block_producer.with(None, |block_producer| { - let vrf_evaluator = &block_producer.vrf_evaluator; - let next_slot = vrf_evaluator.latest_evaluated_slot + 1; - let next_slot = next_slot.max(store.state().cur_global_slot()?); - - Some(( - next_slot, - vrf_evaluator.current_epoch.as_ref()?, - vrf_evaluator.current_epoch_data.as_ref()?, - vrf_evaluator.next_epoch_data.as_ref()?, - )) - }) - else { - return; - }; - - // TODO(adonagy): Can we get this from somewhere? - const SLOTS_PER_EPOCH: u32 = 7140; - let current_epoch_end = current_epoch * SLOTS_PER_EPOCH + SLOTS_PER_EPOCH - 1; - let next_epoch_end = (current_epoch + 1) * SLOTS_PER_EPOCH + SLOTS_PER_EPOCH - 1; - - // slot is in the current epoch - if next_slot <= current_epoch_end { - let vrf_input = VrfEvaluatorInput::new( - current_epoch_data.seed.clone(), - current_epoch_data.delegator_table.clone(), - next_slot, - current_epoch_data.total_currency, - current_epoch_data.ledger.clone(), - ); - store.dispatch(BlockProducerVrfEvaluatorEvaluateVrfAction { vrf_input }); - // slot is in the next epoch - } else if next_slot > current_epoch_end && next_slot <= next_epoch_end { - let vrf_input = VrfEvaluatorInput::new( - next_epoch_data.seed.clone(), - next_epoch_data.delegator_table.clone(), - next_slot, - next_epoch_data.total_currency, - next_epoch_data.ledger.clone(), - ); - store.dispatch(BlockProducerVrfEvaluatorEvaluateVrfAction { vrf_input }); - } - } -} + match self { + BlockProducerVrfEvaluatorAction::EpochDataUpdate { + epoch_data, + next_epoch_data, + .. + } => { + let vrf_evaluator_state_with_config = + store.state().block_producer.vrf_evaluator_with_config(); + if let Some((_, config)) = vrf_evaluator_state_with_config { + store.dispatch( + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates { + current_epoch_ledger_hash: epoch_data.ledger.hash, + next_epoch_ledger_hash: next_epoch_data.ledger.hash, + producer: config.pub_key.clone().into(), + }, + ); + } + } + BlockProducerVrfEvaluatorAction::EvaluateVrf { vrf_input } => { + store.service.evaluate(vrf_input); + } + BlockProducerVrfEvaluatorAction::EvaluationSuccess { .. } => { + let Some((next_slot, current_epoch, current_epoch_data, next_epoch_data)) = + store.state().block_producer.with(None, |block_producer| { + let vrf_evaluator = &block_producer.vrf_evaluator; + let next_slot = vrf_evaluator.latest_evaluated_slot + 1; + let next_slot = next_slot.max(store.state().cur_global_slot()?); -impl BlockProducerVrfEvaluatorUpdateProducerAndDelegatesAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let current_epoch_producer_and_delegators = store.service.get_producer_and_delegates( - self.current_epoch_ledger_hash.clone(), - self.producer.clone(), - ); - let next_epoch_producer_and_delegators = store - .service - .get_producer_and_delegates(self.next_epoch_ledger_hash, self.producer.clone()); + Some(( + next_slot, + vrf_evaluator.current_epoch.as_ref()?, + vrf_evaluator.current_epoch_data.as_ref()?, + vrf_evaluator.next_epoch_data.as_ref()?, + )) + }) + else { + return; + }; - store.dispatch( - BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction { - current_epoch_producer_and_delegators: current_epoch_producer_and_delegators.into(), - next_epoch_producer_and_delegators: next_epoch_producer_and_delegators.into(), - staking_ledger_hash: self.current_epoch_ledger_hash, - }, - ); - } -} + // TODO(adonagy): Can we get this from somewhere? + const SLOTS_PER_EPOCH: u32 = 7140; + let current_epoch_end = current_epoch * SLOTS_PER_EPOCH + SLOTS_PER_EPOCH - 1; + let next_epoch_end = (current_epoch + 1) * SLOTS_PER_EPOCH + SLOTS_PER_EPOCH - 1; -impl BlockProducerVrfEvaluatorUpdateProducerAndDelegatesSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let vrf_evaluator_state = store.state().block_producer.vrf_evaluator(); + // slot is in the current epoch + if next_slot <= current_epoch_end { + let vrf_input = VrfEvaluatorInput::new( + current_epoch_data.seed.clone(), + current_epoch_data.delegator_table.clone(), + next_slot, + current_epoch_data.total_currency, + current_epoch_data.ledger.clone(), + ); + store.dispatch(BlockProducerVrfEvaluatorAction::EvaluateVrf { vrf_input }); + // slot is in the next epoch + } else if next_slot > current_epoch_end && next_slot <= next_epoch_end { + let vrf_input = VrfEvaluatorInput::new( + next_epoch_data.seed.clone(), + next_epoch_data.delegator_table.clone(), + next_slot, + next_epoch_data.total_currency, + next_epoch_data.ledger.clone(), + ); + store.dispatch(BlockProducerVrfEvaluatorAction::EvaluateVrf { vrf_input }); + } + } + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates { + current_epoch_ledger_hash, + next_epoch_ledger_hash, + producer, + } => { + let current_epoch_producer_and_delegators = + store.service.get_producer_and_delegates( + current_epoch_ledger_hash.clone(), + producer.clone(), + ); + let next_epoch_producer_and_delegators = store + .service + .get_producer_and_delegates(next_epoch_ledger_hash, producer.clone()); - if let Some(vrf_evaluator_state) = vrf_evaluator_state { - if let Some(current_epoch_data) = &vrf_evaluator_state.current_epoch_data { - let vrf_input: VrfEvaluatorInput = VrfEvaluatorInput::new( - current_epoch_data.seed.clone(), - current_epoch_data.delegator_table.clone(), - vrf_evaluator_state.current_best_tip_slot + 1, - current_epoch_data.total_currency, - current_epoch_data.ledger.clone(), + store.dispatch( + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess { + current_epoch_producer_and_delegators: + current_epoch_producer_and_delegators.into(), + next_epoch_producer_and_delegators: next_epoch_producer_and_delegators + .into(), + staking_ledger_hash: current_epoch_ledger_hash, + }, ); - store.dispatch(BlockProducerVrfEvaluatorEvaluateVrfAction { vrf_input }); + } + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess { .. } => { + let vrf_evaluator_state = store.state().block_producer.vrf_evaluator(); + + if let Some(vrf_evaluator_state) = vrf_evaluator_state { + if let Some(current_epoch_data) = &vrf_evaluator_state.current_epoch_data { + let vrf_input: VrfEvaluatorInput = VrfEvaluatorInput::new( + current_epoch_data.seed.clone(), + current_epoch_data.delegator_table.clone(), + vrf_evaluator_state.current_best_tip_slot + 1, + current_epoch_data.total_currency, + current_epoch_data.ledger.clone(), + ); + store.dispatch(BlockProducerVrfEvaluatorAction::EvaluateVrf { vrf_input }); + } + } } } } diff --git a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_reducer.rs b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_reducer.rs index 78315abd0..65f90e4ce 100644 --- a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_reducer.rs +++ b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_reducer.rs @@ -7,36 +7,43 @@ impl BlockProducerVrfEvaluatorState { pub fn reducer(&mut self, action: BlockProducerVrfEvaluatorActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - BlockProducerVrfEvaluatorAction::EpochDataUpdate(action) => { + BlockProducerVrfEvaluatorAction::EpochDataUpdate { + new_epoch_number, + epoch_data, + next_epoch_data, + } => { self.status = BlockProducerVrfEvaluatorStatus::EpochChanged { time: meta.time() }; self.current_epoch_data = Some(EpochData::new( - action.epoch_data.seed.to_string(), - action.epoch_data.ledger.hash.clone(), - action.epoch_data.ledger.total_currency.as_u64(), + epoch_data.seed.to_string(), + epoch_data.ledger.hash.clone(), + epoch_data.ledger.total_currency.as_u64(), )); self.next_epoch_data = Some(EpochData::new( - action.next_epoch_data.seed.to_string(), - action.next_epoch_data.ledger.hash.clone(), - action.next_epoch_data.ledger.total_currency.as_u64(), + next_epoch_data.seed.to_string(), + next_epoch_data.ledger.hash.clone(), + next_epoch_data.ledger.total_currency.as_u64(), )); - self.current_epoch = Some(action.new_epoch_number); + self.current_epoch = Some(*new_epoch_number); } - BlockProducerVrfEvaluatorAction::EvaluateVrf(action) => { + BlockProducerVrfEvaluatorAction::EvaluateVrf { vrf_input } => { self.status = BlockProducerVrfEvaluatorStatus::SlotsRequested { time: meta.time(), - global_slot: action.vrf_input.global_slot, - staking_ledger_hash: action.vrf_input.staking_ledger_hash.clone(), + global_slot: vrf_input.global_slot, + staking_ledger_hash: vrf_input.staking_ledger_hash.clone(), }; } // BlockProducerVrfEvaluatorAction::EvaluationPending(_) => todo!(), - BlockProducerVrfEvaluatorAction::EvaluationSuccess(action) => { - let global_slot_evaluated = match &action.vrf_output { + BlockProducerVrfEvaluatorAction::EvaluationSuccess { + vrf_output, + staking_ledger_hash, + } => { + let global_slot_evaluated = match vrf_output { vrf::VrfEvaluationOutput::SlotWon(won_slot_data) => { self.won_slots.insert( won_slot_data.global_slot, VrfWonSlotWithHash::new( won_slot_data.clone(), - action.staking_ledger_hash.clone(), + staking_ledger_hash.clone(), ), ); won_slot_data.global_slot @@ -46,14 +53,17 @@ impl BlockProducerVrfEvaluatorState { self.status = BlockProducerVrfEvaluatorStatus::SlotsReceived { time: meta.time(), global_slot: global_slot_evaluated, - staking_ledger_hash: action.staking_ledger_hash.clone(), + staking_ledger_hash: staking_ledger_hash.clone(), }; self.latest_evaluated_slot = global_slot_evaluated; } - BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates(_) => { + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates { .. } => { self.status = BlockProducerVrfEvaluatorStatus::DataPending { time: meta.time() }; } - BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess(action) => { + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess { + current_epoch_producer_and_delegators, + .. + } => { self.status = BlockProducerVrfEvaluatorStatus::DataSuccess { time: meta.time() }; // TODO(adonagy): causes reevaluation of already evaluated slots. // Needed since delegate table changed and we might miss slots @@ -64,13 +74,11 @@ impl BlockProducerVrfEvaluatorState { self.latest_evaluated_slot = 0; if let Some(epoch_data) = self.current_epoch_data.as_mut() { - epoch_data.delegator_table = - action.current_epoch_producer_and_delegators.clone(); + epoch_data.delegator_table = current_epoch_producer_and_delegators.clone(); } if let Some(epoch_data) = self.next_epoch_data.as_mut() { - epoch_data.delegator_table = - action.current_epoch_producer_and_delegators.clone(); + epoch_data.delegator_table = current_epoch_producer_and_delegators.clone(); } } } diff --git a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_state.rs b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_state.rs index 41283f36b..470904097 100644 --- a/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_state.rs +++ b/node/src/block_producer/vrf_evaluator/block_producer_vrf_evaluator_state.rs @@ -131,7 +131,7 @@ pub enum BlockProducerVrfEvaluatorStatus { } impl BlockProducerVrfEvaluatorStatus { - pub fn matches_requsted_slot( + pub fn matches_requested_slot( &self, expected_global_slot: u32, expected_staking_ledger_hash: &LedgerHash, diff --git a/node/src/block_producer/vrf_evaluator/mod.rs b/node/src/block_producer/vrf_evaluator/mod.rs index cae2accf4..a04d6c44f 100644 --- a/node/src/block_producer/vrf_evaluator/mod.rs +++ b/node/src/block_producer/vrf_evaluator/mod.rs @@ -15,10 +15,10 @@ mod block_producer_vrf_evaluator_actions; pub use block_producer_vrf_evaluator_actions::*; mod block_producer_vrf_evaluator_reducer; -pub use block_producer_vrf_evaluator_reducer::*; + mod block_producer_vrf_evaluator_effects; -pub use block_producer_vrf_evaluator_effects::*; + mod block_producer_vrf_evaluator_service; pub use block_producer_vrf_evaluator_service::*; diff --git a/node/src/consensus/consensus_effects.rs b/node/src/consensus/consensus_effects.rs index f137464ab..046b1eef1 100644 --- a/node/src/consensus/consensus_effects.rs +++ b/node/src/consensus/consensus_effects.rs @@ -1,12 +1,7 @@ -use crate::transition_frontier::sync::{ - TransitionFrontierSyncBestTipUpdateAction, TransitionFrontierSyncInitAction, -}; -use crate::watched_accounts::WatchedAccountsLedgerInitialStateGetInitAction; +use crate::snark::block_verify::SnarkBlockVerifyAction; +use crate::transition_frontier::sync::TransitionFrontierSyncAction; +use crate::watched_accounts::WatchedAccountsAction; use crate::Store; -use crate::{ - snark::block_verify::SnarkBlockVerifyAction, - watched_accounts::WatchedAccountsBlockTransactionsIncludedAction, -}; use super::{ConsensusAction, ConsensusActionWithMeta}; @@ -46,10 +41,10 @@ pub fn consensus_effects(store: &mut Store, action: Consen return; }; for pub_key in store.state().watched_accounts.accounts() { - store.dispatch(WatchedAccountsLedgerInitialStateGetInitAction { + store.dispatch(WatchedAccountsAction::LedgerInitialStateGetInit { pub_key: pub_key.clone(), }); - store.dispatch(WatchedAccountsBlockTransactionsIncludedAction { + store.dispatch(WatchedAccountsAction::TransactionsIncludedInBlock { pub_key, block: block.clone(), }); @@ -90,13 +85,13 @@ fn transition_frontier_new_best_tip(store: &mut Store) { }; if !state.transition_frontier.sync.is_pending() && !state.transition_frontier.sync.is_synced() { - store.dispatch(TransitionFrontierSyncInitAction { + store.dispatch(TransitionFrontierSyncAction::Init { best_tip, root_block, blocks_inbetween, }); } else { - store.dispatch(TransitionFrontierSyncBestTipUpdateAction { + store.dispatch(TransitionFrontierSyncAction::BestTipUpdate { best_tip, root_block, blocks_inbetween, diff --git a/node/src/consensus/mod.rs b/node/src/consensus/mod.rs index 631a3fe7a..0ff6b6af8 100644 --- a/node/src/consensus/mod.rs +++ b/node/src/consensus/mod.rs @@ -5,7 +5,7 @@ mod consensus_actions; pub use consensus_actions::*; mod consensus_reducer; -pub use consensus_reducer::*; + mod consensus_effects; pub use consensus_effects::*; diff --git a/node/src/effects.rs b/node/src/effects.rs index a0f5afc5d..61d16d117 100644 --- a/node/src/effects.rs +++ b/node/src/effects.rs @@ -1,24 +1,21 @@ use p2p::channels::snark::P2pChannelsSnarkAction; use redux::ActionMeta; -use crate::block_producer::{block_producer_effects, BlockProducerWonSlotProduceInitAction}; +use crate::block_producer::{block_producer_effects, BlockProducerAction}; use crate::consensus::consensus_effects; use crate::event_source::event_source_effects; use crate::external_snark_worker::external_snark_worker_effects; use crate::logger::logger_effects; use crate::p2p::channels::rpc::{P2pChannelsRpcAction, P2pRpcKind, P2pRpcRequest}; -use crate::p2p::connection::incoming::P2pConnectionIncomingTimeoutAction; -use crate::p2p::connection::outgoing::{ - P2pConnectionOutgoingRandomInitAction, P2pConnectionOutgoingReconnectAction, - P2pConnectionOutgoingTimeoutAction, -}; -use crate::p2p::discovery::{P2pDiscoveryKademliaBootstrapAction, P2pDiscoveryKademliaInitAction}; +use crate::p2p::connection::incoming::P2pConnectionIncomingAction; +use crate::p2p::connection::outgoing::P2pConnectionOutgoingAction; +use crate::p2p::discovery::P2pDiscoveryAction; use crate::p2p::p2p_effects; use crate::rpc::rpc_effects; use crate::snark::snark_effects; use crate::snark_pool::candidate::SnarkPoolCandidateAction; use crate::snark_pool::{snark_pool_effects, SnarkPoolAction}; -use crate::transition_frontier::sync::TransitionFrontierSyncBlocksNextApplyInitAction; +use crate::transition_frontier::sync::TransitionFrontierSyncAction; use crate::transition_frontier::transition_frontier_effects; use crate::watched_accounts::watched_accounts_effects; use crate::{Action, ActionWithMeta, ExternalSnarkWorkerAction, Service, Store}; @@ -44,7 +41,7 @@ pub fn effects(store: &mut Store, action: ActionWithMeta) { p2p_connection_timeouts(store, &meta); - store.dispatch(P2pConnectionOutgoingRandomInitAction {}); + store.dispatch(P2pConnectionOutgoingAction::RandomInit); p2p_try_reconnect_disconnected_peers(store); @@ -58,8 +55,8 @@ pub fn effects(store: &mut Store, action: ActionWithMeta) { p2p_request_snarks_if_needed(store); - store.dispatch(P2pDiscoveryKademliaBootstrapAction {}); - store.dispatch(P2pDiscoveryKademliaInitAction {}); + store.dispatch(P2pDiscoveryAction::KademliaBootstrap); + store.dispatch(P2pDiscoveryAction::KademliaInit); #[cfg(feature = "p2p-webrtc")] p2p_discovery_request(store, &meta); @@ -69,12 +66,12 @@ pub fn effects(store: &mut Store, action: ActionWithMeta) { } // TODO(binier): remove once ledger communication is async. - store.dispatch(TransitionFrontierSyncBlocksNextApplyInitAction {}); + store.dispatch(TransitionFrontierSyncAction::BlocksNextApplyInit); store.dispatch(ExternalSnarkWorkerAction::StartTimeout { now: meta.time() }); store.dispatch(ExternalSnarkWorkerAction::WorkTimeout { now: meta.time() }); - store.dispatch(BlockProducerWonSlotProduceInitAction {}); + store.dispatch(BlockProducerAction::WonSlotProduceInit); } Action::EventSource(action) => { event_source_effects(store, meta.with_action(action)); @@ -127,8 +124,8 @@ fn p2p_connection_timeouts(store: &mut Store, meta: &ActionMeta) for (peer_id, is_outgoing) in p2p_connection_timeouts { match is_outgoing { - true => store.dispatch(P2pConnectionOutgoingTimeoutAction { peer_id }), - false => store.dispatch(P2pConnectionIncomingTimeoutAction { peer_id }), + true => store.dispatch(P2pConnectionOutgoingAction::Timeout { peer_id }), + false => store.dispatch(P2pConnectionIncomingAction::Timeout { peer_id }), }; } } @@ -140,7 +137,7 @@ fn p2p_try_reconnect_disconnected_peers(store: &mut Store) { .peers .iter() .filter_map(|(_, p)| p.dial_opts.clone()) - .map(|opts| P2pConnectionOutgoingReconnectAction { opts, rpc_id: None }) + .map(|opts| P2pConnectionOutgoingAction::Reconnect { opts, rpc_id: None }) .collect(); for action in reconnect_actions { store.dispatch(action); @@ -214,8 +211,6 @@ fn p2p_request_snarks_if_needed(store: &mut Store) { /// If the elapsed time is large enough, send another discovery request. #[cfg(feature = "p2p-webrtc")] fn p2p_discovery_request(store: &mut Store, meta: &ActionMeta) { - use crate::p2p::discovery::P2pDiscoveryInitAction; - let peer_ids = store .state() .p2p @@ -245,6 +240,6 @@ fn p2p_discovery_request(store: &mut Store, meta: &ActionMeta) { .collect::>(); for peer_id in peer_ids { - store.dispatch(P2pDiscoveryInitAction { peer_id }); + store.dispatch(P2pDiscoveryAction::Init { peer_id }); } } diff --git a/node/src/event_source/event_source_actions.rs b/node/src/event_source/event_source_actions.rs index aaf1b9597..50f62bb3f 100644 --- a/node/src/event_source/event_source_actions.rs +++ b/node/src/event_source/event_source_actions.rs @@ -2,82 +2,34 @@ use serde::{Deserialize, Serialize}; pub type EventSourceActionWithMeta = redux::ActionWithMeta; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] -pub enum EventSourceAction { - ProcessEvents(EventSourceProcessEventsAction), - NewEvent(EventSourceNewEventAction), - WaitForEvents(EventSourceWaitForEventsAction), - WaitTimeout(EventSourceWaitTimeoutAction), -} - -/// Notify state machine that the new events might be received/available, -/// so trigger processing of those events. -/// -/// This action will be continously triggered, until there are no more -/// events in the queue, in which case `EventSourceWaitForEventsAction` -/// will be dispatched. #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct EventSourceProcessEventsAction {} +pub enum EventSourceAction { + /// Notify state machine that the new events might be received/available, + /// so trigger processing of those events. + /// + /// This action will be continuously triggered, until there are no more + /// events in the queue, in which case `EventSourceWaitForEventsAction` + /// will be dispatched. + ProcessEvents, -impl redux::EnablingCondition for EventSourceProcessEventsAction { - fn is_enabled(&self, _: &crate::State) -> bool { - true - } -} + /// Process newly retrieved event. + NewEvent { event: super::Event }, -/// Process newly retrieved event. -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct EventSourceNewEventAction { - pub event: super::Event, -} + /// Next action won't be dispatched, until new events are available or + /// wait times out. + WaitForEvents, -impl redux::EnablingCondition for EventSourceNewEventAction { - fn is_enabled(&self, _: &crate::State) -> bool { - true - } + /// Waiting for events has timed out. + WaitTimeout, } -/// Next action won't be dispatched, until new events are available or -/// wait times out. -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct EventSourceWaitForEventsAction {} - -impl redux::EnablingCondition for EventSourceWaitForEventsAction { +impl redux::EnablingCondition for EventSourceAction { fn is_enabled(&self, _: &crate::State) -> bool { - true - } -} - -/// Waiting for events has timed out. -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct EventSourceWaitTimeoutAction {} - -impl redux::EnablingCondition for EventSourceWaitTimeoutAction { - fn is_enabled(&self, _: &crate::State) -> bool { - true - } -} - -impl From for crate::Action { - fn from(a: EventSourceProcessEventsAction) -> Self { - Self::EventSource(EventSourceAction::ProcessEvents(a)) - } -} - -impl From for crate::Action { - fn from(a: EventSourceNewEventAction) -> Self { - Self::EventSource(EventSourceAction::NewEvent(a)) - } -} - -impl From for crate::Action { - fn from(a: EventSourceWaitForEventsAction) -> Self { - Self::EventSource(EventSourceAction::WaitForEvents(a)) - } -} - -impl From for crate::Action { - fn from(a: EventSourceWaitTimeoutAction) -> Self { - Self::EventSource(EventSourceAction::WaitTimeout(a)) + match self { + EventSourceAction::ProcessEvents => true, + EventSourceAction::NewEvent { event: _ } => true, + EventSourceAction::WaitForEvents => true, + EventSourceAction::WaitTimeout => true, + } } } diff --git a/node/src/event_source/event_source_effects.rs b/node/src/event_source/event_source_effects.rs index 428da9e83..16abc198b 100644 --- a/node/src/event_source/event_source_effects.rs +++ b/node/src/event_source/event_source_effects.rs @@ -1,58 +1,32 @@ use p2p::channels::snark::P2pChannelsSnarkAction; -use p2p::listen::{ - P2pListenClosedAction, P2pListenErrorAction, P2pListenExpiredAction, P2pListenNewAction, -}; +use p2p::listen::P2pListenAction; use p2p::P2pListenEvent; use crate::action::CheckTimeoutsAction; -use crate::block_producer::vrf_evaluator::BlockProducerVrfEvaluatorEvaluationSuccessAction; +use crate::block_producer::vrf_evaluator::BlockProducerVrfEvaluatorAction; use crate::external_snark_worker::ExternalSnarkWorkerEvent; use crate::p2p::channels::best_tip::P2pChannelsBestTipAction; use crate::p2p::channels::rpc::P2pChannelsRpcAction; use crate::p2p::channels::snark_job_commitment::P2pChannelsSnarkJobCommitmentAction; use crate::p2p::channels::{ChannelId, P2pChannelsMessageReceivedAction}; -use crate::p2p::connection::incoming::{ - P2pConnectionIncomingAnswerSdpCreateErrorAction, - P2pConnectionIncomingAnswerSdpCreateSuccessAction, P2pConnectionIncomingFinalizeErrorAction, - P2pConnectionIncomingFinalizeSuccessAction, P2pConnectionIncomingLibp2pReceivedAction, -}; -use crate::p2p::connection::outgoing::{ - P2pConnectionOutgoingAnswerRecvErrorAction, P2pConnectionOutgoingAnswerRecvSuccessAction, - P2pConnectionOutgoingFinalizeErrorAction, P2pConnectionOutgoingFinalizeSuccessAction, - P2pConnectionOutgoingOfferSdpCreateErrorAction, - P2pConnectionOutgoingOfferSdpCreateSuccessAction, -}; +use crate::p2p::connection::incoming::P2pConnectionIncomingAction; +use crate::p2p::connection::outgoing::P2pConnectionOutgoingAction; use crate::p2p::connection::{P2pConnectionErrorResponse, P2pConnectionResponse}; -use crate::p2p::disconnection::{ - P2pDisconnectionFinishAction, P2pDisconnectionInitAction, P2pDisconnectionReason, -}; -use crate::p2p::discovery::{ - P2pDiscoveryKademliaAddRouteAction, P2pDiscoveryKademliaFailureAction, - P2pDiscoveryKademliaSuccessAction, -}; +use crate::p2p::disconnection::{P2pDisconnectionAction, P2pDisconnectionReason}; +use crate::p2p::discovery::P2pDiscoveryAction; use crate::p2p::P2pChannelEvent; -use crate::rpc::{ - RpcActionStatsGetAction, RpcGlobalStateGetAction, RpcHealthCheckAction, - RpcP2pConnectionIncomingInitAction, RpcP2pConnectionOutgoingInitAction, RpcPeersGetAction, - RpcReadinessCheckAction, RpcRequest, RpcScanStateSummaryGetAction, - RpcSnarkPoolAvailableJobsGetAction, RpcSnarkPoolJobGetAction, RpcSnarkerConfigGetAction, - RpcSnarkerJobCommitAction, RpcSnarkerJobSpecAction, RpcSnarkersWorkersGetAction, - RpcSyncStatsGetAction, -}; +use crate::rpc::{RpcAction, RpcRequest}; use crate::snark::block_verify::SnarkBlockVerifyAction; use crate::snark::work_verify::SnarkWorkVerifyAction; use crate::snark::SnarkEvent; use crate::{ExternalSnarkWorkerAction, Service, Store}; -use super::{ - Event, EventSourceAction, EventSourceActionWithMeta, EventSourceNewEventAction, - P2pConnectionEvent, P2pEvent, -}; +use super::{Event, EventSourceAction, EventSourceActionWithMeta, P2pConnectionEvent, P2pEvent}; pub fn event_source_effects(store: &mut Store, action: EventSourceActionWithMeta) { let (action, meta) = action.split(); match action { - EventSourceAction::ProcessEvents(_) => { + EventSourceAction::ProcessEvents => { // This action gets continously called until there are no more // events available. // @@ -63,7 +37,7 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc for _ in 0..1024 { match store.service.next_event() { Some(event) => { - store.dispatch(EventSourceNewEventAction { event }); + store.dispatch(EventSourceAction::NewEvent { event }); } None => break, } @@ -71,32 +45,32 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc store.dispatch(CheckTimeoutsAction {}); } // "Translate" event into the corresponding action and dispatch it. - EventSourceAction::NewEvent(content) => match content.event { + EventSourceAction::NewEvent { event } => match event { Event::P2p(e) => match e { P2pEvent::Listen(e) => match e { P2pListenEvent::NewListenAddr { listener_id, addr } => { - store.dispatch(P2pListenNewAction { listener_id, addr }); + store.dispatch(P2pListenAction::New { listener_id, addr }); } P2pListenEvent::ExpiredListenAddr { listener_id, addr } => { - store.dispatch(P2pListenExpiredAction { listener_id, addr }); + store.dispatch(P2pListenAction::Expired { listener_id, addr }); } P2pListenEvent::ListenerError { listener_id, error } => { - store.dispatch(P2pListenErrorAction { listener_id, error }); + store.dispatch(P2pListenAction::Error { listener_id, error }); } P2pListenEvent::ListenerClosed { listener_id, error } => { - store.dispatch(P2pListenClosedAction { listener_id, error }); + store.dispatch(P2pListenAction::Closed { listener_id, error }); } }, P2pEvent::Connection(e) => match e { P2pConnectionEvent::OfferSdpReady(peer_id, res) => match res { Err(error) => { - store.dispatch(P2pConnectionOutgoingOfferSdpCreateErrorAction { + store.dispatch(P2pConnectionOutgoingAction::OfferSdpCreateError { peer_id, error, }); } Ok(sdp) => { - store.dispatch(P2pConnectionOutgoingOfferSdpCreateSuccessAction { + store.dispatch(P2pConnectionOutgoingAction::OfferSdpCreateSuccess { peer_id, sdp, }); @@ -104,13 +78,13 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc }, P2pConnectionEvent::AnswerSdpReady(peer_id, res) => match res { Err(error) => { - store.dispatch(P2pConnectionIncomingAnswerSdpCreateErrorAction { + store.dispatch(P2pConnectionIncomingAction::AnswerSdpCreateError { peer_id, error, }); } Ok(sdp) => { - store.dispatch(P2pConnectionIncomingAnswerSdpCreateSuccessAction { + store.dispatch(P2pConnectionIncomingAction::AnswerSdpCreateSuccess { peer_id, sdp, }); @@ -118,19 +92,19 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc }, P2pConnectionEvent::AnswerReceived(peer_id, res) => match res { P2pConnectionResponse::Accepted(answer) => { - store.dispatch(P2pConnectionOutgoingAnswerRecvSuccessAction { + store.dispatch(P2pConnectionOutgoingAction::AnswerRecvSuccess { peer_id, answer, }); } P2pConnectionResponse::Rejected(reason) => { - store.dispatch(P2pConnectionOutgoingAnswerRecvErrorAction { + store.dispatch(P2pConnectionOutgoingAction::AnswerRecvError { peer_id, error: P2pConnectionErrorResponse::Rejected(reason), }); } P2pConnectionResponse::InternalError => { - store.dispatch(P2pConnectionOutgoingAnswerRecvErrorAction { + store.dispatch(P2pConnectionOutgoingAction::AnswerRecvError { peer_id, error: P2pConnectionErrorResponse::InternalError, }); @@ -138,28 +112,28 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc }, P2pConnectionEvent::Finalized(peer_id, res) => match res { Err(error) => { - store.dispatch(P2pConnectionOutgoingFinalizeErrorAction { + store.dispatch(P2pConnectionOutgoingAction::FinalizeError { peer_id, error: error.clone(), }); - store.dispatch(P2pConnectionIncomingFinalizeErrorAction { + store.dispatch(P2pConnectionIncomingAction::FinalizeError { peer_id, error, }); } Ok(_) => { let _ = store - .dispatch(P2pConnectionOutgoingFinalizeSuccessAction { peer_id }) - || store.dispatch(P2pConnectionIncomingFinalizeSuccessAction { + .dispatch(P2pConnectionOutgoingAction::FinalizeSuccess { peer_id }) + || store.dispatch(P2pConnectionIncomingAction::FinalizeSuccess { peer_id, }) - || store.dispatch(P2pConnectionIncomingLibp2pReceivedAction { + || store.dispatch(P2pConnectionIncomingAction::Libp2pReceived { peer_id, }); } }, P2pConnectionEvent::Closed(peer_id) => { - store.dispatch(P2pDisconnectionFinishAction { peer_id }); + store.dispatch(P2pDisconnectionAction::Finish { peer_id }); } }, P2pEvent::Channel(e) => match e { @@ -192,13 +166,13 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc P2pChannelEvent::Sent(peer_id, _, _, res) => { if let Err(err) = res { let reason = P2pDisconnectionReason::P2pChannelSendFailed(err); - store.dispatch(P2pDisconnectionInitAction { peer_id, reason }); + store.dispatch(P2pDisconnectionAction::Init { peer_id, reason }); } } P2pChannelEvent::Received(peer_id, res) => match res { Err(err) => { let reason = P2pDisconnectionReason::P2pChannelReceiveFailed(err); - store.dispatch(P2pDisconnectionInitAction { peer_id, reason }); + store.dispatch(P2pDisconnectionAction::Init { peer_id, reason }); } Ok(message) => { store.dispatch(P2pChannelsMessageReceivedAction { peer_id, message }); @@ -213,20 +187,20 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc } P2pChannelEvent::Closed(peer_id, chan_id) => { let reason = P2pDisconnectionReason::P2pChannelClosed(chan_id); - store.dispatch(P2pDisconnectionInitAction { peer_id, reason }); + store.dispatch(P2pDisconnectionAction::Init { peer_id, reason }); } }, #[cfg(not(target_arch = "wasm32"))] P2pEvent::Libp2pIdentify(..) => {} P2pEvent::Discovery(p2p::P2pDiscoveryEvent::Ready) => {} P2pEvent::Discovery(p2p::P2pDiscoveryEvent::DidFindPeers(peers)) => { - store.dispatch(P2pDiscoveryKademliaSuccessAction { peers }); + store.dispatch(P2pDiscoveryAction::KademliaSuccess { peers }); } P2pEvent::Discovery(p2p::P2pDiscoveryEvent::DidFindPeersError(description)) => { - store.dispatch(P2pDiscoveryKademliaFailureAction { description }); + store.dispatch(P2pDiscoveryAction::KademliaFailure { description }); } P2pEvent::Discovery(p2p::P2pDiscoveryEvent::AddRoute(peer_id, addresses)) => { - store.dispatch(P2pDiscoveryKademliaAddRouteAction { peer_id, addresses }); + store.dispatch(P2pDiscoveryAction::KademliaAddRoute { peer_id, addresses }); } }, Event::Snark(event) => match event { @@ -249,52 +223,52 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc }, Event::Rpc(rpc_id, e) => match e { RpcRequest::StateGet => { - store.dispatch(RpcGlobalStateGetAction { rpc_id }); + store.dispatch(RpcAction::GlobalStateGet { rpc_id }); } RpcRequest::ActionStatsGet(query) => { - store.dispatch(RpcActionStatsGetAction { rpc_id, query }); + store.dispatch(RpcAction::ActionStatsGet { rpc_id, query }); } RpcRequest::SyncStatsGet(query) => { - store.dispatch(RpcSyncStatsGetAction { rpc_id, query }); + store.dispatch(RpcAction::SyncStatsGet { rpc_id, query }); } RpcRequest::PeersGet => { - store.dispatch(RpcPeersGetAction { rpc_id }); + store.dispatch(RpcAction::PeersGet { rpc_id }); } RpcRequest::P2pConnectionOutgoing(opts) => { - store.dispatch(RpcP2pConnectionOutgoingInitAction { rpc_id, opts }); + store.dispatch(RpcAction::P2pConnectionOutgoingInit { rpc_id, opts }); } RpcRequest::P2pConnectionIncoming(opts) => { - store.dispatch(RpcP2pConnectionIncomingInitAction { + store.dispatch(RpcAction::P2pConnectionIncomingInit { rpc_id, opts: opts.clone(), }); } RpcRequest::ScanStateSummaryGet(query) => { - store.dispatch(RpcScanStateSummaryGetAction { rpc_id, query }); + store.dispatch(RpcAction::ScanStateSummaryGet { rpc_id, query }); } RpcRequest::SnarkPoolGet => { - store.dispatch(RpcSnarkPoolAvailableJobsGetAction { rpc_id }); + store.dispatch(RpcAction::SnarkPoolAvailableJobsGet { rpc_id }); } RpcRequest::SnarkPoolJobGet { job_id } => { - store.dispatch(RpcSnarkPoolJobGetAction { rpc_id, job_id }); + store.dispatch(RpcAction::SnarkPoolJobGet { rpc_id, job_id }); } RpcRequest::SnarkerConfig => { - store.dispatch(RpcSnarkerConfigGetAction { rpc_id }); + store.dispatch(RpcAction::SnarkerConfigGet { rpc_id }); } RpcRequest::SnarkerJobCommit { job_id } => { - store.dispatch(RpcSnarkerJobCommitAction { rpc_id, job_id }); + store.dispatch(RpcAction::SnarkerJobCommit { rpc_id, job_id }); } RpcRequest::SnarkerJobSpec { job_id } => { - store.dispatch(RpcSnarkerJobSpecAction { rpc_id, job_id }); + store.dispatch(RpcAction::SnarkerJobSpec { rpc_id, job_id }); } RpcRequest::SnarkerWorkers => { - store.dispatch(RpcSnarkersWorkersGetAction { rpc_id }); + store.dispatch(RpcAction::SnarkerWorkersGet { rpc_id }); } RpcRequest::HealthCheck => { - store.dispatch(RpcHealthCheckAction { rpc_id }); + store.dispatch(RpcAction::HealthCheck { rpc_id }); } RpcRequest::ReadinessCheck => { - store.dispatch(RpcReadinessCheckAction { rpc_id }); + store.dispatch(RpcAction::ReadinessCheck { rpc_id }); } }, Event::ExternalSnarkWorker(e) => match e { @@ -325,7 +299,7 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc crate::block_producer::BlockProducerVrfEvaluatorEvent::Evaluated( vrf_output_with_hash, ) => { - store.dispatch(BlockProducerVrfEvaluatorEvaluationSuccessAction { + store.dispatch(BlockProducerVrfEvaluatorAction::EvaluationSuccess { vrf_output: vrf_output_with_hash.evaluation_result, staking_ledger_hash: vrf_output_with_hash.staking_ledger_hash, }); @@ -333,9 +307,9 @@ pub fn event_source_effects(store: &mut Store, action: EventSourc }, }, }, - EventSourceAction::WaitTimeout(_) => { + EventSourceAction::WaitTimeout => { store.dispatch(CheckTimeoutsAction {}); } - EventSourceAction::WaitForEvents(_) => {} + EventSourceAction::WaitForEvents => {} } } diff --git a/node/src/ledger/ledger_service.rs b/node/src/ledger/ledger_service.rs index 1106a1c93..ad2447096 100644 --- a/node/src/ledger/ledger_service.rs +++ b/node/src/ledger/ledger_service.rs @@ -1,5 +1,6 @@ use std::{ collections::{BTreeMap, BTreeSet}, + fs::File, path::Path, sync::Arc, }; @@ -25,15 +26,19 @@ use ledger::{ validate_block::block_body_hash, }, verifier::Verifier, - AccountIndex, BaseLedger, Mask, TreeVersion, UnregisterBehavior, + Account, AccountIndex, BaseLedger, Database, Mask, TreeVersion, UnregisterBehavior, }; use mina_hasher::Fp; -use mina_p2p_messages::v2::{ - self, DataHashLibStateHashStableV1, LedgerHash, MinaBaseAccountBinableArgStableV2, - MinaBaseLedgerHash0StableV1, MinaBaseSokMessageStableV1, MinaBaseStagedLedgerHashStableV1, - MinaLedgerSyncLedgerAnswerStableV2, MinaLedgerSyncLedgerQueryStableV1, - MinaStateBlockchainStateValueStableV2LedgerProofStatement, MinaStateProtocolStateValueStableV2, - MinaTransactionTransactionStableV2, NonZeroCurvePoint, StateHash, +use mina_p2p_messages::{ + binprot::BinProtRead, + v2::{ + self, DataHashLibStateHashStableV1, LedgerHash, MinaBaseAccountBinableArgStableV2, + MinaBaseLedgerHash0StableV1, MinaBaseSokMessageStableV1, MinaBaseStagedLedgerHashStableV1, + MinaLedgerSyncLedgerAnswerStableV2, MinaLedgerSyncLedgerQueryStableV1, + MinaStateBlockchainStateValueStableV2LedgerProofStatement, + MinaStateProtocolStateValueStableV2, MinaTransactionTransactionStableV2, NonZeroCurvePoint, + StateHash, + }, }; use openmina_core::snark::{Snark, SnarkJobId}; @@ -103,8 +108,26 @@ struct LedgerSyncState { } impl LedgerCtx { - pub fn new() -> Self { - Default::default() + pub fn load_genesis_ledger

(&mut self, path: P) + where + P: AsRef, + { + // TODO: return error + let mut reader = File::open(path).unwrap(); + let top_hash = Option::binprot_read(&mut reader).unwrap(); + let accounts = Vec::::binprot_read(&mut reader).unwrap(); + + let mut mask = Mask::new_root(Database::create(35)); + for account in accounts { + let account_id = account.id(); + mask.get_or_create_account(account_id, account).unwrap(); + } + + let top_hash = top_hash.unwrap_or_else(|| { + v2::LedgerHash::from(v2::MinaBaseLedgerHash0StableV1(mask.merkle_root().into())) + }); + + self.snarked_ledgers.insert(top_hash, mask); } pub fn new_with_additional_snarked_ledgers

(path: P) -> Self @@ -113,9 +136,6 @@ impl LedgerCtx { { use std::fs; - use ledger::{Account, Database}; - use mina_p2p_messages::binprot::BinProtRead; - let Ok(dir) = fs::read_dir(path) else { return Self::default(); }; @@ -784,7 +804,7 @@ impl BlockProducerService for T { won_slot.global_slot_since_genesis(pred_block.global_slot_diff()); // TODO(binier): include `invalid_txns` in output. - let (pre_diff, invalid_txns) = staged_ledger + let (pre_diff, _invalid_txns) = staged_ledger .create_diff( &CONSTRAINT_CONSTANTS, (&global_slot_since_genesis).into(), diff --git a/node/src/logger/logger_effects.rs b/node/src/logger/logger_effects.rs index e5170a7b5..812093c9e 100644 --- a/node/src/logger/logger_effects.rs +++ b/node/src/logger/logger_effects.rs @@ -23,340 +23,343 @@ pub fn logger_effects(store: &Store, action: ActionWithMetaRef<'_ match action { Action::P2p(action) => match action { P2pAction::Listen(action) => match action { - p2p::listen::P2pListenAction::New(action) => { + p2p::listen::P2pListenAction::New { listener_id, addr } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("addr: {}", action.addr), - addr = action.addr.to_string(), - listener_id = action.listener_id.to_string(), + summary = format!("addr: {addr}"), + addr = addr.to_string(), + listener_id = listener_id.to_string(), ); } - p2p::listen::P2pListenAction::Expired(action) => { + p2p::listen::P2pListenAction::Expired { listener_id, addr } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("addr: {}", action.addr), - addr = action.addr.to_string(), - listener_id = action.listener_id.to_string(), + summary = format!("addr: {addr}"), + addr = addr.to_string(), + listener_id = listener_id.to_string(), ); } - p2p::listen::P2pListenAction::Error(action) => { + p2p::listen::P2pListenAction::Error { listener_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("id: {}, error: {}", action.listener_id, action.error), - error = action.error, - listener_id = action.listener_id.to_string(), + summary = format!("id: {listener_id}, error: {error}"), + error = error, + listener_id = listener_id.to_string(), ); } - p2p::listen::P2pListenAction::Closed(action) => { - if let Some(error) = &action.error { + p2p::listen::P2pListenAction::Closed { listener_id, error } => { + if let Some(error) = error { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("id: {}, error: {error}", action.listener_id), + summary = format!("id: {listener_id}, error: {error}"), error = error, - listener_id = action.listener_id.to_string(), + listener_id = listener_id.to_string(), ); } else { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("id: {},", action.listener_id), - listener_id = action.listener_id.to_string(), + summary = format!("id: {listener_id},"), + listener_id = listener_id.to_string(), ); } } }, P2pAction::Connection(action) => match action { P2pConnectionAction::Outgoing(action) => match action { - P2pConnectionOutgoingAction::RandomInit(_) => {} - P2pConnectionOutgoingAction::Init(action) => { + P2pConnectionOutgoingAction::RandomInit => {} + P2pConnectionOutgoingAction::Init { opts, .. } => { + let peer_id = opts.peer_id(); openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.opts.peer_id()), - peer_id = action.opts.peer_id().to_string(), - transport = action.opts.kind(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + transport = opts.kind(), ); } - P2pConnectionOutgoingAction::Reconnect(action) => { + P2pConnectionOutgoingAction::Reconnect { opts, .. } => { + let peer_id = opts.peer_id(); openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.opts.peer_id()), - peer_id = action.opts.peer_id().to_string(), - transport = action.opts.kind(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + transport = opts.kind(), ); } - P2pConnectionOutgoingAction::OfferSdpCreatePending(_) => {} - P2pConnectionOutgoingAction::OfferSdpCreateError(action) => { + P2pConnectionOutgoingAction::OfferSdpCreatePending { .. } => {} + P2pConnectionOutgoingAction::OfferSdpCreateError { peer_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - error = action.error.clone(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + error = error.clone(), ); } - P2pConnectionOutgoingAction::OfferSdpCreateSuccess(action) => { + P2pConnectionOutgoingAction::OfferSdpCreateSuccess { peer_id, sdp } => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - sdp = action.sdp.clone(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + sdp = sdp.clone(), ); } - P2pConnectionOutgoingAction::OfferReady(action) => { + P2pConnectionOutgoingAction::OfferReady { peer_id, offer } => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - offer = serde_json::to_string(&action.offer).ok() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + offer = serde_json::to_string(offer).ok() ); } - P2pConnectionOutgoingAction::OfferSendSuccess(action) => { + P2pConnectionOutgoingAction::OfferSendSuccess { peer_id } => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), ); } - P2pConnectionOutgoingAction::AnswerRecvPending(_) => {} - P2pConnectionOutgoingAction::AnswerRecvError(action) => { + P2pConnectionOutgoingAction::AnswerRecvPending { .. } => {} + P2pConnectionOutgoingAction::AnswerRecvError { peer_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - error = format!("{:?}", action.error), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + error = format!("{:?}", error), ); } - P2pConnectionOutgoingAction::AnswerRecvSuccess(action) => { + P2pConnectionOutgoingAction::AnswerRecvSuccess { peer_id, answer } => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - trace_answer = serde_json::to_string(&action.answer).ok() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + trace_answer = serde_json::to_string(answer).ok() ); } - P2pConnectionOutgoingAction::FinalizePending(_) => {} - P2pConnectionOutgoingAction::FinalizeError(action) => { + P2pConnectionOutgoingAction::FinalizePending { .. } => {} + P2pConnectionOutgoingAction::FinalizeError { peer_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - error = action.error.clone(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + error = error.clone(), ); } - P2pConnectionOutgoingAction::FinalizeSuccess(action) => { + P2pConnectionOutgoingAction::FinalizeSuccess { peer_id } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string() ); } - P2pConnectionOutgoingAction::Timeout(action) => { + P2pConnectionOutgoingAction::Timeout { peer_id } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string() ); } - P2pConnectionOutgoingAction::Error(action) => { + P2pConnectionOutgoingAction::Error { peer_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - error = format!("{:?}", action.error), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + error = format!("{:?}", error), ); } - P2pConnectionOutgoingAction::Success(action) => { + P2pConnectionOutgoingAction::Success { peer_id } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string() ); } }, P2pConnectionAction::Incoming(action) => match action { - P2pConnectionIncomingAction::Init(action) => { + P2pConnectionIncomingAction::Init { opts, .. } => { + let peer_id = opts.peer_id; openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.opts.peer_id), - peer_id = action.opts.peer_id.to_string(), - trace_signaling = format!("{:?}", action.opts.signaling), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + trace_signaling = format!("{:?}", opts.signaling), ); } - P2pConnectionIncomingAction::AnswerSdpCreatePending(_) => {} - P2pConnectionIncomingAction::AnswerSdpCreateError(action) => { + P2pConnectionIncomingAction::AnswerSdpCreatePending { .. } => {} + P2pConnectionIncomingAction::AnswerSdpCreateError { peer_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - error = format!("{:?}", action.error), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + error = format!("{:?}", error), ); } - P2pConnectionIncomingAction::AnswerSdpCreateSuccess(action) => { + P2pConnectionIncomingAction::AnswerSdpCreateSuccess { peer_id, sdp } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - trace_sdp = action.sdp.clone(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + trace_sdp = sdp.clone(), ); } - P2pConnectionIncomingAction::AnswerReady(action) => { + P2pConnectionIncomingAction::AnswerReady { peer_id, answer } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - trace_answer = serde_json::to_string(&action.answer).ok() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + trace_answer = serde_json::to_string(answer).ok() ); } - P2pConnectionIncomingAction::AnswerSendSuccess(action) => { + P2pConnectionIncomingAction::AnswerSendSuccess { peer_id } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), ); } - P2pConnectionIncomingAction::FinalizePending(_) => {} - P2pConnectionIncomingAction::FinalizeError(action) => { + P2pConnectionIncomingAction::FinalizePending { .. } => {} + P2pConnectionIncomingAction::FinalizeError { peer_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - error = format!("{:?}", action.error), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + error = format!("{:?}", error), ); } - P2pConnectionIncomingAction::FinalizeSuccess(action) => { + P2pConnectionIncomingAction::FinalizeSuccess { peer_id } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), ); } - P2pConnectionIncomingAction::Timeout(action) => { + P2pConnectionIncomingAction::Timeout { peer_id } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), ); } - P2pConnectionIncomingAction::Error(action) => { + P2pConnectionIncomingAction::Error { peer_id, error } => { openmina_core::log::warn!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - error = format!("{:?}", action.error), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + error = format!("{:?}", error), ); } - P2pConnectionIncomingAction::Success(action) => { + P2pConnectionIncomingAction::Success { peer_id } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), ); } - P2pConnectionIncomingAction::Libp2pReceived(action) => { + P2pConnectionIncomingAction::Libp2pReceived { peer_id } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), ); } }, }, P2pAction::Disconnection(action) => match action { - P2pDisconnectionAction::Init(action) => { + P2pDisconnectionAction::Init { peer_id, reason } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string(), - reason = format!("{:?}", action.reason) + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string(), + reason = format!("{:?}", reason) ); } - P2pDisconnectionAction::Finish(action) => { + P2pDisconnectionAction::Finish { peer_id } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string() ); } }, P2pAction::Discovery(action) => match action { - P2pDiscoveryAction::Init(action) => { + P2pDiscoveryAction::Init { peer_id } => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string() ); } - P2pDiscoveryAction::Success(action) => { + P2pDiscoveryAction::Success { peer_id, .. } => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {}", action.peer_id), - peer_id = action.peer_id.to_string() + summary = format!("peer_id: {peer_id}"), + peer_id = peer_id.to_string() ); } - P2pDiscoveryAction::KademliaBootstrap(..) => { + P2pDiscoveryAction::KademliaBootstrap => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), summary = format!("bootstrap kademlia"), ); } - P2pDiscoveryAction::KademliaInit(..) => { + P2pDiscoveryAction::KademliaInit => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = format!("find node"), ); } - P2pDiscoveryAction::KademliaAddRoute(action) => { + P2pDiscoveryAction::KademliaAddRoute { peer_id, addresses } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("add route {} {:?}", action.peer_id, action.addresses.first()), + summary = format!("add route {peer_id} {:?}", addresses.first()), ); } - P2pDiscoveryAction::KademliaSuccess(action) => { + P2pDiscoveryAction::KademliaSuccess { peers } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("peers: {:?}", action.peers), + summary = format!("peers: {:?}", peers), ); } - P2pDiscoveryAction::KademliaFailure(action) => { + P2pDiscoveryAction::KademliaFailure { description } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("{:?}", action.description), + summary = format!("{:?}", description), ); } }, @@ -386,7 +389,7 @@ pub fn logger_effects(store: &Store, action: ActionWithMetaRef<'_ openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {peer_id}", ), + summary = format!("peer_id: {peer_id}"), peer_id = peer_id.to_string() ); } @@ -394,7 +397,7 @@ pub fn logger_effects(store: &Store, action: ActionWithMetaRef<'_ openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {peer_id}", ), + summary = format!("peer_id: {peer_id}"), peer_id = peer_id.to_string() ); } @@ -424,7 +427,7 @@ pub fn logger_effects(store: &Store, action: ActionWithMetaRef<'_ openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {peer_id}", ), + summary = format!("peer_id: {peer_id}"), peer_id = peer_id.to_string() ); } @@ -432,7 +435,7 @@ pub fn logger_effects(store: &Store, action: ActionWithMetaRef<'_ openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("peer_id: {peer_id}", ), + summary = format!("peer_id: {peer_id}"), peer_id = peer_id.to_string() ); } @@ -579,50 +582,58 @@ pub fn logger_effects(store: &Store, action: ActionWithMetaRef<'_ }, Action::TransitionFrontier(a) => match a { TransitionFrontierAction::Sync(action) => match action { - TransitionFrontierSyncAction::Init(action) => openmina_core::log::info!( + TransitionFrontierSyncAction::Init { + best_tip, + root_block, + .. + } => openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "Transition frontier sync init".to_string(), - block_hash = action.best_tip.hash.to_string(), - root_block_hash = action.root_block.hash.to_string(), + block_hash = best_tip.hash.to_string(), + root_block_hash = root_block.hash.to_string(), ), - TransitionFrontierSyncAction::BestTipUpdate(action) => openmina_core::log::info!( + TransitionFrontierSyncAction::BestTipUpdate { + best_tip, + root_block, + .. + } => openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "New best tip received".to_string(), - block_hash = action.best_tip.hash.to_string(), - root_block_hash = action.root_block.hash.to_string(), + block_hash = best_tip.hash.to_string(), + root_block_hash = root_block.hash.to_string(), ), - TransitionFrontierSyncAction::LedgerStakingPending(_) => openmina_core::log::info!( + TransitionFrontierSyncAction::LedgerStakingPending => openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "Staking ledger sync pending".to_string(), ), - TransitionFrontierSyncAction::LedgerStakingSuccess(_) => openmina_core::log::info!( + TransitionFrontierSyncAction::LedgerStakingSuccess => openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "Staking ledger sync success".to_string(), ), - TransitionFrontierSyncAction::LedgerNextEpochPending(_) => { + TransitionFrontierSyncAction::LedgerNextEpochPending => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "Next epoch ledger sync pending".to_string(), ) } - TransitionFrontierSyncAction::LedgerNextEpochSuccess(_) => { + TransitionFrontierSyncAction::LedgerNextEpochSuccess => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "Next epoch ledger sync pending".to_string(), ) } - TransitionFrontierSyncAction::LedgerRootPending(_) => openmina_core::log::info!( + TransitionFrontierSyncAction::LedgerRootPending => openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "Transition frontier root ledger sync pending".to_string(), ), - TransitionFrontierSyncAction::LedgerRootSuccess(_) => openmina_core::log::info!( + TransitionFrontierSyncAction::LedgerRootSuccess => openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = "Transition frontier root ledger sync success".to_string(), @@ -640,50 +651,55 @@ pub fn logger_effects(store: &Store, action: ActionWithMetaRef<'_ }, Action::BlockProducer(a) => match a { BlockProducerAction::VrfEvaluator(a) => match a { - BlockProducerVrfEvaluatorAction::EpochDataUpdate(a) => { + BlockProducerVrfEvaluatorAction::EpochDataUpdate { epoch_data, .. } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), - summary = format!("seed: {}, ledger: {}", a.epoch_data.seed.to_string(), a.epoch_data.ledger.hash.to_string()), + summary = format!("seed: {}, ledger: {}", epoch_data.seed.to_string(), epoch_data.ledger.hash.to_string()), ); } - BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates(_) => {} - BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess(a) => { + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegates { .. } => {} + BlockProducerVrfEvaluatorAction::UpdateProducerAndDelegatesSuccess { + current_epoch_producer_and_delegators, + next_epoch_producer_and_delegators, + .. + } => { openmina_core::log::info!( meta.time(); kind = kind.to_string(), summary = format!("Current epoch accounts: {:?}, Next epoch accounts: {:?}", - a.current_epoch_producer_and_delegators.values().map(| a | a.0.clone()).collect::>(), - a.next_epoch_producer_and_delegators.values().map(| a | a.0.clone()).collect::>() + current_epoch_producer_and_delegators.values().map(| a | a.0.clone()).collect::>(), + next_epoch_producer_and_delegators.values().map(| a | a.0.clone()).collect::>() ), ); } - BlockProducerVrfEvaluatorAction::EvaluationSuccess(a) => match a.vrf_output { - vrf::VrfEvaluationOutput::SlotWon(_) => { - openmina_core::log::info!( - meta.time(); - kind = kind.to_string(), - summary = format!("Slot evaluation result - won slot: {:?}", a.vrf_output), - ) + BlockProducerVrfEvaluatorAction::EvaluationSuccess { vrf_output, .. } => { + match vrf_output { + vrf::VrfEvaluationOutput::SlotWon(_) => { + openmina_core::log::info!( + meta.time(); + kind = kind.to_string(), + summary = format!("Slot evaluation result - won slot: {:?}", vrf_output), + ) + } + vrf::VrfEvaluationOutput::SlotLost(_) => { + openmina_core::log::debug!( + meta.time(); + kind = kind.to_string(), + summary = format!("Slot evaluation result - lost slot: {:?}", vrf_output), + ) + } } - vrf::VrfEvaluationOutput::SlotLost(_) => { - openmina_core::log::debug!( - meta.time(); - kind = kind.to_string(), - summary = format!("Slot evaluation result - lost slot: {:?}", a.vrf_output), - ) - } - }, - BlockProducerVrfEvaluatorAction::EvaluateVrf(a) => { + } + BlockProducerVrfEvaluatorAction::EvaluateVrf { vrf_input } => { openmina_core::log::debug!( meta.time(); kind = kind.to_string(), - summary = format!("Vrf Evaluation requested: {:?}", a.vrf_input), + summary = format!("Vrf Evaluation requested: {:?}", vrf_input), ) } - _ => {} }, - BlockProducerAction::BestTipUpdate(_) => {} + BlockProducerAction::BestTipUpdate { .. } => {} _ => {} }, _ => {} diff --git a/node/src/p2p/channels/best_tip/mod.rs b/node/src/p2p/channels/best_tip/mod.rs index 23122c6c7..0f243c52d 100644 --- a/node/src/p2p/channels/best_tip/mod.rs +++ b/node/src/p2p/channels/best_tip/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::channels::best_tip::*; mod p2p_channels_best_tip_actions; -pub use p2p_channels_best_tip_actions::*; + diff --git a/node/src/p2p/channels/mod.rs b/node/src/p2p/channels/mod.rs index 0b5bf5b4d..f131c85bb 100644 --- a/node/src/p2p/channels/mod.rs +++ b/node/src/p2p/channels/mod.rs @@ -6,4 +6,4 @@ pub mod snark; pub mod snark_job_commitment; mod p2p_channels_actions; -pub use p2p_channels_actions::*; + diff --git a/node/src/p2p/channels/rpc/mod.rs b/node/src/p2p/channels/rpc/mod.rs index 3e03b95de..83ca5bb04 100644 --- a/node/src/p2p/channels/rpc/mod.rs +++ b/node/src/p2p/channels/rpc/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::channels::rpc::*; mod p2p_channels_rpc_actions; -pub use p2p_channels_rpc_actions::*; + diff --git a/node/src/p2p/channels/snark/mod.rs b/node/src/p2p/channels/snark/mod.rs index f5e4beffb..f47a98129 100644 --- a/node/src/p2p/channels/snark/mod.rs +++ b/node/src/p2p/channels/snark/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::channels::snark::*; mod p2p_channels_snark_actions; -pub use p2p_channels_snark_actions::*; + diff --git a/node/src/p2p/channels/snark_job_commitment/mod.rs b/node/src/p2p/channels/snark_job_commitment/mod.rs index 3eed0bc73..b85eb2071 100644 --- a/node/src/p2p/channels/snark_job_commitment/mod.rs +++ b/node/src/p2p/channels/snark_job_commitment/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::channels::snark_job_commitment::*; mod p2p_channels_snark_job_commitment_actions; -pub use p2p_channels_snark_job_commitment_actions::*; + diff --git a/node/src/p2p/connection/incoming/mod.rs b/node/src/p2p/connection/incoming/mod.rs index e8ffe8236..9f7ad3f6f 100644 --- a/node/src/p2p/connection/incoming/mod.rs +++ b/node/src/p2p/connection/incoming/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::connection::incoming::*; mod p2p_connection_incoming_actions; -pub use p2p_connection_incoming_actions::*; + diff --git a/node/src/p2p/connection/incoming/p2p_connection_incoming_actions.rs b/node/src/p2p/connection/incoming/p2p_connection_incoming_actions.rs index 4fef53d82..1eddb0ae3 100644 --- a/node/src/p2p/connection/incoming/p2p_connection_incoming_actions.rs +++ b/node/src/p2p/connection/incoming/p2p_connection_incoming_actions.rs @@ -1,83 +1,16 @@ use super::*; -impl redux::EnablingCondition for P2pConnectionIncomingInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSdpCreatePendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSdpCreateErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSdpCreateSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerReadyAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSendSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingFinalizePendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingFinalizeErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingFinalizeSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingTimeoutAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let peer = state.p2p.peers.get(&self.peer_id); - let timed_out = peer - .and_then(|peer| peer.status.as_connecting()?.as_incoming()) - .map_or(false, |s| s.is_timed_out(state.time())); - timed_out && self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionIncomingLibp2pReceivedAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) +impl redux::EnablingCondition for P2pConnectionIncomingAction { + fn is_enabled(&self, state: &crate::State) -> bool { + match self { + Self::Timeout { peer_id } => { + let peer = state.p2p.peers.get(peer_id); + let timed_out = peer + .and_then(|peer| peer.status.as_connecting()?.as_incoming()) + .map_or(false, |s| s.is_timed_out(state.time())); + timed_out && self.is_enabled(&state.p2p) + } + _ => self.is_enabled(&state.p2p), + } } } diff --git a/node/src/p2p/connection/outgoing/mod.rs b/node/src/p2p/connection/outgoing/mod.rs index 2f969425a..5cb6f91f5 100644 --- a/node/src/p2p/connection/outgoing/mod.rs +++ b/node/src/p2p/connection/outgoing/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::connection::outgoing::*; mod p2p_connection_outgoing_actions; -pub use p2p_connection_outgoing_actions::*; + diff --git a/node/src/p2p/connection/outgoing/p2p_connection_outgoing_actions.rs b/node/src/p2p/connection/outgoing/p2p_connection_outgoing_actions.rs index e9734c888..e95a5c54e 100644 --- a/node/src/p2p/connection/outgoing/p2p_connection_outgoing_actions.rs +++ b/node/src/p2p/connection/outgoing/p2p_connection_outgoing_actions.rs @@ -5,124 +5,36 @@ use crate::p2p::P2pPeerStatus; use super::*; -impl redux::EnablingCondition for P2pConnectionOutgoingRandomInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingReconnectAction { - fn is_enabled(&self, state: &crate::State) -> bool { - if !self.is_enabled(&state.p2p) { - return false; - } - - let Some(peer) = state.p2p.peers.get(self.opts.peer_id()) else { - return false; - }; - let delay_passed = match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::Error { time, .. }, - )) - | P2pPeerStatus::Disconnected { time, .. } => { - state.time().checked_sub(*time) >= Some(Duration::from_secs(30)) +impl redux::EnablingCondition for P2pConnectionOutgoingAction { + fn is_enabled(&self, state: &crate::State) -> bool { + match self { + P2pConnectionOutgoingAction::Reconnect { opts, .. } => { + if !self.is_enabled(&state.p2p) { + return false; + } + + let Some(peer) = state.p2p.peers.get(opts.peer_id()) else { + return false; + }; + let delay_passed = match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::Error { time, .. }, + )) + | P2pPeerStatus::Disconnected { time, .. } => { + state.time().checked_sub(*time) >= Some(Duration::from_secs(30)) + } + _ => true, + }; + delay_passed } - _ => true, - }; - delay_passed - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSdpCreatePendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSdpCreateErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSdpCreateSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferReadyAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSendSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingAnswerRecvPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingAnswerRecvErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingAnswerRecvSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingFinalizePendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingFinalizeErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingFinalizeSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingTimeoutAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let peer = state.p2p.peers.get(&self.peer_id); - let timed_out = peer - .and_then(|peer| peer.status.as_connecting()?.as_outgoing()) - .map_or(false, |s| s.is_timed_out(state.time())); - timed_out && self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pConnectionOutgoingSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) + P2pConnectionOutgoingAction::Timeout { peer_id } => { + let peer = state.p2p.peers.get(peer_id); + let timed_out = peer + .and_then(|peer| peer.status.as_connecting()?.as_outgoing()) + .map_or(false, |s| s.is_timed_out(state.time())); + timed_out && self.is_enabled(&state.p2p) + } + _ => self.is_enabled(&state.p2p), + } } } diff --git a/node/src/p2p/disconnection/mod.rs b/node/src/p2p/disconnection/mod.rs index d3c0136d3..0aadc28e8 100644 --- a/node/src/p2p/disconnection/mod.rs +++ b/node/src/p2p/disconnection/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::disconnection::*; mod p2p_disconnection_actions; -pub use p2p_disconnection_actions::*; + diff --git a/node/src/p2p/disconnection/p2p_disconnection_actions.rs b/node/src/p2p/disconnection/p2p_disconnection_actions.rs index 7f5d88197..3ebc80ccc 100644 --- a/node/src/p2p/disconnection/p2p_disconnection_actions.rs +++ b/node/src/p2p/disconnection/p2p_disconnection_actions.rs @@ -1,12 +1,6 @@ use super::*; -impl redux::EnablingCondition for P2pDisconnectionInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pDisconnectionFinishAction { +impl redux::EnablingCondition for P2pDisconnectionAction { fn is_enabled(&self, state: &crate::State) -> bool { self.is_enabled(&state.p2p) } diff --git a/node/src/p2p/discovery/mod.rs b/node/src/p2p/discovery/mod.rs index 0b6f31299..8d83e05a0 100644 --- a/node/src/p2p/discovery/mod.rs +++ b/node/src/p2p/discovery/mod.rs @@ -1,42 +1,6 @@ pub use ::p2p::discovery::*; -impl redux::EnablingCondition for P2pDiscoveryInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pDiscoverySuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaBootstrapAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.p2p.enough_time_elapsed(state.time()) && self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaAddRouteAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaFailureAction { +impl redux::EnablingCondition for P2pDiscoveryAction { fn is_enabled(&self, state: &crate::State) -> bool { self.is_enabled(&state.p2p) } diff --git a/node/src/p2p/listen/p2p_listen_actions.rs b/node/src/p2p/listen/p2p_listen_actions.rs index 649a1846f..123e2b2b4 100644 --- a/node/src/p2p/listen/p2p_listen_actions.rs +++ b/node/src/p2p/listen/p2p_listen_actions.rs @@ -1,29 +1,9 @@ -use p2p::listen::{ - P2pListenClosedAction, P2pListenErrorAction, P2pListenExpiredAction, P2pListenNewAction, -}; +use p2p::listen::P2pListenAction; use redux::EnablingCondition; use crate::State; -impl EnablingCondition for P2pListenNewAction { - fn is_enabled(&self, state: &State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl EnablingCondition for P2pListenExpiredAction { - fn is_enabled(&self, state: &State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl EnablingCondition for P2pListenErrorAction { - fn is_enabled(&self, state: &State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl EnablingCondition for P2pListenClosedAction { +impl EnablingCondition for P2pListenAction { fn is_enabled(&self, state: &State) -> bool { self.is_enabled(&state.p2p) } diff --git a/node/src/p2p/mod.rs b/node/src/p2p/mod.rs index 05cde46f3..13a0ec93d 100644 --- a/node/src/p2p/mod.rs +++ b/node/src/p2p/mod.rs @@ -47,53 +47,15 @@ macro_rules! impl_into_global_action { }; } -impl_into_global_action!(listen::P2pListenNewAction); -impl_into_global_action!(listen::P2pListenExpiredAction); -impl_into_global_action!(listen::P2pListenErrorAction); -impl_into_global_action!(listen::P2pListenClosedAction); - -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingRandomInitAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingInitAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingReconnectAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingOfferSdpCreatePendingAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingOfferSdpCreateErrorAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingOfferSdpCreateSuccessAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingOfferReadyAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingOfferSendSuccessAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingAnswerRecvPendingAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingAnswerRecvErrorAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingAnswerRecvSuccessAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingFinalizePendingAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingFinalizeErrorAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingFinalizeSuccessAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingTimeoutAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingErrorAction); -impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingSuccessAction); - -impl_into_global_action!(connection::incoming::P2pConnectionIncomingInitAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingAnswerSdpCreatePendingAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingAnswerSdpCreateErrorAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingAnswerSdpCreateSuccessAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingAnswerReadyAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingAnswerSendSuccessAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingFinalizePendingAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingFinalizeErrorAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingFinalizeSuccessAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingTimeoutAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingErrorAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingSuccessAction); -impl_into_global_action!(connection::incoming::P2pConnectionIncomingLibp2pReceivedAction); - -impl_into_global_action!(disconnection::P2pDisconnectionInitAction); -impl_into_global_action!(disconnection::P2pDisconnectionFinishAction); - -impl_into_global_action!(discovery::P2pDiscoveryInitAction); -impl_into_global_action!(discovery::P2pDiscoverySuccessAction); -impl_into_global_action!(discovery::P2pDiscoveryKademliaBootstrapAction); -impl_into_global_action!(discovery::P2pDiscoveryKademliaInitAction); -impl_into_global_action!(discovery::P2pDiscoveryKademliaSuccessAction); -impl_into_global_action!(discovery::P2pDiscoveryKademliaFailureAction); -impl_into_global_action!(discovery::P2pDiscoveryKademliaAddRouteAction); +impl_into_global_action!(listen::P2pListenAction); + +impl_into_global_action!(connection::outgoing::P2pConnectionOutgoingAction); + +impl_into_global_action!(connection::incoming::P2pConnectionIncomingAction); + +impl_into_global_action!(disconnection::P2pDisconnectionAction); + +impl_into_global_action!(discovery::P2pDiscoveryAction); impl_into_global_action!(channels::P2pChannelsMessageReceivedAction); diff --git a/node/src/p2p/p2p_effects.rs b/node/src/p2p/p2p_effects.rs index e4153f1be..99fe5d71c 100644 --- a/node/src/p2p/p2p_effects.rs +++ b/node/src/p2p/p2p_effects.rs @@ -2,32 +2,19 @@ use mina_p2p_messages::v2::{MinaLedgerSyncLedgerAnswerStableV2, StateHash}; use openmina_core::block::BlockWithHash; use crate::consensus::ConsensusAction; -use crate::rpc::{ - RpcP2pConnectionIncomingErrorAction, RpcP2pConnectionIncomingRespondAction, - RpcP2pConnectionIncomingSuccessAction, RpcP2pConnectionOutgoingErrorAction, - RpcP2pConnectionOutgoingSuccessAction, -}; +use crate::rpc::RpcAction; use crate::snark_pool::candidate::SnarkPoolCandidateAction; use crate::snark_pool::SnarkPoolAction; use crate::transition_frontier::sync::ledger::snarked::{ - PeerLedgerQueryError, PeerLedgerQueryResponse, - TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction, - TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction, - TransitionFrontierSyncLedgerSnarkedPeersQueryAction, + PeerLedgerQueryError, PeerLedgerQueryResponse, TransitionFrontierSyncLedgerSnarkedAction, }; use crate::transition_frontier::sync::ledger::staged::{ - PeerStagedLedgerPartsFetchError, TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction, -}; -use crate::transition_frontier::sync::{ - PeerBlockFetchError, TransitionFrontierSyncBlocksPeerQueryErrorAction, - TransitionFrontierSyncBlocksPeerQuerySuccessAction, - TransitionFrontierSyncBlocksPeersQueryAction, + PeerStagedLedgerPartsFetchError, TransitionFrontierSyncLedgerStagedAction, }; +use crate::transition_frontier::sync::{PeerBlockFetchError, TransitionFrontierSyncAction}; use crate::watched_accounts::{ - WatchedAccountLedgerInitialState, WatchedAccountsLedgerInitialStateGetError, - WatchedAccountsLedgerInitialStateGetErrorAction, + WatchedAccountLedgerInitialState, WatchedAccountsAction, + WatchedAccountsLedgerInitialStateGetError, }; use crate::{Service, Store}; @@ -36,15 +23,11 @@ use super::channels::rpc::{BestTipWithProof, P2pChannelsRpcAction, P2pRpcRequest use super::channels::snark::P2pChannelsSnarkAction; use super::channels::snark_job_commitment::P2pChannelsSnarkJobCommitmentAction; use super::channels::P2pChannelsAction; -use super::connection::incoming::{ - P2pConnectionIncomingAction, P2pConnectionIncomingAnswerSendSuccessAction, -}; +use super::connection::incoming::P2pConnectionIncomingAction; use super::connection::outgoing::P2pConnectionOutgoingAction; use super::connection::{P2pConnectionAction, P2pConnectionResponse}; -use super::disconnection::{ - P2pDisconnectionAction, P2pDisconnectionInitAction, P2pDisconnectionReason, -}; -use super::discovery::{P2pDiscoveryAction, P2pDiscoveryInitAction, P2pDiscoverySuccessAction}; +use super::disconnection::{P2pDisconnectionAction, P2pDisconnectionReason}; +use super::discovery::P2pDiscoveryAction; use super::peer::P2pPeerAction; use super::{P2pAction, P2pActionWithMeta}; @@ -54,215 +37,151 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) let (action, meta) = action.split(); match action { - P2pAction::Listen(action) => match action { - p2p::listen::P2pListenAction::New(action) => { - action.effects(&meta, store); - } - p2p::listen::P2pListenAction::Expired(action) => { - action.effects(&meta, store); - } - p2p::listen::P2pListenAction::Error(action) => { - action.effects(&meta, store); - } - p2p::listen::P2pListenAction::Closed(action) => { - action.effects(&meta, store); - } - }, + P2pAction::Listen(action) => { + action.effects(&meta, store); + } P2pAction::Connection(action) => match action { - P2pConnectionAction::Outgoing(action) => match action { - P2pConnectionOutgoingAction::RandomInit(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::Init(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::Reconnect(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::OfferSdpCreatePending(_) => {} - P2pConnectionOutgoingAction::OfferSdpCreateError(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::OfferSdpCreateSuccess(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::OfferReady(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::OfferSendSuccess(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::AnswerRecvPending(_) => {} - P2pConnectionOutgoingAction::AnswerRecvError(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::AnswerRecvSuccess(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::FinalizePending(_) => {} - P2pConnectionOutgoingAction::FinalizeError(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::FinalizeSuccess(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::Timeout(action) => { - action.effects(&meta, store); - } - P2pConnectionOutgoingAction::Error(action) => { - let p2p = &store.state().p2p; - if let Some(rpc_id) = p2p.peer_connection_rpc_id(&action.peer_id) { - store.dispatch(RpcP2pConnectionOutgoingErrorAction { - rpc_id, - error: action.error.clone(), - }); + P2pConnectionAction::Outgoing(action) => { + match action { + P2pConnectionOutgoingAction::Error { + ref peer_id, + ref error, + } => { + let p2p = &store.state().p2p; + if let Some(rpc_id) = p2p.peer_connection_rpc_id(peer_id) { + store.dispatch(RpcAction::P2pConnectionOutgoingError { + rpc_id, + error: error.clone(), + }); + } } - // action.effects(&meta, store); - } - P2pConnectionOutgoingAction::Success(action) => { - let p2p = &store.state().p2p; - if let Some(rpc_id) = p2p.peer_connection_rpc_id(&action.peer_id) { - store.dispatch(RpcP2pConnectionOutgoingSuccessAction { rpc_id }); + P2pConnectionOutgoingAction::Success { ref peer_id } => { + let p2p = &store.state().p2p; + if let Some(rpc_id) = p2p.peer_connection_rpc_id(peer_id) { + store.dispatch(RpcAction::P2pConnectionOutgoingSuccess { rpc_id }); + } } - action.effects(&meta, store); - } - }, - P2pConnectionAction::Incoming(action) => match action { - P2pConnectionIncomingAction::Init(action) => { - action.effects(&meta, store); - } - P2pConnectionIncomingAction::AnswerSdpCreatePending(_) => {} - P2pConnectionIncomingAction::AnswerSdpCreateError(action) => { - action.effects(&meta, store); - } - P2pConnectionIncomingAction::AnswerSdpCreateSuccess(action) => { - action.effects(&meta, store); + _ => {} } - P2pConnectionIncomingAction::AnswerReady(action) => { - let p2p = &store.state().p2p; - if let Some(rpc_id) = p2p.peer_connection_rpc_id(&action.peer_id) { - store.dispatch(RpcP2pConnectionIncomingRespondAction { - rpc_id, - response: P2pConnectionResponse::Accepted(action.answer.clone()), - }); - store.dispatch(P2pConnectionIncomingAnswerSendSuccessAction { - peer_id: action.peer_id, - }); + action.effects(&meta, store); + } + P2pConnectionAction::Incoming(action) => { + match &action { + P2pConnectionIncomingAction::AnswerReady { peer_id, answer } => { + let p2p = &store.state().p2p; + if let Some(rpc_id) = p2p.peer_connection_rpc_id(peer_id) { + store.dispatch(RpcAction::P2pConnectionIncomingRespond { + rpc_id, + response: P2pConnectionResponse::Accepted(answer.clone()), + }); + store.dispatch(P2pConnectionIncomingAction::AnswerSendSuccess { + peer_id: *peer_id, + }); + } } - action.effects(&meta, store); - } - P2pConnectionIncomingAction::AnswerSendSuccess(action) => { - action.effects(&meta, store); - } - P2pConnectionIncomingAction::FinalizePending(_) => {} - P2pConnectionIncomingAction::FinalizeError(action) => { - action.effects(&meta, store); - } - P2pConnectionIncomingAction::FinalizeSuccess(action) => { - action.effects(&meta, store); - } - P2pConnectionIncomingAction::Timeout(action) => { - action.effects(&meta, store); - } - P2pConnectionIncomingAction::Error(action) => { - let p2p = &store.state().p2p; - if let Some(rpc_id) = p2p.peer_connection_rpc_id(&action.peer_id) { - store.dispatch(RpcP2pConnectionIncomingErrorAction { - rpc_id, - error: format!("{:?}", action.error), - }); + P2pConnectionIncomingAction::Error { peer_id, error } => { + let p2p = &store.state().p2p; + if let Some(rpc_id) = p2p.peer_connection_rpc_id(peer_id) { + store.dispatch(RpcAction::P2pConnectionIncomingError { + rpc_id, + error: format!("{:?}", error), + }); + } } - // action.effects(&meta, store); - } - P2pConnectionIncomingAction::Success(action) => { - let p2p = &store.state().p2p; - if let Some(rpc_id) = p2p.peer_connection_rpc_id(&action.peer_id) { - store.dispatch(RpcP2pConnectionIncomingSuccessAction { rpc_id }); + P2pConnectionIncomingAction::Success { peer_id } => { + let p2p = &store.state().p2p; + if let Some(rpc_id) = p2p.peer_connection_rpc_id(peer_id) { + store.dispatch(RpcAction::P2pConnectionIncomingSuccess { rpc_id }); + } } - action.effects(&meta, store); - } - P2pConnectionIncomingAction::Libp2pReceived(action) => { - action.effects(&meta, store); + _ => {} } - }, + action.effects(&meta, store); + } }, - P2pAction::Disconnection(action) => match action { - P2pDisconnectionAction::Init(action) => action.effects(&meta, store), - P2pDisconnectionAction::Finish(action) => { - if let Some(s) = store.state().transition_frontier.sync.ledger() { - let rpc_ids = s - .snarked() - .map(|s| s.peer_query_pending_rpc_ids(&action.peer_id).collect()) - .unwrap_or(vec![]); - let staged_ledger_parts_fetch_rpc_id = s - .staged() - .and_then(|s| s.parts_fetch_rpc_id(&action.peer_id)); + P2pAction::Disconnection(action) => { + action.effects(&meta, store); - for rpc_id in rpc_ids { - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction { - peer_id: action.peer_id, - rpc_id, - error: PeerLedgerQueryError::Disconnected, - }); - } + match action { + P2pDisconnectionAction::Init { .. } => {} + P2pDisconnectionAction::Finish { peer_id } => { + if let Some(s) = store.state().transition_frontier.sync.ledger() { + let rpc_ids = s + .snarked() + .map(|s| s.peer_query_pending_rpc_ids(&peer_id).collect()) + .unwrap_or(vec![]); + let staged_ledger_parts_fetch_rpc_id = + s.staged().and_then(|s| s.parts_fetch_rpc_id(&peer_id)); - if let Some(rpc_id) = staged_ledger_parts_fetch_rpc_id { - store.dispatch( - TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction { - peer_id: action.peer_id, - rpc_id, - error: PeerStagedLedgerPartsFetchError::Disconnected, - }, - ); + for rpc_id in rpc_ids { + store.dispatch( + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError { + peer_id, + rpc_id, + error: PeerLedgerQueryError::Disconnected, + }, + ); + } + + if let Some(rpc_id) = staged_ledger_parts_fetch_rpc_id { + store.dispatch( + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError { + peer_id, + rpc_id, + error: PeerStagedLedgerPartsFetchError::Disconnected, + }, + ); + } } - } - let blocks_fetch_rpc_ids = store - .state() - .transition_frontier - .sync - .blocks_fetch_from_peer_pending_rpc_ids(&action.peer_id) - .collect::>(); + let blocks_fetch_rpc_ids = store + .state() + .transition_frontier + .sync + .blocks_fetch_from_peer_pending_rpc_ids(&peer_id) + .collect::>(); - for rpc_id in blocks_fetch_rpc_ids { - store.dispatch(TransitionFrontierSyncBlocksPeerQueryErrorAction { - peer_id: action.peer_id, - rpc_id, - error: PeerBlockFetchError::Disconnected, - }); - } + for rpc_id in blocks_fetch_rpc_ids { + store.dispatch(TransitionFrontierSyncAction::BlocksPeerQueryError { + peer_id, + rpc_id, + error: PeerBlockFetchError::Disconnected, + }); + } - let actions = store - .state() - .watched_accounts - .iter() - .filter_map(|(pub_key, a)| match &a.initial_state { - WatchedAccountLedgerInitialState::Pending { peer_id, .. } => { - if peer_id == &action.peer_id { - Some(WatchedAccountsLedgerInitialStateGetErrorAction { + let actions = store + .state() + .watched_accounts + .iter() + .filter_map(|(pub_key, a)| match &a.initial_state { + WatchedAccountLedgerInitialState::Pending { + peer_id: account_peer_id, + .. + } => { + if account_peer_id == &peer_id { + Some(WatchedAccountsAction::LedgerInitialStateGetError { pub_key: pub_key.clone(), error: WatchedAccountsLedgerInitialStateGetError::PeerDisconnected, }) - } else { - None + } else { + None + } } - } - _ => None, - }) - .collect::>(); + _ => None, + }) + .collect::>(); - for action in actions { - store.dispatch(action); - } + for action in actions { + store.dispatch(action); + } - store.dispatch(SnarkPoolCandidateAction::PeerPrune { - peer_id: action.peer_id, - }); + store.dispatch(SnarkPoolCandidateAction::PeerPrune { peer_id }); + } } - }, + } P2pAction::Discovery(action) => match action { - P2pDiscoveryAction::Init(P2pDiscoveryInitAction { peer_id }) => { + P2pDiscoveryAction::Init { peer_id } => { let Some(peer) = store.state().p2p.peers.get(&peer_id) else { return; }; @@ -275,8 +194,8 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) request: P2pRpcRequest::InitialPeers, }); } - P2pDiscoveryAction::Success(_) => {} - P2pDiscoveryAction::KademliaBootstrap(_) => { + P2pDiscoveryAction::Success { .. } => {} + P2pDiscoveryAction::KademliaBootstrap => { // seed node doesn't have initial peers // it will rely on incoming peers let initial_peers = if !store.state().p2p.config.initial_peers.is_empty() { @@ -299,12 +218,12 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) store.service().start_discovery(initial_peers); } } - P2pDiscoveryAction::KademliaInit(_) => { + P2pDiscoveryAction::KademliaInit => { store.service().find_random_peer(); } - P2pDiscoveryAction::KademliaAddRoute(_) => {} - P2pDiscoveryAction::KademliaSuccess(_) => {} - P2pDiscoveryAction::KademliaFailure(_) => {} + P2pDiscoveryAction::KademliaAddRoute { .. } => {} + P2pDiscoveryAction::KademliaSuccess { .. } => {} + P2pDiscoveryAction::KademliaFailure { .. } => {} }, P2pAction::Channels(action) => match action { P2pChannelsAction::MessageReceived(action) => { @@ -365,31 +284,30 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) request: P2pRpcRequest::BestTipWithProof, }); - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}); - store.dispatch( - TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction {}, - ); - store.dispatch(TransitionFrontierSyncBlocksPeersQueryAction {}); + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery); + store + .dispatch(TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit); + store.dispatch(TransitionFrontierSyncAction::BlocksPeersQuery); } P2pChannelsRpcAction::Timeout { peer_id, id } => { - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction { + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError { peer_id, rpc_id: id, error: PeerLedgerQueryError::Timeout, }); store.dispatch( - TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction { + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError { peer_id, rpc_id: id, error: PeerStagedLedgerPartsFetchError::Timeout, }, ); - store.dispatch(TransitionFrontierSyncBlocksPeerQueryErrorAction { + store.dispatch(TransitionFrontierSyncAction::BlocksPeerQueryError { peer_id, rpc_id: id, error: PeerBlockFetchError::Timeout, }); - store.dispatch(P2pDisconnectionInitAction { + store.dispatch(P2pDisconnectionAction::Init { peer_id, reason: P2pDisconnectionReason::TransitionFrontierRpcTimeout, }); @@ -402,24 +320,26 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) match response.as_ref() { None => { store.dispatch( - TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction { + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError { peer_id, rpc_id: id, error: PeerLedgerQueryError::DataUnavailable, }, ); store.dispatch( - TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction { + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError { peer_id, rpc_id: id, error: PeerStagedLedgerPartsFetchError::DataUnavailable, }, ); - store.dispatch(TransitionFrontierSyncBlocksPeerQueryErrorAction { - peer_id, - rpc_id: id, - error: PeerBlockFetchError::DataUnavailable, - }); + store.dispatch( + TransitionFrontierSyncAction::BlocksPeerQueryError { + peer_id, + rpc_id: id, + error: PeerBlockFetchError::DataUnavailable, + }, + ); } Some(P2pRpcResponse::BestTipWithProof(resp)) => { let (body_hashes, root_block) = &resp.proof; @@ -456,7 +376,7 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) Some(P2pRpcResponse::LedgerQuery(answer)) => match answer { MinaLedgerSyncLedgerAnswerStableV2::ChildHashesAre(left, right) => { store.dispatch( - TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction { + TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess { peer_id, rpc_id: id, response: PeerLedgerQueryResponse::ChildHashes( @@ -468,11 +388,11 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) } MinaLedgerSyncLedgerAnswerStableV2::ContentsAre(accounts) => { store.dispatch( - TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction { + TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess { peer_id, rpc_id: id, response: PeerLedgerQueryResponse::ChildAccounts( - accounts.clone(), + accounts.iter().cloned().collect(), ), }, ); @@ -483,7 +403,7 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) parts, )) => { store.dispatch( - TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction { + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchSuccess { peer_id, rpc_id: id, parts: parts.clone(), @@ -493,7 +413,7 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) Some(P2pRpcResponse::Block(block)) => { let block = BlockWithHash::new(block.clone()); store.dispatch( - TransitionFrontierSyncBlocksPeerQuerySuccessAction { + TransitionFrontierSyncAction::BlocksPeerQuerySuccess { peer_id, rpc_id: id, response: block, @@ -507,17 +427,17 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) }); } Some(P2pRpcResponse::InitialPeers(peers)) => { - store.dispatch(P2pDiscoverySuccessAction { + store.dispatch(P2pDiscoveryAction::Success { peer_id, peers: peers.clone(), }); } } - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}); + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery); store.dispatch( - TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction {}, + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit {}, ); - store.dispatch(TransitionFrontierSyncBlocksPeersQueryAction {}); + store.dispatch(TransitionFrontierSyncAction::BlocksPeersQuery); } P2pChannelsRpcAction::RequestReceived { peer_id, @@ -654,18 +574,18 @@ pub fn p2p_effects(store: &mut Store, action: P2pActionWithMeta) } }, P2pAction::Peer(action) => match action { - P2pPeerAction::Ready(action) => { + P2pPeerAction::Ready { .. } => { action.effects(&meta, store); } - P2pPeerAction::BestTipUpdate(action) => { + P2pPeerAction::BestTipUpdate { best_tip, .. } => { store.dispatch(ConsensusAction::BlockReceived { - hash: action.best_tip.hash, - block: action.best_tip.block, + hash: best_tip.hash, + block: best_tip.block, chain_proof: None, }); - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}); - store.dispatch(TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction {}); - store.dispatch(TransitionFrontierSyncBlocksPeersQueryAction {}); + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery); + store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit); + store.dispatch(TransitionFrontierSyncAction::BlocksPeersQuery); } }, } diff --git a/node/src/p2p/peer/mod.rs b/node/src/p2p/peer/mod.rs index e0b32ab20..8564a845b 100644 --- a/node/src/p2p/peer/mod.rs +++ b/node/src/p2p/peer/mod.rs @@ -1,4 +1,4 @@ pub use ::p2p::peer::*; mod p2p_peer_actions; -pub use p2p_peer_actions::*; + diff --git a/node/src/p2p/peer/p2p_peer_actions.rs b/node/src/p2p/peer/p2p_peer_actions.rs index c0976477d..9a86050b2 100644 --- a/node/src/p2p/peer/p2p_peer_actions.rs +++ b/node/src/p2p/peer/p2p_peer_actions.rs @@ -1,12 +1,6 @@ use super::*; -impl redux::EnablingCondition for P2pPeerReadyAction { - fn is_enabled(&self, state: &crate::State) -> bool { - self.is_enabled(&state.p2p) - } -} - -impl redux::EnablingCondition for P2pPeerBestTipUpdateAction { +impl redux::EnablingCondition for P2pPeerAction { fn is_enabled(&self, state: &crate::State) -> bool { self.is_enabled(&state.p2p) } diff --git a/node/src/recorder/recorder.rs b/node/src/recorder/recorder.rs index 87032a705..c40a9fea1 100644 --- a/node/src/recorder/recorder.rs +++ b/node/src/recorder/recorder.rs @@ -70,7 +70,7 @@ impl Recorder { let is_input = match action.action() { Action::CheckTimeouts(_) => true, Action::EventSource(e) => match e { - EventSourceAction::NewEvent(_) => true, + EventSourceAction::NewEvent { .. } => true, _ => return, }, _ => false, diff --git a/node/src/reducer.rs b/node/src/reducer.rs index 60612f899..c3484d089 100644 --- a/node/src/reducer.rs +++ b/node/src/reducer.rs @@ -6,7 +6,7 @@ pub fn reducer(state: &mut State, action: &ActionWithMeta) { let meta = action.meta().clone(); match action.action() { Action::CheckTimeouts(_) => {} - Action::EventSource(EventSourceAction::NewEvent(content)) => match &content.event { + Action::EventSource(EventSourceAction::NewEvent { event }) => match event { #[cfg(not(target_arch = "wasm32"))] Event::P2p(P2pEvent::Libp2pIdentify(peer_id, maddr)) => { if let Some(peer) = state.p2p.peers.get_mut(peer_id) { diff --git a/node/src/rpc/mod.rs b/node/src/rpc/mod.rs index 52c798e4a..aa65090ab 100644 --- a/node/src/rpc/mod.rs +++ b/node/src/rpc/mod.rs @@ -10,7 +10,7 @@ mod rpc_actions; pub use rpc_actions::*; mod rpc_reducer; -pub use rpc_reducer::*; + mod rpc_effects; pub use rpc_effects::*; diff --git a/node/src/rpc/rpc_actions.rs b/node/src/rpc/rpc_actions.rs index 73ac5db82..b3ae34b8b 100644 --- a/node/src/rpc/rpc_actions.rs +++ b/node/src/rpc/rpc_actions.rs @@ -11,321 +11,163 @@ use super::{ActionStatsQuery, RpcId, RpcScanStateSummaryGetQuery, SyncStatsQuery pub type RpcActionWithMeta = redux::ActionWithMeta; pub type RpcActionWithMetaRef<'a> = redux::ActionWithMeta<&'a RpcAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub enum RpcAction { - GlobalStateGet(RpcGlobalStateGetAction), + GlobalStateGet { + rpc_id: RpcId, + }, // Stats - ActionStatsGet(RpcActionStatsGetAction), - SyncStatsGet(RpcSyncStatsGetAction), - - PeersGet(RpcPeersGetAction), - - P2pConnectionOutgoingInit(RpcP2pConnectionOutgoingInitAction), - P2pConnectionOutgoingPending(RpcP2pConnectionOutgoingPendingAction), - P2pConnectionOutgoingError(RpcP2pConnectionOutgoingErrorAction), - P2pConnectionOutgoingSuccess(RpcP2pConnectionOutgoingSuccessAction), - - P2pConnectionIncomingInit(RpcP2pConnectionIncomingInitAction), - P2pConnectionIncomingPending(RpcP2pConnectionIncomingPendingAction), - P2pConnectionIncomingRespond(RpcP2pConnectionIncomingRespondAction), - P2pConnectionIncomingError(RpcP2pConnectionIncomingErrorAction), - P2pConnectionIncomingSuccess(RpcP2pConnectionIncomingSuccessAction), - - ScanStateSummaryGet(RpcScanStateSummaryGetAction), - - SnarkPoolAvailableJobsGet(RpcSnarkPoolAvailableJobsGetAction), - SnarkPoolJobGet(RpcSnarkPoolJobGetAction), - - SnarkerConfigGet(RpcSnarkerConfigGetAction), - SnarkerJobCommit(RpcSnarkerJobCommitAction), - SnarkerJobSpec(RpcSnarkerJobSpecAction), - - SnarkerWorkersGet(RpcSnarkersWorkersGetAction), - - HealthCheck(RpcHealthCheckAction), - ReadinessCheck(RpcReadinessCheckAction), - - Finish(RpcFinishAction), -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcGlobalStateGetAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcGlobalStateGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcActionStatsGetAction { - pub rpc_id: RpcId, - pub query: ActionStatsQuery, -} - -impl redux::EnablingCondition for RpcActionStatsGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcSyncStatsGetAction { - pub rpc_id: RpcId, - pub query: SyncStatsQuery, -} - -impl redux::EnablingCondition for RpcSyncStatsGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcPeersGetAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcPeersGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionOutgoingInitAction { - pub rpc_id: RpcId, - pub opts: P2pConnectionOutgoingInitOpts, -} - -impl redux::EnablingCondition for RpcP2pConnectionOutgoingInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - !state.rpc.requests.contains_key(&self.rpc_id) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionOutgoingPendingAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcP2pConnectionOutgoingPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_init()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionOutgoingErrorAction { - pub rpc_id: RpcId, - pub error: P2pConnectionOutgoingError, -} - -impl redux::EnablingCondition for RpcP2pConnectionOutgoingErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_pending()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionOutgoingSuccessAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcP2pConnectionOutgoingSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_pending()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionIncomingInitAction { - pub rpc_id: RpcId, - pub opts: P2pConnectionIncomingInitOpts, -} - -impl redux::EnablingCondition for RpcP2pConnectionIncomingInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - !state.rpc.requests.contains_key(&self.rpc_id) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionIncomingPendingAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcP2pConnectionIncomingPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_init()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionIncomingRespondAction { - pub rpc_id: RpcId, - pub response: P2pConnectionResponse, -} - -impl redux::EnablingCondition for RpcP2pConnectionIncomingRespondAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_init() || v.status.is_pending()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionIncomingErrorAction { - pub rpc_id: RpcId, - pub error: String, -} - -impl redux::EnablingCondition for RpcP2pConnectionIncomingErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_init() || v.status.is_pending()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcP2pConnectionIncomingSuccessAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcP2pConnectionIncomingSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_pending()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcScanStateSummaryGetAction { - pub rpc_id: RpcId, - pub query: RpcScanStateSummaryGetQuery, -} - -impl redux::EnablingCondition for RpcScanStateSummaryGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcSnarkPoolAvailableJobsGetAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcSnarkPoolAvailableJobsGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcSnarkPoolJobGetAction { - pub job_id: SnarkWorkId, - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcSnarkPoolJobGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcSnarkerConfigGetAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcSnarkerConfigGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcSnarkerJobCommitAction { - pub rpc_id: RpcId, - pub job_id: SnarkJobId, -} - -impl redux::EnablingCondition for RpcSnarkerJobCommitAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcSnarkerJobSpecAction { - pub rpc_id: RpcId, - pub job_id: SnarkJobId, -} - -impl redux::EnablingCondition for RpcSnarkerJobSpecAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcSnarkersWorkersGetAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcSnarkersWorkersGetAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcHealthCheckAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcHealthCheckAction {} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcReadinessCheckAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcReadinessCheckAction {} - -/// Finish/Cleanup rpc request. -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct RpcFinishAction { - pub rpc_id: RpcId, -} - -impl redux::EnablingCondition for RpcFinishAction { + ActionStatsGet { + rpc_id: RpcId, + query: ActionStatsQuery, + }, + SyncStatsGet { + rpc_id: RpcId, + query: SyncStatsQuery, + }, + + PeersGet { + rpc_id: RpcId, + }, + + P2pConnectionOutgoingInit { + rpc_id: RpcId, + opts: P2pConnectionOutgoingInitOpts, + }, + P2pConnectionOutgoingPending { + rpc_id: RpcId, + }, + P2pConnectionOutgoingError { + rpc_id: RpcId, + error: P2pConnectionOutgoingError, + }, + P2pConnectionOutgoingSuccess { + rpc_id: RpcId, + }, + + P2pConnectionIncomingInit { + rpc_id: RpcId, + opts: P2pConnectionIncomingInitOpts, + }, + P2pConnectionIncomingPending { + rpc_id: RpcId, + }, + P2pConnectionIncomingRespond { + rpc_id: RpcId, + response: P2pConnectionResponse, + }, + P2pConnectionIncomingError { + rpc_id: RpcId, + error: String, + }, + P2pConnectionIncomingSuccess { + rpc_id: RpcId, + }, + + ScanStateSummaryGet { + rpc_id: RpcId, + query: RpcScanStateSummaryGetQuery, + }, + + SnarkPoolAvailableJobsGet { + rpc_id: RpcId, + }, + SnarkPoolJobGet { + job_id: SnarkWorkId, + rpc_id: RpcId, + }, + + SnarkerConfigGet { + rpc_id: RpcId, + }, + SnarkerJobCommit { + rpc_id: RpcId, + job_id: SnarkJobId, + }, + SnarkerJobSpec { + rpc_id: RpcId, + job_id: SnarkJobId, + }, + + SnarkerWorkersGet { + rpc_id: RpcId, + }, + + HealthCheck { + rpc_id: RpcId, + }, + ReadinessCheck { + rpc_id: RpcId, + }, + + Finish { + rpc_id: RpcId, + }, +} + +impl redux::EnablingCondition for RpcAction { fn is_enabled(&self, state: &crate::State) -> bool { - state - .rpc - .requests - .get(&self.rpc_id) - .map_or(false, |v| v.status.is_finished()) + match self { + RpcAction::GlobalStateGet { .. } => true, + RpcAction::ActionStatsGet { .. } => true, + RpcAction::SyncStatsGet { .. } => true, + RpcAction::PeersGet { .. } => true, + RpcAction::P2pConnectionOutgoingInit { rpc_id, .. } => { + !state.rpc.requests.contains_key(rpc_id) + } + RpcAction::P2pConnectionOutgoingPending { rpc_id } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_init()), + RpcAction::P2pConnectionOutgoingError { rpc_id, .. } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_pending()), + RpcAction::P2pConnectionOutgoingSuccess { rpc_id } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_pending()), + RpcAction::P2pConnectionIncomingInit { rpc_id, .. } => { + !state.rpc.requests.contains_key(rpc_id) + } + RpcAction::P2pConnectionIncomingPending { rpc_id } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_init()), + RpcAction::P2pConnectionIncomingRespond { rpc_id, .. } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_init() || v.status.is_pending()), + RpcAction::P2pConnectionIncomingError { rpc_id, .. } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_init() || v.status.is_pending()), + RpcAction::P2pConnectionIncomingSuccess { rpc_id } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_pending()), + RpcAction::ScanStateSummaryGet { .. } => true, + RpcAction::SnarkPoolAvailableJobsGet { .. } => true, + RpcAction::SnarkPoolJobGet { .. } => true, + RpcAction::SnarkerConfigGet { .. } => true, + RpcAction::SnarkerJobCommit { .. } => true, + RpcAction::SnarkerJobSpec { .. } => true, + RpcAction::SnarkerWorkersGet { .. } => true, + RpcAction::HealthCheck { .. } => true, + RpcAction::ReadinessCheck { .. } => true, + RpcAction::Finish { rpc_id } => state + .rpc + .requests + .get(rpc_id) + .map_or(false, |v| v.status.is_finished()), + } } } - -impl_into_global_action!( - Rpc: - RpcGlobalStateGetAction, - RpcActionStatsGetAction, - RpcSyncStatsGetAction, - - RpcPeersGetAction, - - RpcP2pConnectionOutgoingInitAction, - RpcP2pConnectionOutgoingPendingAction, - RpcP2pConnectionOutgoingErrorAction, - RpcP2pConnectionOutgoingSuccessAction, - - RpcP2pConnectionIncomingInitAction, - RpcP2pConnectionIncomingPendingAction, - RpcP2pConnectionIncomingRespondAction, - RpcP2pConnectionIncomingErrorAction, - RpcP2pConnectionIncomingSuccessAction, - - RpcScanStateSummaryGetAction, - - RpcSnarkPoolAvailableJobsGetAction, - RpcSnarkPoolJobGetAction, - - RpcSnarkerConfigGetAction, - RpcSnarkerJobCommitAction, - RpcSnarkerJobSpecAction, - - RpcSnarkersWorkersGetAction, - - RpcHealthCheckAction, - RpcReadinessCheckAction, - - RpcFinishAction, -); diff --git a/node/src/rpc/rpc_effects.rs b/node/src/rpc/rpc_effects.rs index 57a5c3e23..af40e707f 100644 --- a/node/src/rpc/rpc_effects.rs +++ b/node/src/rpc/rpc_effects.rs @@ -3,18 +3,16 @@ use std::time::Duration; use mina_p2p_messages::v2::MinaBaseTransactionStatusStableV2; use crate::external_snark_worker::available_job_to_snark_worker_spec; -use crate::p2p::connection::incoming::P2pConnectionIncomingInitAction; -use crate::p2p::connection::outgoing::P2pConnectionOutgoingInitAction; +use crate::p2p::connection::incoming::P2pConnectionIncomingAction; +use crate::p2p::connection::outgoing::P2pConnectionOutgoingAction; use crate::p2p::connection::P2pConnectionResponse; use crate::rpc::{PeerConnectionStatus, RpcPeerInfo}; use crate::snark_pool::SnarkPoolAction; use crate::{Service, Store}; use super::{ - ActionStatsQuery, ActionStatsResponse, RpcAction, RpcActionWithMeta, RpcFinishAction, - RpcP2pConnectionIncomingErrorAction, RpcP2pConnectionIncomingPendingAction, - RpcP2pConnectionIncomingRespondAction, RpcP2pConnectionOutgoingPendingAction, - RpcScanStateSummary, RpcScanStateSummaryBlock, RpcScanStateSummaryBlockTransaction, + ActionStatsQuery, ActionStatsResponse, RpcAction, RpcActionWithMeta, RpcScanStateSummary, + RpcScanStateSummaryBlock, RpcScanStateSummaryBlockTransaction, RpcScanStateSummaryBlockTransactionKind, RpcScanStateSummaryGetQuery, RpcScanStateSummaryScanStateJob, RpcSnarkPoolJobFull, RpcSnarkPoolJobSnarkWork, RpcSnarkPoolJobSummary, RpcSnarkerJobCommitResponse, RpcSnarkerJobSpecResponse, @@ -32,19 +30,17 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) let (action, meta) = action.split(); match action { - RpcAction::GlobalStateGet(action) => { - let _ = store - .service - .respond_state_get(action.rpc_id, store.state.get()); + RpcAction::GlobalStateGet { rpc_id } => { + let _ = store.service.respond_state_get(rpc_id, store.state.get()); } - RpcAction::ActionStatsGet(action) => match action.query { + RpcAction::ActionStatsGet { rpc_id, query } => match query { ActionStatsQuery::SinceStart => { let resp = store .service .stats() .map(|s| s.collect_action_stats_since_start()) .map(|stats| ActionStatsResponse::SinceStart { stats }); - let _ = store.service.respond_action_stats_get(action.rpc_id, resp); + let _ = store.service.respond_action_stats_get(rpc_id, resp); } ActionStatsQuery::ForLatestBlock => { let resp = store @@ -52,7 +48,7 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) .stats() .and_then(|s| s.collect_action_stats_for_block_with_id(None)) .map(ActionStatsResponse::ForBlock); - let _ = store.service.respond_action_stats_get(action.rpc_id, resp); + let _ = store.service.respond_action_stats_get(rpc_id, resp); } ActionStatsQuery::ForBlockWithId(id) => { let resp = store @@ -60,17 +56,17 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) .stats() .and_then(|s| s.collect_action_stats_for_block_with_id(Some(id))) .map(ActionStatsResponse::ForBlock); - let _ = store.service.respond_action_stats_get(action.rpc_id, resp); + let _ = store.service.respond_action_stats_get(rpc_id, resp); } }, - RpcAction::SyncStatsGet(action) => { + RpcAction::SyncStatsGet { rpc_id, query } => { let resp = store .service .stats() - .map(|s| s.collect_sync_stats(action.query.limit)); - let _ = store.service.respond_sync_stats_get(action.rpc_id, resp); + .map(|s| s.collect_sync_stats(query.limit)); + let _ = store.service.respond_sync_stats_get(rpc_id, resp); } - RpcAction::PeersGet(action) => { + RpcAction::PeersGet { rpc_id } => { let peers = store .state() .p2p @@ -117,95 +113,79 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) }) .collect(); respond_or_log!( - store.service().respond_peers_get(action.rpc_id, peers), + store.service().respond_peers_get(rpc_id, peers), meta.time() ); } - RpcAction::P2pConnectionOutgoingInit(action) => { - let (rpc_id, opts) = (action.rpc_id, action.opts); - store.dispatch(P2pConnectionOutgoingInitAction { + RpcAction::P2pConnectionOutgoingInit { rpc_id, opts } => { + store.dispatch(P2pConnectionOutgoingAction::Init { opts, rpc_id: Some(rpc_id), }); - store.dispatch(RpcP2pConnectionOutgoingPendingAction { rpc_id }); + store.dispatch(RpcAction::P2pConnectionOutgoingPending { rpc_id }); } - RpcAction::P2pConnectionOutgoingPending(_) => {} - RpcAction::P2pConnectionOutgoingError(action) => { - let error = Err(format!("{:?}", action.error)); - let _ = store - .service - .respond_p2p_connection_outgoing(action.rpc_id, error); - store.dispatch(RpcFinishAction { - rpc_id: action.rpc_id, - }); + RpcAction::P2pConnectionOutgoingPending { .. } => {} + RpcAction::P2pConnectionOutgoingError { rpc_id, error } => { + let error = Err(format!("{:?}", error)); + let _ = store.service.respond_p2p_connection_outgoing(rpc_id, error); + store.dispatch(RpcAction::Finish { rpc_id: rpc_id }); } - RpcAction::P2pConnectionOutgoingSuccess(action) => { + RpcAction::P2pConnectionOutgoingSuccess { rpc_id } => { let _ = store .service - .respond_p2p_connection_outgoing(action.rpc_id, Ok(())); - store.dispatch(RpcFinishAction { - rpc_id: action.rpc_id, - }); + .respond_p2p_connection_outgoing(rpc_id, Ok(())); + store.dispatch(RpcAction::Finish { rpc_id }); } - RpcAction::P2pConnectionIncomingInit(action) => { - let rpc_id = action.rpc_id; - match store - .state() - .p2p - .incoming_accept(action.opts.peer_id, &action.opts.offer) - { + RpcAction::P2pConnectionIncomingInit { rpc_id, opts } => { + let rpc_id = rpc_id; + match store.state().p2p.incoming_accept(opts.peer_id, &opts.offer) { Ok(_) => { - store.dispatch(P2pConnectionIncomingInitAction { - opts: action.opts, + store.dispatch(P2pConnectionIncomingAction::Init { + opts, rpc_id: Some(rpc_id), }); - store.dispatch(RpcP2pConnectionIncomingPendingAction { rpc_id }); + store.dispatch(RpcAction::P2pConnectionIncomingPending { rpc_id }); } Err(reason) => { let response = P2pConnectionResponse::Rejected(reason); - store.dispatch(RpcP2pConnectionIncomingRespondAction { rpc_id, response }); + store.dispatch(RpcAction::P2pConnectionIncomingRespond { rpc_id, response }); } } } - RpcAction::P2pConnectionIncomingPending(_) => {} - RpcAction::P2pConnectionIncomingRespond(action) => { - let rpc_id = action.rpc_id; - let error = match &action.response { + RpcAction::P2pConnectionIncomingPending { .. } => {} + RpcAction::P2pConnectionIncomingRespond { rpc_id, response } => { + let error = match &response { P2pConnectionResponse::Accepted(_) => None, P2pConnectionResponse::InternalError => Some("RemoteInternalError".to_owned()), P2pConnectionResponse::Rejected(reason) => Some(format!("Rejected({:?})", reason)), }; let _ = store .service - .respond_p2p_connection_incoming_answer(rpc_id, action.response); + .respond_p2p_connection_incoming_answer(rpc_id, response); if let Some(error) = error { - store.dispatch(RpcP2pConnectionIncomingErrorAction { rpc_id, error }); + store.dispatch(RpcAction::P2pConnectionIncomingError { rpc_id, error }); } } - RpcAction::P2pConnectionIncomingError(action) => { + RpcAction::P2pConnectionIncomingError { rpc_id, error } => { let _ = store .service - .respond_p2p_connection_incoming(action.rpc_id, Err(action.error)); - store.dispatch(RpcFinishAction { - rpc_id: action.rpc_id, - }); + .respond_p2p_connection_incoming(rpc_id, Err(error)); + store.dispatch(RpcAction::Finish { rpc_id }); } - RpcAction::P2pConnectionIncomingSuccess(action) => { + RpcAction::P2pConnectionIncomingSuccess { rpc_id } => { let _ = store .service - .respond_p2p_connection_incoming(action.rpc_id, Ok(())); - store.dispatch(RpcFinishAction { - rpc_id: action.rpc_id, - }); + .respond_p2p_connection_incoming(rpc_id, Ok(())); + store.dispatch(RpcAction::Finish { rpc_id }); } - RpcAction::ScanStateSummaryGet(action) => { + RpcAction::ScanStateSummaryGet { rpc_id, query } => { let state = store.state.get(); let transition_frontier = &state.transition_frontier; let snark_pool = &state.snark_pool; let service = &store.service; let res = None.or_else(|| { - let block = match action.query { + let block = match query { RpcScanStateSummaryGetQuery::ForBestTip => transition_frontier.best_tip(), RpcScanStateSummaryGetQuery::ForBlockWithHash(hash) => transition_frontier .best_chain @@ -283,11 +263,9 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) scan_state, }) }); - let _ = store - .service - .respond_scan_state_summary_get(action.rpc_id, res); + let _ = store.service.respond_scan_state_summary_get(rpc_id, res); } - RpcAction::SnarkPoolAvailableJobsGet(action) => { + RpcAction::SnarkPoolAvailableJobsGet { rpc_id } => { let resp = store .state() .snark_pool @@ -304,11 +282,11 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) }), }) .collect::>(); - let _ = store.service().respond_snark_pool_get(action.rpc_id, resp); + let _ = store.service().respond_snark_pool_get(rpc_id, resp); } - RpcAction::SnarkPoolJobGet(action) => { + RpcAction::SnarkPoolJobGet { job_id, rpc_id } => { let resp = store.state().snark_pool.range(..).find_map(|(_, job)| { - if &job.id == &action.job_id { + if job.id == job_id { Some(RpcSnarkPoolJobFull { time: job.time, id: job.id.clone(), @@ -325,11 +303,9 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) None } }); - let _ = store - .service() - .respond_snark_pool_job_get(action.rpc_id, resp); + let _ = store.service().respond_snark_pool_job_get(rpc_id, resp); } - RpcAction::SnarkerConfigGet(action) => { + RpcAction::SnarkerConfigGet { rpc_id } => { let config = store .state @@ -341,42 +317,37 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) public_key: config.public_key.as_ref().clone(), fee: config.fee.clone(), }); - let _ = store - .service() - .respond_snarker_config_get(action.rpc_id, config); + let _ = store.service().respond_snarker_config_get(rpc_id, config); } - RpcAction::SnarkerJobCommit(action) => { - let job_id = action.job_id; + RpcAction::SnarkerJobCommit { rpc_id, job_id } => { if !store.state().snark_pool.should_create_commitment(&job_id) { - let _ = store.service().respond_snarker_job_commit( - action.rpc_id, - RpcSnarkerJobCommitResponse::JobNotFound, - ); + let _ = store + .service() + .respond_snarker_job_commit(rpc_id, RpcSnarkerJobCommitResponse::JobNotFound); // TODO(binier): differentiate between job not found and job already taken. return; } if !store.state().external_snark_worker.has_idle() { - let _ = store.service().respond_snarker_job_commit( - action.rpc_id, - RpcSnarkerJobCommitResponse::SnarkerBusy, - ); + let _ = store + .service() + .respond_snarker_job_commit(rpc_id, RpcSnarkerJobCommitResponse::SnarkerBusy); return; } if store .service() - .respond_snarker_job_commit(action.rpc_id, RpcSnarkerJobCommitResponse::Ok) + .respond_snarker_job_commit(rpc_id, RpcSnarkerJobCommitResponse::Ok) .is_err() { return; } store.dispatch(SnarkPoolAction::CommitmentCreate { job_id }); } - RpcAction::SnarkerJobSpec(action) => { - let job_id = action.job_id; + RpcAction::SnarkerJobSpec { rpc_id, job_id } => { + let job_id = job_id; let Some(job) = store.state().snark_pool.get(&job_id) else { if store .service() - .respond_snarker_job_spec(action.rpc_id, RpcSnarkerJobSpecResponse::JobNotFound) + .respond_snarker_job_spec(rpc_id, RpcSnarkerJobSpecResponse::JobNotFound) .is_err() { return; @@ -407,23 +378,23 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) }; if store .service() - .respond_snarker_job_spec(action.rpc_id, input) + .respond_snarker_job_spec(rpc_id, input) .is_err() { return; } } - RpcAction::SnarkerWorkersGet(action) => { + RpcAction::SnarkerWorkersGet { rpc_id } => { let the_only = store.state().external_snark_worker.0.clone(); if store .service() - .respond_snarker_workers(action.rpc_id, vec![the_only.into()]) + .respond_snarker_workers(rpc_id, vec![the_only.into()]) .is_err() { return; } } - RpcAction::HealthCheck(action) => { + RpcAction::HealthCheck { rpc_id } => { let some_peers = store .state() .p2p @@ -436,13 +407,11 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) openmina_core::log::warn!(openmina_core::log::system_time(); "no ready peers"); String::from("no ready peers") }); respond_or_log!( - store - .service() - .respond_health_check(action.rpc_id, some_peers), + store.service().respond_health_check(rpc_id, some_peers), meta.time() ); } - RpcAction::ReadinessCheck(action) => { + RpcAction::ReadinessCheck { rpc_id } => { let synced = store .service() .stats() @@ -466,10 +435,10 @@ pub fn rpc_effects(store: &mut Store, action: RpcActionWithMeta) }); openmina_core::log::debug!(meta.time(); summary = "readiness check", result = format!("{synced:?}")); respond_or_log!( - store.service().respond_health_check(action.rpc_id, synced), + store.service().respond_health_check(rpc_id, synced), meta.time() ); } - RpcAction::Finish(_) => {} + RpcAction::Finish { .. } => {} } } diff --git a/node/src/rpc/rpc_reducer.rs b/node/src/rpc/rpc_reducer.rs index f6a60f3e8..4a41c8b3d 100644 --- a/node/src/rpc/rpc_reducer.rs +++ b/node/src/rpc/rpc_reducer.rs @@ -6,78 +6,78 @@ impl RpcState { pub fn reducer(&mut self, action: RpcActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - RpcAction::GlobalStateGet(_) => {} - RpcAction::ActionStatsGet(_) => {} - RpcAction::SyncStatsGet(_) => {} - RpcAction::PeersGet(_) => {} - RpcAction::P2pConnectionOutgoingInit(content) => { + RpcAction::GlobalStateGet { .. } => {} + RpcAction::ActionStatsGet { .. } => {} + RpcAction::SyncStatsGet { .. } => {} + RpcAction::PeersGet { .. } => {} + RpcAction::P2pConnectionOutgoingInit { rpc_id, opts } => { let rpc_state = RpcRequestState { - req: RpcRequest::P2pConnectionOutgoing(content.opts.clone()), + req: RpcRequest::P2pConnectionOutgoing(opts.clone()), status: RpcRequestStatus::Init { time: meta.time() }, }; - self.requests.insert(content.rpc_id, rpc_state); + self.requests.insert(*rpc_id, rpc_state); } - RpcAction::P2pConnectionOutgoingPending(content) => { - let Some(rpc) = self.requests.get_mut(&content.rpc_id) else { + RpcAction::P2pConnectionOutgoingPending { rpc_id } => { + let Some(rpc) = self.requests.get_mut(rpc_id) else { return; }; rpc.status = RpcRequestStatus::Pending { time: meta.time() }; } - RpcAction::P2pConnectionOutgoingError(content) => { - let Some(rpc) = self.requests.get_mut(&content.rpc_id) else { + RpcAction::P2pConnectionOutgoingError { rpc_id, error } => { + let Some(rpc) = self.requests.get_mut(rpc_id) else { return; }; rpc.status = RpcRequestStatus::Error { time: meta.time(), - error: format!("{:?}", content.error), + error: format!("{:?}", error), }; } - RpcAction::P2pConnectionOutgoingSuccess(content) => { - let Some(rpc) = self.requests.get_mut(&content.rpc_id) else { + RpcAction::P2pConnectionOutgoingSuccess { rpc_id } => { + let Some(rpc) = self.requests.get_mut(rpc_id) else { return; }; rpc.status = RpcRequestStatus::Success { time: meta.time() }; } - RpcAction::P2pConnectionIncomingInit(content) => { + RpcAction::P2pConnectionIncomingInit { rpc_id, opts } => { let rpc_state = RpcRequestState { - req: RpcRequest::P2pConnectionIncoming(content.opts.clone()), + req: RpcRequest::P2pConnectionIncoming(opts.clone()), status: RpcRequestStatus::Init { time: meta.time() }, }; - self.requests.insert(content.rpc_id, rpc_state); + self.requests.insert(*rpc_id, rpc_state); } - RpcAction::P2pConnectionIncomingPending(content) => { - let Some(rpc) = self.requests.get_mut(&content.rpc_id) else { + RpcAction::P2pConnectionIncomingPending { rpc_id } => { + let Some(rpc) = self.requests.get_mut(rpc_id) else { return; }; rpc.status = RpcRequestStatus::Pending { time: meta.time() }; } - RpcAction::P2pConnectionIncomingRespond(_) => {} - RpcAction::P2pConnectionIncomingError(content) => { - let Some(rpc) = self.requests.get_mut(&content.rpc_id) else { + RpcAction::P2pConnectionIncomingRespond { .. } => {} + RpcAction::P2pConnectionIncomingError { rpc_id, error } => { + let Some(rpc) = self.requests.get_mut(rpc_id) else { return; }; rpc.status = RpcRequestStatus::Error { time: meta.time(), - error: format!("{:?}", content.error), + error: format!("{:?}", error), }; } - RpcAction::P2pConnectionIncomingSuccess(content) => { - let Some(rpc) = self.requests.get_mut(&content.rpc_id) else { + RpcAction::P2pConnectionIncomingSuccess { rpc_id } => { + let Some(rpc) = self.requests.get_mut(rpc_id) else { return; }; rpc.status = RpcRequestStatus::Success { time: meta.time() }; } - RpcAction::ScanStateSummaryGet(_) => {} - RpcAction::SnarkPoolAvailableJobsGet(_) => {} - RpcAction::SnarkPoolJobGet(_) => {} - RpcAction::SnarkerConfigGet(_) => {} - RpcAction::SnarkerJobCommit(_) => {} - RpcAction::SnarkerJobSpec(_) => {} - RpcAction::SnarkerWorkersGet(_) => {} - RpcAction::HealthCheck(_) => {} - RpcAction::ReadinessCheck(_) => {} - RpcAction::Finish(action) => { - self.requests.remove(&action.rpc_id); + RpcAction::ScanStateSummaryGet { .. } => {} + RpcAction::SnarkPoolAvailableJobsGet { .. } => {} + RpcAction::SnarkPoolJobGet { .. } => {} + RpcAction::SnarkerConfigGet { .. } => {} + RpcAction::SnarkerJobCommit { .. } => {} + RpcAction::SnarkerJobSpec { .. } => {} + RpcAction::SnarkerWorkersGet { .. } => {} + RpcAction::HealthCheck { .. } => {} + RpcAction::ReadinessCheck { .. } => {} + RpcAction::Finish { rpc_id } => { + self.requests.remove(rpc_id); } } } diff --git a/node/src/snark/block_verify/mod.rs b/node/src/snark/block_verify/mod.rs index 04c86aa79..95f655daf 100644 --- a/node/src/snark/block_verify/mod.rs +++ b/node/src/snark/block_verify/mod.rs @@ -1,4 +1,4 @@ pub use ::snark::block_verify::*; mod snark_block_verify_actions; -pub use snark_block_verify_actions::*; + diff --git a/node/src/snark/work_verify/mod.rs b/node/src/snark/work_verify/mod.rs index 178411d55..46b5c3790 100644 --- a/node/src/snark/work_verify/mod.rs +++ b/node/src/snark/work_verify/mod.rs @@ -1,4 +1,4 @@ pub use ::snark::work_verify::*; mod snark_work_verify_actions; -pub use snark_work_verify_actions::*; + diff --git a/node/src/snark_pool/candidate/mod.rs b/node/src/snark_pool/candidate/mod.rs index 8e89fa1ac..59f4f3129 100644 --- a/node/src/snark_pool/candidate/mod.rs +++ b/node/src/snark_pool/candidate/mod.rs @@ -5,7 +5,7 @@ mod snark_pool_candidate_actions; pub use snark_pool_candidate_actions::*; mod snark_pool_candidate_reducer; -pub use snark_pool_candidate_reducer::*; + mod snark_pool_candidate_effects; pub use snark_pool_candidate_effects::*; diff --git a/node/src/snark_pool/candidate/snark_pool_candidate_effects.rs b/node/src/snark_pool/candidate/snark_pool_candidate_effects.rs index ff86bfecb..ce963e300 100644 --- a/node/src/snark_pool/candidate/snark_pool_candidate_effects.rs +++ b/node/src/snark_pool/candidate/snark_pool_candidate_effects.rs @@ -3,7 +3,7 @@ use std::collections::BTreeMap; use snark::work_verify::SnarkWorkVerifyAction; use crate::p2p::channels::rpc::{P2pChannelsRpcAction, P2pRpcRequest}; -use crate::p2p::disconnection::{P2pDisconnectionInitAction, P2pDisconnectionReason}; +use crate::p2p::disconnection::{P2pDisconnectionAction, P2pDisconnectionReason}; use crate::Store; use super::{SnarkPoolCandidateAction, SnarkPoolCandidateActionWithMeta}; @@ -85,7 +85,7 @@ pub fn snark_pool_candidate_effects( SnarkPoolCandidateAction::WorkVerifyPending { .. } => {} SnarkPoolCandidateAction::WorkVerifyError { peer_id, .. } => { // TODO(binier): blacklist peer - store.dispatch(P2pDisconnectionInitAction { + store.dispatch(P2pDisconnectionAction::Init { peer_id, reason: P2pDisconnectionReason::SnarkPoolVerifyError, }); diff --git a/node/src/snark_pool/mod.rs b/node/src/snark_pool/mod.rs index 8e885c994..cd1c173c9 100644 --- a/node/src/snark_pool/mod.rs +++ b/node/src/snark_pool/mod.rs @@ -10,7 +10,7 @@ mod snark_pool_actions; pub use snark_pool_actions::*; mod snark_pool_reducer; -pub use snark_pool_reducer::*; + mod snark_pool_effects; pub use snark_pool_effects::*; diff --git a/node/src/transition_frontier/mod.rs b/node/src/transition_frontier/mod.rs index 2e053cf20..b5dc71619 100644 --- a/node/src/transition_frontier/mod.rs +++ b/node/src/transition_frontier/mod.rs @@ -10,7 +10,7 @@ mod transition_frontier_actions; pub use transition_frontier_actions::*; mod transition_frontier_reducer; -pub use transition_frontier_reducer::*; + mod transition_frontier_effects; pub use transition_frontier_effects::*; diff --git a/node/src/transition_frontier/sync/ledger/mod.rs b/node/src/transition_frontier/sync/ledger/mod.rs index 687efdd8b..7c5eb4dcd 100644 --- a/node/src/transition_frontier/sync/ledger/mod.rs +++ b/node/src/transition_frontier/sync/ledger/mod.rs @@ -8,7 +8,6 @@ mod transition_frontier_sync_ledger_actions; pub use transition_frontier_sync_ledger_actions::*; mod transition_frontier_sync_ledger_reducer; -pub use transition_frontier_sync_ledger_reducer::*; mod transition_frontier_sync_ledger_effects; pub use transition_frontier_sync_ledger_effects::*; @@ -59,6 +58,7 @@ impl SyncLedgerTarget { /// Set synchronization target to current best tip's staking epoch ledger. pub fn staking_epoch(best_tip: &ArcBlockWithHash) -> Self { + // TODO(tizoc): should this return None when it matches the genesis ledger? Self { kind: SyncLedgerTargetKind::StakingEpoch, snarked_ledger_hash: best_tip.staking_epoch_ledger_hash().clone(), @@ -69,13 +69,16 @@ impl SyncLedgerTarget { /// Set synchronization target to current best tip's staking epoch ledger. /// /// Will return `None` if we shouldn't synchronize it, in case when - /// current next_epoch_ledger isn't finalized (reached root). + /// current next_epoch_ledger isn't finalized (reached root) or it + /// is equal to the genesis ledger. /// /// In such case, we will reconstruct next_epoch_ledger anyways, /// once transition frontier's root will be first slot in the bew epoch. pub fn next_epoch(best_tip: &ArcBlockWithHash, root_block: &ArcBlockWithHash) -> Option { if best_tip.next_epoch_ledger_hash() != root_block.next_epoch_ledger_hash() { return None; + } else if best_tip.next_epoch_ledger_hash() == best_tip.genesis_ledger_hash() { + return None; } Some(Self { kind: SyncLedgerTargetKind::NextEpoch, diff --git a/node/src/transition_frontier/sync/ledger/snarked/mod.rs b/node/src/transition_frontier/sync/ledger/snarked/mod.rs index 46117d8d6..bc83d13d0 100644 --- a/node/src/transition_frontier/sync/ledger/snarked/mod.rs +++ b/node/src/transition_frontier/sync/ledger/snarked/mod.rs @@ -5,10 +5,10 @@ mod transition_frontier_sync_ledger_snarked_actions; pub use transition_frontier_sync_ledger_snarked_actions::*; mod transition_frontier_sync_ledger_snarked_reducer; -pub use transition_frontier_sync_ledger_snarked_reducer::*; + mod transition_frontier_sync_ledger_snarked_effects; -pub use transition_frontier_sync_ledger_snarked_effects::*; + mod transition_frontier_sync_ledger_snarked_service; pub use transition_frontier_sync_ledger_snarked_service::*; diff --git a/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_actions.rs b/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_actions.rs index 8c2f20f36..f8121a581 100644 --- a/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_actions.rs +++ b/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_actions.rs @@ -16,285 +16,230 @@ pub type TransitionFrontierSyncLedgerSnarkedActionWithMeta = pub type TransitionFrontierSyncLedgerSnarkedActionWithMetaRef<'a> = redux::ActionWithMeta<&'a TransitionFrontierSyncLedgerSnarkedAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] -pub enum TransitionFrontierSyncLedgerSnarkedAction { - Pending(TransitionFrontierSyncLedgerSnarkedPendingAction), - PeersQuery(TransitionFrontierSyncLedgerSnarkedPeersQueryAction), - PeerQueryInit(TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction), - PeerQueryPending(TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction), - PeerQueryRetry(TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction), - PeerQueryError(TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction), - PeerQuerySuccess(TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction), - ChildHashesReceived(TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction), - ChildAccountsReceived(TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction), - Success(TransitionFrontierSyncLedgerSnarkedSuccessAction), -} - #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedPendingAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerSnarkedPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.transition_frontier.sync.ledger().map_or(false, |s| { - matches!(s, TransitionFrontierSyncLedgerState::Init { .. }) - }) - } +pub enum TransitionFrontierSyncLedgerSnarkedAction { + Pending, + PeersQuery, + PeerQueryInit { + address: LedgerAddress, + peer_id: PeerId, + }, + PeerQueryPending { + address: LedgerAddress, + peer_id: PeerId, + rpc_id: P2pRpcId, + }, + PeerQueryRetry { + address: LedgerAddress, + peer_id: PeerId, + }, + PeerQueryError { + peer_id: PeerId, + rpc_id: P2pRpcId, + error: PeerLedgerQueryError, + }, + PeerQuerySuccess { + peer_id: PeerId, + rpc_id: P2pRpcId, + response: PeerLedgerQueryResponse, + }, + ChildHashesReceived { + address: LedgerAddress, + hashes: (LedgerHash, LedgerHash), + sender: PeerId, + }, + ChildAccountsReceived { + address: LedgerAddress, + accounts: Vec, + sender: PeerId, + }, + Success, } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedPeersQueryAction {} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedPeersQueryAction -{ +impl redux::EnablingCondition for TransitionFrontierSyncLedgerSnarkedAction { fn is_enabled(&self, state: &crate::State) -> bool { - let peers_available = state - .p2p - .ready_peers_iter() - .any(|(_, p)| p.channels.rpc.can_send_request()); - peers_available - && state + match self { + TransitionFrontierSyncLedgerSnarkedAction::Pending => { + state.transition_frontier.sync.ledger().map_or(false, |s| { + matches!(s, TransitionFrontierSyncLedgerState::Init { .. }) + }) + } + TransitionFrontierSyncLedgerSnarkedAction::PeersQuery => { + let peers_available = state + .p2p + .ready_peers_iter() + .any(|(_, p)| p.channels.rpc.can_send_request()); + peers_available + && state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()) + .map_or(false, |s| { + s.sync_next().is_some() || s.sync_retry_iter().next().is_some() + }) + } + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryInit { address, peer_id } => { + None.or_else(|| { + let target_best_tip = state.transition_frontier.sync.best_tip()?; + let ledger = state.transition_frontier.sync.ledger()?.snarked()?; + let target = ledger.target(); + + // This is true if there is a next address that needs to be queried + // from a peer and it matches the one requested by this action. + let check_next_addr = match ledger { + TransitionFrontierSyncLedgerSnarkedState::Pending { + pending, + next_addr, + .. + } => next_addr.as_ref().map_or(false, |next_addr| { + next_addr == address + && (next_addr.to_index().0 != 0 || pending.is_empty()) + }), + _ => false, + }; + + let peer = state.p2p.get_ready_peer(peer_id)?; + let check_peer_available = { + let peer_best_tip = peer.best_tip.as_ref()?; + if !peer.channels.rpc.can_send_request() { + false + } else if target.staged.is_some() { + // if peer has same best tip, then he has same root + // so we can sync root snarked+staged ledger from that peer. + target_best_tip.hash() == peer_best_tip.hash() + } else { + &target.snarked_ledger_hash == peer_best_tip.snarked_ledger_hash() + || &target.snarked_ledger_hash + == peer_best_tip.staking_epoch_ledger_hash() + || &target.snarked_ledger_hash + == peer_best_tip.next_epoch_ledger_hash() + } + }; + + Some(check_next_addr && check_peer_available) + }) + .unwrap_or(false) + } + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryRetry { address, peer_id } => { + None.or_else(|| { + let target_best_tip = state.transition_frontier.sync.best_tip()?; + let ledger = state.transition_frontier.sync.ledger()?.snarked()?; + let target = ledger.target(); + + // This is true if there is next retry address and it + // matches the one requested in this action. + let check_next_addr = state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()?.sync_retry_iter().next()) + .map_or(false, |addr| &addr == address); + + let peer = state.p2p.get_ready_peer(peer_id)?; + let check_peer_available = { + let peer_best_tip = peer.best_tip.as_ref()?; + if !peer.channels.rpc.can_send_request() { + false + } else if target.staged.is_some() { + // if peer has same best tip, then he has same root + // so we can sync root snarked+staged ledger from that peer. + target_best_tip.hash() == peer_best_tip.hash() + } else { + &target.snarked_ledger_hash == peer_best_tip.snarked_ledger_hash() + || &target.snarked_ledger_hash + == peer_best_tip.staking_epoch_ledger_hash() + || &target.snarked_ledger_hash + == peer_best_tip.next_epoch_ledger_hash() + } + }; + + Some(check_next_addr && check_peer_available) + }) + .unwrap_or(false) + } + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryPending { peer_id, .. } => state .transition_frontier .sync .ledger() - .and_then(|s| s.snarked()) - .map_or(false, |s| { - s.sync_next().is_some() || s.sync_retry_iter().next().is_some() - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction { - pub address: LedgerAddress, - pub peer_id: PeerId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - None.or_else(|| { - let target_best_tip = state.transition_frontier.sync.best_tip()?; - let ledger = state.transition_frontier.sync.ledger()?.snarked()?; - let target = ledger.target(); - - // This is true if there is a next address that needs to be queried - // from a peer and it matches the one requested by this action. - let check_next_addr = match ledger { - TransitionFrontierSyncLedgerSnarkedState::Pending { - pending, next_addr, .. - } => next_addr.as_ref().map_or(false, |next_addr| { - next_addr == &self.address - && (next_addr.to_index().0 != 0 || pending.is_empty()) + .and_then(|s| s.snarked()?.fetch_pending()) + .map_or(false, |pending| { + pending + .iter() + .filter_map(|(_, query_state)| query_state.attempts.get(peer_id)) + .any(|peer_rpc_state| matches!(peer_rpc_state, PeerRpcState::Init { .. })) }), - _ => false, - }; - - let peer = state.p2p.get_ready_peer(&self.peer_id)?; - let check_peer_available = { - let peer_best_tip = peer.best_tip.as_ref()?; - if !peer.channels.rpc.can_send_request() { - false - } else if target.staged.is_some() { - // if peer has same best tip, then he has same root - // so we can sync root snarked+staged ledger from that peer. - target_best_tip.hash() == peer_best_tip.hash() - } else { - &target.snarked_ledger_hash == peer_best_tip.snarked_ledger_hash() - || &target.snarked_ledger_hash == peer_best_tip.staking_epoch_ledger_hash() - || &target.snarked_ledger_hash == peer_best_tip.next_epoch_ledger_hash() - } - }; - - Some(check_next_addr && check_peer_available) - }) - .unwrap_or(false) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction { - pub address: LedgerAddress, - pub peer_id: PeerId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - None.or_else(|| { - let target_best_tip = state.transition_frontier.sync.best_tip()?; - let ledger = state.transition_frontier.sync.ledger()?.snarked()?; - let target = ledger.target(); - - // This is true if there is next retry address and it - // matches the one requested in this action. - let check_next_addr = state + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError { + peer_id, rpc_id, .. + } => state .transition_frontier .sync .ledger() - .and_then(|s| s.snarked()?.sync_retry_iter().next()) - .map_or(false, |addr| addr == self.address); - - let peer = state.p2p.get_ready_peer(&self.peer_id)?; - let check_peer_available = { - let peer_best_tip = peer.best_tip.as_ref()?; - if !peer.channels.rpc.can_send_request() { - false - } else if target.staged.is_some() { - // if peer has same best tip, then he has same root - // so we can sync root snarked+staged ledger from that peer. - target_best_tip.hash() == peer_best_tip.hash() - } else { - &target.snarked_ledger_hash == peer_best_tip.snarked_ledger_hash() - || &target.snarked_ledger_hash == peer_best_tip.staking_epoch_ledger_hash() - || &target.snarked_ledger_hash == peer_best_tip.next_epoch_ledger_hash() - } - }; - - Some(check_next_addr && check_peer_available) - }) - .unwrap_or(false) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction { - pub address: LedgerAddress, - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()?.fetch_pending()) - .map_or(false, |pending| { - pending - .iter() - .filter_map(|(_, query_state)| query_state.attempts.get(&self.peer_id)) - .any(|peer_rpc_state| matches!(peer_rpc_state, PeerRpcState::Init { .. })) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction { - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, - pub error: PeerLedgerQueryError, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .map_or(false, |s| { - s.peer_query_get(&self.peer_id, self.rpc_id) - .and_then(|(_, s)| s.attempts.get(&self.peer_id)) - .map_or(false, |s| matches!(s, PeerRpcState::Pending { .. })) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction { - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, - pub response: PeerLedgerQueryResponse, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .map_or(false, |s| { - // TODO(binier): check if expected response - // kind is correct. - s.peer_query_get(&self.peer_id, self.rpc_id) - .and_then(|(_, s)| s.attempts.get(&self.peer_id)) - .map_or(false, |s| matches!(s, PeerRpcState::Pending { .. })) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction { - pub address: LedgerAddress, - pub hashes: (LedgerHash, LedgerHash), - pub sender: PeerId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - self.address.length() < LEDGER_DEPTH - 1 - && state + .and_then(|s| s.snarked()) + .map_or(false, |s| { + s.peer_query_get(peer_id, *rpc_id) + .and_then(|(_, s)| s.attempts.get(peer_id)) + .map_or(false, |s| matches!(s, PeerRpcState::Pending { .. })) + }), + TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess { + peer_id, rpc_id, .. + } => { + state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()) + .map_or(false, |s| { + // TODO(binier): check if expected response + // kind is correct. + s.peer_query_get(peer_id, *rpc_id) + .and_then(|(_, s)| s.attempts.get(peer_id)) + .map_or(false, |s| matches!(s, PeerRpcState::Pending { .. })) + }) + } + TransitionFrontierSyncLedgerSnarkedAction::ChildHashesReceived { + address, + sender, + .. + } => { + address.length() < LEDGER_DEPTH - 1 + && state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()?.fetch_pending()?.get(address)) + .and_then(|s| s.attempts.get(sender)) + .map_or(false, |s| s.is_success()) + } + TransitionFrontierSyncLedgerSnarkedAction::ChildAccountsReceived { + address, + sender, + .. + } => { + state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()?.fetch_pending()?.get(address)) + .and_then(|s| s.attempts.get(sender)) + // TODO(binier): check if expected response + // kind is correct. + .map_or(false, |s| s.is_success()) + } + TransitionFrontierSyncLedgerSnarkedAction::Success => state .transition_frontier .sync .ledger() - .and_then(|s| s.snarked()?.fetch_pending()?.get(&self.address)) - .and_then(|s| s.attempts.get(&self.sender)) - .map_or(false, |s| s.is_success()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction { - pub address: LedgerAddress, - pub accounts: Vec, - pub sender: PeerId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()?.fetch_pending()?.get(&self.address)) - .and_then(|s| s.attempts.get(&self.sender)) - // TODO(binier): check if expected response - // kind is correct. - .map_or(false, |s| s.is_success()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSnarkedSuccessAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerSnarkedSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .map_or(false, |s| match s { - TransitionFrontierSyncLedgerSnarkedState::Pending { - pending, next_addr, .. - } => next_addr.is_none() && pending.is_empty(), - _ => false, - }) + .and_then(|s| s.snarked()) + .map_or(false, |s| match s { + TransitionFrontierSyncLedgerSnarkedState::Pending { + pending, + next_addr, + .. + } => next_addr.is_none() && pending.is_empty(), + _ => false, + }), + } } } @@ -303,27 +248,12 @@ use crate::transition_frontier::{ TransitionFrontierAction, }; -macro_rules! impl_into_global_action { - ($a:ty) => { - impl From<$a> for crate::Action { - fn from(value: $a) -> Self { - Self::TransitionFrontier(TransitionFrontierAction::Sync( - TransitionFrontierSyncAction::Ledger( - TransitionFrontierSyncLedgerAction::Snarked(value.into()), - ), - )) - } - } - }; +impl From for crate::Action { + fn from(value: TransitionFrontierSyncLedgerSnarkedAction) -> Self { + Self::TransitionFrontier(TransitionFrontierAction::Sync( + TransitionFrontierSyncAction::Ledger(TransitionFrontierSyncLedgerAction::Snarked( + value, + )), + )) + } } - -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedPeersQueryAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSnarkedSuccessAction); diff --git a/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_effects.rs b/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_effects.rs index 745a55bc5..b756eaa21 100644 --- a/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_effects.rs +++ b/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_effects.rs @@ -7,16 +7,8 @@ use crate::ledger::{LedgerAddress, LEDGER_DEPTH}; use crate::Store; use super::{ - PeerLedgerQueryResponse, TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction, - TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction, - TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction, - TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction, - TransitionFrontierSyncLedgerSnarkedPeersQueryAction, - TransitionFrontierSyncLedgerSnarkedPendingAction, TransitionFrontierSyncLedgerSnarkedService, - TransitionFrontierSyncLedgerSnarkedSuccessAction, + PeerLedgerQueryResponse, TransitionFrontierSyncLedgerSnarkedAction, + TransitionFrontierSyncLedgerSnarkedService, }; fn query_peer_init( @@ -48,164 +40,164 @@ fn query_peer_init( id: rpc_id, request: P2pRpcRequest::LedgerQuery(ledger_hash, query), }) { - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeerQueryPendingAction { - address, - peer_id, - rpc_id, - }); + store.dispatch( + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryPending { + address, + peer_id, + rpc_id, + }, + ); } } -impl TransitionFrontierSyncLedgerSnarkedPendingAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}); - } -} - -impl TransitionFrontierSyncLedgerSnarkedPeersQueryAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - // TODO(binier): make sure they have the ledger we want to query. - let mut peer_ids = store - .state() - .p2p - .ready_peers_iter() - .filter(|(_, p)| p.channels.rpc.can_send_request()) - .map(|(id, p)| (*id, p.connected_since)) - .collect::>(); - peer_ids.sort_by(|(_, t1), (_, t2)| t2.cmp(t1)); - - let mut retry_addresses = store - .state() - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .map_or(vec![], |s| s.sync_retry_iter().collect()); - retry_addresses.reverse(); - - for (peer_id, _) in peer_ids { - if let Some(address) = retry_addresses.last() { - if store.dispatch(TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction { - peer_id, - address: address.clone(), - }) { - retry_addresses.pop(); - continue; +impl TransitionFrontierSyncLedgerSnarkedAction { + pub fn effects(&self, _: &ActionMeta, store: &mut Store) + where + S: TransitionFrontierSyncLedgerSnarkedService, + { + match self { + TransitionFrontierSyncLedgerSnarkedAction::Pending => { + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery); + } + TransitionFrontierSyncLedgerSnarkedAction::PeersQuery => { + // TODO(binier): make sure they have the ledger we want to query. + let mut peer_ids = store + .state() + .p2p + .ready_peers_iter() + .filter(|(_, p)| p.channels.rpc.can_send_request()) + .map(|(id, p)| (*id, p.connected_since)) + .collect::>(); + peer_ids.sort_by(|(_, t1), (_, t2)| t2.cmp(t1)); + + let mut retry_addresses = store + .state() + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()) + .map_or(vec![], |s| s.sync_retry_iter().collect()); + retry_addresses.reverse(); + + for (peer_id, _) in peer_ids { + if let Some(address) = retry_addresses.last() { + if store.dispatch( + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryRetry { + peer_id, + address: address.clone(), + }, + ) { + retry_addresses.pop(); + continue; + } + } + + let address = store + .state() + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()) + .and_then(|s| s.sync_next()); + match address { + Some(address) => { + store.dispatch( + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryInit { + peer_id, + address, + }, + ); + } + None if retry_addresses.is_empty() => break, + None => {} + } } } - - let address = store - .state() - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .and_then(|s| s.sync_next()); - match address { - Some(address) => { - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction { - peer_id, - address, - }); + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryInit { peer_id, address } => { + query_peer_init(store, *peer_id, address.clone()); + } + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryRetry { peer_id, address } => { + query_peer_init(store, *peer_id, address.clone()); + } + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError { .. } => { + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery); + } + TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess { + peer_id, + rpc_id, + response, + } => { + let ledger = store.state().transition_frontier.sync.ledger(); + let Some(address) = ledger + .and_then(|s| s.snarked()?.peer_query_get(peer_id, *rpc_id)) + .map(|(addr, _)| addr.clone()) + else { + return; + }; + + match response { + PeerLedgerQueryResponse::ChildHashes(left, right) => { + store.dispatch( + TransitionFrontierSyncLedgerSnarkedAction::ChildHashesReceived { + address, + hashes: (left.clone(), right.clone()), + sender: *peer_id, + }, + ); + } + PeerLedgerQueryResponse::ChildAccounts(accounts) => { + store.dispatch( + TransitionFrontierSyncLedgerSnarkedAction::ChildAccountsReceived { + address, + accounts: accounts.clone(), + sender: *peer_id, + }, + ); + } } - None if retry_addresses.is_empty() => break, - None => {} } - } - } -} - -impl TransitionFrontierSyncLedgerSnarkedPeerQueryInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - query_peer_init(store, self.peer_id, self.address); - } -} - -impl TransitionFrontierSyncLedgerSnarkedPeerQueryRetryAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - query_peer_init(store, self.peer_id, self.address); - } -} - -impl TransitionFrontierSyncLedgerSnarkedPeerQueryErrorAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}); - } -} - -impl TransitionFrontierSyncLedgerSnarkedPeerQuerySuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let ledger = store.state().transition_frontier.sync.ledger(); - let Some(address) = ledger - .and_then(|s| s.snarked()?.peer_query_get(&self.peer_id, self.rpc_id)) - .map(|(addr, _)| addr.clone()) - else { - return; - }; - - match self.response { - PeerLedgerQueryResponse::ChildHashes(left, right) => { - store.dispatch( - TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction { - address, - hashes: (left, right), - sender: self.peer_id, - }, - ); + TransitionFrontierSyncLedgerSnarkedAction::ChildHashesReceived { + address, + hashes, + .. + } => { + let Some(snarked_ledger_hash) = None.or_else(|| { + let ledger = store.state().transition_frontier.sync.ledger()?; + Some(ledger.snarked()?.ledger_hash().clone()) + }) else { + return; + }; + store + .service + .hashes_set(snarked_ledger_hash, address, hashes.clone()) + .unwrap(); + + if !store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery) { + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::Success); + } } - PeerLedgerQueryResponse::ChildAccounts(accounts) => { - store.dispatch( - TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction { - address, - accounts, - sender: self.peer_id, - }, - ); + TransitionFrontierSyncLedgerSnarkedAction::ChildAccountsReceived { + address, + accounts, + .. + } => { + let Some(snarked_ledger_hash) = None.or_else(|| { + let ledger = store.state().transition_frontier.sync.ledger()?; + Some(ledger.snarked()?.ledger_hash().clone()) + }) else { + return; + }; + store + .service + .accounts_set(snarked_ledger_hash, address, accounts.clone()) + .unwrap(); + + if !store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery) { + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::Success); + } } - } - } -} - -impl TransitionFrontierSyncLedgerSnarkedChildHashesReceivedAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - S: TransitionFrontierSyncLedgerSnarkedService, - { - let Some(snarked_ledger_hash) = None.or_else(|| { - let ledger = store.state().transition_frontier.sync.ledger()?; - Some(ledger.snarked()?.ledger_hash().clone()) - }) else { - return; - }; - store - .service - .hashes_set(snarked_ledger_hash, &self.address, self.hashes) - .unwrap(); - - if !store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}) { - store.dispatch(TransitionFrontierSyncLedgerSnarkedSuccessAction {}); - } - } -} - -impl TransitionFrontierSyncLedgerSnarkedChildAccountsReceivedAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - S: TransitionFrontierSyncLedgerSnarkedService, - { - let Some(snarked_ledger_hash) = None.or_else(|| { - let ledger = store.state().transition_frontier.sync.ledger()?; - Some(ledger.snarked()?.ledger_hash().clone()) - }) else { - return; - }; - store - .service - .accounts_set(snarked_ledger_hash, &self.address, self.accounts) - .unwrap(); - - if !store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}) { - store.dispatch(TransitionFrontierSyncLedgerSnarkedSuccessAction {}); + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryPending { .. } => {} + TransitionFrontierSyncLedgerSnarkedAction::Success => {} } } } diff --git a/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_reducer.rs b/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_reducer.rs index f81add66a..9445ef48e 100644 --- a/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_reducer.rs +++ b/node/src/transition_frontier/sync/ledger/snarked/transition_frontier_sync_ledger_snarked_reducer.rs @@ -9,11 +9,11 @@ impl TransitionFrontierSyncLedgerSnarkedState { pub fn reducer(&mut self, action: TransitionFrontierSyncLedgerSnarkedActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - TransitionFrontierSyncLedgerSnarkedAction::Pending(_) => { + TransitionFrontierSyncLedgerSnarkedAction::Pending => { // handled in parent reducer. } - TransitionFrontierSyncLedgerSnarkedAction::PeersQuery(_) => {} - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryInit(action) => { + TransitionFrontierSyncLedgerSnarkedAction::PeersQuery => {} + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryInit { address, peer_id } => { if let Self::Pending { pending, next_addr, @@ -22,11 +22,11 @@ impl TransitionFrontierSyncLedgerSnarkedState { } = self { pending.insert( - action.address.clone(), + address.clone(), LedgerQueryPending { time: meta.time(), attempts: std::iter::once(( - action.peer_id, + *peer_id, PeerRpcState::Init { time: meta.time() }, )) .collect(), @@ -54,54 +54,66 @@ impl TransitionFrontierSyncLedgerSnarkedState { .filter(|addr| addr.length() < LEDGER_DEPTH); } } - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryRetry(action) => { + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryRetry { address, peer_id } => { if let Self::Pending { pending, .. } = self { - if let Some(pending) = pending.get_mut(&action.address) { + if let Some(pending) = pending.get_mut(address) { pending .attempts - .insert(action.peer_id, PeerRpcState::Init { time: meta.time() }); + .insert(*peer_id, PeerRpcState::Init { time: meta.time() }); } } } - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryPending(action) => { + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryPending { + address, + peer_id, + rpc_id, + } => { let Self::Pending { pending, .. } = self else { return; }; let Some(rpc_state) = pending - .get_mut(&action.address) - .and_then(|s| s.attempts.get_mut(&action.peer_id)) + .get_mut(address) + .and_then(|s| s.attempts.get_mut(peer_id)) else { return; }; *rpc_state = PeerRpcState::Pending { time: meta.time(), - rpc_id: action.rpc_id, + rpc_id: *rpc_id, }; } - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError(action) => { - let Some(rpc_state) = self.peer_query_get_mut(&action.peer_id, action.rpc_id) - else { + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError { + peer_id, + rpc_id, + error, + } => { + let Some(rpc_state) = self.peer_query_get_mut(peer_id, *rpc_id) else { return; }; *rpc_state = PeerRpcState::Error { time: meta.time(), - rpc_id: action.rpc_id, - error: action.error.clone(), + rpc_id: *rpc_id, + error: error.clone(), }; } - TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess(action) => { - let Some(rpc_state) = self.peer_query_get_mut(&action.peer_id, action.rpc_id) - else { + TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess { + peer_id, rpc_id, .. + } => { + let Some(rpc_state) = self.peer_query_get_mut(peer_id, *rpc_id) else { return; }; *rpc_state = PeerRpcState::Success { time: meta.time(), - rpc_id: action.rpc_id, + rpc_id: *rpc_id, }; } - TransitionFrontierSyncLedgerSnarkedAction::ChildHashesReceived(action) => { + TransitionFrontierSyncLedgerSnarkedAction::ChildHashesReceived { + address, + hashes, + .. + } => { let Self::Pending { pending, next_addr, @@ -111,9 +123,9 @@ impl TransitionFrontierSyncLedgerSnarkedState { else { return; }; - let addr = &action.address; + let addr = address; pending.remove(&addr); - let (left, right) = &action.hashes; + let (left, right) = hashes; let empty_hash = ledger_empty_hash_at_depth(addr.length() + 1); if right == &empty_hash { @@ -131,13 +143,15 @@ impl TransitionFrontierSyncLedgerSnarkedState { } } } - TransitionFrontierSyncLedgerSnarkedAction::ChildAccountsReceived(action) => { + TransitionFrontierSyncLedgerSnarkedAction::ChildAccountsReceived { + address, .. + } => { let Self::Pending { pending, .. } = self else { return; }; - pending.remove(&action.address); + pending.remove(address); } - TransitionFrontierSyncLedgerSnarkedAction::Success(_) => { + TransitionFrontierSyncLedgerSnarkedAction::Success => { let Self::Pending { target, .. } = self else { return; }; diff --git a/node/src/transition_frontier/sync/ledger/staged/mod.rs b/node/src/transition_frontier/sync/ledger/staged/mod.rs index 7e6da6032..1b897e26c 100644 --- a/node/src/transition_frontier/sync/ledger/staged/mod.rs +++ b/node/src/transition_frontier/sync/ledger/staged/mod.rs @@ -5,10 +5,10 @@ mod transition_frontier_sync_ledger_staged_actions; pub use transition_frontier_sync_ledger_staged_actions::*; mod transition_frontier_sync_ledger_staged_reducer; -pub use transition_frontier_sync_ledger_staged_reducer::*; + mod transition_frontier_sync_ledger_staged_effects; -pub use transition_frontier_sync_ledger_staged_effects::*; + mod transition_frontier_sync_ledger_staged_service; pub use transition_frontier_sync_ledger_staged_service::*; diff --git a/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_actions.rs b/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_actions.rs index 9edb81adc..922469767 100644 --- a/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_actions.rs +++ b/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_actions.rs @@ -16,325 +16,202 @@ pub type TransitionFrontierSyncLedgerStagedActionWithMeta = pub type TransitionFrontierSyncLedgerStagedActionWithMetaRef<'a> = redux::ActionWithMeta<&'a TransitionFrontierSyncLedgerStagedAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] -pub enum TransitionFrontierSyncLedgerStagedAction { - PartsFetchPending(TransitionFrontierSyncLedgerStagedPartsFetchPendingAction), - PartsPeerFetchInit(TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction), - PartsPeerFetchPending(TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction), - PartsPeerFetchError(TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction), - PartsPeerFetchSuccess(TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction), - PartsPeerInvalid(TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction), - PartsPeerValid(TransitionFrontierSyncLedgerStagedPartsPeerValidAction), - PartsFetchSuccess(TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction), - ReconstructEmpty(TransitionFrontierSyncLedgerStagedReconstructEmptyAction), - ReconstructInit(TransitionFrontierSyncLedgerStagedReconstructInitAction), - ReconstructPending(TransitionFrontierSyncLedgerStagedReconstructPendingAction), - ReconstructError(TransitionFrontierSyncLedgerStagedReconstructErrorAction), - ReconstructSuccess(TransitionFrontierSyncLedgerStagedReconstructSuccessAction), - Success(TransitionFrontierSyncLedgerStagedSuccessAction), -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsFetchPendingAction {} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsFetchPendingAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .map_or(false, |s| match s { - TransitionFrontierSyncLedgerSnarkedState::Success { target, .. } => { - target.staged.is_some() - } - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction {} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()) - .map_or(false, |staged| { - let iter = state.p2p.ready_rpc_peers_iter(); - staged.filter_available_peers(iter).next().is_some() - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction { - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()) - .map_or(false, |s| { - matches!( - s, - TransitionFrontierSyncLedgerStagedState::PartsFetchPending { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction { - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, - pub error: PeerStagedLedgerPartsFetchError, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()?.fetch_attempts()?.get(&self.peer_id)) - .and_then(|s| s.fetch_pending_rpc_id()) - .map_or(false, |rpc_id| rpc_id == self.rpc_id) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction { - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, - pub parts: Arc, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()?.fetch_attempts()?.get(&self.peer_id)) - .and_then(|s| s.fetch_pending_rpc_id()) - .map_or(false, |rpc_id| rpc_id == self.rpc_id) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction { - pub sender: PeerId, - pub parts: Arc, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()?.fetch_attempts()?.get(&self.sender)) - .map_or(false, |s| match s { - PeerStagedLedgerPartsFetchState::Success { parts, .. } => !parts.is_valid(), - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsPeerValidAction { - pub sender: PeerId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsPeerValidAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()?.fetch_attempts()?.get(&self.sender)) - .map_or(false, |s| match s { - PeerStagedLedgerPartsFetchState::Success { parts, .. } => parts.is_valid(), - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction { - pub sender: PeerId, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()?.fetch_attempts()?.get(&self.sender)) - .map_or(false, |s| s.is_valid()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedReconstructEmptyAction {} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedReconstructEmptyAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .and_then(|s| match s { - TransitionFrontierSyncLedgerSnarkedState::Success { target, .. } => { - target.clone().with_staged() - } - _ => None, - }) - .map_or(false, |target| { - let hashes = &target.staged.hashes; - let empty_hash = &[0; 32]; - target.snarked_ledger_hash == hashes.non_snark.ledger_hash - && hashes.non_snark.aux_hash.as_ref() == empty_hash - && hashes.non_snark.pending_coinbase_aux.as_ref() == empty_hash - // TODO(binier): `pending_coinbase_hash` isn't empty hash. - // Do we need to check it? - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedReconstructInitAction {} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedReconstructInitAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()) - .map_or(false, |s| { - matches!( - s, - TransitionFrontierSyncLedgerStagedState::PartsFetchSuccess { .. } - | TransitionFrontierSyncLedgerStagedState::ReconstructEmpty { .. } - ) - }) - } -} - #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedReconstructPendingAction {} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedReconstructPendingAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()) - .map_or(false, |s| { - matches!( - s, - TransitionFrontierSyncLedgerStagedState::PartsFetchSuccess { .. } - | TransitionFrontierSyncLedgerStagedState::ReconstructEmpty { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedReconstructErrorAction { - pub error: String, -} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedReconstructErrorAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()) - .map_or(false, |s| { - matches!( - s, - TransitionFrontierSyncLedgerStagedState::ReconstructPending { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedReconstructSuccessAction {} - -impl redux::EnablingCondition - for TransitionFrontierSyncLedgerStagedReconstructSuccessAction -{ - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()) - .map_or(false, |s| { - matches!( - s, - TransitionFrontierSyncLedgerStagedState::ReconstructPending { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStagedSuccessAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerStagedSuccessAction { +pub enum TransitionFrontierSyncLedgerStagedAction { + PartsFetchPending, + PartsPeerFetchInit, + PartsPeerFetchPending { + peer_id: PeerId, + rpc_id: P2pRpcId, + }, + PartsPeerFetchError { + peer_id: PeerId, + rpc_id: P2pRpcId, + error: PeerStagedLedgerPartsFetchError, + }, + PartsPeerFetchSuccess { + peer_id: PeerId, + rpc_id: P2pRpcId, + parts: Arc, + }, + PartsPeerInvalid { + sender: PeerId, + parts: Arc, + }, + PartsPeerValid { + sender: PeerId, + }, + PartsFetchSuccess { + sender: PeerId, + }, + ReconstructEmpty, + ReconstructInit, + ReconstructPending, + ReconstructError { + error: String, + }, + ReconstructSuccess, + Success, +} + +impl redux::EnablingCondition for TransitionFrontierSyncLedgerStagedAction { fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .ledger() - .and_then(|s| s.staged()) - .map_or(false, |s| { - matches!( - s, - TransitionFrontierSyncLedgerStagedState::ReconstructSuccess { .. } - ) - }) + match self { + TransitionFrontierSyncLedgerStagedAction::PartsFetchPending => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()) + .map_or(false, |s| match s { + TransitionFrontierSyncLedgerSnarkedState::Success { target, .. } => { + target.staged.is_some() + } + _ => false, + }), + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()) + .map_or(false, |staged| { + let iter = state.p2p.ready_rpc_peers_iter(); + staged.filter_available_peers(iter).next().is_some() + }), + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchPending { .. } => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()) + .map_or(false, |s| { + matches!( + s, + TransitionFrontierSyncLedgerStagedState::PartsFetchPending { .. } + ) + }), + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError { + peer_id, + rpc_id, + .. + } => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()?.fetch_attempts()?.get(peer_id)) + .and_then(|s| s.fetch_pending_rpc_id()) + .map_or(false, |fetch_rpc_id| fetch_rpc_id == *rpc_id), + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchSuccess { + peer_id, + rpc_id, + .. + } => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()?.fetch_attempts()?.get(peer_id)) + .and_then(|s| s.fetch_pending_rpc_id()) + .map_or(false, |fetch_rpc_id| fetch_rpc_id == *rpc_id), + TransitionFrontierSyncLedgerStagedAction::PartsPeerInvalid { sender, .. } => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()?.fetch_attempts()?.get(sender)) + .map_or(false, |s| match s { + PeerStagedLedgerPartsFetchState::Success { parts, .. } => !parts.is_valid(), + _ => false, + }), + TransitionFrontierSyncLedgerStagedAction::PartsPeerValid { sender } => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()?.fetch_attempts()?.get(sender)) + .map_or(false, |s| match s { + PeerStagedLedgerPartsFetchState::Success { parts, .. } => parts.is_valid(), + _ => false, + }), + TransitionFrontierSyncLedgerStagedAction::PartsFetchSuccess { sender } => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()?.fetch_attempts()?.get(sender)) + .map_or(false, |s| s.is_valid()), + TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()) + .and_then(|s| match s { + TransitionFrontierSyncLedgerSnarkedState::Success { target, .. } => { + target.clone().with_staged() + } + _ => None, + }) + .map_or(false, |target| { + let hashes = &target.staged.hashes; + let empty_hash = &[0; 32]; + target.snarked_ledger_hash == hashes.non_snark.ledger_hash + && hashes.non_snark.aux_hash.as_ref() == empty_hash + && hashes.non_snark.pending_coinbase_aux.as_ref() == empty_hash + // TODO(binier): `pending_coinbase_hash` isn't empty hash. + // Do we need to check it? + }), + TransitionFrontierSyncLedgerStagedAction::ReconstructInit => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()) + .map_or(false, |s| { + matches!( + s, + TransitionFrontierSyncLedgerStagedState::PartsFetchSuccess { .. } + | TransitionFrontierSyncLedgerStagedState::ReconstructEmpty { .. } + ) + }), + TransitionFrontierSyncLedgerStagedAction::ReconstructPending => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()) + .map_or(false, |s| { + matches!( + s, + TransitionFrontierSyncLedgerStagedState::PartsFetchSuccess { .. } + | TransitionFrontierSyncLedgerStagedState::ReconstructEmpty { .. } + ) + }), + TransitionFrontierSyncLedgerStagedAction::ReconstructError { .. } => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()) + .map_or(false, |s| { + matches!( + s, + TransitionFrontierSyncLedgerStagedState::ReconstructPending { .. } + ) + }), + TransitionFrontierSyncLedgerStagedAction::ReconstructSuccess => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()) + .map_or(false, |s| { + matches!( + s, + TransitionFrontierSyncLedgerStagedState::ReconstructPending { .. } + ) + }), + TransitionFrontierSyncLedgerStagedAction::Success => state + .transition_frontier + .sync + .ledger() + .and_then(|s| s.staged()) + .map_or(false, |s| { + matches!( + s, + TransitionFrontierSyncLedgerStagedState::ReconstructSuccess { .. } + ) + }), + } } } @@ -343,31 +220,10 @@ use crate::transition_frontier::{ TransitionFrontierAction, }; -macro_rules! impl_into_global_action { - ($a:ty) => { - impl From<$a> for crate::Action { - fn from(value: $a) -> Self { - Self::TransitionFrontier(TransitionFrontierAction::Sync( - TransitionFrontierSyncAction::Ledger( - TransitionFrontierSyncLedgerAction::Staged(value.into()), - ), - )) - } - } - }; +impl From for crate::Action { + fn from(value: TransitionFrontierSyncLedgerStagedAction) -> Self { + Self::TransitionFrontier(TransitionFrontierAction::Sync( + TransitionFrontierSyncAction::Ledger(TransitionFrontierSyncLedgerAction::Staged(value)), + )) + } } - -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsFetchPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsPeerValidAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedReconstructEmptyAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedReconstructInitAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedReconstructPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedReconstructErrorAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedReconstructSuccessAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStagedSuccessAction); diff --git a/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_effects.rs b/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_effects.rs index b832a9038..63cf20b3a 100644 --- a/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_effects.rs +++ b/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_effects.rs @@ -3,140 +3,111 @@ use redux::ActionMeta; use crate::p2p::channels::rpc::{P2pChannelsRpcAction, P2pRpcRequest}; use crate::Store; -use super::{ - TransitionFrontierSyncLedgerStagedPartsFetchPendingAction, - TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction, - TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction, - TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction, - TransitionFrontierSyncLedgerStagedPartsPeerValidAction, - TransitionFrontierSyncLedgerStagedReconstructEmptyAction, - TransitionFrontierSyncLedgerStagedReconstructErrorAction, - TransitionFrontierSyncLedgerStagedReconstructInitAction, - TransitionFrontierSyncLedgerStagedReconstructPendingAction, - TransitionFrontierSyncLedgerStagedReconstructSuccessAction, - TransitionFrontierSyncLedgerStagedService, TransitionFrontierSyncLedgerStagedSuccessAction, -}; +use super::{TransitionFrontierSyncLedgerStagedAction, TransitionFrontierSyncLedgerStagedService}; -impl TransitionFrontierSyncLedgerStagedPartsFetchPendingAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let state = store.state(); - let Some(staged_ledger) = - None.or_else(|| state.transition_frontier.sync.ledger()?.staged()) - else { - return; - }; - let block_hash = staged_ledger.target().staged.block_hash.clone(); - - let ready_peers = staged_ledger - .filter_available_peers(state.p2p.ready_rpc_peers_iter()) - .collect::>(); - - for (peer_id, rpc_id) in ready_peers { - // TODO(binier): maybe - if store.dispatch(P2pChannelsRpcAction::RequestSend { +impl TransitionFrontierSyncLedgerStagedAction { + pub fn effects(self, _: &ActionMeta, store: &mut Store) + where + S: TransitionFrontierSyncLedgerStagedService, + { + match self { + TransitionFrontierSyncLedgerStagedAction::PartsFetchPending => { + store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit); + } + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit => { + let state = store.state(); + let Some(staged_ledger) = + None.or_else(|| state.transition_frontier.sync.ledger()?.staged()) + else { + return; + }; + let block_hash = staged_ledger.target().staged.block_hash.clone(); + + let ready_peers = staged_ledger + .filter_available_peers(state.p2p.ready_rpc_peers_iter()) + .collect::>(); + + for (peer_id, rpc_id) in ready_peers { + // TODO(binier): maybe + if store.dispatch(P2pChannelsRpcAction::RequestSend { + peer_id, + id: rpc_id, + request: P2pRpcRequest::StagedLedgerAuxAndPendingCoinbasesAtBlock( + block_hash.clone(), + ), + }) { + store.dispatch( + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchPending { + peer_id, + rpc_id, + }, + ); + break; + } + } + } + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError { .. } => { + store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit); + } + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchSuccess { peer_id, - id: rpc_id, - request: P2pRpcRequest::StagedLedgerAuxAndPendingCoinbasesAtBlock( - block_hash.clone(), - ), - }) { + parts, + .. + } => { + if !store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsPeerValid { + sender: peer_id, + }) { + store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsPeerInvalid { + sender: peer_id, + parts, + }); + } + } + TransitionFrontierSyncLedgerStagedAction::PartsPeerInvalid { .. } => { + store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit); + } + TransitionFrontierSyncLedgerStagedAction::PartsPeerValid { sender } => { store.dispatch( - TransitionFrontierSyncLedgerStagedPartsPeerFetchPendingAction { - peer_id, - rpc_id, - }, + TransitionFrontierSyncLedgerStagedAction::PartsFetchSuccess { sender }, ); - break; } - } - } -} - -impl TransitionFrontierSyncLedgerStagedPartsPeerFetchErrorAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerStagedPartsPeerFetchSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - if !store.dispatch(TransitionFrontierSyncLedgerStagedPartsPeerValidAction { - sender: self.peer_id, - }) { - store.dispatch(TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction { - sender: self.peer_id, - parts: self.parts, - }); - } - } -} - -impl TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStagedPartsPeerFetchInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerStagedPartsPeerValidAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction { - sender: self.sender, - }); - } -} - -impl TransitionFrontierSyncLedgerStagedPartsFetchSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStagedReconstructInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerStagedReconstructEmptyAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStagedReconstructInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerStagedReconstructInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - S: TransitionFrontierSyncLedgerStagedService, - { - let ledger_state = store.state().transition_frontier.sync.ledger(); - let Some((target, parts)) = ledger_state.and_then(|s| s.staged()?.target_with_parts()) - else { - return; - }; - let snarked_ledger_hash = target.snarked_ledger_hash.clone(); - let parts = parts.cloned(); - - store.dispatch(TransitionFrontierSyncLedgerStagedReconstructPendingAction {}); - - match store - .service - .staged_ledger_reconstruct(snarked_ledger_hash, parts) - { - Err(error) => { - store.dispatch(TransitionFrontierSyncLedgerStagedReconstructErrorAction { error }); + TransitionFrontierSyncLedgerStagedAction::PartsFetchSuccess { .. } => { + store.dispatch(TransitionFrontierSyncLedgerStagedAction::ReconstructInit); + } + TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty => { + store.dispatch(TransitionFrontierSyncLedgerStagedAction::ReconstructInit); + } + TransitionFrontierSyncLedgerStagedAction::ReconstructInit => { + let ledger_state = store.state().transition_frontier.sync.ledger(); + let Some((target, parts)) = + ledger_state.and_then(|s| s.staged()?.target_with_parts()) + else { + return; + }; + let snarked_ledger_hash = target.snarked_ledger_hash.clone(); + let parts = parts.cloned(); + + store.dispatch(TransitionFrontierSyncLedgerStagedAction::ReconstructPending); + + match store + .service + .staged_ledger_reconstruct(snarked_ledger_hash, parts) + { + Err(error) => { + store.dispatch( + TransitionFrontierSyncLedgerStagedAction::ReconstructError { error }, + ); + } + Ok(_) => { + store + .dispatch(TransitionFrontierSyncLedgerStagedAction::ReconstructSuccess); + } + } } - Ok(_) => { - store.dispatch(TransitionFrontierSyncLedgerStagedReconstructSuccessAction {}); + TransitionFrontierSyncLedgerStagedAction::ReconstructSuccess => { + store.dispatch(TransitionFrontierSyncLedgerStagedAction::Success); } + _ => {} } } } - -impl TransitionFrontierSyncLedgerStagedReconstructSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStagedSuccessAction {}); - } -} diff --git a/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_reducer.rs b/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_reducer.rs index 12cf67247..bb7be527d 100644 --- a/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_reducer.rs +++ b/node/src/transition_frontier/sync/ledger/staged/transition_frontier_sync_ledger_staged_reducer.rs @@ -1,8 +1,9 @@ +use ledger::scan_state::protocol_state::MinaHash; +use mina_p2p_messages::v2; + use super::{ PeerStagedLedgerPartsFetchState, StagedLedgerAuxAndPendingCoinbasesValidated, TransitionFrontierSyncLedgerStagedAction, TransitionFrontierSyncLedgerStagedActionWithMetaRef, - TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction, - TransitionFrontierSyncLedgerStagedPartsPeerValidAction, TransitionFrontierSyncLedgerStagedState, }; @@ -10,27 +11,31 @@ impl TransitionFrontierSyncLedgerStagedState { pub fn reducer(&mut self, action: TransitionFrontierSyncLedgerStagedActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - TransitionFrontierSyncLedgerStagedAction::PartsFetchPending(_) => { + TransitionFrontierSyncLedgerStagedAction::PartsFetchPending => { // handled in parent. } - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit(_) => {} - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchPending(action) => { + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit => {} + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchPending { peer_id, rpc_id } => { let Self::PartsFetchPending { attempts, .. } = self else { return; }; attempts.insert( - action.peer_id, + *peer_id, PeerStagedLedgerPartsFetchState::Pending { time: meta.time(), - rpc_id: action.rpc_id, + rpc_id: *rpc_id, }, ); } - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError(action) => { + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError { + peer_id, + error, + .. + } => { let Self::PartsFetchPending { attempts, .. } = self else { return; }; - let Some(attempt) = attempts.get_mut(&action.peer_id) else { + let Some(attempt) = attempts.get_mut(peer_id) else { return; }; let PeerStagedLedgerPartsFetchState::Pending { rpc_id, .. } = &attempt else { @@ -39,37 +44,35 @@ impl TransitionFrontierSyncLedgerStagedState { *attempt = PeerStagedLedgerPartsFetchState::Error { time: meta.time(), rpc_id: *rpc_id, - error: action.error.clone(), + error: error.clone(), }; } - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchSuccess(action) => { + TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchSuccess { + peer_id, + parts, + .. + } => { let Self::PartsFetchPending { target, attempts, .. } = self else { return; }; - let Some(attempt) = attempts.get_mut(&action.peer_id) else { + let Some(attempt) = attempts.get_mut(peer_id) else { return; }; let expected_hash = &target.staged.hashes; - let validated = StagedLedgerAuxAndPendingCoinbasesValidated::validate( - &action.parts, - expected_hash, - ); + let validated = + StagedLedgerAuxAndPendingCoinbasesValidated::validate(parts, expected_hash); *attempt = PeerStagedLedgerPartsFetchState::Success { time: meta.time(), parts: validated, }; } - TransitionFrontierSyncLedgerStagedAction::PartsPeerInvalid( - TransitionFrontierSyncLedgerStagedPartsPeerInvalidAction { sender, .. }, - ) - | TransitionFrontierSyncLedgerStagedAction::PartsPeerValid( - TransitionFrontierSyncLedgerStagedPartsPeerValidAction { sender, .. }, - ) => { + TransitionFrontierSyncLedgerStagedAction::PartsPeerInvalid { sender, .. } + | TransitionFrontierSyncLedgerStagedAction::PartsPeerValid { sender, .. } => { let Self::PartsFetchPending { attempts, .. } = self else { return; }; @@ -92,14 +95,14 @@ impl TransitionFrontierSyncLedgerStagedState { } } } - TransitionFrontierSyncLedgerStagedAction::PartsFetchSuccess(action) => { + TransitionFrontierSyncLedgerStagedAction::PartsFetchSuccess { sender } => { let Self::PartsFetchPending { target, attempts, .. } = self else { return; }; - let Some(attempt) = attempts.get_mut(&action.sender) else { + let Some(attempt) = attempts.get_mut(sender) else { return; }; let PeerStagedLedgerPartsFetchState::Valid { parts, .. } = attempt else { @@ -111,11 +114,11 @@ impl TransitionFrontierSyncLedgerStagedState { parts: parts.clone(), }; } - TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty(_) => { + TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty => { // handled in parent. } - TransitionFrontierSyncLedgerStagedAction::ReconstructInit(_) => {} - TransitionFrontierSyncLedgerStagedAction::ReconstructPending(_) => { + TransitionFrontierSyncLedgerStagedAction::ReconstructInit => {} + TransitionFrontierSyncLedgerStagedAction::ReconstructPending => { let Some((target, parts)) = self.target_with_parts() else { return; }; @@ -125,7 +128,7 @@ impl TransitionFrontierSyncLedgerStagedState { parts: parts.cloned(), } } - TransitionFrontierSyncLedgerStagedAction::ReconstructError(action) => { + TransitionFrontierSyncLedgerStagedAction::ReconstructError { error } => { let Self::ReconstructPending { target, parts, .. } = self else { return; }; @@ -133,10 +136,10 @@ impl TransitionFrontierSyncLedgerStagedState { time: meta.time(), target: target.clone(), parts: parts.clone(), - error: action.error.clone(), + error: error.clone(), }; } - TransitionFrontierSyncLedgerStagedAction::ReconstructSuccess(_) => { + TransitionFrontierSyncLedgerStagedAction::ReconstructSuccess => { let Self::ReconstructPending { target, parts, .. } = self else { return; }; @@ -146,7 +149,7 @@ impl TransitionFrontierSyncLedgerStagedState { parts: parts.clone(), }; } - TransitionFrontierSyncLedgerStagedAction::Success(_) => { + TransitionFrontierSyncLedgerStagedAction::Success => { let Self::ReconstructSuccess { target, parts, .. } = self else { return; }; @@ -159,7 +162,7 @@ impl TransitionFrontierSyncLedgerStagedState { .map(|parts| &parts.needed_blocks[..]) .unwrap_or(&[]) .iter() - .map(|block| (block.hash(), block.clone())) + .map(|block| (v2::StateHash::from_fp(MinaHash::hash(block)), block.clone())) .collect(), }; } diff --git a/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_actions.rs b/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_actions.rs index fca10f675..194b7dd21 100644 --- a/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_actions.rs +++ b/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_actions.rs @@ -1,5 +1,8 @@ use serde::{Deserialize, Serialize}; +use crate::transition_frontier::sync::TransitionFrontierSyncAction; +use crate::TransitionFrontierAction; + use super::snarked::TransitionFrontierSyncLedgerSnarkedAction; use super::staged::TransitionFrontierSyncLedgerStagedAction; use super::TransitionFrontierSyncLedgerState; @@ -11,45 +14,32 @@ pub type TransitionFrontierSyncLedgerActionWithMetaRef<'a> = #[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] pub enum TransitionFrontierSyncLedgerAction { - Init(TransitionFrontierSyncLedgerInitAction), + Init, Snarked(TransitionFrontierSyncLedgerSnarkedAction), Staged(TransitionFrontierSyncLedgerStagedAction), - Success(TransitionFrontierSyncLedgerSuccessAction), + Success, } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerInitAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerInitAction { +impl redux::EnablingCondition for TransitionFrontierSyncLedgerAction { fn is_enabled(&self, state: &crate::State) -> bool { - state.transition_frontier.sync.ledger().map_or(false, |s| { - matches!(s, TransitionFrontierSyncLedgerState::Init { .. }) - }) + match self { + TransitionFrontierSyncLedgerAction::Init => { + state.transition_frontier.sync.ledger().map_or(false, |s| { + matches!(s, TransitionFrontierSyncLedgerState::Init { .. }) + }) + } + TransitionFrontierSyncLedgerAction::Success => { + state.transition_frontier.sync.is_ledger_sync_complete() + } + _ => true, + } } } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerSuccessAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.transition_frontier.sync.is_ledger_sync_complete() +impl From for crate::Action { + fn from(value: TransitionFrontierSyncLedgerAction) -> Self { + Self::TransitionFrontier(TransitionFrontierAction::Sync( + TransitionFrontierSyncAction::Ledger(value), + )) } } - -use crate::transition_frontier::{sync::TransitionFrontierSyncAction, TransitionFrontierAction}; - -macro_rules! impl_into_global_action { - ($a:ty) => { - impl From<$a> for crate::Action { - fn from(value: $a) -> Self { - Self::TransitionFrontier(TransitionFrontierAction::Sync( - TransitionFrontierSyncAction::Ledger(value.into()), - )) - } - } - }; -} - -impl_into_global_action!(TransitionFrontierSyncLedgerInitAction); -impl_into_global_action!(TransitionFrontierSyncLedgerSuccessAction); diff --git a/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_effects.rs b/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_effects.rs index 3545aa7a9..14f3506f7 100644 --- a/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_effects.rs +++ b/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_effects.rs @@ -2,34 +2,30 @@ use redux::ActionMeta; use crate::Store; -use super::snarked::{ - TransitionFrontierSyncLedgerSnarkedPendingAction, - TransitionFrontierSyncLedgerSnarkedSuccessAction, -}; -use super::staged::{ - TransitionFrontierSyncLedgerStagedPartsFetchPendingAction, - TransitionFrontierSyncLedgerStagedReconstructEmptyAction, - TransitionFrontierSyncLedgerStagedSuccessAction, -}; -use super::{TransitionFrontierSyncLedgerInitAction, TransitionFrontierSyncLedgerSuccessAction}; +use super::snarked::TransitionFrontierSyncLedgerSnarkedAction; +use super::staged::TransitionFrontierSyncLedgerStagedAction; +use super::TransitionFrontierSyncLedgerAction; -impl TransitionFrontierSyncLedgerInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerSnarkedPendingAction {}); - } +pub fn transition_frontier_sync_ledger_init_effects( + _: &ActionMeta, + store: &mut Store, +) { + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::Pending); } -impl TransitionFrontierSyncLedgerSnarkedSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - if store.dispatch(TransitionFrontierSyncLedgerSuccessAction {}) { - } else if store.dispatch(TransitionFrontierSyncLedgerStagedReconstructEmptyAction {}) { - } else if store.dispatch(TransitionFrontierSyncLedgerStagedPartsFetchPendingAction {}) { - } +pub fn transition_frontier_sync_ledger_snarked_success_effects( + _: &ActionMeta, + store: &mut Store, +) { + if store.dispatch(TransitionFrontierSyncLedgerAction::Success) { + } else if store.dispatch(TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty) { + } else if store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsFetchPending) { } } -impl TransitionFrontierSyncLedgerStagedSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerSuccessAction {}); - } +pub fn transition_frontier_sync_ledger_staged_success_effects( + _: &ActionMeta, + store: &mut Store, +) { + store.dispatch(TransitionFrontierSyncLedgerAction::Success); } diff --git a/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_reducer.rs b/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_reducer.rs index 7096f051b..06b47a66e 100644 --- a/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_reducer.rs +++ b/node/src/transition_frontier/sync/ledger/transition_frontier_sync_ledger_reducer.rs @@ -13,9 +13,9 @@ impl TransitionFrontierSyncLedgerState { pub fn reducer(&mut self, action: TransitionFrontierSyncLedgerActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - TransitionFrontierSyncLedgerAction::Init(_) => {} + TransitionFrontierSyncLedgerAction::Init => {} TransitionFrontierSyncLedgerAction::Snarked(action) => { - if let TransitionFrontierSyncLedgerSnarkedAction::Pending(_) = action { + if let TransitionFrontierSyncLedgerSnarkedAction::Pending = action { let Self::Init { target, .. } = self else { return; }; @@ -30,7 +30,7 @@ impl TransitionFrontierSyncLedgerState { } } TransitionFrontierSyncLedgerAction::Staged(action) => { - if let TransitionFrontierSyncLedgerStagedAction::PartsFetchPending(_) = action { + if let TransitionFrontierSyncLedgerStagedAction::PartsFetchPending = action { let Self::Snarked(TransitionFrontierSyncLedgerSnarkedState::Success { target, .. @@ -50,7 +50,7 @@ impl TransitionFrontierSyncLedgerState { .. }) if matches!( action, - TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty(_) + TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty ) => { let s = TransitionFrontierSyncLedgerStagedState::ReconstructEmpty { @@ -64,7 +64,7 @@ impl TransitionFrontierSyncLedgerState { } } } - TransitionFrontierSyncLedgerAction::Success(_) => { + TransitionFrontierSyncLedgerAction::Success => { match self { Self::Staged(TransitionFrontierSyncLedgerStagedState::Success { target, diff --git a/node/src/transition_frontier/sync/mod.rs b/node/src/transition_frontier/sync/mod.rs index 53a71153a..bba110c7e 100644 --- a/node/src/transition_frontier/sync/mod.rs +++ b/node/src/transition_frontier/sync/mod.rs @@ -7,10 +7,10 @@ mod transition_frontier_sync_actions; pub use transition_frontier_sync_actions::*; mod transition_frontier_sync_reducer; -pub use transition_frontier_sync_reducer::*; + mod transition_frontier_sync_effects; -pub use transition_frontier_sync_effects::*; + use serde::{Deserialize, Serialize}; diff --git a/node/src/transition_frontier/sync/transition_frontier_sync_actions.rs b/node/src/transition_frontier/sync/transition_frontier_sync_actions.rs index 19d6f7a4c..8d42e6ae8 100644 --- a/node/src/transition_frontier/sync/transition_frontier_sync_actions.rs +++ b/node/src/transition_frontier/sync/transition_frontier_sync_actions.rs @@ -6,6 +6,7 @@ use serde::{Deserialize, Serialize}; use crate::p2p::channels::rpc::P2pRpcId; use crate::p2p::PeerId; use crate::transition_frontier::sync::TransitionFrontierSyncLedgerPending; +use crate::TransitionFrontierAction; use super::ledger::{ SyncLedgerTarget, TransitionFrontierSyncLedgerAction, TransitionFrontierSyncLedgerState, @@ -16,436 +17,292 @@ pub type TransitionFrontierSyncActionWithMeta = redux::ActionWithMeta = redux::ActionWithMeta<&'a TransitionFrontierSyncAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub enum TransitionFrontierSyncAction { /// Set transition frontier target to new best tip (for still unsynced frontiers) - Init(TransitionFrontierSyncInitAction), + Init { + best_tip: ArcBlockWithHash, + root_block: ArcBlockWithHash, + blocks_inbetween: Vec, + }, /// Set sync target to a new best tip (for already synced frontiers) - BestTipUpdate(TransitionFrontierSyncBestTipUpdateAction), + BestTipUpdate { + best_tip: ArcBlockWithHash, + root_block: ArcBlockWithHash, + blocks_inbetween: Vec, + }, /// Staking Ledger sync is pending - LedgerStakingPending(TransitionFrontierSyncLedgerStakingPendingAction), + LedgerStakingPending, /// Staking Ledger sync was successful - LedgerStakingSuccess(TransitionFrontierSyncLedgerStakingSuccessAction), + LedgerStakingSuccess, /// Next Epoch Ledger sync is pending - LedgerNextEpochPending(TransitionFrontierSyncLedgerNextEpochPendingAction), + LedgerNextEpochPending, /// Next Epoch Ledger sync was successful - LedgerNextEpochSuccess(TransitionFrontierSyncLedgerNextEpochSuccessAction), + LedgerNextEpochSuccess, /// Transition frontier Root Ledger sync is pending - LedgerRootPending(TransitionFrontierSyncLedgerRootPendingAction), + LedgerRootPending, /// Transition frontier Root Ledger sync was successful - LedgerRootSuccess(TransitionFrontierSyncLedgerRootSuccessAction), - BlocksPending(TransitionFrontierSyncBlocksPendingAction), - BlocksPeersQuery(TransitionFrontierSyncBlocksPeersQueryAction), - BlocksPeerQueryInit(TransitionFrontierSyncBlocksPeerQueryInitAction), - BlocksPeerQueryRetry(TransitionFrontierSyncBlocksPeerQueryRetryAction), - BlocksPeerQueryPending(TransitionFrontierSyncBlocksPeerQueryPendingAction), - BlocksPeerQueryError(TransitionFrontierSyncBlocksPeerQueryErrorAction), - BlocksPeerQuerySuccess(TransitionFrontierSyncBlocksPeerQuerySuccessAction), - BlocksFetchSuccess(TransitionFrontierSyncBlocksFetchSuccessAction), - BlocksNextApplyInit(TransitionFrontierSyncBlocksNextApplyInitAction), - BlocksNextApplyPending(TransitionFrontierSyncBlocksNextApplyPendingAction), - BlocksNextApplySuccess(TransitionFrontierSyncBlocksNextApplySuccessAction), - BlocksSuccess(TransitionFrontierSyncBlocksSuccessAction), - + LedgerRootSuccess, + BlocksPending, + BlocksPeersQuery, + BlocksPeerQueryInit { + hash: StateHash, + peer_id: PeerId, + }, + BlocksPeerQueryRetry { + hash: StateHash, + peer_id: PeerId, + }, + BlocksPeerQueryPending { + hash: StateHash, + peer_id: PeerId, + rpc_id: P2pRpcId, + }, + BlocksPeerQueryError { + peer_id: PeerId, + rpc_id: P2pRpcId, + error: PeerBlockFetchError, + }, + BlocksPeerQuerySuccess { + peer_id: PeerId, + rpc_id: P2pRpcId, + response: ArcBlockWithHash, + }, + BlocksFetchSuccess { + hash: StateHash, + }, + BlocksNextApplyInit, + BlocksNextApplyPending { + hash: StateHash, + }, + BlocksNextApplySuccess { + hash: StateHash, + }, + BlocksSuccess, /// Synchronization to a target ledger Ledger(TransitionFrontierSyncLedgerAction), } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncInitAction { - pub best_tip: ArcBlockWithHash, - pub root_block: ArcBlockWithHash, - pub blocks_inbetween: Vec, -} - -impl redux::EnablingCondition for TransitionFrontierSyncInitAction { +impl redux::EnablingCondition for TransitionFrontierSyncAction { fn is_enabled(&self, state: &crate::State) -> bool { - !state.transition_frontier.sync.is_pending() - && !state.transition_frontier.sync.is_synced() - && state + match self { + TransitionFrontierSyncAction::Init { best_tip, .. } => { + !state.transition_frontier.sync.is_pending() + && !state.transition_frontier.sync.is_synced() + && state + .transition_frontier + .best_tip() + .map_or(true, |tip| best_tip.hash != tip.hash) + && state + .consensus + .best_tip() + .map_or(false, |tip| &best_tip.hash == tip.hash) + } + TransitionFrontierSyncAction::BestTipUpdate { best_tip, .. } => { + (state.transition_frontier.sync.is_pending() || state.transition_frontier.sync.is_synced()) + && state + .transition_frontier + .best_tip() + .map_or(true, |tip| best_tip.hash != tip.hash) + && state + .transition_frontier + .sync + .best_tip() + .map_or(true, |tip| best_tip.hash != tip.hash) + // TODO(binier): TMP. we shouldn't need to check consensus here. + && state + .transition_frontier + .sync + .best_tip() + .or(state.transition_frontier.best_tip()) + .map_or(false, |tip| { + consensus_take(tip.consensus_state(), best_tip.consensus_state(), tip.hash(), best_tip.hash()) + }) + // Don't sync to best tip if we are in the middle of producing + // a block unless that best tip candidate is better consensus-wise + // than the one that we are producing. + // + // Otherwise other block producers might spam the network + // with blocks that are better than current best tip, yet + // inferior to the block that we are producing and we can't + // let that get in the way of us producing a block. + && state.block_producer.producing_won_slot() + .filter(|_| !state.block_producer.is_me(best_tip.producer())) + // TODO(binier): check if candidate best tip is short or + // long range fork and based on that compare slot that + // we are producing. + .map_or(true, |won_slot| won_slot < best_tip) + } + TransitionFrontierSyncAction::LedgerStakingPending => { + matches!( + state.transition_frontier.sync, + TransitionFrontierSyncState::Init { .. } + ) + } + TransitionFrontierSyncAction::LedgerStakingSuccess => matches!( + state.transition_frontier.sync, + TransitionFrontierSyncState::StakingLedgerPending( + TransitionFrontierSyncLedgerPending { + ledger: TransitionFrontierSyncLedgerState::Success { .. }, + .. + } + ) + ), + TransitionFrontierSyncAction::LedgerNextEpochPending => { + match &state.transition_frontier.sync { + TransitionFrontierSyncState::Init { + best_tip, + root_block, + .. + } => SyncLedgerTarget::next_epoch(best_tip, root_block).is_some(), + TransitionFrontierSyncState::StakingLedgerSuccess { + best_tip, + root_block, + .. + } => SyncLedgerTarget::next_epoch(best_tip, root_block).is_some(), + _ => false, + } + } + TransitionFrontierSyncAction::LedgerNextEpochSuccess => matches!( + state.transition_frontier.sync, + TransitionFrontierSyncState::NextEpochLedgerPending( + TransitionFrontierSyncLedgerPending { + ledger: TransitionFrontierSyncLedgerState::Success { .. }, + .. + } + ) + ), + TransitionFrontierSyncAction::LedgerRootPending => { + match &state.transition_frontier.sync { + TransitionFrontierSyncState::Init { + best_tip, + root_block, + .. + } + | TransitionFrontierSyncState::StakingLedgerSuccess { + best_tip, + root_block, + .. + } => SyncLedgerTarget::next_epoch(best_tip, root_block).is_none(), + TransitionFrontierSyncState::NextEpochLedgerSuccess { .. } => true, + _ => false, + } + } + TransitionFrontierSyncAction::LedgerRootSuccess => matches!( + state.transition_frontier.sync, + TransitionFrontierSyncState::RootLedgerPending( + TransitionFrontierSyncLedgerPending { + ledger: TransitionFrontierSyncLedgerState::Success { .. }, + .. + } + ) + ), + TransitionFrontierSyncAction::BlocksPending => matches!( + state.transition_frontier.sync, + TransitionFrontierSyncState::RootLedgerSuccess { .. } + ), + TransitionFrontierSyncAction::BlocksPeersQuery => { + let peers_available = state + .p2p + .ready_peers_iter() + .any(|(_, p)| p.channels.rpc.can_send_request()); + let sync = &state.transition_frontier.sync; + peers_available + && (sync.blocks_fetch_next().is_some() + || sync.blocks_fetch_retry_iter().next().is_some()) + } + TransitionFrontierSyncAction::BlocksPeerQueryInit { hash, peer_id } => { + let check_next_hash = state + .transition_frontier + .sync + .blocks_fetch_next() + .map_or(false, |expected| &expected == hash); + + let check_peer_available = state + .p2p + .get_ready_peer(peer_id) + .and_then(|p| { + let sync_best_tip = state.transition_frontier.sync.best_tip()?; + let peer_best_tip = p.best_tip.as_ref()?; + Some(p).filter(|_| sync_best_tip.hash == peer_best_tip.hash) + }) + .map_or(false, |p| p.channels.rpc.can_send_request()); + + check_next_hash && check_peer_available + } + TransitionFrontierSyncAction::BlocksPeerQueryRetry { hash, peer_id } => { + let check_next_hash = state + .transition_frontier + .sync + .blocks_fetch_retry_iter() + .next() + .map_or(false, |expected| &expected == hash); + + let check_peer_available = state + .p2p + .get_ready_peer(peer_id) + .and_then(|p| { + let sync_best_tip = state.transition_frontier.sync.best_tip()?; + let peer_best_tip = p.best_tip.as_ref()?; + Some(p).filter(|_| sync_best_tip.hash == peer_best_tip.hash) + }) + .map_or(false, |p| p.channels.rpc.can_send_request()); + + check_next_hash && check_peer_available + } + TransitionFrontierSyncAction::BlocksPeerQueryPending { hash, peer_id, .. } => state .transition_frontier - .best_tip() - .map_or(true, |tip| self.best_tip.hash != tip.hash) - && state - .consensus - .best_tip() - .map_or(false, |tip| &self.best_tip.hash == tip.hash) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBestTipUpdateAction { - pub best_tip: ArcBlockWithHash, - pub root_block: ArcBlockWithHash, - pub blocks_inbetween: Vec, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBestTipUpdateAction { - fn is_enabled(&self, state: &crate::State) -> bool { - (state.transition_frontier.sync.is_pending() || state.transition_frontier.sync.is_synced()) - && state + .sync + .block_state(hash) + .map_or(false, |b| b.is_fetch_init_from_peer(peer_id)), + TransitionFrontierSyncAction::BlocksPeerQueryError { + peer_id, rpc_id, .. + } => state .transition_frontier - .best_tip() - .map_or(true, |tip| self.best_tip.hash != tip.hash) - && state + .sync + .blocks_iter() + .any(|s| s.is_fetch_pending_from_peer(peer_id, *rpc_id)), + TransitionFrontierSyncAction::BlocksPeerQuerySuccess { + peer_id, + rpc_id, + response, + } => state .transition_frontier .sync - .best_tip() - .map_or(true, |tip| self.best_tip.hash != tip.hash) - // TODO(binier): TMP. we shouldn't need to check consensus here. - && state + .block_state(&response.hash) + .filter(|s| s.is_fetch_pending_from_peer(peer_id, *rpc_id)) + .map_or(false, |s| s.block_hash() == &response.hash), + TransitionFrontierSyncAction::BlocksFetchSuccess { hash } => state .transition_frontier .sync - .best_tip() - .or(state.transition_frontier.best_tip()) - .map_or(false, |tip| { - consensus_take(tip.consensus_state(), self.best_tip.consensus_state(), tip.hash(), self.best_tip.hash()) - }) - // Don't sync to best tip if we are in the middle of producing - // a block unless that best tip candidate is better consensus-wise - // than the one that we are producing. - // - // Otherwise other block producers might spam the network - // with blocks that are better than current best tip, yet - // inferior to the block that we are producing and we can't - // let that get in the way of us producing a block. - && state.block_producer.producing_won_slot() - .filter(|_| !state.block_producer.is_me(self.best_tip.producer())) - // TODO(binier): check if candidate best tip is short or - // long range fork and based on that compare slot that - // we are producing. - .map_or(true, |won_slot| won_slot < &self.best_tip) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStakingPendingAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerStakingPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - matches!( - state.transition_frontier.sync, - TransitionFrontierSyncState::Init { .. } - ) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerStakingSuccessAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerStakingSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - matches!( - state.transition_frontier.sync, - TransitionFrontierSyncState::StakingLedgerPending( - TransitionFrontierSyncLedgerPending { - ledger: TransitionFrontierSyncLedgerState::Success { .. }, - .. - } - ) - ) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerNextEpochPendingAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerNextEpochPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - match &state.transition_frontier.sync { - TransitionFrontierSyncState::StakingLedgerSuccess { - best_tip, - root_block, - .. - } => SyncLedgerTarget::next_epoch(best_tip, root_block).is_some(), - _ => false, - } - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerNextEpochSuccessAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerNextEpochSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - matches!( - state.transition_frontier.sync, - TransitionFrontierSyncState::NextEpochLedgerPending( - TransitionFrontierSyncLedgerPending { - ledger: TransitionFrontierSyncLedgerState::Success { .. }, - .. + .block_state(hash) + .map_or(false, |s| s.fetch_pending_fetched_block().is_some()), + TransitionFrontierSyncAction::BlocksNextApplyInit => { + state.transition_frontier.sync.blocks_apply_next().is_some() + } + TransitionFrontierSyncAction::BlocksNextApplyPending { hash } => state + .transition_frontier + .sync + .blocks_apply_next() + .map_or(false, |(b, _)| &b.hash == hash), + TransitionFrontierSyncAction::BlocksNextApplySuccess { hash } => state + .transition_frontier + .sync + .blocks_apply_pending() + .map_or(false, |b| &b.hash == hash), + TransitionFrontierSyncAction::BlocksSuccess => match &state.transition_frontier.sync { + TransitionFrontierSyncState::BlocksPending { chain, .. } => { + chain.iter().all(|v| v.is_apply_success()) } - ) - ) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerRootPendingAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerRootPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - match &state.transition_frontier.sync { - TransitionFrontierSyncState::StakingLedgerSuccess { - best_tip, - root_block, - .. - } => SyncLedgerTarget::next_epoch(best_tip, root_block).is_none(), - TransitionFrontierSyncState::NextEpochLedgerSuccess { .. } => true, - _ => false, + _ => false, + }, + TransitionFrontierSyncAction::Ledger(action) => action.is_enabled(state), } } } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncLedgerRootSuccessAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncLedgerRootSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - matches!( - state.transition_frontier.sync, - TransitionFrontierSyncState::RootLedgerPending(TransitionFrontierSyncLedgerPending { - ledger: TransitionFrontierSyncLedgerState::Success { .. }, - .. - }) - ) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksPendingAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - matches!( - state.transition_frontier.sync, - TransitionFrontierSyncState::RootLedgerSuccess { .. } - ) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksPeersQueryAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksPeersQueryAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let peers_available = state - .p2p - .ready_peers_iter() - .any(|(_, p)| p.channels.rpc.can_send_request()); - let sync = &state.transition_frontier.sync; - peers_available - && (sync.blocks_fetch_next().is_some() - || sync.blocks_fetch_retry_iter().next().is_some()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksPeerQueryInitAction { - pub hash: StateHash, - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksPeerQueryInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let check_next_hash = state - .transition_frontier - .sync - .blocks_fetch_next() - .map_or(false, |expected| expected == self.hash); - - let check_peer_available = state - .p2p - .get_ready_peer(&self.peer_id) - .and_then(|p| { - let sync_best_tip = state.transition_frontier.sync.best_tip()?; - let peer_best_tip = p.best_tip.as_ref()?; - Some(p).filter(|_| sync_best_tip.hash == peer_best_tip.hash) - }) - .map_or(false, |p| p.channels.rpc.can_send_request()); - - check_next_hash && check_peer_available - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksPeerQueryRetryAction { - pub hash: StateHash, - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksPeerQueryRetryAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let check_next_hash = state - .transition_frontier - .sync - .blocks_fetch_retry_iter() - .next() - .map_or(false, |expected| expected == self.hash); - - let check_peer_available = state - .p2p - .get_ready_peer(&self.peer_id) - .and_then(|p| { - let sync_best_tip = state.transition_frontier.sync.best_tip()?; - let peer_best_tip = p.best_tip.as_ref()?; - Some(p).filter(|_| sync_best_tip.hash == peer_best_tip.hash) - }) - .map_or(false, |p| p.channels.rpc.can_send_request()); - - check_next_hash && check_peer_available - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksPeerQueryPendingAction { - pub hash: StateHash, - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksPeerQueryPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .block_state(&self.hash) - .map_or(false, |b| b.is_fetch_init_from_peer(&self.peer_id)) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksPeerQueryErrorAction { - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, - pub error: PeerBlockFetchError, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksPeerQueryErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .blocks_iter() - .any(|s| s.is_fetch_pending_from_peer(&self.peer_id, self.rpc_id)) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksPeerQuerySuccessAction { - pub peer_id: PeerId, - pub rpc_id: P2pRpcId, - pub response: ArcBlockWithHash, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksPeerQuerySuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .block_state(&self.response.hash) - .filter(|s| s.is_fetch_pending_from_peer(&self.peer_id, self.rpc_id)) - .map_or(false, |s| s.block_hash() == &self.response.hash) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksFetchSuccessAction { - pub hash: StateHash, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksFetchSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .block_state(&self.hash) - .map_or(false, |s| s.fetch_pending_fetched_block().is_some()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksNextApplyInitAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksNextApplyInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.transition_frontier.sync.blocks_apply_next().is_some() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksNextApplyPendingAction { - pub hash: StateHash, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksNextApplyPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .blocks_apply_next() - .map_or(false, |(b, _)| b.hash == self.hash) +impl From for crate::Action { + fn from(value: TransitionFrontierSyncAction) -> Self { + Self::TransitionFrontier(TransitionFrontierAction::Sync(value)) } } - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksNextApplySuccessAction { - pub hash: StateHash, -} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksNextApplySuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .transition_frontier - .sync - .blocks_apply_pending() - .map_or(false, |b| b.hash == self.hash) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TransitionFrontierSyncBlocksSuccessAction {} - -impl redux::EnablingCondition for TransitionFrontierSyncBlocksSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - match &state.transition_frontier.sync { - TransitionFrontierSyncState::BlocksPending { chain, .. } => { - chain.iter().all(|v| v.is_apply_success()) - } - _ => false, - } - } -} - -use crate::transition_frontier::TransitionFrontierAction; - -macro_rules! impl_into_global_action { - ($a:ty) => { - impl From<$a> for crate::Action { - fn from(value: $a) -> Self { - Self::TransitionFrontier(TransitionFrontierAction::Sync(value.into())) - } - } - }; -} - -impl_into_global_action!(TransitionFrontierSyncInitAction); -impl_into_global_action!(TransitionFrontierSyncBestTipUpdateAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStakingPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerStakingSuccessAction); -impl_into_global_action!(TransitionFrontierSyncLedgerNextEpochPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerNextEpochSuccessAction); -impl_into_global_action!(TransitionFrontierSyncLedgerRootPendingAction); -impl_into_global_action!(TransitionFrontierSyncLedgerRootSuccessAction); -impl_into_global_action!(TransitionFrontierSyncBlocksPendingAction); -impl_into_global_action!(TransitionFrontierSyncBlocksPeersQueryAction); -impl_into_global_action!(TransitionFrontierSyncBlocksPeerQueryInitAction); -impl_into_global_action!(TransitionFrontierSyncBlocksPeerQueryRetryAction); -impl_into_global_action!(TransitionFrontierSyncBlocksPeerQueryPendingAction); -impl_into_global_action!(TransitionFrontierSyncBlocksPeerQueryErrorAction); -impl_into_global_action!(TransitionFrontierSyncBlocksPeerQuerySuccessAction); -impl_into_global_action!(TransitionFrontierSyncBlocksFetchSuccessAction); -impl_into_global_action!(TransitionFrontierSyncBlocksNextApplyInitAction); -impl_into_global_action!(TransitionFrontierSyncBlocksNextApplyPendingAction); -impl_into_global_action!(TransitionFrontierSyncBlocksNextApplySuccessAction); -impl_into_global_action!(TransitionFrontierSyncBlocksSuccessAction); diff --git a/node/src/transition_frontier/sync/transition_frontier_sync_effects.rs b/node/src/transition_frontier/sync/transition_frontier_sync_effects.rs index b1cb0c599..e59be6598 100644 --- a/node/src/transition_frontier/sync/transition_frontier_sync_effects.rs +++ b/node/src/transition_frontier/sync/transition_frontier_sync_effects.rs @@ -5,243 +5,211 @@ use crate::p2p::channels::rpc::P2pRpcRequest; use crate::transition_frontier::TransitionFrontierService; use crate::Store; -use super::ledger::snarked::TransitionFrontierSyncLedgerSnarkedPeersQueryAction; -use super::ledger::staged::TransitionFrontierSyncLedgerStagedPartsFetchPendingAction; -use super::ledger::TransitionFrontierSyncLedgerInitAction; -use super::{ - TransitionFrontierSyncBestTipUpdateAction, TransitionFrontierSyncBlocksFetchSuccessAction, - TransitionFrontierSyncBlocksNextApplyInitAction, - TransitionFrontierSyncBlocksNextApplyPendingAction, - TransitionFrontierSyncBlocksNextApplySuccessAction, - TransitionFrontierSyncBlocksPeerQueryErrorAction, - TransitionFrontierSyncBlocksPeerQueryInitAction, - TransitionFrontierSyncBlocksPeerQueryPendingAction, - TransitionFrontierSyncBlocksPeerQueryRetryAction, - TransitionFrontierSyncBlocksPeerQuerySuccessAction, - TransitionFrontierSyncBlocksPeersQueryAction, TransitionFrontierSyncBlocksPendingAction, - TransitionFrontierSyncBlocksSuccessAction, TransitionFrontierSyncInitAction, - TransitionFrontierSyncLedgerNextEpochPendingAction, - TransitionFrontierSyncLedgerNextEpochSuccessAction, - TransitionFrontierSyncLedgerRootPendingAction, TransitionFrontierSyncLedgerRootSuccessAction, - TransitionFrontierSyncLedgerStakingPendingAction, - TransitionFrontierSyncLedgerStakingSuccessAction, -}; +use super::ledger::snarked::TransitionFrontierSyncLedgerSnarkedAction; +use super::ledger::staged::TransitionFrontierSyncLedgerStagedAction; +use super::ledger::TransitionFrontierSyncLedgerAction; +use super::TransitionFrontierSyncAction; -impl TransitionFrontierSyncInitAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerStakingPendingAction {}); - } -} - -impl TransitionFrontierSyncBestTipUpdateAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - // if root snarked ledger changed. - store.dispatch(TransitionFrontierSyncLedgerInitAction {}); - // if root snarked ledger stayed same but root block changed - // while reconstructing staged ledger. - store.dispatch(TransitionFrontierSyncLedgerStagedPartsFetchPendingAction {}); - store.dispatch(TransitionFrontierSyncLedgerSnarkedPeersQueryAction {}); - // if we don't need to sync root staged ledger. - store.dispatch(TransitionFrontierSyncBlocksPeersQueryAction {}); - // if we already have a block ready to be applied. - store.dispatch(TransitionFrontierSyncBlocksNextApplyInitAction {}); - - // TODO(binier): cleanup ledgers - } -} - -impl TransitionFrontierSyncLedgerStakingPendingAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerStakingSuccessAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - if store.dispatch(TransitionFrontierSyncLedgerNextEpochPendingAction {}) { - } else if store.dispatch(TransitionFrontierSyncLedgerRootPendingAction {}) { - } - } -} - -impl TransitionFrontierSyncLedgerNextEpochPendingAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerNextEpochSuccessAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerRootPendingAction {}); - } -} - -impl TransitionFrontierSyncLedgerRootPendingAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncLedgerInitAction {}); - } -} - -impl TransitionFrontierSyncLedgerRootSuccessAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncBlocksPendingAction {}); - } -} - -impl TransitionFrontierSyncBlocksPendingAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - if !store.dispatch(TransitionFrontierSyncBlocksSuccessAction {}) { - store.dispatch(TransitionFrontierSyncBlocksPeersQueryAction {}); - } - } -} - -impl TransitionFrontierSyncBlocksPeersQueryAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - // TODO(binier): make sure they have the ledger we want to query. - let mut peer_ids = store - .state() - .p2p - .ready_peers_iter() - .filter(|(_, p)| p.channels.rpc.can_send_request()) - .map(|(id, p)| (*id, p.connected_since)) - .collect::>(); - peer_ids.sort_by(|(_, t1), (_, t2)| t2.cmp(t1)); - - let mut retry_hashes = store - .state() - .transition_frontier - .sync - .blocks_fetch_retry_iter() - .collect::>(); - retry_hashes.reverse(); - - for (peer_id, _) in peer_ids { - if let Some(hash) = retry_hashes.last() { - if store.dispatch(TransitionFrontierSyncBlocksPeerQueryRetryAction { - peer_id, - hash: hash.clone(), +impl TransitionFrontierSyncAction { + pub fn effects(&self, _: &ActionMeta, store: &mut Store) + where + S: TransitionFrontierService, + { + match self { + TransitionFrontierSyncAction::Init { best_tip, .. } => { + let protocol_state_body = &best_tip.block.header.protocol_state.body; + let genesis_ledger_hash = &protocol_state_body.blockchain_state.genesis_ledger_hash; + let staking_epoch_ledger_hash = &protocol_state_body + .consensus_state + .staking_epoch_data + .ledger + .hash; + let next_epoch_ledger_hash = &protocol_state_body + .consensus_state + .next_epoch_data + .ledger + .hash; + + // TODO(tizoc): if root ledger matches genesis, should anything special be done? + // snarked ledger will not need to be synced but staged ledger parts are still + // required + + if genesis_ledger_hash != staking_epoch_ledger_hash { + store.dispatch(TransitionFrontierSyncAction::LedgerStakingPending); + } else if genesis_ledger_hash != next_epoch_ledger_hash { + store.dispatch(TransitionFrontierSyncAction::LedgerNextEpochPending); + } else { + store.dispatch(TransitionFrontierSyncAction::LedgerRootPending); + } + } + TransitionFrontierSyncAction::BestTipUpdate { .. } => { + // if root snarked ledger changed. + store.dispatch(TransitionFrontierSyncLedgerAction::Init); + // if root snarked ledger stayed same but root block changed + // while reconstructing staged ledger. + store.dispatch(TransitionFrontierSyncLedgerStagedAction::PartsFetchPending); + store.dispatch(TransitionFrontierSyncLedgerSnarkedAction::PeersQuery); + // if we don't need to sync root staged ledger. + store.dispatch(TransitionFrontierSyncAction::BlocksPeersQuery); + // if we already have a block ready to be applied. + store.dispatch(TransitionFrontierSyncAction::BlocksNextApplyInit); + + // TODO(binier): cleanup ledgers + } + TransitionFrontierSyncAction::LedgerStakingPending => { + store.dispatch(TransitionFrontierSyncLedgerAction::Init); + } + TransitionFrontierSyncAction::LedgerStakingSuccess => { + if store.dispatch(TransitionFrontierSyncAction::LedgerNextEpochPending) { + } else if store.dispatch(TransitionFrontierSyncAction::LedgerRootPending) { + } + } + TransitionFrontierSyncAction::LedgerNextEpochPending => { + store.dispatch(TransitionFrontierSyncLedgerAction::Init); + } + TransitionFrontierSyncAction::LedgerNextEpochSuccess => { + store.dispatch(TransitionFrontierSyncAction::LedgerRootPending); + } + TransitionFrontierSyncAction::LedgerRootPending => { + store.dispatch(TransitionFrontierSyncLedgerAction::Init); + } + TransitionFrontierSyncAction::LedgerRootSuccess => { + store.dispatch(TransitionFrontierSyncAction::BlocksPending); + } + TransitionFrontierSyncAction::BlocksPending => { + if !store.dispatch(TransitionFrontierSyncAction::BlocksSuccess) { + store.dispatch(TransitionFrontierSyncAction::BlocksPeersQuery); + } + } + TransitionFrontierSyncAction::BlocksPeersQuery => { + // TODO(binier): make sure they have the ledger we want to query. + let mut peer_ids = store + .state() + .p2p + .ready_peers_iter() + .filter(|(_, p)| p.channels.rpc.can_send_request()) + .map(|(id, p)| (*id, p.connected_since)) + .collect::>(); + peer_ids.sort_by(|(_, t1), (_, t2)| t2.cmp(t1)); + + let mut retry_hashes = store + .state() + .transition_frontier + .sync + .blocks_fetch_retry_iter() + .collect::>(); + retry_hashes.reverse(); + + for (peer_id, _) in peer_ids { + if let Some(hash) = retry_hashes.last() { + if store.dispatch(TransitionFrontierSyncAction::BlocksPeerQueryRetry { + peer_id, + hash: hash.clone(), + }) { + retry_hashes.pop(); + continue; + } + } + + match store.state().transition_frontier.sync.blocks_fetch_next() { + Some(hash) => { + store.dispatch(TransitionFrontierSyncAction::BlocksPeerQueryInit { + peer_id, + hash, + }); + } + None if retry_hashes.is_empty() => break, + None => {} + } + } + } + TransitionFrontierSyncAction::BlocksPeerQueryInit { hash, peer_id } => { + let Some(rpc_id) = store + .state() + .p2p + .get_ready_peer(peer_id) + .map(|v| v.channels.rpc.next_local_rpc_id()) + else { + return; + }; + + if store.dispatch(P2pChannelsRpcAction::RequestSend { + peer_id: *peer_id, + id: rpc_id, + request: P2pRpcRequest::Block(hash.clone()), }) { - retry_hashes.pop(); - continue; + store.dispatch(TransitionFrontierSyncAction::BlocksPeerQueryPending { + hash: hash.clone(), + peer_id: *peer_id, + rpc_id, + }); } } - - match store.state().transition_frontier.sync.blocks_fetch_next() { - Some(hash) => { - store.dispatch(TransitionFrontierSyncBlocksPeerQueryInitAction { - peer_id, - hash, + TransitionFrontierSyncAction::BlocksPeerQueryRetry { hash, peer_id } => { + let Some(rpc_id) = store + .state() + .p2p + .get_ready_peer(peer_id) + .map(|v| v.channels.rpc.next_local_rpc_id()) + else { + return; + }; + + if store.dispatch(P2pChannelsRpcAction::RequestSend { + peer_id: *peer_id, + id: rpc_id, + request: P2pRpcRequest::Block(hash.clone()), + }) { + store.dispatch(TransitionFrontierSyncAction::BlocksPeerQueryPending { + hash: hash.clone(), + peer_id: *peer_id, + rpc_id, }); } - None if retry_hashes.is_empty() => break, - None => {} } - } - } -} - -impl TransitionFrontierSyncBlocksPeerQueryInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let Some(rpc_id) = store - .state() - .p2p - .get_ready_peer(&self.peer_id) - .map(|v| v.channels.rpc.next_local_rpc_id()) - else { - return; - }; - - if store.dispatch(P2pChannelsRpcAction::RequestSend { - peer_id: self.peer_id, - id: rpc_id, - request: P2pRpcRequest::Block(self.hash.clone()), - }) { - store.dispatch(TransitionFrontierSyncBlocksPeerQueryPendingAction { - hash: self.hash, - peer_id: self.peer_id, - rpc_id, - }); - } - } -} - -impl TransitionFrontierSyncBlocksPeerQueryRetryAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - let Some(rpc_id) = store - .state() - .p2p - .get_ready_peer(&self.peer_id) - .map(|v| v.channels.rpc.next_local_rpc_id()) - else { - return; - }; + TransitionFrontierSyncAction::BlocksPeerQueryPending { .. } => {} + TransitionFrontierSyncAction::BlocksPeerQueryError { .. } => { + store.dispatch(TransitionFrontierSyncAction::BlocksPeersQuery); + } + TransitionFrontierSyncAction::BlocksPeerQuerySuccess { response, .. } => { + store.dispatch(TransitionFrontierSyncAction::BlocksPeersQuery); + store.dispatch(TransitionFrontierSyncAction::BlocksFetchSuccess { + hash: response.hash.clone(), + }); + } + TransitionFrontierSyncAction::BlocksFetchSuccess { .. } => { + let _ = store; + // TODO(binier): uncomment once ledger communication is async. + // store.dispatch(TransitionFrontierSyncBlocksNextApplyInitAction {}); + } + TransitionFrontierSyncAction::BlocksNextApplyInit => { + let Some((block, pred_block)) = store + .state() + .transition_frontier + .sync + .blocks_apply_next() + .map(|v| (v.0.clone(), v.1.clone())) + else { + return; + }; + let hash = block.hash.clone(); + + store.dispatch(TransitionFrontierSyncAction::BlocksNextApplyPending { + hash: hash.clone(), + }); + store.service.block_apply(block, pred_block).unwrap(); - if store.dispatch(P2pChannelsRpcAction::RequestSend { - peer_id: self.peer_id, - id: rpc_id, - request: P2pRpcRequest::Block(self.hash.clone()), - }) { - store.dispatch(TransitionFrontierSyncBlocksPeerQueryPendingAction { - hash: self.hash, - peer_id: self.peer_id, - rpc_id, - }); + store.dispatch(TransitionFrontierSyncAction::BlocksNextApplySuccess { hash }); + } + TransitionFrontierSyncAction::BlocksNextApplyPending { .. } => {} + TransitionFrontierSyncAction::BlocksNextApplySuccess { .. } => { + // TODO(binier): uncomment once ledger communication is async. + // if !store.dispatch(TransitionFrontierSyncAction::BlockNextApplyInit) { + store.dispatch(TransitionFrontierSyncAction::BlocksSuccess); + // } + } + TransitionFrontierSyncAction::BlocksSuccess => {} + TransitionFrontierSyncAction::Ledger(_) => {} } } } - -impl TransitionFrontierSyncBlocksPeerQueryErrorAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncBlocksPeersQueryAction {}); - } -} - -impl TransitionFrontierSyncBlocksPeerQuerySuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - store.dispatch(TransitionFrontierSyncBlocksPeersQueryAction {}); - store.dispatch(TransitionFrontierSyncBlocksFetchSuccessAction { - hash: self.response.hash, - }); - } -} - -impl TransitionFrontierSyncBlocksFetchSuccessAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) { - let _ = store; - // TODO(binier): uncomment once ledger communication is async. - // store.dispatch(TransitionFrontierSyncBlocksNextApplyInitAction {}); - } -} - -impl TransitionFrontierSyncBlocksNextApplyInitAction { - pub fn effects(&self, _: &ActionMeta, store: &mut Store) - where - S: TransitionFrontierService, - { - let Some((block, pred_block)) = store - .state() - .transition_frontier - .sync - .blocks_apply_next() - .map(|v| (v.0.clone(), v.1.clone())) - else { - return; - }; - let hash = block.hash.clone(); - - store.dispatch(TransitionFrontierSyncBlocksNextApplyPendingAction { hash: hash.clone() }); - store.service.block_apply(block, pred_block).unwrap(); - - store.dispatch(TransitionFrontierSyncBlocksNextApplySuccessAction { hash }); - } -} - -impl TransitionFrontierSyncBlocksNextApplySuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) { - // TODO(binier): uncomment once ledger communication is async. - // if !store.dispatch(TransitionFrontierSyncBlockNextApplyInitAction {}) { - store.dispatch(TransitionFrontierSyncBlocksSuccessAction {}); - // } - } -} diff --git a/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs b/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs index d7093207d..187001371 100644 --- a/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs +++ b/node/src/transition_frontier/sync/transition_frontier_sync_reducer.rs @@ -24,27 +24,34 @@ impl TransitionFrontierSyncState { ) { let (action, meta) = action.split(); match action { - TransitionFrontierSyncAction::Init(a) => { + TransitionFrontierSyncAction::Init { + best_tip, + root_block, + blocks_inbetween, + } => { *self = Self::Init { time: meta.time(), - best_tip: a.best_tip.clone(), - root_block: a.root_block.clone(), - blocks_inbetween: a.blocks_inbetween.clone(), + best_tip: best_tip.clone(), + root_block: root_block.clone(), + blocks_inbetween: blocks_inbetween.clone(), }; } // TODO(binier): refactor - TransitionFrontierSyncAction::BestTipUpdate(a) => match self { + TransitionFrontierSyncAction::BestTipUpdate { + best_tip, + root_block, + blocks_inbetween, + } => match self { Self::StakingLedgerPending(state) | Self::NextEpochLedgerPending(state) | Self::RootLedgerPending(state) => { state.time = meta.time(); - state.root_block = a.root_block.clone(); - state.blocks_inbetween = a.blocks_inbetween.clone(); - let old_best_tip = std::mem::replace(&mut state.best_tip, a.best_tip.clone()); + state.root_block = root_block.clone(); + state.blocks_inbetween = blocks_inbetween.clone(); + let old_best_tip = std::mem::replace(&mut state.best_tip, best_tip.clone()); - let staking_epoch_target = SyncLedgerTarget::staking_epoch(&a.best_tip); - let next_epoch_target = - SyncLedgerTarget::next_epoch(&a.best_tip, &a.root_block); + let staking_epoch_target = SyncLedgerTarget::staking_epoch(best_tip); + let next_epoch_target = SyncLedgerTarget::next_epoch(best_tip, root_block); let new_target = if let Self::StakingLedgerPending(state) = self { state @@ -69,13 +76,13 @@ impl TransitionFrontierSyncState { Some((state, staking_epoch_target)) } else if let Some(next_epoch_target) = next_epoch_target.filter(|_| { old_best_tip.next_epoch_ledger_hash() - != a.best_tip.next_epoch_ledger_hash() + != best_tip.next_epoch_ledger_hash() }) { Some((state, next_epoch_target)) } else { state .ledger - .update_target(meta.time(), SyncLedgerTarget::root(&a.root_block)); + .update_target(meta.time(), SyncLedgerTarget::root(root_block)); None } } else { @@ -111,8 +118,8 @@ impl TransitionFrontierSyncState { let old_chain = VecDeque::from(std::mem::take(chain)); let old_root = old_chain.front().and_then(|b| b.block()).unwrap().clone(); let old_best_tip = old_chain.back().and_then(|b| b.block()).unwrap().clone(); - let new_root = &a.root_block; - let new_best_tip = &a.best_tip; + let new_root = root_block; + let new_best_tip = best_tip; let old_chain_has_new_root_applied = old_chain .iter() @@ -162,7 +169,7 @@ impl TransitionFrontierSyncState { }; push_block(new_root.hash(), Some(new_root)); - for hash in &a.blocks_inbetween { + for hash in blocks_inbetween { push_block(hash, None); } push_block(new_best_tip.hash(), Some(new_best_tip)); @@ -183,7 +190,7 @@ impl TransitionFrontierSyncState { &old_root, new_best_tip, new_root, - &a.blocks_inbetween, + blocks_inbetween, ); } } @@ -193,12 +200,12 @@ impl TransitionFrontierSyncState { let old_best_tip = best_chain.last().unwrap(); let old_root = best_chain.first().unwrap(); - let new_best_tip = &a.best_tip; - let new_root = &a.root_block; + let new_best_tip = best_tip; + let new_root = root_block; if applied_blocks.contains_key(&new_root.hash) { - let chain = std::iter::once(a.root_block.hash()) - .chain(&a.blocks_inbetween) + let chain = std::iter::once(root_block.hash()) + .chain(blocks_inbetween) .chain(std::iter::once(new_best_tip.hash())) .map(|hash| match applied_blocks.get(hash) { Some(&block) => TransitionFrontierSyncBlockState::ApplySuccess { @@ -233,13 +240,13 @@ impl TransitionFrontierSyncState { old_root, new_best_tip, new_root, - &a.blocks_inbetween, + blocks_inbetween, ); } } _ => return, }, - TransitionFrontierSyncAction::LedgerStakingPending(_) => { + TransitionFrontierSyncAction::LedgerStakingPending => { if let Self::Init { best_tip, root_block, @@ -259,7 +266,7 @@ impl TransitionFrontierSyncState { }); } } - TransitionFrontierSyncAction::LedgerStakingSuccess(_) => { + TransitionFrontierSyncAction::LedgerStakingSuccess => { if let Self::StakingLedgerPending(state) = self { let TransitionFrontierSyncLedgerState::Success { needed_protocol_states, @@ -277,30 +284,37 @@ impl TransitionFrontierSyncState { }; } } - TransitionFrontierSyncAction::LedgerNextEpochPending(_) => { - if let Self::StakingLedgerSuccess { - best_tip, - root_block, - blocks_inbetween, - .. - } = self - { - let Some(target) = SyncLedgerTarget::next_epoch(best_tip, root_block) else { - return; - }; - *self = Self::NextEpochLedgerPending(TransitionFrontierSyncLedgerPending { + TransitionFrontierSyncAction::LedgerNextEpochPending => { + let (best_tip, root_block, blocks_inbetween) = match self { + Self::Init { + best_tip, + root_block, + blocks_inbetween, + .. + } + | Self::StakingLedgerSuccess { + best_tip, + root_block, + blocks_inbetween, + .. + } => (best_tip, root_block, blocks_inbetween), + _ => return, + }; + let Some(target) = SyncLedgerTarget::next_epoch(best_tip, root_block) else { + return; + }; + *self = Self::NextEpochLedgerPending(TransitionFrontierSyncLedgerPending { + time: meta.time(), + best_tip: best_tip.clone(), + root_block: root_block.clone(), + blocks_inbetween: std::mem::take(blocks_inbetween), + ledger: TransitionFrontierSyncLedgerState::Init { time: meta.time(), - best_tip: best_tip.clone(), - root_block: root_block.clone(), - blocks_inbetween: std::mem::take(blocks_inbetween), - ledger: TransitionFrontierSyncLedgerState::Init { - time: meta.time(), - target, - }, - }); - } + target, + }, + }); } - TransitionFrontierSyncAction::LedgerNextEpochSuccess(_) => { + TransitionFrontierSyncAction::LedgerNextEpochSuccess => { if let Self::NextEpochLedgerPending(state) = self { let TransitionFrontierSyncLedgerState::Success { needed_protocol_states, @@ -318,9 +332,15 @@ impl TransitionFrontierSyncState { }; } } - TransitionFrontierSyncAction::LedgerRootPending(_) => { + TransitionFrontierSyncAction::LedgerRootPending => { let (best_tip, root_block, blocks_inbetween) = match self { - Self::StakingLedgerSuccess { + Self::Init { + best_tip, + root_block, + blocks_inbetween, + .. + } + | Self::StakingLedgerSuccess { best_tip, root_block, blocks_inbetween, @@ -345,7 +365,7 @@ impl TransitionFrontierSyncState { }, }); } - TransitionFrontierSyncAction::LedgerRootSuccess(_) => { + TransitionFrontierSyncAction::LedgerRootSuccess => { if let Self::RootLedgerPending(state) = self { let TransitionFrontierSyncLedgerState::Success { needed_protocol_states, @@ -363,7 +383,7 @@ impl TransitionFrontierSyncState { }; } } - TransitionFrontierSyncAction::BlocksPending(_) => { + TransitionFrontierSyncAction::BlocksPending => { let Self::RootLedgerSuccess { best_tip, root_block, @@ -425,67 +445,77 @@ impl TransitionFrontierSyncState { needed_protocol_states: std::mem::take(needed_protocol_states), }; } - TransitionFrontierSyncAction::BlocksPeersQuery(_) => {} - TransitionFrontierSyncAction::BlocksPeerQueryInit(a) => { - let Some(block_state) = self.block_state_mut(&a.hash) else { + TransitionFrontierSyncAction::BlocksPeersQuery => {} + TransitionFrontierSyncAction::BlocksPeerQueryInit { hash, peer_id } => { + let Some(block_state) = self.block_state_mut(hash) else { return; }; let Some(attempts) = block_state.fetch_pending_attempts_mut() else { return; }; - attempts.insert(a.peer_id.clone(), PeerRpcState::Init { time: meta.time() }); + attempts.insert(peer_id.clone(), PeerRpcState::Init { time: meta.time() }); } - TransitionFrontierSyncAction::BlocksPeerQueryRetry(a) => { - let Some(block_state) = self.block_state_mut(&a.hash) else { + TransitionFrontierSyncAction::BlocksPeerQueryRetry { hash, peer_id } => { + let Some(block_state) = self.block_state_mut(hash) else { return; }; let Some(attempts) = block_state.fetch_pending_attempts_mut() else { return; }; - attempts.insert(a.peer_id.clone(), PeerRpcState::Init { time: meta.time() }); + attempts.insert(peer_id.clone(), PeerRpcState::Init { time: meta.time() }); } - TransitionFrontierSyncAction::BlocksPeerQueryPending(a) => { - let Some(block_state) = self.block_state_mut(&a.hash) else { + TransitionFrontierSyncAction::BlocksPeerQueryPending { + hash, + peer_id, + rpc_id, + } => { + let Some(block_state) = self.block_state_mut(hash) else { return; }; - let Some(peer_state) = block_state.fetch_pending_from_peer_mut(&a.peer_id) else { + let Some(peer_state) = block_state.fetch_pending_from_peer_mut(peer_id) else { return; }; *peer_state = PeerRpcState::Pending { time: meta.time(), - rpc_id: a.rpc_id, + rpc_id: *rpc_id, }; } - TransitionFrontierSyncAction::BlocksPeerQueryError(a) => { + TransitionFrontierSyncAction::BlocksPeerQueryError { + peer_id, + rpc_id, + error, + } => { let Self::BlocksPending { chain, .. } = self else { return; }; let Some(peer_state) = chain .iter_mut() - .find_map(|b| b.fetch_pending_from_peer_mut(&a.peer_id)) + .find_map(|b| b.fetch_pending_from_peer_mut(peer_id)) else { return; }; *peer_state = PeerRpcState::Error { time: meta.time(), - rpc_id: a.rpc_id, - error: a.error.clone(), + rpc_id: *rpc_id, + error: error.clone(), }; } - TransitionFrontierSyncAction::BlocksPeerQuerySuccess(a) => { - let Some(block_state) = self.block_state_mut(&a.response.hash) else { + TransitionFrontierSyncAction::BlocksPeerQuerySuccess { + peer_id, response, .. + } => { + let Some(block_state) = self.block_state_mut(&response.hash) else { return; }; - let Some(peer_state) = block_state.fetch_pending_from_peer_mut(&a.peer_id) else { + let Some(peer_state) = block_state.fetch_pending_from_peer_mut(peer_id) else { return; }; *peer_state = PeerRpcState::Success { time: meta.time(), - block: a.response.clone(), + block: response.clone(), }; } - TransitionFrontierSyncAction::BlocksFetchSuccess(a) => { - let Some(block_state) = self.block_state_mut(&a.hash) else { + TransitionFrontierSyncAction::BlocksFetchSuccess { hash } => { + let Some(block_state) = self.block_state_mut(hash) else { return; }; let Some(block) = block_state.fetch_pending_fetched_block() else { @@ -496,9 +526,9 @@ impl TransitionFrontierSyncState { block: block.clone(), }; } - TransitionFrontierSyncAction::BlocksNextApplyInit(_) => {} - TransitionFrontierSyncAction::BlocksNextApplyPending(a) => { - let Some(block_state) = self.block_state_mut(&a.hash) else { + TransitionFrontierSyncAction::BlocksNextApplyInit => {} + TransitionFrontierSyncAction::BlocksNextApplyPending { hash } => { + let Some(block_state) = self.block_state_mut(hash) else { return; }; let Some(block) = block_state.block() else { @@ -510,8 +540,8 @@ impl TransitionFrontierSyncState { block: block.clone(), }; } - TransitionFrontierSyncAction::BlocksNextApplySuccess(a) => { - let Some(block_state) = self.block_state_mut(&a.hash) else { + TransitionFrontierSyncAction::BlocksNextApplySuccess { hash } => { + let Some(block_state) = self.block_state_mut(hash) else { return; }; let Some(block) = block_state.block() else { @@ -523,7 +553,7 @@ impl TransitionFrontierSyncState { block: block.clone(), }; } - TransitionFrontierSyncAction::BlocksSuccess(_) => { + TransitionFrontierSyncAction::BlocksSuccess => { let Self::BlocksPending { chain, root_snarked_ledger_updates, diff --git a/node/src/transition_frontier/transition_frontier_config.rs b/node/src/transition_frontier/transition_frontier_config.rs index 7aee82448..e62f96956 100644 --- a/node/src/transition_frontier/transition_frontier_config.rs +++ b/node/src/transition_frontier/transition_frontier_config.rs @@ -1,3 +1,6 @@ +use mina_p2p_messages::v2::{ + BlockTimeTimeStableV1, UnsignedExtendedUInt64Int64ForVersionTagsStableV1, +}; use serde::{Deserialize, Serialize}; use crate::ProtocolConstants; @@ -16,16 +19,17 @@ impl TransitionFrontierConfig { impl Default for TransitionFrontierConfig { fn default() -> Self { // TODO(binier): better way. - Self { - protocol_constants: serde_json::from_value(serde_json::json!({ - "k": "290", - "slots_per_epoch": "7140", - "slots_per_sub_window": "7", - "delta": "0", - // TODO(binier): fix wrong timestamp - "genesis_state_timestamp": "0", - })) - .unwrap(), + TransitionFrontierConfig { + protocol_constants: ProtocolConstants { + k: 290.into(), + slots_per_epoch: 7140.into(), + slots_per_sub_window: 7.into(), + grace_period_slots: 0.into(), + delta: 0.into(), + genesis_state_timestamp: BlockTimeTimeStableV1( + UnsignedExtendedUInt64Int64ForVersionTagsStableV1(0.into()), + ), + }, } } } diff --git a/node/src/transition_frontier/transition_frontier_effects.rs b/node/src/transition_frontier/transition_frontier_effects.rs index 32d60c7e3..550035aaf 100644 --- a/node/src/transition_frontier/transition_frontier_effects.rs +++ b/node/src/transition_frontier/transition_frontier_effects.rs @@ -1,6 +1,6 @@ use redux::Timestamp; -use crate::block_producer::BlockProducerBestTipUpdateAction; +use crate::block_producer::BlockProducerAction; use crate::consensus::ConsensusAction; use crate::ledger::LEDGER_DEPTH; use crate::p2p::channels::best_tip::P2pChannelsBestTipAction; @@ -10,12 +10,12 @@ use crate::Store; use super::sync::ledger::snarked::TransitionFrontierSyncLedgerSnarkedAction; use super::sync::ledger::staged::TransitionFrontierSyncLedgerStagedAction; -use super::sync::ledger::TransitionFrontierSyncLedgerAction; -use super::sync::{ - TransitionFrontierSyncAction, TransitionFrontierSyncLedgerNextEpochSuccessAction, - TransitionFrontierSyncLedgerRootSuccessAction, - TransitionFrontierSyncLedgerStakingSuccessAction, TransitionFrontierSyncState, +use super::sync::ledger::{ + transition_frontier_sync_ledger_init_effects, + transition_frontier_sync_ledger_snarked_success_effects, + transition_frontier_sync_ledger_staged_success_effects, TransitionFrontierSyncLedgerAction, }; +use super::sync::{TransitionFrontierSyncAction, TransitionFrontierSyncState}; use super::{ TransitionFrontierAction, TransitionFrontierActionWithMeta, TransitionFrontierSyncedAction, }; @@ -27,289 +27,255 @@ pub fn transition_frontier_effects( let (action, meta) = action.split(); match action { - TransitionFrontierAction::Sync(a) => match a { - TransitionFrontierSyncAction::Init(a) => { - if let Some(stats) = store.service.stats() { - stats.new_sync_target(meta.time(), &a.best_tip); - if let TransitionFrontierSyncState::BlocksPending { chain, .. } = - &store.state.get().transition_frontier.sync - { - stats.syncing_blocks_init(chain); + TransitionFrontierAction::Sync(a) => { + match a { + TransitionFrontierSyncAction::Init { ref best_tip, .. } => { + if let Some(stats) = store.service.stats() { + stats.new_sync_target(meta.time(), best_tip); + if let TransitionFrontierSyncState::BlocksPending { chain, .. } = + &store.state.get().transition_frontier.sync + { + stats.syncing_blocks_init(chain); + } } } - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BestTipUpdate(a) => { - if let Some(stats) = store.service.stats() { - stats.new_sync_target(meta.time(), &a.best_tip); - if let Some(target) = store.state.get().transition_frontier.sync.ledger_target() - { - stats.syncing_ledger( - target.kind, - SyncingLedger::Init { - snarked_ledger_hash: target.snarked_ledger_hash.clone(), - staged_ledger_hash: target - .staged - .as_ref() - .map(|v| v.hashes.non_snark.ledger_hash.clone()), - }, - ); + TransitionFrontierSyncAction::BestTipUpdate { ref best_tip, .. } => { + if let Some(stats) = store.service.stats() { + stats.new_sync_target(meta.time(), best_tip); + if let Some(target) = + store.state.get().transition_frontier.sync.ledger_target() + { + stats.syncing_ledger( + target.kind, + SyncingLedger::Init { + snarked_ledger_hash: target.snarked_ledger_hash.clone(), + staged_ledger_hash: target + .staged + .as_ref() + .map(|v| v.hashes.non_snark.ledger_hash.clone()), + }, + ); + } + if let TransitionFrontierSyncState::BlocksPending { chain, .. } = + &store.state.get().transition_frontier.sync + { + stats.syncing_blocks_init(chain); + } } - if let TransitionFrontierSyncState::BlocksPending { chain, .. } = - &store.state.get().transition_frontier.sync - { - stats.syncing_blocks_init(chain); + } + TransitionFrontierSyncAction::LedgerStakingPending => { + if let Some(stats) = store.service.stats() { + if let Some(target) = + store.state.get().transition_frontier.sync.ledger_target() + { + stats.syncing_ledger( + target.kind, + SyncingLedger::Init { + snarked_ledger_hash: target.snarked_ledger_hash.clone(), + staged_ledger_hash: target + .staged + .as_ref() + .map(|v| v.hashes.non_snark.ledger_hash.clone()), + }, + ); + } } } - a.effects(&meta, store); - } - TransitionFrontierSyncAction::LedgerStakingPending(a) => { - if let Some(stats) = store.service.stats() { - if let Some(target) = store.state.get().transition_frontier.sync.ledger_target() - { - stats.syncing_ledger( - target.kind, - SyncingLedger::Init { - snarked_ledger_hash: target.snarked_ledger_hash.clone(), - staged_ledger_hash: target - .staged - .as_ref() - .map(|v| v.hashes.non_snark.ledger_hash.clone()), - }, - ); + TransitionFrontierSyncAction::LedgerStakingSuccess => {} + TransitionFrontierSyncAction::LedgerNextEpochPending => { + if let Some(stats) = store.service.stats() { + if let Some(target) = + store.state.get().transition_frontier.sync.ledger_target() + { + stats.syncing_ledger( + target.kind, + SyncingLedger::Init { + snarked_ledger_hash: target.snarked_ledger_hash.clone(), + staged_ledger_hash: target + .staged + .as_ref() + .map(|v| v.hashes.non_snark.ledger_hash.clone()), + }, + ); + } } } - a.effects(&meta, store); - } - TransitionFrontierSyncAction::LedgerStakingSuccess(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::LedgerNextEpochPending(a) => { - if let Some(stats) = store.service.stats() { - if let Some(target) = store.state.get().transition_frontier.sync.ledger_target() - { - stats.syncing_ledger( - target.kind, - SyncingLedger::Init { - snarked_ledger_hash: target.snarked_ledger_hash.clone(), - staged_ledger_hash: target - .staged - .as_ref() - .map(|v| v.hashes.non_snark.ledger_hash.clone()), - }, - ); + TransitionFrontierSyncAction::LedgerNextEpochSuccess => {} + TransitionFrontierSyncAction::LedgerRootPending => { + if let Some(stats) = store.service.stats() { + if let Some(target) = + store.state.get().transition_frontier.sync.ledger_target() + { + stats.syncing_ledger( + target.kind, + SyncingLedger::Init { + snarked_ledger_hash: target.snarked_ledger_hash.clone(), + staged_ledger_hash: target + .staged + .as_ref() + .map(|v| v.hashes.non_snark.ledger_hash.clone()), + }, + ); + } } } - a.effects(&meta, store); - } - TransitionFrontierSyncAction::LedgerNextEpochSuccess(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::LedgerRootPending(a) => { - if let Some(stats) = store.service.stats() { - if let Some(target) = store.state.get().transition_frontier.sync.ledger_target() - { - stats.syncing_ledger( - target.kind, - SyncingLedger::Init { - snarked_ledger_hash: target.snarked_ledger_hash.clone(), - staged_ledger_hash: target - .staged - .as_ref() - .map(|v| v.hashes.non_snark.ledger_hash.clone()), - }, - ); + TransitionFrontierSyncAction::LedgerRootSuccess => {} + TransitionFrontierSyncAction::BlocksPending => { + if let Some(stats) = store.service.stats() { + if let TransitionFrontierSyncState::BlocksPending { chain, .. } = + &store.state.get().transition_frontier.sync + { + stats.syncing_blocks_init(chain); + } } } - a.effects(&meta, store); - } - TransitionFrontierSyncAction::LedgerRootSuccess(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksPending(a) => { - if let Some(stats) = store.service.stats() { - if let TransitionFrontierSyncState::BlocksPending { chain, .. } = - &store.state.get().transition_frontier.sync - { - stats.syncing_blocks_init(chain); + TransitionFrontierSyncAction::BlocksPeersQuery => {} + TransitionFrontierSyncAction::BlocksPeerQueryInit { .. } => {} + TransitionFrontierSyncAction::BlocksPeerQueryRetry { .. } => {} + TransitionFrontierSyncAction::BlocksPeerQueryPending { ref hash, .. } => { + if let Some(stats) = store.service.stats() { + if let Some(state) = + store.state.get().transition_frontier.sync.block_state(hash) + { + stats.syncing_block_update(state); + } } } - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksPeersQuery(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksPeerQueryInit(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksPeerQueryRetry(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksPeerQueryPending(a) => { - if let Some(stats) = store.service.stats() { - if let Some(state) = store - .state - .get() - .transition_frontier - .sync - .block_state(&a.hash) - { - stats.syncing_block_update(state); + TransitionFrontierSyncAction::BlocksPeerQueryError { .. } => {} + TransitionFrontierSyncAction::BlocksPeerQuerySuccess { .. } => {} + TransitionFrontierSyncAction::BlocksFetchSuccess { ref hash } => { + if let Some(stats) = store.service.stats() { + if let Some(state) = + store.state.get().transition_frontier.sync.block_state(hash) + { + stats.syncing_block_update(state); + } } } - } - TransitionFrontierSyncAction::BlocksPeerQueryError(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksPeerQuerySuccess(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksFetchSuccess(a) => { - if let Some(stats) = store.service.stats() { - if let Some(state) = store - .state - .get() - .transition_frontier - .sync - .block_state(&a.hash) - { - stats.syncing_block_update(state); + TransitionFrontierSyncAction::BlocksNextApplyInit => {} + TransitionFrontierSyncAction::BlocksNextApplyPending { ref hash } => { + if let Some(stats) = store.service.stats() { + if let Some(state) = + store.state.get().transition_frontier.sync.block_state(hash) + { + stats.syncing_block_update(state); + } } } - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksNextApplyInit(a) => { - a.effects(&meta, store); - } - TransitionFrontierSyncAction::BlocksNextApplyPending(a) => { - if let Some(stats) = store.service.stats() { - if let Some(state) = store - .state - .get() - .transition_frontier - .sync - .block_state(&a.hash) - { - stats.syncing_block_update(state); + TransitionFrontierSyncAction::BlocksNextApplySuccess { ref hash } => { + if let Some(stats) = store.service.stats() { + if let Some(state) = + store.state.get().transition_frontier.sync.block_state(hash) + { + stats.syncing_block_update(state); + } } + // TODO(tizoc): push new snarked roots here? } - } - TransitionFrontierSyncAction::BlocksNextApplySuccess(a) => { - if let Some(stats) = store.service.stats() { - if let Some(state) = store - .state - .get() - .transition_frontier - .sync - .block_state(&a.hash) + // Bootstrap/Catchup is practically complete at this point. + // This effect is where the finalization part needs to be + // executed, which is mostly to grab some data that we need + // from previous chain, before it's discarded after dispatching + // `TransitionFrontierSyncedAction`. + TransitionFrontierSyncAction::BlocksSuccess => { + let transition_frontier = &store.state.get().transition_frontier; + let sync = &transition_frontier.sync; + let TransitionFrontierSyncState::BlocksSuccess { + chain, + root_snarked_ledger_updates, + needed_protocol_states, + .. + } = sync + else { + return; + }; + let Some(root_block) = chain.first() else { + return; + }; + let Some(best_tip) = chain.last() else { + return; + }; + let ledgers_to_keep = chain + .iter() + .flat_map(|b| { + [ + b.snarked_ledger_hash(), + b.staged_ledger_hash(), + b.staking_epoch_ledger_hash(), + b.next_epoch_ledger_hash(), + ] + }) + .cloned() + .collect(); + let mut root_snarked_ledger_updates = root_snarked_ledger_updates.clone(); + if transition_frontier + .best_chain + .iter() + .any(|b| b.hash() == root_block.hash()) { - stats.syncing_block_update(state); + root_snarked_ledger_updates + .extend_with_needed(root_block, &transition_frontier.best_chain); } - } - // TODO(tizoc): push new snarked roots here? - a.effects(&meta, store); - } - // Bootstrap/Catchup is practically complete at this point. - // This effect is where the finalization part needs to be - // executed, which is mostly to grab some data that we need - // from previous chain, before it's discarded after dispatching - // `TransitionFrontierSyncedAction`. - TransitionFrontierSyncAction::BlocksSuccess(_) => { - let transition_frontier = &store.state.get().transition_frontier; - let sync = &transition_frontier.sync; - let TransitionFrontierSyncState::BlocksSuccess { - chain, - root_snarked_ledger_updates, - needed_protocol_states, - .. - } = sync - else { - return; - }; - let Some(root_block) = chain.first() else { - return; - }; - let Some(best_tip) = chain.last() else { - return; - }; - let ledgers_to_keep = chain - .iter() - .flat_map(|b| { - [ - b.snarked_ledger_hash(), - b.staged_ledger_hash(), - b.staking_epoch_ledger_hash(), - b.next_epoch_ledger_hash(), - ] - }) - .cloned() - .collect(); - let mut root_snarked_ledger_updates = root_snarked_ledger_updates.clone(); - if transition_frontier - .best_chain - .iter() - .any(|b| b.hash() == root_block.hash()) - { - root_snarked_ledger_updates - .extend_with_needed(root_block, &transition_frontier.best_chain); - } - let needed_protocol_states = if root_snarked_ledger_updates.is_empty() { - // We don't need protocol states unless we need to - // recreate some snarked ledgers during `commit`. - Default::default() - } else { - needed_protocol_states - .iter() - .chain(&transition_frontier.needed_protocol_states) - .map(|(k, v)| (k.clone(), v.clone())) - .collect() - }; + let needed_protocol_states = if root_snarked_ledger_updates.is_empty() { + // We don't need protocol states unless we need to + // recreate some snarked ledgers during `commit`. + Default::default() + } else { + needed_protocol_states + .iter() + .chain(&transition_frontier.needed_protocol_states) + .map(|(k, v)| (k.clone(), v.clone())) + .collect() + }; - let own_peer_id = store.state().p2p.my_id(); - let orphaned_snarks = transition_frontier - .best_chain - .iter() - .rev() - .take_while(|b1| { - let height_diff = best_tip.height().saturating_sub(b1.height()) as usize; - if height_diff == 0 { - best_tip.hash() != b1.hash() - } else if let Some(index) = chain.len().checked_sub(height_diff + 1) { - chain.get(index).map_or(true, |b2| b1.hash() != b2.hash()) - } else { - true - } - }) - .flat_map(|v| v.completed_works_iter()) - .map(|v| SnarkWork { - work: v.clone().into(), - received_t: meta.time(), - sender: own_peer_id, - }) - .collect(); + let own_peer_id = store.state().p2p.my_id(); + let orphaned_snarks = transition_frontier + .best_chain + .iter() + .rev() + .take_while(|b1| { + let height_diff = + best_tip.height().saturating_sub(b1.height()) as usize; + if height_diff == 0 { + best_tip.hash() != b1.hash() + } else if let Some(index) = chain.len().checked_sub(height_diff + 1) { + chain.get(index).map_or(true, |b2| b1.hash() != b2.hash()) + } else { + true + } + }) + .flat_map(|v| v.completed_works_iter()) + .map(|v| SnarkWork { + work: v.clone().into(), + received_t: meta.time(), + sender: own_peer_id, + }) + .collect(); - let res = store.service.commit( - ledgers_to_keep, - root_snarked_ledger_updates, - needed_protocol_states, - root_block, - best_tip, - ); - let needed_protocol_states = res.needed_protocol_states; - let jobs = res.available_jobs; - store.dispatch(TransitionFrontierSyncedAction { - needed_protocol_states, - }); - store.dispatch(SnarkPoolAction::JobsUpdate { - jobs, - orphaned_snarks, - }); - } - TransitionFrontierSyncAction::Ledger(a) => { - handle_transition_frontier_sync_ledger_action(a, &meta, store) + let res = store.service.commit( + ledgers_to_keep, + root_snarked_ledger_updates, + needed_protocol_states, + root_block, + best_tip, + ); + let needed_protocol_states = res.needed_protocol_states; + let jobs = res.available_jobs; + store.dispatch(TransitionFrontierSyncedAction { + needed_protocol_states, + }); + store.dispatch(SnarkPoolAction::JobsUpdate { + jobs, + orphaned_snarks, + }); + } + TransitionFrontierSyncAction::Ledger(ref a) => { + handle_transition_frontier_sync_ledger_action(a.clone(), &meta, store) + } } - }, + a.effects(&meta, store); + } TransitionFrontierAction::Synced(_) => { let Some(best_tip) = store.state.get().transition_frontier.best_tip() else { return; @@ -328,7 +294,7 @@ pub fn transition_frontier_effects( } store.dispatch(ConsensusAction::Prune); - store.dispatch(BlockProducerBestTipUpdateAction { best_tip }); + store.dispatch(BlockProducerAction::BestTipUpdate { best_tip }); } } } @@ -344,174 +310,151 @@ fn handle_transition_frontier_sync_ledger_action( store: &mut redux::Store, ) { match action { - TransitionFrontierSyncLedgerAction::Init(action) => { - action.effects(meta, store); + TransitionFrontierSyncLedgerAction::Init => { + transition_frontier_sync_ledger_init_effects(meta, store); } - TransitionFrontierSyncLedgerAction::Snarked(a) => match a { - TransitionFrontierSyncLedgerSnarkedAction::Pending(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::PeersQuery(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryInit(action) => { - if let Some(stats) = store.service.stats() { - let (start, end) = (meta.time(), meta.time()); - if let Some(kind) = store - .state - .get() - .transition_frontier - .sync - .ledger_target_kind() - { - if action.address.length() < LEDGER_DEPTH - 1 { - stats.syncing_ledger(kind, SyncingLedger::FetchHashes { start, end }); - } else { - stats.syncing_ledger(kind, SyncingLedger::FetchAccounts { start, end }); + TransitionFrontierSyncLedgerAction::Snarked(a) => { + match a { + TransitionFrontierSyncLedgerSnarkedAction::PeerQueryInit { + ref address, .. + } => { + if let Some(stats) = store.service.stats() { + let (start, end) = (meta.time(), meta.time()); + if let Some(kind) = store + .state + .get() + .transition_frontier + .sync + .ledger_target_kind() + { + if address.length() < LEDGER_DEPTH - 1 { + stats.syncing_ledger( + kind, + SyncingLedger::FetchHashes { start, end }, + ); + } else { + stats.syncing_ledger( + kind, + SyncingLedger::FetchAccounts { start, end }, + ); + } } } } - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryPending(_) => {} - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryRetry(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::PeerQueryError(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess(action) => { - if let Some(stats) = store.service.stats() { - if let Some((kind, start, end)) = store - .state - .get() - .transition_frontier - .sync - .ledger() - .and_then(|s| s.snarked()) - .and_then(|s| { - Some(( - s.target().kind, - s.peer_query_get(&action.peer_id, action.rpc_id)?, - )) - }) - .map(|(kind, (_, s))| (kind, s.time, meta.time())) - { - if action.response.is_child_hashes() { - stats.syncing_ledger(kind, SyncingLedger::FetchHashes { start, end }); - } else if action.response.is_child_accounts() { - stats.syncing_ledger(kind, SyncingLedger::FetchAccounts { start, end }); + TransitionFrontierSyncLedgerSnarkedAction::PeerQuerySuccess { + peer_id, + rpc_id, + ref response, + } => { + if let Some(stats) = store.service.stats() { + if let Some((kind, start, end)) = store + .state + .get() + .transition_frontier + .sync + .ledger() + .and_then(|s| s.snarked()) + .and_then(|s| { + Some((s.target().kind, s.peer_query_get(&peer_id, rpc_id)?)) + }) + .map(|(kind, (_, s))| (kind, s.time, meta.time())) + { + if response.is_child_hashes() { + stats.syncing_ledger( + kind, + SyncingLedger::FetchHashes { start, end }, + ); + } else if response.is_child_accounts() { + stats.syncing_ledger( + kind, + SyncingLedger::FetchAccounts { start, end }, + ); + } } } } - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::ChildHashesReceived(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::ChildAccountsReceived(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerSnarkedAction::Success(action) => { - action.effects(meta, store); + TransitionFrontierSyncLedgerSnarkedAction::Success => { + transition_frontier_sync_ledger_snarked_success_effects(meta, store); + } + _ => {} } - }, - TransitionFrontierSyncLedgerAction::Staged(a) => match a { - TransitionFrontierSyncLedgerStagedAction::PartsFetchPending(action) => { - if let Some(stats) = store.service.stats() { - if let Some(kind) = store - .state - .get() - .transition_frontier - .sync - .ledger_target_kind() - { - let (start, end) = (meta.time(), None); - stats.syncing_ledger(kind, SyncingLedger::FetchParts { start, end }); + a.effects(meta, store); + } + TransitionFrontierSyncLedgerAction::Staged(a) => { + match a { + TransitionFrontierSyncLedgerStagedAction::PartsFetchPending => { + if let Some(stats) = store.service.stats() { + if let Some(kind) = store + .state + .get() + .transition_frontier + .sync + .ledger_target_kind() + { + let (start, end) = (meta.time(), None); + stats.syncing_ledger(kind, SyncingLedger::FetchParts { start, end }); + } } } - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchInit(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchPending(_) => {} - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchError(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::PartsPeerFetchSuccess(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::PartsPeerInvalid(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::PartsPeerValid(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::PartsFetchSuccess(action) => { - if let Some(stats) = store.service.stats() { - let (start, end) = (Timestamp::ZERO, Some(meta.time())); - if let Some(kind) = store - .state - .get() - .transition_frontier - .sync - .ledger_target_kind() - { - stats.syncing_ledger(kind, SyncingLedger::FetchParts { start, end }); + TransitionFrontierSyncLedgerStagedAction::PartsFetchSuccess { .. } => { + if let Some(stats) = store.service.stats() { + let (start, end) = (Timestamp::ZERO, Some(meta.time())); + if let Some(kind) = store + .state + .get() + .transition_frontier + .sync + .ledger_target_kind() + { + stats.syncing_ledger(kind, SyncingLedger::FetchParts { start, end }); + } } } - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::ReconstructEmpty(action) => { - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::ReconstructInit(action) => { - if let Some(stats) = store.service.stats() { - let (start, end) = (meta.time(), None); - if let Some(kind) = store - .state - .get() - .transition_frontier - .sync - .ledger_target_kind() - { - stats.syncing_ledger(kind, SyncingLedger::ApplyParts { start, end }); + TransitionFrontierSyncLedgerStagedAction::ReconstructInit { .. } => { + if let Some(stats) = store.service.stats() { + let (start, end) = (meta.time(), None); + if let Some(kind) = store + .state + .get() + .transition_frontier + .sync + .ledger_target_kind() + { + stats.syncing_ledger(kind, SyncingLedger::ApplyParts { start, end }); + } } } - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::ReconstructPending(_) => {} - TransitionFrontierSyncLedgerStagedAction::ReconstructError(_) => {} - TransitionFrontierSyncLedgerStagedAction::ReconstructSuccess(action) => { - if let Some(stats) = store.service.stats() { - let (start, end) = (Timestamp::ZERO, Some(meta.time())); - if let Some(kind) = store - .state - .get() - .transition_frontier - .sync - .ledger_target_kind() - { - stats.syncing_ledger(kind, SyncingLedger::ApplyParts { start, end }); + TransitionFrontierSyncLedgerStagedAction::ReconstructSuccess { .. } => { + if let Some(stats) = store.service.stats() { + let (start, end) = (Timestamp::ZERO, Some(meta.time())); + if let Some(kind) = store + .state + .get() + .transition_frontier + .sync + .ledger_target_kind() + { + stats.syncing_ledger(kind, SyncingLedger::ApplyParts { start, end }); + } } } - action.effects(meta, store); - } - TransitionFrontierSyncLedgerStagedAction::Success(action) => { - action.effects(meta, store); + TransitionFrontierSyncLedgerStagedAction::Success => { + transition_frontier_sync_ledger_staged_success_effects(meta, store); + } + _ => {} } - }, - TransitionFrontierSyncLedgerAction::Success(_) => { + a.effects(meta, store) + } + TransitionFrontierSyncLedgerAction::Success => { match &store.state().transition_frontier.sync { TransitionFrontierSyncState::StakingLedgerPending { .. } => { - store.dispatch(TransitionFrontierSyncLedgerStakingSuccessAction {}); + store.dispatch(TransitionFrontierSyncAction::LedgerStakingSuccess); } TransitionFrontierSyncState::NextEpochLedgerPending { .. } => { - store.dispatch(TransitionFrontierSyncLedgerNextEpochSuccessAction {}); + store.dispatch(TransitionFrontierSyncAction::LedgerNextEpochSuccess); } TransitionFrontierSyncState::RootLedgerPending { .. } => { - store.dispatch(TransitionFrontierSyncLedgerRootSuccessAction {}); + store.dispatch(TransitionFrontierSyncAction::LedgerRootSuccess); } _ => {} } diff --git a/node/src/watched_accounts/mod.rs b/node/src/watched_accounts/mod.rs index c970305a0..1eb507ec9 100644 --- a/node/src/watched_accounts/mod.rs +++ b/node/src/watched_accounts/mod.rs @@ -5,7 +5,7 @@ mod watched_accounts_actions; pub use watched_accounts_actions::*; mod watched_accounts_reducer; -pub use watched_accounts_reducer::*; + mod watched_accounts_effects; pub use watched_accounts_effects::*; diff --git a/node/src/watched_accounts/watched_accounts_actions.rs b/node/src/watched_accounts/watched_accounts_actions.rs index c527dd8a5..43a0cf14a 100644 --- a/node/src/watched_accounts/watched_accounts_actions.rs +++ b/node/src/watched_accounts/watched_accounts_actions.rs @@ -16,31 +16,48 @@ use super::{ pub type WatchedAccountsActionWithMeta = redux::ActionWithMeta; pub type WatchedAccountsActionWithMetaRef<'a> = redux::ActionWithMeta<&'a WatchedAccountsAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] -pub enum WatchedAccountsAction { - Add(WatchedAccountsAddAction), - - LedgerInitialStateGetInit(WatchedAccountsLedgerInitialStateGetInitAction), - LedgerInitialStateGetPending(WatchedAccountsLedgerInitialStateGetPendingAction), - LedgerInitialStateGetError(WatchedAccountsLedgerInitialStateGetErrorAction), - LedgerInitialStateGetRetry(WatchedAccountsLedgerInitialStateGetRetryAction), - LedgerInitialStateGetSuccess(WatchedAccountsLedgerInitialStateGetSuccessAction), - - TransactionsIncludedInBlock(WatchedAccountsBlockTransactionsIncludedAction), - BlockLedgerQueryInit(WatchedAccountsBlockLedgerQueryInitAction), - BlockLedgerQueryPending(WatchedAccountsBlockLedgerQueryPendingAction), - BlockLedgerQuerySuccess(WatchedAccountsBlockLedgerQuerySuccessAction), -} - #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsAddAction { - pub pub_key: NonZeroCurvePoint, -} - -impl redux::EnablingCondition for WatchedAccountsAddAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state.watched_accounts.get(&self.pub_key).is_none() - } +pub enum WatchedAccountsAction { + Add { + pub_key: NonZeroCurvePoint, + }, + LedgerInitialStateGetInit { + pub_key: NonZeroCurvePoint, + }, + LedgerInitialStateGetPending { + pub_key: NonZeroCurvePoint, + block: WatchedAccountBlockInfo, + peer_id: PeerId, + }, + LedgerInitialStateGetError { + pub_key: NonZeroCurvePoint, + error: WatchedAccountsLedgerInitialStateGetError, + }, + LedgerInitialStateGetRetry { + pub_key: NonZeroCurvePoint, + }, + LedgerInitialStateGetSuccess { + pub_key: NonZeroCurvePoint, + data: Option, + }, + TransactionsIncludedInBlock { + pub_key: NonZeroCurvePoint, + block: BlockWithHash>, + }, + BlockLedgerQueryInit { + pub_key: NonZeroCurvePoint, + block_hash: StateHash, + }, + BlockLedgerQueryPending { + pub_key: NonZeroCurvePoint, + block_hash: StateHash, + peer_id: PeerId, + }, + BlockLedgerQuerySuccess { + pub_key: NonZeroCurvePoint, + block_hash: StateHash, + ledger_account: MinaBaseAccountBinableArgStableV2, + }, } fn should_request_ledger_initial_state(state: &crate::State, pub_key: &NonZeroCurvePoint) -> bool { @@ -66,196 +83,106 @@ fn should_request_ledger_initial_state(state: &crate::State, pub_key: &NonZeroCu }) } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsLedgerInitialStateGetInitAction { - pub pub_key: NonZeroCurvePoint, -} - -impl redux::EnablingCondition for WatchedAccountsLedgerInitialStateGetInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - should_request_ledger_initial_state(state, &self.pub_key) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsLedgerInitialStateGetPendingAction { - pub pub_key: NonZeroCurvePoint, - pub block: WatchedAccountBlockInfo, - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for WatchedAccountsLedgerInitialStateGetPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - should_request_ledger_initial_state(state, &self.pub_key) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsLedgerInitialStateGetErrorAction { - pub pub_key: NonZeroCurvePoint, - pub error: WatchedAccountsLedgerInitialStateGetError, -} - -impl redux::EnablingCondition for WatchedAccountsLedgerInitialStateGetErrorAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .watched_accounts - .get(&self.pub_key) - .map_or(false, |a| { - matches!( - &a.initial_state, - WatchedAccountLedgerInitialState::Pending { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsLedgerInitialStateGetRetryAction { - pub pub_key: NonZeroCurvePoint, -} - -impl redux::EnablingCondition for WatchedAccountsLedgerInitialStateGetRetryAction { +impl redux::EnablingCondition for WatchedAccountsAction { fn is_enabled(&self, state: &crate::State) -> bool { - state - .watched_accounts - .get(&self.pub_key) - .map_or(false, |a| match &a.initial_state { - WatchedAccountLedgerInitialState::Error { time, .. } => state - .time() - .checked_sub(*time) - .map_or(false, |d| d.as_secs() >= 3), - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsLedgerInitialStateGetSuccessAction { - pub pub_key: NonZeroCurvePoint, - pub data: Option, -} - -impl redux::EnablingCondition for WatchedAccountsLedgerInitialStateGetSuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - state - .watched_accounts - .get(&self.pub_key) - .map_or(false, |a| { - matches!( - &a.initial_state, - WatchedAccountLedgerInitialState::Pending { .. } - ) - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsBlockTransactionsIncludedAction { - pub pub_key: NonZeroCurvePoint, - pub block: BlockWithHash>, -} - -impl redux::EnablingCondition for WatchedAccountsBlockTransactionsIncludedAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let diff = &self.block.block.body.staged_ledger_diff.diff; - state - .watched_accounts - .get(&self.pub_key) - .map_or(false, |v| v.initial_state.is_success()) - && super::account_relevant_transactions_in_diff_iter(&self.pub_key, diff).any(|_| true) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsBlockLedgerQueryInitAction { - pub pub_key: NonZeroCurvePoint, - pub block_hash: StateHash, -} - -impl redux::EnablingCondition for WatchedAccountsBlockLedgerQueryInitAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let Some(acc) = state.watched_accounts.get(&self.pub_key) else { - return false; - }; - acc.blocks - .iter() - .rev() - .find(|b| b.block().hash == self.block_hash) - .filter(|b| matches!(b, WatchedAccountBlockState::TransactionsInBlockBody { .. })) - .is_some() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsBlockLedgerQueryPendingAction { - pub pub_key: NonZeroCurvePoint, - pub block_hash: StateHash, - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for WatchedAccountsBlockLedgerQueryPendingAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let Some(acc) = state.watched_accounts.get(&self.pub_key) else { - return false; - }; - - let should_req_for_block = acc - .block_find_by_hash(&self.block_hash) - .filter(|b| matches!(b, WatchedAccountBlockState::TransactionsInBlockBody { .. })) - .is_some(); - - // TODO(binier) - let p2p_rpc_is_pending = false; - // let p2p_rpc_is_pending = None - // .or_else(|| { - // let peer = state.p2p.get_ready_peer(&self.peer_id)?; - // peer.rpc.outgoing.get(self.p2p_rpc_id) - // }) - // .map_or(false, |v| v.is_init() || v.is_pending()); - - should_req_for_block && p2p_rpc_is_pending - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct WatchedAccountsBlockLedgerQuerySuccessAction { - pub pub_key: NonZeroCurvePoint, - pub block_hash: StateHash, - pub ledger_account: MinaBaseAccountBinableArgStableV2, -} - -impl redux::EnablingCondition for WatchedAccountsBlockLedgerQuerySuccessAction { - fn is_enabled(&self, state: &crate::State) -> bool { - let Some(acc) = state.watched_accounts.get(&self.pub_key) else { - return false; - }; + match self { + WatchedAccountsAction::Add { pub_key } => state.watched_accounts.get(pub_key).is_none(), + WatchedAccountsAction::LedgerInitialStateGetInit { pub_key } => { + should_request_ledger_initial_state(state, pub_key) + } + WatchedAccountsAction::LedgerInitialStateGetPending { pub_key, .. } => { + should_request_ledger_initial_state(state, pub_key) + } + WatchedAccountsAction::LedgerInitialStateGetError { pub_key, .. } => { + state.watched_accounts.get(pub_key).map_or(false, |a| { + matches!( + &a.initial_state, + WatchedAccountLedgerInitialState::Pending { .. } + ) + }) + } + WatchedAccountsAction::LedgerInitialStateGetRetry { pub_key } => state + .watched_accounts + .get(pub_key) + .map_or(false, |a| match &a.initial_state { + WatchedAccountLedgerInitialState::Error { time, .. } => state + .time() + .checked_sub(*time) + .map_or(false, |d| d.as_secs() >= 3), + _ => false, + }), + WatchedAccountsAction::LedgerInitialStateGetSuccess { pub_key, .. } => { + state.watched_accounts.get(pub_key).map_or(false, |a| { + matches!( + &a.initial_state, + WatchedAccountLedgerInitialState::Pending { .. } + ) + }) + } + WatchedAccountsAction::TransactionsIncludedInBlock { pub_key, block } => { + let diff = &block.block.body.staged_ledger_diff.diff; + state + .watched_accounts + .get(pub_key) + .map_or(false, |v| v.initial_state.is_success()) + && super::account_relevant_transactions_in_diff_iter(pub_key, diff) + .any(|_| true) + } + WatchedAccountsAction::BlockLedgerQueryInit { + pub_key, + block_hash, + } => { + let Some(acc) = state.watched_accounts.get(pub_key) else { + return false; + }; + acc.block_find_by_hash(&block_hash) + .filter(|b| { + matches!(b, WatchedAccountBlockState::TransactionsInBlockBody { .. }) + }) + .is_some() + } + WatchedAccountsAction::BlockLedgerQueryPending { + pub_key, + block_hash, + .. + } => { + let Some(acc) = state.watched_accounts.get(pub_key) else { + return false; + }; - acc.block_find_by_hash(&self.block_hash) - .filter(|b| matches!(b, WatchedAccountBlockState::LedgerAccountGetPending { .. })) - .is_some() - } -} + let should_req_for_block = acc + .block_find_by_hash(block_hash) + .filter(|b| { + matches!(b, WatchedAccountBlockState::TransactionsInBlockBody { .. }) + }) + .is_some(); + + // TODO(binier) + let p2p_rpc_is_pending = false; + // let p2p_rpc_is_pending = None + // .or_else(|| { + // let peer = state.p2p.get_ready_peer(&self.peer_id)?; + // peer.rpc.outgoing.get(self.p2p_rpc_id) + // }) + // .map_or(false, |v| v.is_init() || v.is_pending()); + + should_req_for_block && p2p_rpc_is_pending + } + WatchedAccountsAction::BlockLedgerQuerySuccess { + pub_key, + block_hash, + .. + } => { + let Some(acc) = state.watched_accounts.get(pub_key) else { + return false; + }; -macro_rules! impl_into_global_action { - ($a:ty) => { - impl From<$a> for crate::Action { - fn from(value: $a) -> Self { - Self::WatchedAccounts(value.into()) + acc.block_find_by_hash(block_hash) + .filter(|b| { + matches!(b, WatchedAccountBlockState::LedgerAccountGetPending { .. }) + }) + .is_some() } } - }; + } } - -impl_into_global_action!(WatchedAccountsAddAction); - -impl_into_global_action!(WatchedAccountsLedgerInitialStateGetInitAction); -impl_into_global_action!(WatchedAccountsLedgerInitialStateGetPendingAction); -impl_into_global_action!(WatchedAccountsLedgerInitialStateGetErrorAction); -impl_into_global_action!(WatchedAccountsLedgerInitialStateGetRetryAction); -impl_into_global_action!(WatchedAccountsLedgerInitialStateGetSuccessAction); - -impl_into_global_action!(WatchedAccountsBlockTransactionsIncludedAction); -impl_into_global_action!(WatchedAccountsBlockLedgerQueryInitAction); -impl_into_global_action!(WatchedAccountsBlockLedgerQueryPendingAction); -impl_into_global_action!(WatchedAccountsBlockLedgerQuerySuccessAction); diff --git a/node/src/watched_accounts/watched_accounts_effects.rs b/node/src/watched_accounts/watched_accounts_effects.rs index 0a5b576e4..db848eef5 100644 --- a/node/src/watched_accounts/watched_accounts_effects.rs +++ b/node/src/watched_accounts/watched_accounts_effects.rs @@ -7,13 +7,7 @@ use mina_p2p_messages::{ use crate::Store; -use super::{ - WatchedAccountBlockInfo, WatchedAccountsAction, WatchedAccountsActionWithMeta, - WatchedAccountsBlockLedgerQueryInitAction, WatchedAccountsBlockLedgerQueryPendingAction, - WatchedAccountsLedgerInitialStateGetInitAction, - WatchedAccountsLedgerInitialStateGetPendingAction, - WatchedAccountsLedgerInitialStateGetRetryAction, -}; +use super::{WatchedAccountBlockInfo, WatchedAccountsAction, WatchedAccountsActionWithMeta}; pub fn watched_accounts_effects( store: &mut Store, @@ -22,23 +16,17 @@ pub fn watched_accounts_effects( let (action, _) = action.split(); match action { - WatchedAccountsAction::Add(action) => { - store.dispatch(WatchedAccountsLedgerInitialStateGetInitAction { - pub_key: action.pub_key.clone(), - }); + WatchedAccountsAction::Add { pub_key } => { + store.dispatch(WatchedAccountsAction::LedgerInitialStateGetInit { pub_key }); } - WatchedAccountsAction::TransactionsIncludedInBlock(action) => { - store.dispatch(WatchedAccountsBlockLedgerQueryInitAction { - pub_key: action.pub_key, - block_hash: action.block.hash, + WatchedAccountsAction::TransactionsIncludedInBlock { pub_key, block } => { + store.dispatch(WatchedAccountsAction::BlockLedgerQueryInit { + pub_key, + block_hash: block.hash, }); } - WatchedAccountsAction::LedgerInitialStateGetInit( - WatchedAccountsLedgerInitialStateGetInitAction { pub_key }, - ) - | WatchedAccountsAction::LedgerInitialStateGetRetry( - WatchedAccountsLedgerInitialStateGetRetryAction { pub_key }, - ) => { + WatchedAccountsAction::LedgerInitialStateGetInit { pub_key } + | WatchedAccountsAction::LedgerInitialStateGetRetry { pub_key } => { // TODO(binier) // let Some((peer_id, p2p_rpc_id)) = store.state().p2p.get_free_peer_id_for_rpc() else { return }; // let block = { @@ -82,10 +70,10 @@ pub fn watched_accounts_effects( // p2p_rpc_id, // }); } - WatchedAccountsAction::LedgerInitialStateGetPending(_) => {} - WatchedAccountsAction::LedgerInitialStateGetError(_) => {} - WatchedAccountsAction::LedgerInitialStateGetSuccess(_) => {} - WatchedAccountsAction::BlockLedgerQueryInit(action) => { + WatchedAccountsAction::LedgerInitialStateGetPending { .. } => {} + WatchedAccountsAction::LedgerInitialStateGetError { .. } => {} + WatchedAccountsAction::LedgerInitialStateGetSuccess { .. } => {} + WatchedAccountsAction::BlockLedgerQueryInit { .. } => { // TODO(binier) // let Some((peer_id, p2p_rpc_id)) = store.state().p2p.get_free_peer_id_for_rpc() else { return }; // let ledger_hash = { @@ -119,7 +107,7 @@ pub fn watched_accounts_effects( // p2p_rpc_id, // }); } - WatchedAccountsAction::BlockLedgerQueryPending(_) => {} - WatchedAccountsAction::BlockLedgerQuerySuccess(_) => {} + WatchedAccountsAction::BlockLedgerQueryPending { .. } => {} + WatchedAccountsAction::BlockLedgerQuerySuccess { .. } => {} } } diff --git a/node/src/watched_accounts/watched_accounts_reducer.rs b/node/src/watched_accounts/watched_accounts_reducer.rs index 28b3bc6db..f871b9f80 100644 --- a/node/src/watched_accounts/watched_accounts_reducer.rs +++ b/node/src/watched_accounts/watched_accounts_reducer.rs @@ -8,45 +8,45 @@ impl WatchedAccountsState { pub fn reducer(&mut self, action: WatchedAccountsActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - WatchedAccountsAction::Add(action) => { + WatchedAccountsAction::Add { pub_key } => { self.insert( - action.pub_key.clone(), + pub_key.clone(), WatchedAccountState { initial_state: WatchedAccountLedgerInitialState::Idle { time: meta.time() }, blocks: Default::default(), }, ); - } - WatchedAccountsAction::LedgerInitialStateGetInit(_) => {} - WatchedAccountsAction::LedgerInitialStateGetPending(action) => { - let Some(account) = self.get_mut(&action.pub_key) else { + }, + WatchedAccountsAction::LedgerInitialStateGetInit { .. } => {}, + WatchedAccountsAction::LedgerInitialStateGetPending { pub_key, block, peer_id } => { + let Some(account) = self.get_mut(pub_key) else { return; }; account.blocks.clear(); account.initial_state = WatchedAccountLedgerInitialState::Pending { time: meta.time(), - block: action.block.clone(), - peer_id: action.peer_id, + block: block.clone(), + peer_id: *peer_id, }; - } - WatchedAccountsAction::LedgerInitialStateGetError(action) => { - let Some(account) = self.get_mut(&action.pub_key) else { + }, + WatchedAccountsAction::LedgerInitialStateGetError { pub_key, error } => { + let Some(account) = self.get_mut(pub_key) else { return; }; let peer_id = match &account.initial_state { - WatchedAccountLedgerInitialState::Pending { peer_id, .. } => peer_id.clone(), + WatchedAccountLedgerInitialState::Pending { peer_id, .. } => *peer_id, _ => return, }; account.initial_state = WatchedAccountLedgerInitialState::Error { time: meta.time(), - error: action.error.clone(), + error: error.clone(), peer_id, }; - } - WatchedAccountsAction::LedgerInitialStateGetRetry(_) => {} - WatchedAccountsAction::LedgerInitialStateGetSuccess(action) => { - let Some(account) = self.get_mut(&action.pub_key) else { + }, + WatchedAccountsAction::LedgerInitialStateGetRetry { .. } => {}, + WatchedAccountsAction::LedgerInitialStateGetSuccess { pub_key, data } => { + let Some(account) = self.get_mut(pub_key) else { return; }; let Some(block) = account.initial_state.block() else { @@ -55,85 +55,60 @@ impl WatchedAccountsState { account.initial_state = WatchedAccountLedgerInitialState::Success { time: meta.time(), block: block.clone(), - data: action.data.clone(), + data: data.clone(), }; - } - WatchedAccountsAction::TransactionsIncludedInBlock(action) => { - let block = &action.block; - let header = &block.block.header; - let diff = &block.block.body.staged_ledger_diff.diff; - + }, + WatchedAccountsAction::TransactionsIncludedInBlock { pub_key, block } => { let transactions = - account_relevant_transactions_in_diff_iter(&action.pub_key, diff).collect(); + account_relevant_transactions_in_diff_iter(pub_key, &block.block.body.staged_ledger_diff.diff).collect(); - let Some(account) = self.get_mut(&action.pub_key) else { + let Some(account) = self.get_mut(pub_key) else { return; }; account .blocks .push_back(WatchedAccountBlockState::TransactionsInBlockBody { block: WatchedAccountBlockInfo { - level: header - .protocol_state - .body - .consensus_state - .blockchain_length - .0 - .0 as u32, + level: block.block.header.protocol_state.body.consensus_state.blockchain_length.0 .0 as u32, hash: block.hash.clone(), - pred_hash: header.protocol_state.previous_state_hash.clone(), - staged_ledger_hash: header - .protocol_state - .body - .blockchain_state - .staged_ledger_hash - .non_snark - .ledger_hash - .clone(), + pred_hash: block.block.header.protocol_state.previous_state_hash.clone(), + staged_ledger_hash: block.block.header.protocol_state.body.blockchain_state.staged_ledger_hash.non_snark.ledger_hash.clone(), }, transactions, }); - } - WatchedAccountsAction::BlockLedgerQueryInit(_) => {} - WatchedAccountsAction::BlockLedgerQueryPending(action) => { - let Some(account) = self.get_mut(&action.pub_key) else { + }, + WatchedAccountsAction::BlockLedgerQueryInit { .. } => {}, + WatchedAccountsAction::BlockLedgerQueryPending { pub_key, block_hash, .. } => { + let Some(account) = self.get_mut(pub_key) else { return; }; - let Some(block_state) = account.block_find_by_hash_mut(&action.block_hash) else { + let Some(block_state) = account.block_find_by_hash_mut(block_hash) else { return; }; *block_state = match block_state { - WatchedAccountBlockState::TransactionsInBlockBody { - block, - transactions, - } => WatchedAccountBlockState::LedgerAccountGetPending { + WatchedAccountBlockState::TransactionsInBlockBody { block, transactions } => WatchedAccountBlockState::LedgerAccountGetPending { block: block.clone(), transactions: std::mem::take(transactions), - // p2p_rpc_id: action.p2p_rpc_id, }, _ => return, }; - } - WatchedAccountsAction::BlockLedgerQuerySuccess(action) => { - let Some(account) = self.get_mut(&action.pub_key) else { + }, + WatchedAccountsAction::BlockLedgerQuerySuccess { pub_key, block_hash, ledger_account } => { + let Some(account) = self.get_mut(pub_key) else { return; }; - let Some(block_state) = account.block_find_by_hash_mut(&action.block_hash) else { + let Some(block_state) = account.block_find_by_hash_mut(block_hash) else { return; }; *block_state = match block_state { - WatchedAccountBlockState::LedgerAccountGetPending { - block, - transactions, - .. - } => WatchedAccountBlockState::LedgerAccountGetSuccess { + WatchedAccountBlockState::LedgerAccountGetPending { block, transactions, .. } => WatchedAccountBlockState::LedgerAccountGetSuccess { block: block.clone(), transactions: std::mem::take(transactions), - ledger_account: action.ledger_account.clone(), + ledger_account: ledger_account.clone(), }, _ => return, }; - } + }, } } } diff --git a/node/testing/Cargo.toml b/node/testing/Cargo.toml index ae43be82f..e0ce1e486 100644 --- a/node/testing/Cargo.toml +++ b/node/testing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "openmina-node-testing" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/node/testing/docker/Dockerfile.openmina b/node/testing/docker/Dockerfile.openmina index f75a5d7f2..855517bb0 100644 --- a/node/testing/docker/Dockerfile.openmina +++ b/node/testing/docker/Dockerfile.openmina @@ -9,7 +9,7 @@ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y RUN rm /bin/sh && ln -s /bin/bash /bin/sh -RUN source ~/.cargo/env && rustup update nightly-2023-12-21 +RUN source ~/.cargo/env && rustup update 1.75 RUN git clone https://github.com/openmina/openmina diff --git a/node/testing/docker/Dockerfile.test b/node/testing/docker/Dockerfile.test index f42e265af..d483a9f8a 100644 --- a/node/testing/docker/Dockerfile.test +++ b/node/testing/docker/Dockerfile.test @@ -2,7 +2,7 @@ FROM vladsimplestakingcom/mina-openmina-builder:focal as builder RUN git fetch && git checkout feat/tests-with-debugger -RUN source ~/.cargo/env && cargo +nightly-2023-12-21 build --release -p openmina-node-testing --bin runner --bin openmina-node-testing +RUN source ~/.cargo/env && cargo +1.75 build --release -p openmina-node-testing --bin runner --bin openmina-node-testing FROM vladsimplestakingcom/mina-debugger:2.0.0rampup4-focal diff --git a/node/testing/src/node/rust/mod.rs b/node/testing/src/node/rust/mod.rs index 7bf4de068..d8fe094f3 100644 --- a/node/testing/src/node/rust/mod.rs +++ b/node/testing/src/node/rust/mod.rs @@ -4,7 +4,7 @@ pub use config::{RustNodeBlockProducerTestingConfig, RustNodeTestingConfig, Test mod event; pub use event::*; -use node::event_source::EventSourceNewEventAction; +use node::event_source::EventSourceAction; use node::p2p::connection::outgoing::{ P2pConnectionOutgoingInitLibp2pOpts, P2pConnectionOutgoingInitOpts, }; @@ -94,7 +94,7 @@ impl Node { } pub fn dispatch_event(&mut self, event: Event) -> bool { - self.dispatch(EventSourceNewEventAction { event }) + self.dispatch(EventSourceAction::NewEvent { event }) } pub fn get_pending_event(&self, event_id: PendingEventId) -> Option<&Event> { diff --git a/node/testing/src/service/mod.rs b/node/testing/src/service/mod.rs index ffb8ddad2..b8826993f 100644 --- a/node/testing/src/service/mod.rs +++ b/node/testing/src/service/mod.rs @@ -7,8 +7,9 @@ use std::{collections::BTreeMap, ffi::OsStr, sync::Arc}; use ledger::dummy::dummy_transaction_proof; use ledger::scan_state::scan_state::transaction_snark::SokMessage; use ledger::Mask; +use mina_p2p_messages::string::ByteString; use mina_p2p_messages::v2::{ - CurrencyFeeStableV1, LedgerHash, LedgerProofProdStableV2, MinaBaseZkappAccountZkappUriStableV1, + CurrencyFeeStableV1, LedgerHash, LedgerProofProdStableV2, MinaStateSnarkedLedgerStateWithSokStableV2, NonZeroCurvePoint, SnarkWorkerWorkerRpcsVersionedGetWorkV2TResponseA0Single, TransactionSnarkStableV2, TransactionSnarkWorkTStableV2Proofs, @@ -72,7 +73,7 @@ pub struct NodeTestingService { pending_events: PendingRequests, dyn_effects: Option, - snarker_sok_digest: Option, + snarker_sok_digest: Option, /// Once dropped, it will cause all threads associated to shutdown. _shutdown: mpsc::Receiver<()>, } @@ -130,7 +131,7 @@ impl NodeTestingService { self.dyn_effects.take() } - pub fn set_snarker_sok_digest(&mut self, digest: MinaBaseZkappAccountZkappUriStableV1) { + pub fn set_snarker_sok_digest(&mut self, digest: ByteString) { self.snarker_sok_digest = Some(digest); } diff --git a/p2p/Cargo.toml b/p2p/Cargo.toml index 266377e14..9aa239051 100644 --- a/p2p/Cargo.toml +++ b/p2p/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "p2p" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/p2p/libp2p-rpc-behaviour/Cargo.toml b/p2p/libp2p-rpc-behaviour/Cargo.toml index 3632e4d9e..6bd466c4d 100644 --- a/p2p/libp2p-rpc-behaviour/Cargo.toml +++ b/p2p/libp2p-rpc-behaviour/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libp2p-rpc-behaviour" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/p2p/readme.md b/p2p/readme.md new file mode 100644 index 000000000..27e49ebdd --- /dev/null +++ b/p2p/readme.md @@ -0,0 +1,192 @@ +# Implementation of the LibP2P networking stack + +A peer-to-peer (P2P) network serves as the backbone of decentralized communication and data sharing among blockchain nodes. It enables the propagation of transaction and block information across the network, facilitating the consensus process crucial for maintaining the blockchain's integrity. Without a P2P network, nodes in the Mina blockchain would be isolated and unable to exchange vital information, leading to fragmentation and compromising the blockchain's trustless nature. + +To begin with, we need a P2P _networking stack_, a set of protocols and layers that define how P2P communication occurs between devices over our network. Think of it as a set of rules and conventions for data transmission, addressing, and error handling, enabling different devices and applications to exchange data effectively in a networked environment. We want our networking stack to have the following features: + +For our networking stack, we are utilizing LibP2P, a modular networking stack that provides a unified framework for building decentralized P2P network applications. + + +## LibP2P + +LibP2P has the following features: + +### Modularity + +Being modular means that we can customize the stacks for various types of devices, i.e. a smartphone may use a different set of modules than a server. + + +### Cohesion + +Modules in the stack can communicate between each other despite differences in what each module should do according to its specification. + + +### Layers + +LibP2P provides vertical complexity in the form of layers. Each layer serves a specific purpose, which lets us neatly organize the various functions of the P2P network. It allows us to separate concerns, making the network architecture easier to manage and debug. + + +JustLayers (1) + + +_Above: A simplified overview of the Open Mina LibP2P networking stack. The abstraction is in an ascending order, i.e. the layers at the top have more abstraction than the layers at the bottom._ + + +Now we describe each layer of the P2P networking stack in descending order of abstraction. + + +## RPCs + +A node needs to continuously receive and send information across the P2P network. + +For certain types of information, such as new transitions (blocks), the best tips or ban notifications, Mina nodes utilize remote procedure calls (RPCs). + +An RPC is a query for a particular type of information that is sent to a peer over the P2P network. After an RPC is made, the node expects a response from it. + +Mina nodes use the following RPCs. + + + +* `get_staged_ledger_aux_and_pending_coinbases_at_hash` +* `answer_sync_ledger_query` +* `get_transition_chain` +* `get_transition_chain_proof` +* `Get_transition_knowledge` (note the initial capital) +* `get_ancestry` +* `ban_notify` +* `get_best_tip` +* `get_node_status` (v1 and v2) +* `Get_epoch_ledger` + + + +### Kademlia for peer discovery + +The P2P layer enables nodes in the Mina network to discover and connect with each other. We want the Open Mina node to be able to connect to peers, both other Open Mina nodes (that are written in Rust) as well as native Mina nodes (written in OCaml). + +To achieve that, we need to implement peer discovery via Kademlia as part of our LibP2P networking stack. Previously, we used the RPC `get_initial_peers` as a sort of workaround to connect our nodes between themselves. Now, to ensure compatibility with the native Mina node, we’ve implemented KAD for peer discovery for the Openmina node. + +Kademlia, or KAD, is a distributed hash table (DHT) for peer-to-peer computer networks. Hash tables are a type of data structure that maps _keys_ to _values_. In very broad and simplistic terms, think of a hash table as a dictionary, where a word (i.e. dog) is mapped to a definition (furry, four-legged animal that barks). In more practical terms, each key is passed through a hash function, which computes an index based on the key's content. + +KAD specifically works as a distributed hash table by storing key-value pairs across the network, where keys are mapped to nodes using the so-called XOR metric, ensuring that data can be efficiently located and retrieved by querying nodes that are closest to the key's hash. + + +#### Measuring distance via XOR + +XOR is a unique feature of how KAD measures the distance between peers - it is defined as the XOR metric between two node IDs or between a node ID and a key, providing a way to measure closeness in the network's address space for efficient routing and data lookup. + +The term "XOR" stands for "exclusive or," which is a logical operation that outputs true only when the inputs differ (one is true, the other is false). See the diagram below for a visual explanation: + + +![image6](https://github.com/openmina/openmina/assets/60480123/4e57f9b9-9e68-4400-b0ad-ff17c14766a1) + + +_Above: A Kademlia binary tree organized into four distinct buckets (marked in orange) of varying sizes. _ + +The XOR metric used by Kademlia for measuring distance ensures uniformity and symmetry in distance calculations, allowing for predictable and decentralized routing without the need for hierarchical or centralized structures, which allows for better scalability and fault tolerance in our P2P network. + +LibP2P leverages Kademlia for peer discovery and DHT functionalities, ensuring efficient routing and data location in the network. In Mina nodes, KAD specifies the structure of the network and the exchange of information through node lookups, which makes it efficient for locating nodes in the network. + + +## Multiplexing via Yamux + +In a P2P network, connections are a key resource. Establishing multiple connections between peers can be costly and impractical, particularly in a network consisting of devices with limited resources. To make the most of a single connection, we employ _multiplexing_, which means having multiple data streams transmitted over a single network connection concurrently. + + +![image3](https://github.com/openmina/openmina/assets/60480123/5f6a48c7-bbae-4ca2-9189-badae2369f3d) + + +For multiplexing, we utilize [_Yamux_](https://github.com/hashicorp/yamux), a multiplexer that provides efficient, concurrent handling of multiple data streams over a single connection, aligning well with the needs of modern, scalable, and efficient network protocols and applications. + + +## Noise encryption + +We want to ensure that data exchanged between nodes remains confidential, authenticated, and resistant to tampering. For that purpose, we utilize Noise, a cryptographic protocol featuring ephemeral keys and forward secrecy, used to secure the connection. + +Noise provides the following capabilities: + + +### Async + +Noise supports asynchronous communication, allowing nodes to communicate without both being online simultaneously can efficiently handle the kind of non-blocking I/O operations that are typical in P2P networks, where nodes may not be continuously connected, even in the asynchronous and unpredictable environments that are characteristic of blockchain P2P networks. + + +### Forward secrecy + +Noise utilizes _ephemeral keys_, which are random keys generated for each new connection that must be destroyed after use. The use of ephemeral keys forward secrecy. This means that decrypting a segment of the data does not provide any additional ability to decrypt the rest of the data. Simply put, forward secrecy means that if an adversary gains knowledge of the secret key, they will be able to participate in the network on the behalf of the peer, but they will not be able to decrypt past nor future messages. + + +### How Noise works + +The Noise protocol implemented by libp2p uses the [XX](http://www.noiseprotocol.org/noise.html#interactive-handshake-patterns-fundamental) handshake pattern, which happens in the following stages: + + +![image4](https://github.com/openmina/openmina/assets/60480123/a1b2b2bf-980e-459c-8375-9e8b6162b6d1) + + + + +1. Alice sends Bob her ephemeral public key (32 bytes). + + +![image2](https://github.com/openmina/openmina/assets/60480123/721103dd-0bb9-4f0b-8998-97b0cc19f6fc) + + + +2. Bob responds to Alice with a message that contains: +* Bob’s ephemeral public key (32 bytes). +* Bob's static public key (32 bytes). +* The tag (MAC) of the static public key (16 bytes). + +As well as a payload of extra data that includes the peer’s `identity_key`, an `identity_sig`, Noise's static public key and the tag (MAC) of the payload (16 bytes). + + +![image5](https://github.com/openmina/openmina/assets/60480123/b7ed062d-2204-4b94-87af-abc6eecd7013) + + +1. Alice responds to Bob with her own message that contains: +* Alice's static public key (32 bytes). +* The tag (MAC) of Alice’s static public key (16 bytes). +* The payload, in the same fashion as Bob does in the second step, but with Alice's information instead. +* The tag (MAC) of the payload (16 bytes). + +After the messages are exchanged (two sent by Alice, the _initiator,_ and one sent by Bob, the _responder_), both parties can derive a pair of symmetric keys that can be used to cipher and decipher messages. + + +## Pnet layer + +We want to be able to determine whether the peer to whom we want to connect to is running the same network as our node. For instance, a node running on the Mina mainnet will connect to other mainnet nodes and avoid connecting to peers running on Mina’s testnet. + +For that purpose, Mina utilizes pnet, an encryption transport layer that constitutes the lowest layer of libp2p. Please note that while the network (IP) and transport (TCP) layers are lower than pnet, they are not unique to LiP2P. + +In Mina, the pnet _secret key_ refers to the chain on which the node is running, + +for instance `mina/mainnet` or `mina/testnet`. This prevents nodes from attempting connections with the incorrect chain. + +Although pnet utilizes a type of secret key known as a pre-shared key (PSK), every peer in the network knows this key. This is why, despite being encrypted, the pnet channel itself isn’t secure - that is achieved via the aforementioned Noise protocol. + + +## Transport + +At the lowest level of abstraction, we want our P2P network to have a reliable, ordered, and error-checked method of transporting data between peers. crucial for maintaining the integrity and consistency of the blockchain. + +Libp2p connections are established by _dialing_ the peer address across a transport layer. Currently, Mina uses TCP, but it can also utilize UDP, which can be useful if we implement a node based on WebRTC. + +Peer addresses are written in a convention known as _Multiaddress_, which is a universal method of specifying various kinds of addresses. + +For example, let’s look at one of the addresses from the [Mina Protocol peer list](https://storage.googleapis.com/mina-seed-lists/mainnet_seeds.txt). + + +``` +/dns4/seed-1.mainnet.o1test.net/tcp/10000/p2p/12D3KooWCa1d7G3SkRxy846qTvdAFX69NnoYZ32orWVLqJcDVGHW + +``` + + + +* `/dns4/seed-1.mainnet.o1test.net/ `States that the domain name is resolvable only to IPv4 addresses +* `tcp/10000 `tells us we want to send TCP packets to port 10000. +* `p2p/12D3KooWCa1d7G3SkRxy846qTvdAFX69NnoYZ32orWVLqJcDVGHW` informs us of the hash of the peer’s public key, which allows us to encrypt communication with said peer. + +An address written under the _Multiaddress_ convention is ‘future-proof’ in the sense that it is backwards-compatible. For example, since multiple transports are supported, we can change `tcp `to `udp`, and the address will still be readable and valid. + diff --git a/p2p/src/channels/best_tip/mod.rs b/p2p/src/channels/best_tip/mod.rs index b8ba1fb97..fa829578d 100644 --- a/p2p/src/channels/best_tip/mod.rs +++ b/p2p/src/channels/best_tip/mod.rs @@ -5,10 +5,10 @@ mod p2p_channels_best_tip_actions; pub use p2p_channels_best_tip_actions::*; mod p2p_channels_best_tip_reducer; -pub use p2p_channels_best_tip_reducer::*; + mod p2p_channels_best_tip_effects; -pub use p2p_channels_best_tip_effects::*; + use binprot_derive::{BinProtRead, BinProtWrite}; use openmina_core::block::ArcBlock; diff --git a/p2p/src/channels/best_tip/p2p_channels_best_tip_effects.rs b/p2p/src/channels/best_tip/p2p_channels_best_tip_effects.rs index c0cc0544a..c2b2e299a 100644 --- a/p2p/src/channels/best_tip/p2p_channels_best_tip_effects.rs +++ b/p2p/src/channels/best_tip/p2p_channels_best_tip_effects.rs @@ -2,7 +2,7 @@ use redux::ActionMeta; use crate::{ channels::{ChannelId, MsgId, P2pChannelsService}, - peer::P2pPeerBestTipUpdateAction, + peer::P2pPeerAction, }; use super::{BestTipPropagationChannelMsg, P2pChannelsBestTipAction}; @@ -13,7 +13,7 @@ impl P2pChannelsBestTipAction { Store: crate::P2pStore, Store::Service: P2pChannelsService, P2pChannelsBestTipAction: redux::EnablingCondition, - P2pPeerBestTipUpdateAction: redux::EnablingCondition, + P2pPeerAction: redux::EnablingCondition, { match self { P2pChannelsBestTipAction::Init { peer_id } => { @@ -35,7 +35,7 @@ impl P2pChannelsBestTipAction { .channel_send(peer_id, MsgId::first(), msg.into()); } P2pChannelsBestTipAction::Received { peer_id, best_tip } => { - store.dispatch(P2pPeerBestTipUpdateAction { + store.dispatch(P2pPeerAction::BestTipUpdate { peer_id, best_tip: best_tip.clone(), }); diff --git a/p2p/src/channels/mod.rs b/p2p/src/channels/mod.rs index 292a2c70d..d7fe71f67 100644 --- a/p2p/src/channels/mod.rs +++ b/p2p/src/channels/mod.rs @@ -10,10 +10,10 @@ mod p2p_channels_actions; pub use p2p_channels_actions::*; mod p2p_channels_reducer; -pub use p2p_channels_reducer::*; + mod p2p_channels_effects; -pub use p2p_channels_effects::*; + mod p2p_channels_service; pub use p2p_channels_service::*; diff --git a/p2p/src/channels/p2p_channels_effects.rs b/p2p/src/channels/p2p_channels_effects.rs index 8008c6cf6..5927308d1 100644 --- a/p2p/src/channels/p2p_channels_effects.rs +++ b/p2p/src/channels/p2p_channels_effects.rs @@ -1,7 +1,7 @@ use openmina_core::block::BlockWithHash; use redux::ActionMeta; -use crate::disconnection::{P2pDisconnectionInitAction, P2pDisconnectionReason}; +use crate::disconnection::{P2pDisconnectionAction, P2pDisconnectionReason}; use super::{ best_tip::{BestTipPropagationChannelMsg, P2pChannelsBestTipAction}, @@ -21,7 +21,7 @@ impl P2pChannelsMessageReceivedAction { P2pChannelsSnarkAction: redux::EnablingCondition, P2pChannelsSnarkJobCommitmentAction: redux::EnablingCondition, P2pChannelsRpcAction: redux::EnablingCondition, - P2pDisconnectionInitAction: redux::EnablingCondition, + P2pDisconnectionAction: redux::EnablingCondition, { let peer_id = self.peer_id; let chan_id = self.message.channel_id(); @@ -89,7 +89,7 @@ impl P2pChannelsMessageReceivedAction { if !was_expected { let reason = P2pDisconnectionReason::P2pChannelMsgUnexpected(chan_id); - store.dispatch(P2pDisconnectionInitAction { peer_id, reason }); + store.dispatch(P2pDisconnectionAction::Init { peer_id, reason }); } } } diff --git a/p2p/src/channels/rpc/mod.rs b/p2p/src/channels/rpc/mod.rs index 5923230fb..f7ee55cfb 100644 --- a/p2p/src/channels/rpc/mod.rs +++ b/p2p/src/channels/rpc/mod.rs @@ -5,10 +5,10 @@ mod p2p_channels_rpc_actions; pub use p2p_channels_rpc_actions::*; mod p2p_channels_rpc_reducer; -pub use p2p_channels_rpc_reducer::*; + mod p2p_channels_rpc_effects; -pub use p2p_channels_rpc_effects::*; + use std::{sync::Arc, time::Duration}; diff --git a/p2p/src/channels/rpc/p2p_channels_rpc_effects.rs b/p2p/src/channels/rpc/p2p_channels_rpc_effects.rs index 18c007b5f..b36dc424c 100644 --- a/p2p/src/channels/rpc/p2p_channels_rpc_effects.rs +++ b/p2p/src/channels/rpc/p2p_channels_rpc_effects.rs @@ -1,9 +1,10 @@ use openmina_core::block::BlockWithHash; + use redux::ActionMeta; use crate::{ channels::{ChannelId, MsgId, P2pChannelsService}, - peer::P2pPeerBestTipUpdateAction, + peer::P2pPeerAction, }; use super::{P2pChannelsRpcAction, P2pRpcResponse, RpcChannelMsg}; @@ -13,7 +14,7 @@ impl P2pChannelsRpcAction { where Store: crate::P2pStore, Store::Service: P2pChannelsService, - P2pPeerBestTipUpdateAction: redux::EnablingCondition, + P2pPeerAction: redux::EnablingCondition, Self: redux::EnablingCondition, { match self { @@ -35,7 +36,7 @@ impl P2pChannelsRpcAction { peer_id, response, .. } => { if let Some(P2pRpcResponse::BestTipWithProof(resp)) = response { - store.dispatch(P2pPeerBestTipUpdateAction { + store.dispatch(P2pPeerAction::BestTipUpdate { peer_id, best_tip: BlockWithHash::new(resp.best_tip.clone()), }); diff --git a/p2p/src/channels/snark/mod.rs b/p2p/src/channels/snark/mod.rs index 910650db9..53735a604 100644 --- a/p2p/src/channels/snark/mod.rs +++ b/p2p/src/channels/snark/mod.rs @@ -5,10 +5,10 @@ mod p2p_channels_snark_actions; pub use p2p_channels_snark_actions::*; mod p2p_channels_snark_reducer; -pub use p2p_channels_snark_reducer::*; + mod p2p_channels_snark_effects; -pub use p2p_channels_snark_effects::*; + use binprot_derive::{BinProtRead, BinProtWrite}; use openmina_core::snark::SnarkInfo; diff --git a/p2p/src/channels/snark_job_commitment/mod.rs b/p2p/src/channels/snark_job_commitment/mod.rs index 7d72cfe7a..501f3136d 100644 --- a/p2p/src/channels/snark_job_commitment/mod.rs +++ b/p2p/src/channels/snark_job_commitment/mod.rs @@ -5,10 +5,10 @@ mod p2p_channels_snark_job_commitment_actions; pub use p2p_channels_snark_job_commitment_actions::*; mod p2p_channels_snark_job_commitment_reducer; -pub use p2p_channels_snark_job_commitment_reducer::*; + mod p2p_channels_snark_job_commitment_effects; -pub use p2p_channels_snark_job_commitment_effects::*; + use binprot_derive::{BinProtRead, BinProtWrite}; use openmina_core::snark::SnarkJobCommitment; diff --git a/p2p/src/connection/incoming/mod.rs b/p2p/src/connection/incoming/mod.rs index 5357a6fa6..ea8eedd46 100644 --- a/p2p/src/connection/incoming/mod.rs +++ b/p2p/src/connection/incoming/mod.rs @@ -5,10 +5,10 @@ mod p2p_connection_incoming_actions; pub use p2p_connection_incoming_actions::*; mod p2p_connection_incoming_reducer; -pub use p2p_connection_incoming_reducer::*; + mod p2p_connection_incoming_effects; -pub use p2p_connection_incoming_effects::*; + use serde::{Deserialize, Serialize}; diff --git a/p2p/src/connection/incoming/p2p_connection_incoming_actions.rs b/p2p/src/connection/incoming/p2p_connection_incoming_actions.rs index bdf790aff..efc347a37 100644 --- a/p2p/src/connection/incoming/p2p_connection_incoming_actions.rs +++ b/p2p/src/connection/incoming/p2p_connection_incoming_actions.rs @@ -2,294 +2,201 @@ use serde::{Deserialize, Serialize}; use openmina_core::requests::RpcId; -use crate::{webrtc, P2pState, PeerId}; +use crate::{webrtc, P2pAction, P2pState, PeerId}; use super::P2pConnectionIncomingInitOpts; pub type P2pConnectionIncomingActionWithMetaRef<'a> = redux::ActionWithMeta<&'a P2pConnectionIncomingAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub enum P2pConnectionIncomingAction { - Init(P2pConnectionIncomingInitAction), - AnswerSdpCreatePending(P2pConnectionIncomingAnswerSdpCreatePendingAction), - AnswerSdpCreateError(P2pConnectionIncomingAnswerSdpCreateErrorAction), - AnswerSdpCreateSuccess(P2pConnectionIncomingAnswerSdpCreateSuccessAction), - AnswerReady(P2pConnectionIncomingAnswerReadyAction), - AnswerSendSuccess(P2pConnectionIncomingAnswerSendSuccessAction), - FinalizePending(P2pConnectionIncomingFinalizePendingAction), - FinalizeError(P2pConnectionIncomingFinalizeErrorAction), - FinalizeSuccess(P2pConnectionIncomingFinalizeSuccessAction), - Timeout(P2pConnectionIncomingTimeoutAction), - Error(P2pConnectionIncomingErrorAction), - Success(P2pConnectionIncomingSuccessAction), - Libp2pReceived(P2pConnectionIncomingLibp2pReceivedAction), + Init { + opts: P2pConnectionIncomingInitOpts, + rpc_id: Option, + }, + AnswerSdpCreatePending { + peer_id: PeerId, + }, + AnswerSdpCreateError { + peer_id: PeerId, + error: String, + }, + AnswerSdpCreateSuccess { + peer_id: PeerId, + sdp: String, + }, + AnswerReady { + peer_id: PeerId, + answer: webrtc::Answer, + }, + AnswerSendSuccess { + peer_id: PeerId, + }, + FinalizePending { + peer_id: PeerId, + }, + FinalizeError { + peer_id: PeerId, + error: String, + }, + FinalizeSuccess { + peer_id: PeerId, + }, + Timeout { + peer_id: PeerId, + }, + Error { + peer_id: PeerId, + error: P2pConnectionIncomingError, + }, + Success { + peer_id: PeerId, + }, + Libp2pReceived { + peer_id: PeerId, + }, } impl P2pConnectionIncomingAction { pub fn peer_id(&self) -> Option<&PeerId> { match self { - Self::Init(v) => Some(&v.opts.peer_id), - Self::AnswerSdpCreatePending(v) => Some(&v.peer_id), - Self::AnswerSdpCreateError(v) => Some(&v.peer_id), - Self::AnswerSdpCreateSuccess(v) => Some(&v.peer_id), - Self::AnswerReady(v) => Some(&v.peer_id), - Self::AnswerSendSuccess(v) => Some(&v.peer_id), - Self::FinalizePending(v) => Some(&v.peer_id), - Self::FinalizeError(v) => Some(&v.peer_id), - Self::FinalizeSuccess(v) => Some(&v.peer_id), - Self::Timeout(v) => Some(&v.peer_id), - Self::Error(v) => Some(&v.peer_id), - Self::Success(v) => Some(&v.peer_id), - Self::Libp2pReceived(v) => Some(&v.peer_id), + Self::Init { opts, .. } => Some(&opts.peer_id), + Self::AnswerSdpCreatePending { peer_id } + | Self::AnswerSdpCreateError { peer_id, .. } + | Self::AnswerSdpCreateSuccess { peer_id, .. } + | Self::AnswerReady { peer_id, .. } + | Self::AnswerSendSuccess { peer_id } + | Self::FinalizePending { peer_id } + | Self::FinalizeError { peer_id, .. } + | Self::FinalizeSuccess { peer_id } + | Self::Timeout { peer_id } + | Self::Error { peer_id, .. } + | Self::Success { peer_id } + | Self::Libp2pReceived { peer_id } => Some(peer_id), } } } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingInitAction { - pub opts: P2pConnectionIncomingInitOpts, - pub rpc_id: Option, -} - -impl redux::EnablingCondition for P2pConnectionIncomingInitAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .incoming_accept(self.opts.peer_id, &self.opts.offer) - .is_ok() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingAnswerSdpCreatePendingAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSdpCreatePendingAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::Init { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingAnswerSdpCreateErrorAction { - pub peer_id: PeerId, - pub error: String, -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSdpCreateErrorAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::AnswerSdpCreatePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingAnswerSdpCreateSuccessAction { - pub peer_id: PeerId, - pub sdp: String, -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSdpCreateSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::AnswerSdpCreatePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingAnswerReadyAction { - pub peer_id: PeerId, - pub answer: webrtc::Answer, -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerReadyAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::AnswerSdpCreateSuccess { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingAnswerSendSuccessAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionIncomingAnswerSendSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::AnswerReady { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingFinalizePendingAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionIncomingFinalizePendingAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::AnswerSendSuccess { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingFinalizeErrorAction { - pub peer_id: PeerId, - pub error: String, -} - -impl redux::EnablingCondition for P2pConnectionIncomingFinalizeErrorAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::FinalizePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingFinalizeSuccessAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionIncomingFinalizeSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::FinalizePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingTimeoutAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionIncomingTimeoutAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .and_then(|peer| peer.status.as_connecting()?.as_incoming()) - .is_some() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingErrorAction { - pub peer_id: PeerId, - pub error: P2pConnectionIncomingError, -} - -impl redux::EnablingCondition for P2pConnectionIncomingErrorAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming(s)) => match &self.error { - P2pConnectionIncomingError::SdpCreateError(_) => { - matches!(s, P2pConnectionIncomingState::AnswerSdpCreatePending { .. }) - } - P2pConnectionIncomingError::FinalizeError(_) => { - matches!(s, P2pConnectionIncomingState::FinalizePending { .. }) - } - P2pConnectionIncomingError::Timeout => true, - }, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingSuccessAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionIncomingSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Incoming( - P2pConnectionIncomingState::FinalizeSuccess { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionIncomingLibp2pReceivedAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionIncomingLibp2pReceivedAction { +impl redux::EnablingCondition for P2pConnectionIncomingAction { fn is_enabled(&self, state: &P2pState) -> bool { - state.peers.get(&self.peer_id).map_or(true, |peer| { - matches!(&peer.status, P2pPeerStatus::Disconnected { .. }) - }) + match self { + P2pConnectionIncomingAction::Init { opts, .. } => { + state.incoming_accept(opts.peer_id, &opts.offer).is_ok() + } + P2pConnectionIncomingAction::AnswerSdpCreatePending { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::Init { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::AnswerSdpCreateError { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::AnswerSdpCreatePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::AnswerSdpCreateSuccess { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::AnswerSdpCreatePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::AnswerReady { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::AnswerSdpCreateSuccess { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::AnswerSendSuccess { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::AnswerReady { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::FinalizePending { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::AnswerSendSuccess { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::FinalizeError { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::FinalizePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::FinalizeSuccess { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::FinalizePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionIncomingAction::Timeout { peer_id } => state + .peers + .get(peer_id) + .and_then(|peer| peer.status.as_connecting()?.as_incoming()) + .is_some(), + P2pConnectionIncomingAction::Error { peer_id, error } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming(s)) => match error { + P2pConnectionIncomingError::SdpCreateError(_) => { + matches!(s, P2pConnectionIncomingState::AnswerSdpCreatePending { .. }) + } + P2pConnectionIncomingError::FinalizeError(_) => { + matches!(s, P2pConnectionIncomingState::FinalizePending { .. }) + } + P2pConnectionIncomingError::Timeout => true, + }, + _ => false, + }), + P2pConnectionIncomingAction::Success { peer_id } => { + state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Incoming( + P2pConnectionIncomingState::FinalizeSuccess { .. }, + )) => true, + _ => false, + }) + } + + P2pConnectionIncomingAction::Libp2pReceived { peer_id } => { + state.peers.get(&peer_id).map_or(true, |peer| { + matches!(&peer.status, P2pPeerStatus::Disconnected { .. }) + }) + } + } } } -// --- From for Action impls. use crate::{ connection::{P2pConnectionAction, P2pConnectionState}, P2pPeerStatus, @@ -297,80 +204,8 @@ use crate::{ use super::{P2pConnectionIncomingError, P2pConnectionIncomingState}; -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingInitAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingAnswerSdpCreatePendingAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingAnswerSdpCreateErrorAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingAnswerSdpCreateSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingAnswerReadyAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingAnswerSendSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingFinalizePendingAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingFinalizeErrorAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingFinalizeSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingTimeoutAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingErrorAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionIncomingLibp2pReceivedAction) -> Self { - Self::Connection(P2pConnectionAction::Incoming(a.into())) +impl From for P2pAction { + fn from(a: P2pConnectionIncomingAction) -> Self { + Self::Connection(P2pConnectionAction::Incoming(a)) } } diff --git a/p2p/src/connection/incoming/p2p_connection_incoming_effects.rs b/p2p/src/connection/incoming/p2p_connection_incoming_effects.rs index bf1593558..2014541bc 100644 --- a/p2p/src/connection/incoming/p2p_connection_incoming_effects.rs +++ b/p2p/src/connection/incoming/p2p_connection_incoming_effects.rs @@ -1,164 +1,83 @@ use redux::ActionMeta; -use crate::disconnection::{P2pDisconnectionInitAction, P2pDisconnectionReason}; -use crate::peer::P2pPeerReadyAction; +use crate::disconnection::{P2pDisconnectionAction, P2pDisconnectionReason}; +use crate::peer::P2pPeerAction; use crate::{connection::P2pConnectionService, webrtc}; -use super::{ - P2pConnectionIncomingAnswerReadyAction, P2pConnectionIncomingAnswerSdpCreateErrorAction, - P2pConnectionIncomingAnswerSdpCreatePendingAction, - P2pConnectionIncomingAnswerSdpCreateSuccessAction, - P2pConnectionIncomingAnswerSendSuccessAction, P2pConnectionIncomingError, - P2pConnectionIncomingErrorAction, P2pConnectionIncomingFinalizeErrorAction, - P2pConnectionIncomingFinalizePendingAction, P2pConnectionIncomingFinalizeSuccessAction, - P2pConnectionIncomingInitAction, P2pConnectionIncomingLibp2pReceivedAction, - P2pConnectionIncomingSuccessAction, P2pConnectionIncomingTimeoutAction, -}; +use super::{P2pConnectionIncomingAction, P2pConnectionIncomingError}; -impl P2pConnectionIncomingInitAction { +impl P2pConnectionIncomingAction { pub fn effects(self, _: &ActionMeta, store: &mut Store) where Store: crate::P2pStore, Store::Service: P2pConnectionService, - P2pConnectionIncomingAnswerSdpCreatePendingAction: redux::EnablingCondition, + P2pDisconnectionAction: redux::EnablingCondition, + P2pPeerAction: redux::EnablingCondition, + P2pConnectionIncomingAction: redux::EnablingCondition, { - let peer_id = self.opts.peer_id; - store.service().incoming_init(peer_id, self.opts.offer); - store.dispatch(P2pConnectionIncomingAnswerSdpCreatePendingAction { peer_id }); - } -} - -impl P2pConnectionIncomingAnswerSdpCreateErrorAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionIncomingErrorAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionIncomingErrorAction { - peer_id: self.peer_id, - error: P2pConnectionIncomingError::SdpCreateError(self.error), - }); - } -} - -impl P2pConnectionIncomingAnswerSdpCreateSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionIncomingAnswerReadyAction: redux::EnablingCondition, - { - let answer = webrtc::Answer { - sdp: self.sdp, - identity_pub_key: store.state().config.identity_pub_key.clone(), - target_peer_id: self.peer_id, - }; - store.dispatch(P2pConnectionIncomingAnswerReadyAction { - peer_id: self.peer_id, - answer, - }); - } -} - -impl P2pConnectionIncomingAnswerReadyAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - { - store.service().set_answer(self.peer_id, self.answer); - } -} - -impl P2pConnectionIncomingAnswerSendSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionIncomingFinalizePendingAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionIncomingFinalizePendingAction { - peer_id: self.peer_id, - }); - } -} - -impl P2pConnectionIncomingFinalizeErrorAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionIncomingErrorAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionIncomingErrorAction { - peer_id: self.peer_id, - error: P2pConnectionIncomingError::FinalizeError(self.error), - }); - } -} - -impl P2pConnectionIncomingFinalizeSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionIncomingSuccessAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionIncomingSuccessAction { - peer_id: self.peer_id, - }); - } -} - -impl P2pConnectionIncomingTimeoutAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionIncomingErrorAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionIncomingErrorAction { - peer_id: self.peer_id, - error: P2pConnectionIncomingError::Timeout, - }); - } -} - -impl P2pConnectionIncomingSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pPeerReadyAction: redux::EnablingCondition, - { - let peer_id = self.peer_id; - store.dispatch(P2pPeerReadyAction { - peer_id, - incoming: true, - }); - } -} - -impl P2pConnectionIncomingLibp2pReceivedAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pPeerReadyAction: redux::EnablingCondition, - P2pDisconnectionInitAction: redux::EnablingCondition, - { - let peer_id = self.peer_id; - if let Err(err) = store.state().libp2p_incoming_accept(peer_id) { - store.dispatch(P2pDisconnectionInitAction { - peer_id, - reason: P2pDisconnectionReason::Libp2pIncomingRejected(err), - }); - } else { - store.dispatch(P2pPeerReadyAction { - peer_id, - incoming: true, - }); + match self { + P2pConnectionIncomingAction::Init { opts, .. } => { + let peer_id = opts.peer_id; + store.service().incoming_init(peer_id, opts.offer); + store.dispatch(P2pConnectionIncomingAction::AnswerSdpCreatePending { peer_id }); + } + P2pConnectionIncomingAction::AnswerSdpCreateError { peer_id, error } => { + store.dispatch(P2pConnectionIncomingAction::Error { + peer_id, + error: P2pConnectionIncomingError::SdpCreateError(error), + }); + } + P2pConnectionIncomingAction::AnswerSdpCreateSuccess { peer_id, sdp } => { + let answer = webrtc::Answer { + sdp, + identity_pub_key: store.state().config.identity_pub_key.clone(), + target_peer_id: peer_id, + }; + store.dispatch(P2pConnectionIncomingAction::AnswerReady { peer_id, answer }); + } + P2pConnectionIncomingAction::AnswerReady { peer_id, answer } => { + store.service().set_answer(peer_id, answer); + } + P2pConnectionIncomingAction::AnswerSendSuccess { peer_id } => { + store.dispatch(P2pConnectionIncomingAction::FinalizePending { peer_id }); + } + P2pConnectionIncomingAction::FinalizeError { peer_id, error } => { + store.dispatch(P2pConnectionIncomingAction::Error { + peer_id, + error: P2pConnectionIncomingError::FinalizeError(error), + }); + } + P2pConnectionIncomingAction::FinalizeSuccess { peer_id } => { + store.dispatch(P2pConnectionIncomingAction::Success { peer_id }); + } + P2pConnectionIncomingAction::Timeout { peer_id } => { + store.dispatch(P2pConnectionIncomingAction::Error { + peer_id, + error: P2pConnectionIncomingError::Timeout, + }); + } + P2pConnectionIncomingAction::Success { peer_id } => { + store.dispatch(P2pPeerAction::Ready { + peer_id, + incoming: true, + }); + } + P2pConnectionIncomingAction::Libp2pReceived { peer_id } => { + if let Err(err) = store.state().libp2p_incoming_accept(peer_id) { + store.dispatch(P2pDisconnectionAction::Init { + peer_id, + reason: P2pDisconnectionReason::Libp2pIncomingRejected(err), + }); + } else { + store.dispatch(P2pPeerAction::Ready { + peer_id, + incoming: true, + }); + } + } + P2pConnectionIncomingAction::AnswerSdpCreatePending { .. } => {} + P2pConnectionIncomingAction::FinalizePending { .. } => {} + P2pConnectionIncomingAction::Error { .. } => {} } } } diff --git a/p2p/src/connection/incoming/p2p_connection_incoming_reducer.rs b/p2p/src/connection/incoming/p2p_connection_incoming_reducer.rs index dcdfc264a..411e6edd2 100644 --- a/p2p/src/connection/incoming/p2p_connection_incoming_reducer.rs +++ b/p2p/src/connection/incoming/p2p_connection_incoming_reducer.rs @@ -6,15 +6,15 @@ impl P2pConnectionIncomingState { pub fn reducer(&mut self, action: P2pConnectionIncomingActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - P2pConnectionIncomingAction::Init(content) => { + P2pConnectionIncomingAction::Init { opts, rpc_id } => { *self = Self::Init { time: meta.time(), - signaling: content.opts.signaling.clone(), - offer: content.opts.offer.clone(), - rpc_id: content.rpc_id, + signaling: opts.signaling.clone(), + offer: opts.offer.clone(), + rpc_id: *rpc_id, }; } - P2pConnectionIncomingAction::AnswerSdpCreatePending(_) => { + P2pConnectionIncomingAction::AnswerSdpCreatePending { .. } => { if let Self::Init { signaling, offer, @@ -30,8 +30,8 @@ impl P2pConnectionIncomingState { }; } } - P2pConnectionIncomingAction::AnswerSdpCreateError(_) => {} - P2pConnectionIncomingAction::AnswerSdpCreateSuccess(action) => { + P2pConnectionIncomingAction::AnswerSdpCreateError { .. } => {} + P2pConnectionIncomingAction::AnswerSdpCreateSuccess { sdp, .. } => { if let Self::AnswerSdpCreatePending { signaling, offer, @@ -43,12 +43,12 @@ impl P2pConnectionIncomingState { time: meta.time(), signaling: signaling.clone(), offer: offer.clone(), - sdp: action.sdp.clone(), + sdp: sdp.clone(), rpc_id: rpc_id.take(), }; } } - P2pConnectionIncomingAction::AnswerReady(action) => { + P2pConnectionIncomingAction::AnswerReady { answer, .. } => { if let Self::AnswerSdpCreateSuccess { signaling, offer, @@ -60,12 +60,12 @@ impl P2pConnectionIncomingState { time: meta.time(), signaling: signaling.clone(), offer: offer.clone(), - answer: action.answer.clone(), + answer: answer.clone(), rpc_id: rpc_id.take(), }; } } - P2pConnectionIncomingAction::AnswerSendSuccess(_) => { + P2pConnectionIncomingAction::AnswerSendSuccess { .. } => { if let Self::AnswerReady { signaling, offer, @@ -83,7 +83,7 @@ impl P2pConnectionIncomingState { }; } } - P2pConnectionIncomingAction::FinalizePending(_) => { + P2pConnectionIncomingAction::FinalizePending { .. } => { if let Self::AnswerSendSuccess { signaling, offer, @@ -101,8 +101,8 @@ impl P2pConnectionIncomingState { }; } } - P2pConnectionIncomingAction::FinalizeError(_) => {} - P2pConnectionIncomingAction::FinalizeSuccess(_) => { + P2pConnectionIncomingAction::FinalizeError { .. } => {} + P2pConnectionIncomingAction::FinalizeSuccess { .. } => { if let Self::FinalizePending { signaling, offer, @@ -120,16 +120,16 @@ impl P2pConnectionIncomingState { }; } } - P2pConnectionIncomingAction::Timeout(_) => {} - P2pConnectionIncomingAction::Error(action) => { + P2pConnectionIncomingAction::Timeout { .. } => {} + P2pConnectionIncomingAction::Error { error, .. } => { let rpc_id = self.rpc_id(); *self = Self::Error { time: meta.time(), - error: action.error.clone(), + error: error.clone(), rpc_id, }; } - P2pConnectionIncomingAction::Success(_) => { + P2pConnectionIncomingAction::Success { .. } => { if let Self::FinalizeSuccess { signaling, offer, @@ -147,7 +147,7 @@ impl P2pConnectionIncomingState { }; } } - P2pConnectionIncomingAction::Libp2pReceived(_) => { + P2pConnectionIncomingAction::Libp2pReceived { .. } => { // handled in the parent reducer. } } diff --git a/p2p/src/connection/outgoing/mod.rs b/p2p/src/connection/outgoing/mod.rs index ec18a10d7..2536da907 100644 --- a/p2p/src/connection/outgoing/mod.rs +++ b/p2p/src/connection/outgoing/mod.rs @@ -5,10 +5,10 @@ mod p2p_connection_outgoing_actions; pub use p2p_connection_outgoing_actions::*; mod p2p_connection_outgoing_reducer; -pub use p2p_connection_outgoing_reducer::*; + mod p2p_connection_outgoing_effects; -pub use p2p_connection_outgoing_effects::*; + use std::{fmt, str::FromStr}; diff --git a/p2p/src/connection/outgoing/p2p_connection_outgoing_actions.rs b/p2p/src/connection/outgoing/p2p_connection_outgoing_actions.rs index 0b16d5add..01fe59a49 100644 --- a/p2p/src/connection/outgoing/p2p_connection_outgoing_actions.rs +++ b/p2p/src/connection/outgoing/p2p_connection_outgoing_actions.rs @@ -11,389 +11,264 @@ use super::{P2pConnectionOutgoingError, P2pConnectionOutgoingInitOpts}; pub type P2pConnectionOutgoingActionWithMetaRef<'a> = redux::ActionWithMeta<&'a P2pConnectionOutgoingAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub enum P2pConnectionOutgoingAction { - RandomInit(P2pConnectionOutgoingRandomInitAction), - Init(P2pConnectionOutgoingInitAction), - Reconnect(P2pConnectionOutgoingReconnectAction), - OfferSdpCreatePending(P2pConnectionOutgoingOfferSdpCreatePendingAction), - OfferSdpCreateError(P2pConnectionOutgoingOfferSdpCreateErrorAction), - OfferSdpCreateSuccess(P2pConnectionOutgoingOfferSdpCreateSuccessAction), - OfferReady(P2pConnectionOutgoingOfferReadyAction), - OfferSendSuccess(P2pConnectionOutgoingOfferSendSuccessAction), - AnswerRecvPending(P2pConnectionOutgoingAnswerRecvPendingAction), - AnswerRecvError(P2pConnectionOutgoingAnswerRecvErrorAction), - AnswerRecvSuccess(P2pConnectionOutgoingAnswerRecvSuccessAction), - FinalizePending(P2pConnectionOutgoingFinalizePendingAction), - FinalizeError(P2pConnectionOutgoingFinalizeErrorAction), - FinalizeSuccess(P2pConnectionOutgoingFinalizeSuccessAction), - Timeout(P2pConnectionOutgoingTimeoutAction), - Error(P2pConnectionOutgoingErrorAction), - Success(P2pConnectionOutgoingSuccessAction), + RandomInit, + Init { + opts: P2pConnectionOutgoingInitOpts, + rpc_id: Option, + }, + Reconnect { + opts: P2pConnectionOutgoingInitOpts, + rpc_id: Option, + }, + OfferSdpCreatePending { + peer_id: PeerId, + }, + OfferSdpCreateError { + peer_id: PeerId, + error: String, + }, + OfferSdpCreateSuccess { + peer_id: PeerId, + sdp: String, + }, + OfferReady { + peer_id: PeerId, + offer: webrtc::Offer, + }, + OfferSendSuccess { + peer_id: PeerId, + }, + AnswerRecvPending { + peer_id: PeerId, + }, + AnswerRecvError { + peer_id: PeerId, + error: P2pConnectionErrorResponse, + }, + AnswerRecvSuccess { + peer_id: PeerId, + answer: webrtc::Answer, + }, + FinalizePending { + peer_id: PeerId, + }, + FinalizeError { + peer_id: PeerId, + error: String, + }, + FinalizeSuccess { + peer_id: PeerId, + }, + Timeout { + peer_id: PeerId, + }, + Error { + peer_id: PeerId, + error: P2pConnectionOutgoingError, + }, + Success { + peer_id: PeerId, + }, } impl P2pConnectionOutgoingAction { pub fn peer_id(&self) -> Option<&PeerId> { match self { - Self::RandomInit(_) => None, - Self::Init(v) => Some(v.opts.peer_id()), - Self::Reconnect(v) => Some(v.opts.peer_id()), - Self::OfferSdpCreatePending(v) => Some(&v.peer_id), - Self::OfferSdpCreateError(v) => Some(&v.peer_id), - Self::OfferSdpCreateSuccess(v) => Some(&v.peer_id), - Self::OfferReady(v) => Some(&v.peer_id), - Self::OfferSendSuccess(v) => Some(&v.peer_id), - Self::AnswerRecvPending(v) => Some(&v.peer_id), - Self::AnswerRecvError(v) => Some(&v.peer_id), - Self::AnswerRecvSuccess(v) => Some(&v.peer_id), - Self::FinalizePending(v) => Some(&v.peer_id), - Self::FinalizeError(v) => Some(&v.peer_id), - Self::FinalizeSuccess(v) => Some(&v.peer_id), - Self::Timeout(v) => Some(&v.peer_id), - Self::Error(v) => Some(&v.peer_id), - Self::Success(v) => Some(&v.peer_id), + Self::RandomInit => None, + Self::Init { opts, .. } | Self::Reconnect { opts, .. } => Some(opts.peer_id()), + Self::OfferSdpCreatePending { peer_id, .. } + | Self::OfferSdpCreateError { peer_id, .. } + | Self::OfferSdpCreateSuccess { peer_id, .. } + | Self::OfferReady { peer_id, .. } + | Self::OfferSendSuccess { peer_id } + | Self::AnswerRecvPending { peer_id } + | Self::AnswerRecvError { peer_id, .. } + | Self::AnswerRecvSuccess { peer_id, .. } + | Self::FinalizePending { peer_id } + | Self::FinalizeError { peer_id, .. } + | Self::FinalizeSuccess { peer_id } + | Self::Timeout { peer_id } + | Self::Error { peer_id, .. } + | Self::Success { peer_id } => Some(peer_id), } } } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingRandomInitAction {} - -impl redux::EnablingCondition for P2pConnectionOutgoingRandomInitAction { - fn is_enabled(&self, state: &P2pState) -> bool { - !state.already_has_min_peers() && !state.initial_unused_peers().is_empty() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingInitAction { - pub opts: P2pConnectionOutgoingInitOpts, - pub rpc_id: Option, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingInitAction { +impl redux::EnablingCondition for P2pConnectionOutgoingAction { fn is_enabled(&self, state: &P2pState) -> bool { - !state.already_has_min_peers() && !state.peers.contains_key(self.opts.peer_id()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingReconnectAction { - pub opts: P2pConnectionOutgoingInitOpts, - pub rpc_id: Option, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingReconnectAction { - fn is_enabled(&self, state: &P2pState) -> bool { - if state.already_has_min_peers() { - return false; - } - - state - .peers - .iter() - .filter_map(|(id, p)| match &p.status { - P2pPeerStatus::Connecting(s) => match s { - P2pConnectionState::Outgoing(P2pConnectionOutgoingState::Error { - time, - .. - }) => Some((*time, id, &p.dial_opts)), - P2pConnectionState::Incoming(P2pConnectionIncomingState::Error { - time, - .. - }) => Some((*time, id, &p.dial_opts)), - _ => None, - }, - P2pPeerStatus::Disconnected { time } => Some((*time, id, &p.dial_opts)), - P2pPeerStatus::Ready(_) => None, - }) - .min_by_key(|(time, ..)| *time) - .filter(|(_, id, _)| *id == self.opts.peer_id()) - .filter(|(.., opts)| opts.as_ref().map_or(true, |opts| opts == &self.opts)) - .is_some() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingOfferSdpCreatePendingAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSdpCreatePendingAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::Init { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingOfferSdpCreateErrorAction { - pub peer_id: PeerId, - pub error: String, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSdpCreateErrorAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::OfferSdpCreatePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingOfferSdpCreateSuccessAction { - pub peer_id: PeerId, - pub sdp: String, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSdpCreateSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::OfferSdpCreatePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingOfferReadyAction { - pub peer_id: PeerId, - pub offer: webrtc::Offer, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferReadyAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::OfferSdpCreateSuccess { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingOfferSendSuccessAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingOfferSendSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::OfferReady { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingAnswerRecvPendingAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingAnswerRecvPendingAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::OfferSendSuccess { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingAnswerRecvErrorAction { - pub peer_id: PeerId, - pub error: P2pConnectionErrorResponse, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingAnswerRecvErrorAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::AnswerRecvPending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingAnswerRecvSuccessAction { - pub peer_id: PeerId, - pub answer: webrtc::Answer, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingAnswerRecvSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::AnswerRecvPending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingFinalizePendingAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingFinalizePendingAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing(v)) => match v { - P2pConnectionOutgoingState::Init { opts, .. } => opts.is_libp2p(), - P2pConnectionOutgoingState::AnswerRecvSuccess { .. } => true, + match self { + P2pConnectionOutgoingAction::RandomInit => { + !state.already_has_min_peers() && !state.initial_unused_peers().is_empty() + } + P2pConnectionOutgoingAction::Init { opts, .. } => { + !state.already_has_min_peers() && !state.peers.contains_key(opts.peer_id()) + } + P2pConnectionOutgoingAction::Reconnect { opts, .. } => { + if state.already_has_min_peers() { + return false; + } + state + .peers + .iter() + .filter_map(|(id, p)| match &p.status { + P2pPeerStatus::Connecting(s) => { + match s { + P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::Error { time, .. }, + ) + | P2pConnectionState::Incoming( + P2pConnectionIncomingState::Error { time, .. }, + ) => Some((*time, id, &p.dial_opts)), + _ => None, + } + } + P2pPeerStatus::Disconnected { time } => Some((*time, id, &p.dial_opts)), + _ => None, + }) + .min_by_key(|(time, ..)| *time) + .filter(|(_, id, _)| *id == opts.peer_id()) + .filter(|(.., peer_opts)| peer_opts.as_ref().map_or(true, |o| o == opts)) + .is_some() + } + P2pConnectionOutgoingAction::OfferSdpCreatePending { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::Init { .. }, + )) => true, _ => false, - }, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingFinalizeErrorAction { - pub peer_id: PeerId, - pub error: String, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingFinalizeErrorAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::FinalizePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingFinalizeSuccessAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingFinalizeSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::FinalizePending { .. }, - )) => true, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingTimeoutAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingTimeoutAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .and_then(|peer| peer.status.as_connecting()?.as_outgoing()) - .is_some() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingErrorAction { - pub peer_id: PeerId, - pub error: P2pConnectionOutgoingError, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingErrorAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing(s)) => match &self.error { - P2pConnectionOutgoingError::SdpCreateError(_) => { - matches!(s, P2pConnectionOutgoingState::OfferSdpCreatePending { .. }) - } - P2pConnectionOutgoingError::Rejected(_) => { - matches!(s, P2pConnectionOutgoingState::AnswerRecvPending { .. }) - } - P2pConnectionOutgoingError::RemoteInternalError => { - matches!(s, P2pConnectionOutgoingState::AnswerRecvPending { .. }) - } - P2pConnectionOutgoingError::FinalizeError(_) => { - matches!(s, P2pConnectionOutgoingState::FinalizePending { .. }) - } - P2pConnectionOutgoingError::Timeout => true, - }, - _ => false, - }) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pConnectionOutgoingSuccessAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pConnectionOutgoingSuccessAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::FinalizeSuccess { .. }, - )) => true, - _ => false, - }) + }), + P2pConnectionOutgoingAction::OfferSdpCreateError { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::OfferSdpCreatePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::OfferSdpCreateSuccess { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::OfferSdpCreatePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::OfferReady { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::OfferSdpCreateSuccess { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::OfferSendSuccess { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::OfferReady { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::AnswerRecvPending { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::OfferSendSuccess { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::AnswerRecvError { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::AnswerRecvPending { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::AnswerRecvSuccess { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::AnswerRecvPending { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::FinalizePending { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing(v)) => match v { + P2pConnectionOutgoingState::Init { opts, .. } => opts.is_libp2p(), + P2pConnectionOutgoingState::AnswerRecvSuccess { .. } => true, + _ => false, + }, + _ => false, + }), + P2pConnectionOutgoingAction::FinalizeError { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::FinalizePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::FinalizeSuccess { peer_id } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::FinalizePending { .. }, + )) => true, + _ => false, + }), + P2pConnectionOutgoingAction::Timeout { peer_id } => state + .peers + .get(peer_id) + .and_then(|peer| peer.status.as_connecting()?.as_outgoing()) + .is_some(), + P2pConnectionOutgoingAction::Error { peer_id, error } => state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing(s)) => match error { + P2pConnectionOutgoingError::SdpCreateError(_) => { + matches!(s, P2pConnectionOutgoingState::OfferSdpCreatePending { .. }) + } + P2pConnectionOutgoingError::Rejected(_) + | P2pConnectionOutgoingError::RemoteInternalError => { + matches!(s, P2pConnectionOutgoingState::AnswerRecvPending { .. }) + } + P2pConnectionOutgoingError::FinalizeError(_) => { + matches!(s, P2pConnectionOutgoingState::FinalizePending { .. }) + } + P2pConnectionOutgoingError::Timeout => true, + }, + _ => false, + }), + P2pConnectionOutgoingAction::Success { peer_id } => { + state + .peers + .get(peer_id) + .map_or(false, |peer| match &peer.status { + P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::FinalizeSuccess { .. }, + )) => true, + _ => false, + }) + } + } } } @@ -405,104 +280,8 @@ use crate::{ use super::P2pConnectionOutgoingState; -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingRandomInitAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingInitAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingReconnectAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingOfferSdpCreatePendingAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingOfferSdpCreateErrorAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingOfferSdpCreateSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingOfferReadyAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingOfferSendSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingAnswerRecvPendingAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingAnswerRecvErrorAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingAnswerRecvSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingFinalizePendingAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingFinalizeErrorAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingFinalizeSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingTimeoutAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingErrorAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) - } -} - -impl From for crate::P2pAction { - fn from(a: P2pConnectionOutgoingSuccessAction) -> Self { - Self::Connection(P2pConnectionAction::Outgoing(a.into())) +impl From for crate::P2pAction { + fn from(a: P2pConnectionOutgoingAction) -> Self { + Self::Connection(P2pConnectionAction::Outgoing(a)) } } diff --git a/p2p/src/connection/outgoing/p2p_connection_outgoing_effects.rs b/p2p/src/connection/outgoing/p2p_connection_outgoing_effects.rs index 8273c933f..d0870ee64 100644 --- a/p2p/src/connection/outgoing/p2p_connection_outgoing_effects.rs +++ b/p2p/src/connection/outgoing/p2p_connection_outgoing_effects.rs @@ -1,248 +1,134 @@ use redux::ActionMeta; use crate::connection::{P2pConnectionErrorResponse, P2pConnectionState}; -use crate::peer::P2pPeerReadyAction; +use crate::peer::P2pPeerAction; use crate::webrtc::Host; use crate::P2pPeerStatus; use crate::{connection::P2pConnectionService, webrtc}; use super::{ - P2pConnectionOutgoingAnswerRecvErrorAction, P2pConnectionOutgoingAnswerRecvPendingAction, - P2pConnectionOutgoingAnswerRecvSuccessAction, P2pConnectionOutgoingError, - P2pConnectionOutgoingErrorAction, P2pConnectionOutgoingFinalizeErrorAction, - P2pConnectionOutgoingFinalizePendingAction, P2pConnectionOutgoingFinalizeSuccessAction, - P2pConnectionOutgoingInitAction, P2pConnectionOutgoingInitOpts, - P2pConnectionOutgoingOfferReadyAction, P2pConnectionOutgoingOfferSdpCreateErrorAction, - P2pConnectionOutgoingOfferSdpCreatePendingAction, - P2pConnectionOutgoingOfferSdpCreateSuccessAction, P2pConnectionOutgoingOfferSendSuccessAction, - P2pConnectionOutgoingRandomInitAction, P2pConnectionOutgoingReconnectAction, - P2pConnectionOutgoingState, P2pConnectionOutgoingSuccessAction, - P2pConnectionOutgoingTimeoutAction, + P2pConnectionOutgoingAction, P2pConnectionOutgoingError, P2pConnectionOutgoingInitOpts, + P2pConnectionOutgoingState, }; -impl P2pConnectionOutgoingRandomInitAction { +impl P2pConnectionOutgoingAction { pub fn effects(self, _: &ActionMeta, store: &mut Store) where Store: crate::P2pStore, Store::Service: P2pConnectionService, - P2pConnectionOutgoingInitAction: redux::EnablingCondition, + Self: redux::EnablingCondition, + P2pPeerAction: redux::EnablingCondition, { - let peers = store.state().initial_unused_peers(); - let picked_peer = store.service().random_pick(&peers); - store.dispatch(P2pConnectionOutgoingInitAction { - opts: picked_peer, - rpc_id: None, - }); - } -} - -impl P2pConnectionOutgoingInitAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingOfferSdpCreatePendingAction: redux::EnablingCondition, - P2pConnectionOutgoingFinalizePendingAction: redux::EnablingCondition, - { - let peer_id = *self.opts.peer_id(); - store.service().outgoing_init(self.opts); - if !store.dispatch(P2pConnectionOutgoingFinalizePendingAction { peer_id }) { - store.dispatch(P2pConnectionOutgoingOfferSdpCreatePendingAction { peer_id }); - } - } -} - -impl P2pConnectionOutgoingReconnectAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingOfferSdpCreatePendingAction: redux::EnablingCondition, - P2pConnectionOutgoingFinalizePendingAction: redux::EnablingCondition, - { - let peer_id = *self.opts.peer_id(); - store.service().outgoing_init(self.opts); - // for libp2p - if !store.dispatch(P2pConnectionOutgoingFinalizePendingAction { peer_id }) { - store.dispatch(P2pConnectionOutgoingOfferSdpCreatePendingAction { peer_id }); - } - } -} - -impl P2pConnectionOutgoingOfferSdpCreateErrorAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingErrorAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionOutgoingErrorAction { - peer_id: self.peer_id, - error: P2pConnectionOutgoingError::SdpCreateError(self.error), - }); - } -} - -impl P2pConnectionOutgoingOfferSdpCreateSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingOfferReadyAction: redux::EnablingCondition, - { - let offer = webrtc::Offer { - sdp: self.sdp, - identity_pub_key: store.state().config.identity_pub_key.clone(), - target_peer_id: self.peer_id, - // TODO(vlad9486): put real address - host: Host::Ipv4([127, 0, 0, 1].into()), - listen_port: store.state().config.listen_port, - }; - store.dispatch(P2pConnectionOutgoingOfferReadyAction { - peer_id: self.peer_id, - offer, - }); - } -} - -impl P2pConnectionOutgoingOfferReadyAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingOfferSendSuccessAction: redux::EnablingCondition, - { - let (state, service) = store.state_and_service(); - let Some(peer) = state.peers.get(&self.peer_id) else { - return; - }; - let P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( - P2pConnectionOutgoingState::OfferReady { opts, .. }, - )) = &peer.status - else { - return; - }; - let signaling_method = match opts { - P2pConnectionOutgoingInitOpts::WebRTC { signaling, .. } => signaling, - #[allow(unreachable_patterns)] - _ => return, - }; - match signaling_method { - webrtc::SignalingMethod::Http(_) | webrtc::SignalingMethod::Https(_) => { - let Some(url) = signaling_method.http_url() else { + match self { + P2pConnectionOutgoingAction::RandomInit => { + let peers = store.state().initial_unused_peers(); + let picked_peer = store.service().random_pick(&peers); + store.dispatch(P2pConnectionOutgoingAction::Init { + opts: picked_peer, + rpc_id: None, + }); + } + P2pConnectionOutgoingAction::Init { opts, .. } => { + let peer_id = *opts.peer_id(); + store.service().outgoing_init(opts.clone()); + // for libp2p + if !store.dispatch(P2pConnectionOutgoingAction::FinalizePending { peer_id }) { + store.dispatch(P2pConnectionOutgoingAction::OfferSdpCreatePending { peer_id }); + } + } + P2pConnectionOutgoingAction::Reconnect { opts, .. } => { + let peer_id = *opts.peer_id(); + store.service().outgoing_init(opts); + // for libp2p + if !store.dispatch(P2pConnectionOutgoingAction::FinalizePending { peer_id }) { + store.dispatch(P2pConnectionOutgoingAction::OfferSdpCreatePending { peer_id }); + } + } + P2pConnectionOutgoingAction::OfferSdpCreateError { peer_id, error } => { + store.dispatch(P2pConnectionOutgoingAction::Error { + peer_id, + error: P2pConnectionOutgoingError::SdpCreateError(error), + }); + } + P2pConnectionOutgoingAction::OfferSdpCreateSuccess { peer_id, sdp } => { + let offer = webrtc::Offer { + sdp, + identity_pub_key: store.state().config.identity_pub_key.clone(), + target_peer_id: peer_id, + // TODO(vlad9486): put real address + host: Host::Ipv4([127, 0, 0, 1].into()), + listen_port: store.state().config.listen_port, + }; + store.dispatch(P2pConnectionOutgoingAction::OfferReady { peer_id, offer }); + } + P2pConnectionOutgoingAction::OfferReady { peer_id, offer } => { + let (state, service) = store.state_and_service(); + let Some(peer) = state.peers.get(&peer_id) else { + return; + }; + let P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( + P2pConnectionOutgoingState::OfferReady { opts, .. }, + )) = &peer.status + else { return; }; - service.http_signaling_request(url, self.offer); + let signaling_method = match opts { + P2pConnectionOutgoingInitOpts::WebRTC { signaling, .. } => signaling, + #[allow(unreachable_patterns)] + _ => return, + }; + match signaling_method { + webrtc::SignalingMethod::Http(_) | webrtc::SignalingMethod::Https(_) => { + let Some(url) = signaling_method.http_url() else { + return; + }; + service.http_signaling_request(url, offer); + } + } + store.dispatch(P2pConnectionOutgoingAction::OfferSendSuccess { peer_id }); + } + P2pConnectionOutgoingAction::OfferSendSuccess { peer_id } => { + store.dispatch(P2pConnectionOutgoingAction::AnswerRecvPending { peer_id }); + } + P2pConnectionOutgoingAction::AnswerRecvError { peer_id, error } => { + store.dispatch(P2pConnectionOutgoingAction::Error { + peer_id, + error: match error { + P2pConnectionErrorResponse::Rejected(reason) => { + P2pConnectionOutgoingError::Rejected(reason) + } + P2pConnectionErrorResponse::InternalError => { + P2pConnectionOutgoingError::RemoteInternalError + } + }, + }); + } + P2pConnectionOutgoingAction::AnswerRecvSuccess { peer_id, answer } => { + store.service().set_answer(peer_id, answer.clone()); + store.dispatch(P2pConnectionOutgoingAction::FinalizePending { peer_id }); + } + P2pConnectionOutgoingAction::FinalizeError { peer_id, error } => { + store.dispatch(P2pConnectionOutgoingAction::Error { + peer_id, + error: P2pConnectionOutgoingError::FinalizeError(error), + }); + } + P2pConnectionOutgoingAction::FinalizeSuccess { peer_id } => { + store.dispatch(P2pConnectionOutgoingAction::Success { peer_id }); + } + P2pConnectionOutgoingAction::Timeout { peer_id } => { + store.dispatch(P2pConnectionOutgoingAction::Error { + peer_id, + error: P2pConnectionOutgoingError::Timeout, + }); } + P2pConnectionOutgoingAction::Success { peer_id } => { + store.dispatch(P2pPeerAction::Ready { + peer_id, + incoming: false, + }); + } + _ => {} } - store.dispatch(P2pConnectionOutgoingOfferSendSuccessAction { - peer_id: self.peer_id, - }); - } -} - -impl P2pConnectionOutgoingOfferSendSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingAnswerRecvPendingAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionOutgoingAnswerRecvPendingAction { - peer_id: self.peer_id, - }); - } -} - -impl P2pConnectionOutgoingAnswerRecvErrorAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingErrorAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionOutgoingErrorAction { - peer_id: self.peer_id, - error: match self.error { - P2pConnectionErrorResponse::Rejected(reason) => { - P2pConnectionOutgoingError::Rejected(reason) - } - P2pConnectionErrorResponse::InternalError => { - P2pConnectionOutgoingError::RemoteInternalError - } - }, - }); - } -} - -impl P2pConnectionOutgoingAnswerRecvSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingFinalizePendingAction: redux::EnablingCondition, - { - store - .service() - .set_answer(self.peer_id, self.answer.clone()); - store.dispatch(P2pConnectionOutgoingFinalizePendingAction { - peer_id: self.peer_id, - }); - } -} - -impl P2pConnectionOutgoingFinalizeErrorAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingErrorAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionOutgoingErrorAction { - peer_id: self.peer_id, - error: P2pConnectionOutgoingError::FinalizeError(self.error), - }); - } -} - -impl P2pConnectionOutgoingFinalizeSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingSuccessAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionOutgoingSuccessAction { - peer_id: self.peer_id, - }); - } -} - -impl P2pConnectionOutgoingTimeoutAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pConnectionOutgoingErrorAction: redux::EnablingCondition, - { - store.dispatch(P2pConnectionOutgoingErrorAction { - peer_id: self.peer_id, - error: P2pConnectionOutgoingError::Timeout, - }); - } -} - -impl P2pConnectionOutgoingSuccessAction { - pub fn effects(self, _: &ActionMeta, store: &mut Store) - where - Store: crate::P2pStore, - Store::Service: P2pConnectionService, - P2pPeerReadyAction: redux::EnablingCondition, - { - let peer_id = self.peer_id; - store.dispatch(P2pPeerReadyAction { - peer_id, - incoming: false, - }); } } diff --git a/p2p/src/connection/outgoing/p2p_connection_outgoing_reducer.rs b/p2p/src/connection/outgoing/p2p_connection_outgoing_reducer.rs index c19a27610..ad1359805 100644 --- a/p2p/src/connection/outgoing/p2p_connection_outgoing_reducer.rs +++ b/p2p/src/connection/outgoing/p2p_connection_outgoing_reducer.rs @@ -6,22 +6,22 @@ impl P2pConnectionOutgoingState { pub fn reducer(&mut self, action: P2pConnectionOutgoingActionWithMetaRef<'_>) { let (action, meta) = action.split(); match action { - P2pConnectionOutgoingAction::RandomInit(_) => {} - P2pConnectionOutgoingAction::Init(content) => { + P2pConnectionOutgoingAction::RandomInit => {} + P2pConnectionOutgoingAction::Init { opts, rpc_id } => { *self = Self::Init { time: meta.time(), - opts: content.opts.clone(), - rpc_id: content.rpc_id, + opts: opts.clone(), + rpc_id: *rpc_id, }; } - P2pConnectionOutgoingAction::Reconnect(action) => { + P2pConnectionOutgoingAction::Reconnect { opts, rpc_id } => { *self = Self::Init { time: meta.time(), - opts: action.opts.clone(), - rpc_id: action.rpc_id, + opts: opts.clone(), + rpc_id: *rpc_id, }; } - P2pConnectionOutgoingAction::OfferSdpCreatePending(_) => { + P2pConnectionOutgoingAction::OfferSdpCreatePending { .. } => { if let Self::Init { opts, rpc_id, .. } = self { *self = Self::OfferSdpCreatePending { time: meta.time(), @@ -30,28 +30,28 @@ impl P2pConnectionOutgoingState { }; } } - P2pConnectionOutgoingAction::OfferSdpCreateError(_) => {} - P2pConnectionOutgoingAction::OfferSdpCreateSuccess(action) => { + P2pConnectionOutgoingAction::OfferSdpCreateError { .. } => {} + P2pConnectionOutgoingAction::OfferSdpCreateSuccess { sdp, .. } => { if let Self::OfferSdpCreatePending { opts, rpc_id, .. } = self { *self = Self::OfferSdpCreateSuccess { time: meta.time(), opts: opts.clone(), - sdp: action.sdp.clone(), + sdp: sdp.clone(), rpc_id: rpc_id.take(), }; } } - P2pConnectionOutgoingAction::OfferReady(action) => { + P2pConnectionOutgoingAction::OfferReady { offer, .. } => { if let Self::OfferSdpCreateSuccess { opts, rpc_id, .. } = self { *self = Self::OfferReady { time: meta.time(), opts: opts.clone(), - offer: action.offer.clone(), + offer: offer.clone(), rpc_id: rpc_id.take(), }; } } - P2pConnectionOutgoingAction::OfferSendSuccess(_) => { + P2pConnectionOutgoingAction::OfferSendSuccess { .. } => { if let Self::OfferReady { opts, offer, @@ -67,7 +67,7 @@ impl P2pConnectionOutgoingState { }; } } - P2pConnectionOutgoingAction::AnswerRecvPending(_) => { + P2pConnectionOutgoingAction::AnswerRecvPending { .. } => { if let Self::OfferSendSuccess { opts, offer, @@ -83,8 +83,8 @@ impl P2pConnectionOutgoingState { }; } } - P2pConnectionOutgoingAction::AnswerRecvError(_) => {} - P2pConnectionOutgoingAction::AnswerRecvSuccess(action) => { + P2pConnectionOutgoingAction::AnswerRecvError { .. } => {} + P2pConnectionOutgoingAction::AnswerRecvSuccess { answer, .. } => { if let Self::AnswerRecvPending { opts, offer, @@ -96,12 +96,12 @@ impl P2pConnectionOutgoingState { time: meta.time(), opts: opts.clone(), offer: offer.clone(), - answer: action.answer.clone(), + answer: answer.clone(), rpc_id: rpc_id.take(), }; } } - P2pConnectionOutgoingAction::FinalizePending(_) => match self { + P2pConnectionOutgoingAction::FinalizePending { .. } => match self { Self::Init { opts, rpc_id, .. } => { *self = Self::FinalizePending { time: meta.time(), @@ -128,8 +128,8 @@ impl P2pConnectionOutgoingState { } _ => {} }, - P2pConnectionOutgoingAction::FinalizeError(_) => {} - P2pConnectionOutgoingAction::FinalizeSuccess(_) => { + P2pConnectionOutgoingAction::FinalizeError { .. } => {} + P2pConnectionOutgoingAction::FinalizeSuccess { .. } => { if let Self::FinalizePending { opts, offer, @@ -147,16 +147,16 @@ impl P2pConnectionOutgoingState { }; } } - P2pConnectionOutgoingAction::Timeout(_) => {} - P2pConnectionOutgoingAction::Error(action) => { + P2pConnectionOutgoingAction::Timeout { .. } => {} + P2pConnectionOutgoingAction::Error { error, .. } => { let rpc_id = self.rpc_id(); *self = Self::Error { time: meta.time(), - error: action.error.clone(), + error: error.clone(), rpc_id, }; } - P2pConnectionOutgoingAction::Success(_) => { + P2pConnectionOutgoingAction::Success { .. } => { if let Self::FinalizeSuccess { offer, answer, diff --git a/p2p/src/connection/p2p_connection_reducer.rs b/p2p/src/connection/p2p_connection_reducer.rs index 89ad4372a..6ed25ec39 100644 --- a/p2p/src/connection/p2p_connection_reducer.rs +++ b/p2p/src/connection/p2p_connection_reducer.rs @@ -13,12 +13,12 @@ pub fn p2p_connection_reducer( let (action, meta) = action.split(); match action { P2pConnectionAction::Outgoing(action) => { - if let P2pConnectionOutgoingAction::Reconnect(a) = action { + if let P2pConnectionOutgoingAction::Reconnect { opts, rpc_id } = action { state.status = P2pPeerStatus::Connecting(P2pConnectionState::Outgoing( P2pConnectionOutgoingState::Init { time: meta.time(), - opts: a.opts.clone(), - rpc_id: a.rpc_id, + opts: opts.clone(), + rpc_id: *rpc_id, }, )); } @@ -29,16 +29,16 @@ pub fn p2p_connection_reducer( state.reducer(meta.with_action(action)); } P2pConnectionAction::Incoming(action) => { - if let P2pConnectionIncomingAction::Init(a) = action { + if let P2pConnectionIncomingAction::Init { opts, rpc_id } = action { state.status = P2pPeerStatus::Connecting(P2pConnectionState::Incoming( P2pConnectionIncomingState::Init { time: meta.time(), - signaling: a.opts.signaling.clone(), - offer: a.opts.offer.clone(), - rpc_id: a.rpc_id, + signaling: opts.signaling.clone(), + offer: opts.offer.clone(), + rpc_id: *rpc_id, }, )) - } else if let P2pConnectionIncomingAction::Libp2pReceived(_) = action { + } else if let P2pConnectionIncomingAction::Libp2pReceived { .. } = action { state.status = P2pPeerStatus::Connecting(P2pConnectionState::Incoming( P2pConnectionIncomingState::Libp2pReceived { time: meta.time() }, )) diff --git a/p2p/src/disconnection/mod.rs b/p2p/src/disconnection/mod.rs index 0ff5ecec7..b2743d38b 100644 --- a/p2p/src/disconnection/mod.rs +++ b/p2p/src/disconnection/mod.rs @@ -5,7 +5,7 @@ mod p2p_disconnection_actions; pub use p2p_disconnection_actions::*; mod p2p_disconnection_effects; -pub use p2p_disconnection_effects::*; + mod p2p_disconnection_service; pub use p2p_disconnection_service::*; diff --git a/p2p/src/disconnection/p2p_disconnection_actions.rs b/p2p/src/disconnection/p2p_disconnection_actions.rs index 3da360947..0779c247f 100644 --- a/p2p/src/disconnection/p2p_disconnection_actions.rs +++ b/p2p/src/disconnection/p2p_disconnection_actions.rs @@ -1,61 +1,30 @@ use serde::{Deserialize, Serialize}; use super::P2pDisconnectionReason; +use crate::{P2pPeerStatus, P2pState, PeerId}; pub type P2pDisconnectionActionWithMetaRef<'a> = redux::ActionWithMeta<&'a P2pDisconnectionAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] -pub enum P2pDisconnectionAction { - Init(P2pDisconnectionInitAction), - Finish(P2pDisconnectionFinishAction), -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDisconnectionInitAction { - pub peer_id: crate::PeerId, - pub reason: P2pDisconnectionReason, -} - -impl redux::EnablingCondition for P2pDisconnectionInitAction { - fn is_enabled(&self, state: &crate::P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Disconnected { .. } => false, - _ => true, - }) - } -} - #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDisconnectionFinishAction { - pub peer_id: crate::PeerId, -} - -impl redux::EnablingCondition for P2pDisconnectionFinishAction { - fn is_enabled(&self, state: &crate::P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |peer| match &peer.status { - P2pPeerStatus::Disconnected { .. } => false, - _ => true, - }) - } -} - -// --- From for Action impls. -use crate::P2pPeerStatus; - -impl From for crate::P2pAction { - fn from(a: P2pDisconnectionInitAction) -> Self { - Self::Disconnection(P2pDisconnectionAction::Init(a.into())) - } +pub enum P2pDisconnectionAction { + Init { + peer_id: PeerId, + reason: P2pDisconnectionReason, + }, + Finish { + peer_id: PeerId, + }, } -impl From for crate::P2pAction { - fn from(a: P2pDisconnectionFinishAction) -> Self { - Self::Disconnection(P2pDisconnectionAction::Finish(a.into())) +impl redux::EnablingCondition for P2pDisconnectionAction { + fn is_enabled(&self, state: &P2pState) -> bool { + match self { + P2pDisconnectionAction::Init { peer_id, .. } + | P2pDisconnectionAction::Finish { peer_id } => { + state.peers.get(peer_id).map_or(false, |peer| { + !matches!(peer.status, P2pPeerStatus::Disconnected { .. }) + }) + } + } } } diff --git a/p2p/src/disconnection/p2p_disconnection_effects.rs b/p2p/src/disconnection/p2p_disconnection_effects.rs index d61de8f54..a3e442bd2 100644 --- a/p2p/src/disconnection/p2p_disconnection_effects.rs +++ b/p2p/src/disconnection/p2p_disconnection_effects.rs @@ -1,17 +1,22 @@ use redux::ActionMeta; -use super::{P2pDisconnectionFinishAction, P2pDisconnectionInitAction, P2pDisconnectionService}; +use super::{P2pDisconnectionAction, P2pDisconnectionService}; -impl P2pDisconnectionInitAction { +impl P2pDisconnectionAction { pub fn effects(&self, _: &ActionMeta, store: &mut Store) where Store: crate::P2pStore, Store::Service: P2pDisconnectionService, - P2pDisconnectionFinishAction: redux::EnablingCondition, + P2pDisconnectionAction: redux::EnablingCondition, { - store.service().disconnect(self.peer_id); - store.dispatch(P2pDisconnectionFinishAction { - peer_id: self.peer_id, - }); + match self { + P2pDisconnectionAction::Init { peer_id, .. } => { + store.service().disconnect(*peer_id); + store.dispatch(P2pDisconnectionAction::Finish { + peer_id: *peer_id, + }); + } + P2pDisconnectionAction::Finish { .. } => {} + } } } diff --git a/p2p/src/discovery/p2p_discovery_actions.rs b/p2p/src/discovery/p2p_discovery_actions.rs index 7859f9684..22e71d79e 100644 --- a/p2p/src/discovery/p2p_discovery_actions.rs +++ b/p2p/src/discovery/p2p_discovery_actions.rs @@ -6,146 +6,43 @@ use crate::{connection::outgoing::P2pConnectionOutgoingInitOpts, P2pState, PeerI pub type P2pDiscoveryActionWithMetaRef<'a> = redux::ActionWithMeta<&'a P2pDiscoveryAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub enum P2pDiscoveryAction { - Init(P2pDiscoveryInitAction), - Success(P2pDiscoverySuccessAction), - KademliaBootstrap(P2pDiscoveryKademliaBootstrapAction), - KademliaInit(P2pDiscoveryKademliaInitAction), - KademliaAddRoute(P2pDiscoveryKademliaAddRouteAction), - KademliaSuccess(P2pDiscoveryKademliaSuccessAction), - KademliaFailure(P2pDiscoveryKademliaFailureAction), + Init { + peer_id: PeerId, + }, + Success { + peer_id: PeerId, + peers: Vec, + }, + KademliaBootstrap, + KademliaInit, + KademliaAddRoute { + peer_id: PeerId, + addresses: Vec, + }, + KademliaSuccess { + peers: Vec, + }, + KademliaFailure { + description: String, + }, } impl redux::EnablingCondition for P2pDiscoveryAction { fn is_enabled(&self, state: &P2pState) -> bool { match self { - Self::Init(action) => action.is_enabled(state), - Self::Success(action) => action.is_enabled(state), - Self::KademliaBootstrap(action) => action.is_enabled(state), - Self::KademliaAddRoute(action) => action.is_enabled(state), - Self::KademliaInit(action) => action.is_enabled(state), - Self::KademliaSuccess(action) => action.is_enabled(state), - Self::KademliaFailure(action) => action.is_enabled(state), + Self::Init { peer_id } => state.get_ready_peer(peer_id).is_some(), + Self::Success { .. } => true, + Self::KademliaBootstrap => !state.kademlia.is_ready && !state.kademlia.is_bootstrapping, + Self::KademliaInit => { + state.kademlia.is_ready + && state.kademlia.outgoing_requests < 1 + && !state.already_knows_max_peers() + } + Self::KademliaAddRoute { .. } => true, + Self::KademliaSuccess { .. } => true, + Self::KademliaFailure { .. } => true, } } } - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDiscoveryInitAction { - pub peer_id: PeerId, -} - -impl redux::EnablingCondition for P2pDiscoveryInitAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state.get_ready_peer(&self.peer_id).is_some() - } -} - -impl From for crate::P2pAction { - fn from(a: P2pDiscoveryInitAction) -> Self { - Self::Discovery(a.into()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDiscoveryKademliaAddRouteAction { - pub peer_id: PeerId, - pub addresses: Vec, -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaAddRouteAction { - fn is_enabled(&self, _state: &P2pState) -> bool { - true - } -} - -impl From for crate::P2pAction { - fn from(a: P2pDiscoveryKademliaAddRouteAction) -> Self { - Self::Discovery(a.into()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDiscoverySuccessAction { - pub peer_id: PeerId, - pub peers: Vec, -} - -impl redux::EnablingCondition for P2pDiscoverySuccessAction { - fn is_enabled(&self, _state: &P2pState) -> bool { - true - } -} - -impl From for crate::P2pAction { - fn from(a: P2pDiscoverySuccessAction) -> Self { - Self::Discovery(a.into()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDiscoveryKademliaBootstrapAction {} - -impl redux::EnablingCondition for P2pDiscoveryKademliaBootstrapAction { - fn is_enabled(&self, state: &P2pState) -> bool { - !state.kademlia.is_ready && !state.kademlia.is_bootstrapping - } -} - -impl From for crate::P2pAction { - fn from(a: P2pDiscoveryKademliaBootstrapAction) -> Self { - Self::Discovery(a.into()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDiscoveryKademliaInitAction {} - -impl redux::EnablingCondition for P2pDiscoveryKademliaInitAction { - fn is_enabled(&self, state: &P2pState) -> bool { - state.kademlia.is_ready - && state.kademlia.outgoing_requests < 1 - && !state.already_knows_max_peers() - } -} - -impl From for crate::P2pAction { - fn from(a: P2pDiscoveryKademliaInitAction) -> Self { - Self::Discovery(a.into()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDiscoveryKademliaSuccessAction { - pub peers: Vec, -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaSuccessAction { - fn is_enabled(&self, _state: &P2pState) -> bool { - true - } -} - -impl From for crate::P2pAction { - fn from(a: P2pDiscoveryKademliaSuccessAction) -> Self { - Self::Discovery(a.into()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pDiscoveryKademliaFailureAction { - pub description: String, -} - -impl redux::EnablingCondition for P2pDiscoveryKademliaFailureAction { - fn is_enabled(&self, _state: &P2pState) -> bool { - true - } -} - -impl From for crate::P2pAction { - fn from(a: P2pDiscoveryKademliaFailureAction) -> Self { - Self::Discovery(a.into()) - } -} diff --git a/p2p/src/discovery/p2p_discovery_reducer.rs b/p2p/src/discovery/p2p_discovery_reducer.rs index ab62fbb80..ec3ce5536 100644 --- a/p2p/src/discovery/p2p_discovery_reducer.rs +++ b/p2p/src/discovery/p2p_discovery_reducer.rs @@ -1,40 +1,33 @@ use crate::P2pKademliaState; -use super::{ - P2pDiscoveryAction, P2pDiscoveryActionWithMetaRef, P2pDiscoveryInitAction, - P2pDiscoveryKademliaAddRouteAction, P2pDiscoverySuccessAction, -}; +use super::{P2pDiscoveryAction, P2pDiscoveryActionWithMetaRef}; impl P2pKademliaState { pub fn reducer(&mut self, action: P2pDiscoveryActionWithMetaRef) { let (action, meta) = action.split(); match action { - P2pDiscoveryAction::KademliaBootstrap(_) => { + P2pDiscoveryAction::KademliaBootstrap => { self.is_bootstrapping = true; } - P2pDiscoveryAction::Init(P2pDiscoveryInitAction { .. }) => {} - P2pDiscoveryAction::Success(P2pDiscoverySuccessAction { peers, peer_id }) => { + P2pDiscoveryAction::Init { .. } => {} + P2pDiscoveryAction::Success { peers, peer_id } => { self.peer_timestamp.insert(*peer_id, meta.time()); self.known_peers .extend(peers.iter().cloned().map(|peer| (*peer.peer_id(), peer))); } - P2pDiscoveryAction::KademliaInit(..) => { + P2pDiscoveryAction::KademliaInit => { self.outgoing_requests += 1; } - P2pDiscoveryAction::KademliaAddRoute(P2pDiscoveryKademliaAddRouteAction { - peer_id, - addresses, - }) => { + P2pDiscoveryAction::KademliaAddRoute { peer_id, addresses } => { self.routes.insert(*peer_id, addresses.clone()); } - P2pDiscoveryAction::KademliaSuccess(action) => { + P2pDiscoveryAction::KademliaSuccess { peers } => { // TODO(vlad9486): handle failure, decrement the counter self.outgoing_requests -= 1; let len = self.known_peers.len(); self.known_peers.extend( - action - .peers + peers .iter() .map(|peer_id| { // TODO(vlad9486): use all @@ -52,7 +45,7 @@ impl P2pKademliaState { self.saturated = None; } } - P2pDiscoveryAction::KademliaFailure(_) => { + P2pDiscoveryAction::KademliaFailure { .. } => { if !self.known_peers.is_empty() { self.saturated = Some(meta.time()); } diff --git a/p2p/src/lib.rs b/p2p/src/lib.rs index 01d4cea92..e013e56e8 100644 --- a/p2p/src/lib.rs +++ b/p2p/src/lib.rs @@ -26,7 +26,7 @@ mod p2p_state; pub use p2p_state::*; mod p2p_reducer; -pub use p2p_reducer::*; + use redux::SubStore; pub trait P2pStore: SubStore {} diff --git a/p2p/src/listen/p2p_listen_actions.rs b/p2p/src/listen/p2p_listen_actions.rs index 2410b6126..a05553cb5 100644 --- a/p2p/src/listen/p2p_listen_actions.rs +++ b/p2p/src/listen/p2p_listen_actions.rs @@ -1,86 +1,28 @@ use redux::EnablingCondition; use serde::{Deserialize, Serialize}; -use crate::{P2pAction, P2pListenerId, P2pState}; +use crate::{P2pListenerId, P2pState}; pub type P2pListenActionWithMetaRef<'a> = redux::ActionWithMeta<&'a P2pListenAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] -pub enum P2pListenAction { - New(P2pListenNewAction), - Expired(P2pListenExpiredAction), - Error(P2pListenErrorAction), - Closed(P2pListenClosedAction), -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pListenNewAction { - pub listener_id: P2pListenerId, - pub addr: libp2p::Multiaddr, -} - -impl EnablingCondition for P2pListenNewAction { - fn is_enabled(&self, #[allow(unused_variables)] state: &P2pState) -> bool { - true - } -} - -impl From for P2pAction { - fn from(value: P2pListenNewAction) -> Self { - P2pListenAction::from(value).into() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pListenExpiredAction { - pub listener_id: P2pListenerId, - pub addr: libp2p::Multiaddr, -} - -impl EnablingCondition for P2pListenExpiredAction { - fn is_enabled(&self, #[allow(unused_variables)] state: &P2pState) -> bool { - true - } -} - -impl From for P2pAction { - fn from(value: P2pListenExpiredAction) -> Self { - P2pListenAction::from(value).into() - } -} - #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pListenErrorAction { - pub listener_id: P2pListenerId, - pub error: String, -} - -impl EnablingCondition for P2pListenErrorAction { - fn is_enabled(&self, #[allow(unused_variables)] state: &P2pState) -> bool { - true - } -} - -impl From for P2pAction { - fn from(value: P2pListenErrorAction) -> Self { - P2pListenAction::from(value).into() - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pListenClosedAction { - pub listener_id: P2pListenerId, - pub error: Option, -} - -impl EnablingCondition for P2pListenClosedAction { - fn is_enabled(&self, #[allow(unused_variables)] state: &P2pState) -> bool { - true - } -} - -impl From for P2pAction { - fn from(value: P2pListenClosedAction) -> Self { - P2pListenAction::from(value).into() - } -} +pub enum P2pListenAction { + New { + listener_id: P2pListenerId, + addr: libp2p::Multiaddr, + }, + Expired { + listener_id: P2pListenerId, + addr: libp2p::Multiaddr, + }, + Error { + listener_id: P2pListenerId, + error: String, + }, + Closed { + listener_id: P2pListenerId, + error: Option, + }, +} + +impl EnablingCondition for P2pListenAction {} diff --git a/p2p/src/listen/p2p_listen_effects.rs b/p2p/src/listen/p2p_listen_effects.rs index 472de8722..2fe82d1ed 100644 --- a/p2p/src/listen/p2p_listen_effects.rs +++ b/p2p/src/listen/p2p_listen_effects.rs @@ -1,37 +1,8 @@ use redux::ActionMeta; -use super::{ - P2pListenClosedAction, P2pListenErrorAction, P2pListenExpiredAction, P2pListenNewAction, -}; +use super::P2pListenAction; -impl P2pListenNewAction { - pub fn effects(self, _: &ActionMeta, _store: &mut Store) - where - Store: crate::P2pStore, - { - // TODO run Kademlia expose - } -} - -impl P2pListenExpiredAction { - pub fn effects(self, _: &ActionMeta, _store: &mut Store) - where - Store: crate::P2pStore, - { - // TODO run Kademlia expose - } -} - -impl P2pListenErrorAction { - pub fn effects(self, _: &ActionMeta, _store: &mut Store) - where - Store: crate::P2pStore, - { - // TODO run Kademlia expose - } -} - -impl P2pListenClosedAction { +impl P2pListenAction { pub fn effects(self, _: &ActionMeta, _store: &mut Store) where Store: crate::P2pStore, diff --git a/p2p/src/listen/p2p_listen_reducer.rs b/p2p/src/listen/p2p_listen_reducer.rs index 7e999e7e7..2f65f44a6 100644 --- a/p2p/src/listen/p2p_listen_reducer.rs +++ b/p2p/src/listen/p2p_listen_reducer.rs @@ -7,33 +7,30 @@ impl P2pListenersState { let (action, _meta) = action.split(); match action { - super::P2pListenAction::New(action) => { + super::P2pListenAction::New { listener_id, addr } => { if let P2pListenerState::Open { addrs, .. } = - self.0.entry(action.listener_id.clone()).or_default() + self.0.entry(listener_id.clone()).or_default() { - addrs.insert(action.addr.clone()); + addrs.insert(addr.clone()); } } - super::P2pListenAction::Expired(action) => { - if let Some(P2pListenerState::Open { addrs, .. }) = - self.0.get_mut(&action.listener_id) - { - addrs.remove(&action.addr); + super::P2pListenAction::Expired { listener_id, addr } => { + if let Some(P2pListenerState::Open { addrs, .. }) = self.0.get_mut(&listener_id) { + addrs.remove(&addr); } } - super::P2pListenAction::Error(action) => { + super::P2pListenAction::Error { listener_id, error } => { if let P2pListenerState::Open { errors, .. } = - self.0.entry(action.listener_id.clone()).or_default() + self.0.entry(listener_id.clone()).or_default() { - errors.push(action.error.clone()); + errors.push(error.clone()); } } - super::P2pListenAction::Closed(action) => { - let new_state = action - .error + super::P2pListenAction::Closed { listener_id, error } => { + let new_state = error .clone() .map_or(P2pListenerState::Closed, P2pListenerState::ClosedWithError); - self.0.insert(action.listener_id.clone(), new_state); + self.0.insert(listener_id.clone(), new_state); } } } diff --git a/p2p/src/p2p_reducer.rs b/p2p/src/p2p_reducer.rs index 0a59486b4..0c07480b4 100644 --- a/p2p/src/p2p_reducer.rs +++ b/p2p/src/p2p_reducer.rs @@ -18,40 +18,38 @@ impl P2pState { return; }; let peer = match action { - P2pConnectionAction::Outgoing(P2pConnectionOutgoingAction::Init(v)) => { - self.peers.entry(*peer_id).or_insert_with(|| P2pPeerState { - is_libp2p: v.opts.is_libp2p(), - dial_opts: Some(v.opts.clone()), - status: P2pPeerStatus::Connecting(P2pConnectionState::outgoing_init( - &v.opts, - )), - }) - } - P2pConnectionAction::Incoming(P2pConnectionIncomingAction::Init(v)) => { - self.peers.entry(*peer_id).or_insert_with(|| P2pPeerState { - is_libp2p: false, - dial_opts: { - let signaling = match v.opts.signaling { - IncomingSignalingMethod::Http => { - SignalingMethod::Http(HttpSignalingInfo { - host: v.opts.offer.host.clone(), - port: v.opts.offer.listen_port, - }) - } - }; - Some(P2pConnectionOutgoingInitOpts::WebRTC { - peer_id: *peer_id, - signaling, - }) - }, - status: P2pPeerStatus::Connecting(P2pConnectionState::incoming_init( - &v.opts, - )), - }) - } - P2pConnectionAction::Incoming(P2pConnectionIncomingAction::Libp2pReceived( - _, - )) => { + P2pConnectionAction::Outgoing(P2pConnectionOutgoingAction::Init { + opts, + .. + }) => self.peers.entry(*peer_id).or_insert_with(|| P2pPeerState { + is_libp2p: opts.is_libp2p(), + dial_opts: Some(opts.clone()), + status: P2pPeerStatus::Connecting(P2pConnectionState::outgoing_init(opts)), + }), + P2pConnectionAction::Incoming(P2pConnectionIncomingAction::Init { + opts, + .. + }) => self.peers.entry(*peer_id).or_insert_with(|| P2pPeerState { + is_libp2p: false, + dial_opts: { + let signaling = match opts.signaling { + IncomingSignalingMethod::Http => { + SignalingMethod::Http(HttpSignalingInfo { + host: opts.offer.host.clone(), + port: opts.offer.listen_port, + }) + } + }; + Some(P2pConnectionOutgoingInitOpts::WebRTC { + peer_id: *peer_id, + signaling, + }) + }, + status: P2pPeerStatus::Connecting(P2pConnectionState::incoming_init(opts)), + }), + P2pConnectionAction::Incoming( + P2pConnectionIncomingAction::Libp2pReceived { .. }, + ) => { self.peers.entry(*peer_id).or_insert_with(|| P2pPeerState { is_libp2p: true, dial_opts: None, @@ -67,9 +65,9 @@ impl P2pState { p2p_connection_reducer(peer, meta.with_action(action)); } P2pAction::Disconnection(action) => match action { - P2pDisconnectionAction::Init(_) => {} - P2pDisconnectionAction::Finish(a) => { - let Some(peer) = self.peers.get_mut(&a.peer_id) else { + P2pDisconnectionAction::Init { .. } => {} + P2pDisconnectionAction::Finish { peer_id } => { + let Some(peer) = self.peers.get_mut(peer_id) else { return; }; peer.status = P2pPeerStatus::Disconnected { time: meta.time() }; diff --git a/p2p/src/peer/mod.rs b/p2p/src/peer/mod.rs index e8a225854..9b5cba174 100644 --- a/p2p/src/peer/mod.rs +++ b/p2p/src/peer/mod.rs @@ -5,4 +5,4 @@ mod p2p_peer_reducer; pub use p2p_peer_reducer::*; mod p2p_peer_effects; -pub use p2p_peer_effects::*; + diff --git a/p2p/src/peer/p2p_peer_actions.rs b/p2p/src/peer/p2p_peer_actions.rs index f9e326e32..f3af332d8 100644 --- a/p2p/src/peer/p2p_peer_actions.rs +++ b/p2p/src/peer/p2p_peer_actions.rs @@ -1,63 +1,44 @@ use openmina_core::block::ArcBlockWithHash; use serde::{Deserialize, Serialize}; -use crate::{P2pAction, P2pState, PeerId}; +use crate::{P2pState, PeerId}; pub type P2pPeerActionWithMeta = redux::ActionWithMeta; pub type P2pPeerActionWithMetaRef<'a> = redux::ActionWithMeta<&'a P2pPeerAction>; -#[derive(derive_more::From, Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub enum P2pPeerAction { - Ready(P2pPeerReadyAction), - BestTipUpdate(P2pPeerBestTipUpdateAction), + Ready { + peer_id: PeerId, + incoming: bool, + }, + BestTipUpdate { + peer_id: PeerId, + best_tip: ArcBlockWithHash, + }, } impl P2pPeerAction { pub fn peer_id(&self) -> &PeerId { match self { - Self::Ready(v) => &v.peer_id, - Self::BestTipUpdate(v) => &v.peer_id, + Self::Ready { peer_id, .. } => peer_id, + Self::BestTipUpdate { peer_id, .. } => peer_id, } } } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pPeerReadyAction { - pub peer_id: PeerId, - pub incoming: bool, -} - -impl redux::EnablingCondition for P2pPeerReadyAction { +impl redux::EnablingCondition for P2pPeerAction { fn is_enabled(&self, state: &P2pState) -> bool { - state - .peers - .get(&self.peer_id) - .map_or(false, |p| p.status.is_connecting_success()) - } -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2pPeerBestTipUpdateAction { - pub peer_id: PeerId, - pub best_tip: ArcBlockWithHash, -} - -impl redux::EnablingCondition for P2pPeerBestTipUpdateAction { - fn is_enabled(&self, state: &P2pState) -> bool { - // TODO(binier): don't enable if block inferior than existing peer's - // best tip. - state.get_ready_peer(&self.peer_id).is_some() - } -} - -impl From for P2pAction { - fn from(value: P2pPeerReadyAction) -> Self { - Self::Peer(value.into()) - } -} - -impl From for P2pAction { - fn from(value: P2pPeerBestTipUpdateAction) -> Self { - Self::Peer(value.into()) + match self { + Self::Ready { peer_id, .. } => state + .peers + .get(peer_id) + .map_or(false, |p| p.status.is_connecting_success()), + Self::BestTipUpdate { peer_id, .. } => { + // TODO: don't enable if block inferior than existing peer's + // best tip. + state.get_ready_peer(peer_id).is_some() + } + } } } diff --git a/p2p/src/peer/p2p_peer_effects.rs b/p2p/src/peer/p2p_peer_effects.rs index ad58e0731..66fa7e8b5 100644 --- a/p2p/src/peer/p2p_peer_effects.rs +++ b/p2p/src/peer/p2p_peer_effects.rs @@ -5,9 +5,9 @@ use crate::channels::{ snark_job_commitment::P2pChannelsSnarkJobCommitmentAction, ChannelId, }; -use super::P2pPeerReadyAction; +use super::P2pPeerAction; -impl P2pPeerReadyAction { +impl P2pPeerAction { pub fn effects(self, _: &ActionMeta, store: &mut Store) where Store: crate::P2pStore, @@ -16,24 +16,29 @@ impl P2pPeerReadyAction { P2pChannelsSnarkJobCommitmentAction: redux::EnablingCondition, P2pChannelsRpcAction: redux::EnablingCondition, { - let peer_id = self.peer_id; - // Dispatches can be done without a loop, but inside we do - // exhaustive matching so that we don't miss any channels. - for id in ChannelId::iter_all() { - match id { - ChannelId::BestTipPropagation => { - store.dispatch(P2pChannelsBestTipAction::Init { peer_id }); - } - ChannelId::SnarkPropagation => { - store.dispatch(P2pChannelsSnarkAction::Init { peer_id }); - } - ChannelId::SnarkJobCommitmentPropagation => { - store.dispatch(P2pChannelsSnarkJobCommitmentAction::Init { peer_id }); - } - ChannelId::Rpc => { - store.dispatch(P2pChannelsRpcAction::Init { peer_id }); + match self { + P2pPeerAction::Ready { peer_id, .. } => { + let peer_id = peer_id; + // Dispatches can be done without a loop, but inside we do + // exhaustive matching so that we don't miss any channels. + for id in ChannelId::iter_all() { + match id { + ChannelId::BestTipPropagation => { + store.dispatch(P2pChannelsBestTipAction::Init { peer_id }); + } + ChannelId::SnarkPropagation => { + store.dispatch(P2pChannelsSnarkAction::Init { peer_id }); + } + ChannelId::SnarkJobCommitmentPropagation => { + store.dispatch(P2pChannelsSnarkJobCommitmentAction::Init { peer_id }); + } + ChannelId::Rpc => { + store.dispatch(P2pChannelsRpcAction::Init { peer_id }); + } + } } } + P2pPeerAction::BestTipUpdate { .. } => {} } } } diff --git a/p2p/src/peer/p2p_peer_reducer.rs b/p2p/src/peer/p2p_peer_reducer.rs index 04aa713dd..d1512aa3c 100644 --- a/p2p/src/peer/p2p_peer_reducer.rs +++ b/p2p/src/peer/p2p_peer_reducer.rs @@ -6,21 +6,21 @@ pub fn p2p_peer_reducer(state: &mut P2pState, action: P2pPeerActionWithMetaRef<' let (action, meta) = action.split(); match action { - P2pPeerAction::Ready(action) => { - let Some(peer) = state.peers.get_mut(&action.peer_id) else { + P2pPeerAction::Ready { peer_id, incoming } => { + let Some(peer) = state.peers.get_mut(peer_id) else { return; }; peer.status = P2pPeerStatus::Ready(P2pPeerStatusReady::new( - action.incoming, + *incoming, meta.time(), &state.config.enabled_channels, )); } - P2pPeerAction::BestTipUpdate(action) => { - let Some(peer) = state.get_ready_peer_mut(&action.peer_id) else { + P2pPeerAction::BestTipUpdate { peer_id, best_tip } => { + let Some(peer) = state.get_ready_peer_mut(peer_id) else { return; }; - peer.best_tip = Some(action.best_tip.clone()); + peer.best_tip = Some(best_tip.clone()); } } } diff --git a/p2p/src/service_impl/libp2p/mod.rs b/p2p/src/service_impl/libp2p/mod.rs index 2b11a5d0e..6b5bb8dcb 100644 --- a/p2p/src/service_impl/libp2p/mod.rs +++ b/p2p/src/service_impl/libp2p/mod.rs @@ -480,12 +480,13 @@ impl Libp2pService { b.rpc.respond::(peer_id, stream_id, id, Ok(None))? } (AnswerSyncLedgerQueryV2::NAME, AnswerSyncLedgerQueryV2::VERSION) => { + // TODO: shouldn't we disable this method in menu? type T = AnswerSyncLedgerQueryV2; b.rpc.respond::( peer_id, stream_id, id, - Ok(RpcResult(Err(Info::String(Vec::new().into())))), + Ok(RpcResult(Err(Info::from_str("not implemented")))), )? } ( diff --git a/run.yaml b/run.yaml index b324c7497..37128b551 100644 --- a/run.yaml +++ b/run.yaml @@ -60,11 +60,11 @@ spec: - | apt-get update && apt-get -y install git curl gcc libssl-dev pkg-config curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - PATH=$PATH:~/.cargo/bin && rustup update nightly-2023-10-01 + PATH=$PATH:~/.cargo/bin && rustup update 1.75 git clone https://github.com/openmina/openmina cd openmina git fetch && git checkout feat/tests-with-debugger - PATH=$PATH:~/.cargo/bin && cargo +nightly-2023-10-01 build --release --bin openmina + PATH=$PATH:~/.cargo/bin && cargo +1.75 build --release --bin openmina cp target/release/openmina /usr/local/bin/openmina openmina node -p 10000 --libp2p-port 8302 ports: diff --git a/snark/Cargo.toml b/snark/Cargo.toml index ea66ad280..04f14b6bf 100644 --- a/snark/Cargo.toml +++ b/snark/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "snark" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/snark/src/block_verify/mod.rs b/snark/src/block_verify/mod.rs index 9ab2cc1bd..0958d6a35 100644 --- a/snark/src/block_verify/mod.rs +++ b/snark/src/block_verify/mod.rs @@ -5,10 +5,10 @@ mod snark_block_verify_actions; pub use snark_block_verify_actions::*; mod snark_block_verify_reducer; -pub use snark_block_verify_reducer::*; + mod snark_block_verify_effects; -pub use snark_block_verify_effects::*; + mod snark_block_verify_service; pub use snark_block_verify_service::*; diff --git a/snark/src/lib.rs b/snark/src/lib.rs index a58ef2a06..69e35c158 100644 --- a/snark/src/lib.rs +++ b/snark/src/lib.rs @@ -25,7 +25,7 @@ mod snark_state; pub use snark_state::*; mod snark_reducer; -pub use snark_reducer::*; + pub type VerifierIndex = kimchi::verifier_index::VerifierIndex; pub type VerifierSRS = poly_commitment::srs::SRS; diff --git a/snark/src/work_verify/mod.rs b/snark/src/work_verify/mod.rs index b8c12f136..973b11f52 100644 --- a/snark/src/work_verify/mod.rs +++ b/snark/src/work_verify/mod.rs @@ -5,10 +5,10 @@ mod snark_work_verify_actions; pub use snark_work_verify_actions::*; mod snark_work_verify_reducer; -pub use snark_work_verify_reducer::*; + mod snark_work_verify_effects; -pub use snark_work_verify_effects::*; + mod snark_work_verify_service; pub use snark_work_verify_service::*; diff --git a/status.md b/status.md new file mode 100644 index 000000000..f7c8f036e --- /dev/null +++ b/status.md @@ -0,0 +1,340 @@ +# Current status of the Rust node + +* [High Level Functionality Overview](#overview) +* [VRF Evaluator](#vrf-evaluator) +* [Block Producer](#block-producer) +* [Ledger](#ledger) +* [Proofs](#proofs) +* [P2P Implementation (State Machine Version)](#state-machine-p2p) +* [P2P Related Tests](#p2p-tests) +* [Frontend](#frontend) +* [Documentation](#documentation) +* [Experimental State Machine Architecture](#experimental-state-machine-architecture) + +## High Level Functionality Overview + +- [x] Consensus logic +- [x] VRF evaluator +- Block production logic + - [x] Without transactions and without proof + - [ ] Full block with proof + - [ ] Blocks with transactions. - Missing because we don't yet have the transaction pool logic. +- Networking layer + - [x] P2P layer in general along with serialization/deserialization of all messages + - RPCs support + - [x] `Get_some_initial_peers`(this is not used by the OCaml node) + - [x] `Get_staged_ledger_aux_and_pending_coinbases_at_hash` + - [x] `Answer_sync_ledger_query` + - [x] `Get_transition_chain` + - `Get_transition_knowledge` (I don't think this one is used at all, `Get_transition_chain_proof` is used instead) + - [x] `Get_transition_chain_proof` + - [x] `Get_ancestry` + - `Ban_notify` + - [x] `Get_best_tip` + - `Get_node_status` + - Peer discovery/advertising + - [x] Peer discovery through kademlia + - [x] Advertising the node through kademlia so that OCaml nodes can see us +- [ ] Trust system (to punish/ban peers): **not implemented (and no equivalent)** +- Pools + - [ ] Transaction pool: **not implemented** + - No pool is maintained, transactions received over the gossip network are not processed or re-broadcasted + - SNARK pool + - [x] SNARK Verification + - [x] Pool is implemented + - [x] SNARK work production is implemented (through OCaml). Node can complete and broadcast SNARK work. +- [x] Compatible ledger implementation +- [x] Transition frontier +- Bootstrap/Catchup process + - [x] Ledger synchronization + - [x] Snarked ledgers (staking and next epoch ledgers + transition frontier root) + - [x] Handling of peer disconnections, timeouts or cases when the peer doesn't have the data + - [x] Detecting ledger hash mismatches for the downloaded chunk + - [ ] Handling ledger hash mismatches gracefully, without crashing the node + - [ ] Optimized snarked ledgers synchronization (reusing previous ledgers when constructing the next during (re)synchronization) + - Not done right now, each synchronization starts from scratch. + - Tested this on a server (very quick sync) and locally (slower) and both were able to sync up to berkeleynet (it took a while locally). On mainnet, with a much bigger ledger we may not be able to sync up in time without this optimization. + - [x] Staged ledgers (transition frontier root) + - [x] Handling of peer disconnections, timeouts or cases when the peer doesn't have the data + - [x] Detection and handling of validation errors + - [x] Handling of the rpc requests from other nodes to sync them up + - [x] Moving root of the transition frontier + - [x] Maintaining ledgers for transition frontier root, staking and next epoch ledgers + - [x] When scan state tree gets committed, snarked ledger of the block is updated. When that happens for the root block in the transition frontier, reconstruct the new root snarked ledger + - [x] At the end of an epoch make the "next epoch" ledger the new "staking" ledger, discard the old "staking" ledger and make the snarked ledger of the best tip the new "next epoch" ledger + - [x] Best chain synchronization + - [x] Download missing blocks from peers + - [x] Handling of peer disconnections, timeouts or cases when the peer doesn't have the data + - [x] Downloaded block header integrity validation by checking it's hash and handling the mismatch + - [ ] Downloaded block body integrity validation by checking it's hash and handling the mismatch + - [x] Missing blocks application + - [ ] Graceful handling of block application error without crashing the node + - [x] Handling of reorgs (short/long range forks) or best chain extension after or even mid-synchronization, by adjusting synchronization target and reusing what we can from the previous synchronization attempt +- Block application + - [x] Transaction application logic + - [x] Block application logic + - Proof verification: + - [x] Block proof verification + - [x] Transaction proof verification (same as above) + - [x] Zkapp proof verification (same as above) +- [ ] Client API (currently the node has a very partial support, not planned at the moment) +- [ ] Archive node (not planned at the moment) + +## VRF Evaluator + +- [x] VRF evaluator functionality: + - [x] Calculation of the VRF output + - [x] Threshold calculation determining if the slot has been won + - [ ] (Optional) Providing verification of the producers VRF output (Does not impact the node functionality, just provides a way for the delegates to verify their impact on winning/losing a slot) +- [x] Implement VRF evaluator state machine + - [x] Computation service + - [x] Collecting the delegator table for the producer + - [x] Integrate with the block producer + - [x] Handling epoch changes - starting new evaluation as soon as new epoch data is available + - [ ] Retention logic - cleanup slot data that is in the past based on current global slot (Slight node impact - the won slot map grows indefinitely) +- [ ] Testing + - [ ] Correctness test - Selecting the correct ledgers + - [x] (Edge case) In genesis epoch + - [ ] In other (higher) epochs + - [x] Correctness test - Computation output comparison with mina cli + - [x] Correctness test - Start a new VRF evaluation on epoch switch for the next available epoch + - [ ] Correctness test - Retaining the slot data only for future blocks +- [ ] Documentation + +## Block Producer + +- [ ] Block producer + - [x] Integrate with VRF evaluator + - [x] Include coinbase transactions + - [x] Include fee transfers + - [ ] Include simple transactions (transaction pool missing) + - [ ] Include zkapp transactions (transaction pool missing) + - [x] Ledger diff creation + - [x] Integrate with transition frontier + - [x] New epoch seed calculation + - [x] Staking epoch ledger selection + - [ ] Proof generation +- [ ] Testing +- [ ] Documentation + +## Ledger + +- [x] Ledger/Mask implementation +- [x] Staged Ledger implementation + - [x] Scan state + - [x] Pending coinbase collection + - [x] Transaction application + - [x] Regular transaction (payment, delegation, coinbase, fee transfer) + - [x] Zkapps +- [x] Persistent database + - https://github.com/MinaProtocol/mina/pull/13340 + - Drop-in replacement for RocksDB + +## Proofs + +- [x] Proof verification + - [x] Block proof + - [x] Transaction/Merge proof + - [x] Zkapp proof +- [x] Proof/Witness generation + - [x] Block proof + - [x] Transaction/Merge proof + - [x] Zkapp proof +- [ ] Circuit generation + +## P2P Implementation (State Machine Version) + +### Handshake + +- [x] Create a service for low level TCP networking (mio, epoll). +- [ ] DNS support. +- [x] Pnet protocol. +- [x] Multistream select protocol. +- [ ] Handle simultaneous connect case. +- [x] Noise protocol for outgoing connections. +- [x] Noise protocol for incoming connections. +- [x] Yamux multiplexer. + +### Peer discovery + +- [ ] Create connection scheduler to limit work for each peer +- [ ] Handle reconnection and exponential backoff. +- [ ] Implement Kademlia algorithm. + +### RPC + +- [x] Perform outgoing RPC requests. +- [ ] Handle incoming RPC requests. + +### Gossipsub + +- [ ] Implement gossipsub compatible with libp2p. +- [ ] Research how to use "expander graph" theory to make gossipsub robust and efficient. + +### Testing + +- [ ] Fix bootstrap sandbox record/replay for the latest berkeley network. +- [x] Fix network debugger for the latest berkeley network. +- [x] Test that the Openmina node can bootstrap from the replayer tool. +- [ ] Test that the OCaml node can bootstrap from the Openmina node. +- [ ] Test that the Openmina node can bootstrap from another instance of openmina node. + +## P2P Related Tests + +- [ ] P2p functionality tests + - [ ] p2p messages + - [ ] Binprot types (de)serialization testing/fuzzing + - [ ] Mina RPC types testing (ideally along with OCaml codecs) + - [ ] hashing testing (ideally along with OCaml hash implementations) + - [ ] Connection + - [ ] Proper initial peers handling, like reconnecting if offline + - [ ] Peers number maintaining, including edge cases, when we have max peers but still allow peers to connect for e.g. discovery, that is dropping connection strategy + - [ ] Other connection constraints, like no duplicate connections to the same peer, peer_id, no self connections etc + - [ ] Connection quality metrics + - [ ] Kademlia + - [ ] Peers discovery, according to Kademlia parameters (a new node gets 20 new peers) + - [ ] Kademlia routing table is up-to-date with the network (each peer status, like connected/disconnected/can_connect/cant_connect, reflects actual peer state) + - [ ] Gossipsub + - [ ] Reacheability (all nodes get the message) + - [ ] Non-redundancy (minimal number of duplicating/unneeded messages) +- [ ] Interoperability with OCaml node + - [ ] Bootstrap Rust node from OCaml and vice versa + - [ ] Discovery using Rust node + - [ ] Gossipsub relaying +- [ ] Public network tests. This should be the only set of tests that involve publicly available networks, and should be executed if we're sure we don't ruin them. +- [ ] Attack resistance testing + +## Frontend + +### Pages + +- [x] Nodes - Overview +- [x] Nodes - Live +- [x] Nodes - Bootstrap +- [x] State - Actions +- [x] Snarks - Work Pool +- [x] Snarks - Scan State +- [x] Resources - Memory +- [x] Network - Messages +- [x] Network - Blocks +- [x] Network - Connections +- [ ] Network - Topology +- [ ] Network - Node DHT +- [x] Peers - Dashboard +- [x] Testing Framework - Scenarios + +### Testing +- [x] Tests for Nodes Overview +- [x] Tests for Nodes Live +- [ ] Tests for Nodes Bootstrap +- [ ] Tests for State - Actions +- [ ] Tests for Snarks - Work Pool +- [ ] Tests for Snarks - Scan State +- [x] Tests for Resources - Memory +- [x] Tests for Network - Messages +- [x] Tests for Network - Blocks +- [x] Tests for Network - Connections +- [ ] Tests for Network - Topology +- [ ] Tests for Network - Node DHT +- [x] Tests for Peers - Dashboard +- [ ] Tests for Testing Framework - Scenarios + +### Other +- [x] CI Integration and Docker build & upload +- [x] State management +- [x] Update to Angular v16 +- [x] Ensure performant application (lazy load & standalone components) +- [x] Ensure reusable components/css/BL + +## Documentation + +### By module + +- [x] [Openmina Node](https://github.com/openmina/openmina#the-open-mina-node) +- [x] [The Mina Web Node](https://github.com/openmina/webnode/blob/main/README.md) +- P2P + - [ ] [P2P Networking Stack](https://github.com/openmina/openmina/blob/develop/p2p/readme.md) in progress + - [x] [P2P services](https://github.com/openmina/openmina/blob/documentation/docs/p2p_service.md) + - [ ] [RPCs support](https://github.com/JanSlobodnik/pre-publishing/blob/main/RPCs.md) - in progress + - [x] [GossipSub](https://github.com/openmina/mina-wiki/blob/3ea9041e52fb2e606918f6c60bd3a32b8652f016/p2p/mina-gossip.md) +- [x] [Scan state](https://github.com/openmina/openmina/blob/main/docs/scan-state.md) +- [x] [SNARKs](https://github.com/openmina/openmina/blob/main/docs/snark-work.md) +- Developer tools + - [x] [Debugger](https://github.com/openmina/mina-network-debugger/blob/main/README.md) + - [x] [Front End](https://github.com/openmina/mina-frontend/blob/main/README.md) + - [x] [Dashboard](https://github.com/openmina/mina-frontend/blob/main/docs/MetricsTracing.md#Dashboard) + - [x] [Debugger](https://github.com/openmina/mina-network-debugger) + + +### By use-case + +- [x] [Why we are developing Open Mina](https://github.com/openmina/openmina/blob/main/docs/why-openmina.md) +- [ ] Consensus logic - not documented yet +- Block production logic + - [ ] [Internal transition](https://github.com/JanSlobodnik/pre-publishing/blob/main/block-production.md) - in progress + - [ ] External transition - not documented yet + - [ ] [VRF function](https://github.com/openmina/openmina/blob/feat/block_producer/vrf_evaluator/vrf/README.md) - in progress +- Peer discovery/advertising + - [ ] [Peer discovery through Kademlia](https://github.com/openmina/openmina/blob/develop/p2p/readme.md#kademlia-for-peer-discovery) - in progress +- [x] [SNARK work](https://github.com/openmina/openmina/blob/main/docs/snark-work.md) - SNARK production is implemented (through OCaml). Node can complete and broadcast SNARK work. + - [ ] [Witness folding](https://github.com/JanSlobodnik/pre-publishing/blob/main/witness-folding.md) - in progress +- [ ] [Bootstrapping process](https://github.com/JanSlobodnik/pre-publishing/blob/main/bootstrap-catchup.md) - in progress +- [ ] Block application - not documented yet +- Testing + - [ ] [Testing framework](https://github.com/openmina/openmina/blob/main/docs/testing/testing.md) - partially complete (some tests are documented) +- How to run + - [x] [Launch Openmina node](https://github.com/openmina/openmina#how-to-launch-without-docker-compose) + - [x] [Launch Node with UI](https://github.com/openmina/openmina#how-to-launch-with-docker-compose) + - [x] [Launch Debugger](https://github.com/openmina/mina-network-debugger?tab=readme-ov-file#Preparing-for-build) + - [x] [Launch Web Node](https://github.com/openmina/webnode/blob/main/README.md#try-out-the-mina-web-node) + +## Experimental State Machine Architecture + +### Core state machine + +- [x] Automaton implementation that separates *action* kinds in *pure* and *effectful*. +- [x] Callback (dispatch-back) support for action composition: enable us to specify in the action itself the actions that will dispatched next. +- [x] Fully serializable state machine state and actions (including descriptors to callbacks!). +- State machine state management + - [x] Partitioning of the state machine state between models sub-states (for *pure* models). + - [x] Forbid direct access to state machine state in *effectful* models. + - [x] Support for running multiple instances concurrently in the same state machine for testing scenarios: for example if the state machine represents a node, we can "run" multiple of them inside the same state machine. + +### Models + +Each model handles a subset of actions and they are registered like a plugin system. + +#### Effectful + +Thin layer of abstraction between the "external world" (IO) and the state machine. + +- [x] MIO model: provides the abstraction layer for the polling and TCP APIs of the MIO crate. +- [x] Time model: provides the abstraction layer for `SystemTime::now()` + +#### Pure + +Handle state transitions and can dispatch actions to other models. + +- [x] Time model: this is the *pure* counterpart which dispatches an action to *effectful* time model to get the system time and updates the internal time in the state machine state. +- [x] TCP model: built on top of the MIO layer to provide all necessary features for handling TCP connections (it also uses the time model to provide timeout support for all actions). +- [x] TCP-client model: built on top of the TCP model, provides a high-level interface for building client applications. +- [x] TCP-server model: built on top of the TCP model, provides a high-level interface for building server applications. +- [x] PRNG model: unsafe, fast, pure RNG for testing purposes. +- PNET models: implements the private network transport used in libp2p. + - [x] Server + - [x] Client + - Testing models: + - [x] Echo client: connects to an echo server and sends random data, then checks that it receives the same data. + - [x] Echo server. + - [x] Echo client (PNET). + - [x] Echo server (PNET). + - [x] Simple PNET client: connects to berkeleynet and does a simple multistream negotiation. + +### Tests + +- Echo network + - [x] State machine with a network composed of 1 client and 1 server instance. + - [x] State machine with a network composed of 5 clients and 1 erver instance. + - [x] State machine with a network composed of 50 clients and 1 erver instance. +- [x] Echo network PNET (same tests as echo network but over the PNET transport). +- [x] Berkeley PNET test: runs the simple PNET client model. \ No newline at end of file diff --git a/tools/ledger-tool/Cargo.toml b/tools/ledger-tool/Cargo.toml new file mode 100644 index 000000000..886ab2576 --- /dev/null +++ b/tools/ledger-tool/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "ledger-tool" +version = "0.2.0" +edition = "2021" + +[dependencies] +serde = { version = "1.0" } +serde_json = { version = "1.0", features = ["preserve_order"] } +anyhow = { version = "1.0" } +structopt = { version = "0.3.26" } +reqwest = { version = "0.11.24", features = ["blocking"] } + +ledger = { path = "../../ledger", package = "mina-tree" } + +mina-p2p-messages = { workspace = true } +mina-signer = { workspace = true } +mina-curves = { workspace = true } diff --git a/tools/ledger-tool/README.md b/tools/ledger-tool/README.md new file mode 100644 index 000000000..1d0a83d4f --- /dev/null +++ b/tools/ledger-tool/README.md @@ -0,0 +1,9 @@ +# Converts mina genesis ledger from json to binprot format suitable for OpenMina + +Download json ledger [here](https://raw.githubusercontent.com/MinaProtocol/mina/2.0.0berkeley_rc1/genesis_ledgers/berkeley.json): + +Use the tool: + +``` +cargo run --release --bin ledger-tool -- --url https://raw.githubusercontent.com/MinaProtocol/mina/2.0.0berkeley_rc1/genesis_ledgers/berkeley.json --output genesis_ledgers/berkeley_genesis_ledger.bin +``` diff --git a/tools/ledger-tool/src/main.rs b/tools/ledger-tool/src/main.rs new file mode 100644 index 000000000..c20a363a0 --- /dev/null +++ b/tools/ledger-tool/src/main.rs @@ -0,0 +1,165 @@ +use std::{borrow::Cow, fs::File, path::PathBuf}; + +use reqwest::Url; +use serde::Deserialize; + +use ledger::{ + scan_state::currency::{Balance, Slot, SlotSpan}, + Account, BaseLedger, Database, Mask, Timing, +}; + +use mina_p2p_messages::{binprot::BinProtWrite, v2}; +use mina_signer::CompressedPubKey; + +use structopt::StructOpt; + +#[derive(StructOpt)] +struct Args { + #[structopt(short, long)] + input: Option, + #[structopt(long)] + url: Option, + #[structopt(short, long)] + output: PathBuf, +} + +fn parse_account(mut a: serde_json::Value) -> anyhow::Result { + let account_value = a + .as_object_mut() + .ok_or_else(|| anyhow::anyhow!("expected object"))?; + + let mut account = Account::empty(); + account.public_key = CompressedPubKey::from_address( + account_value + .remove("pk") + .ok_or_else(|| anyhow::anyhow!("expected field `pk`"))? + .clone() + .as_str() + .ok_or_else(|| anyhow::anyhow!("`pk` must be string"))?, + )?; + if let Some(balance) = account_value.remove("balance") { + let balance = balance + .as_str() + .ok_or_else(|| anyhow::anyhow!("`balance` must be string"))?; + let balance = if !balance.contains('.') { + Cow::Owned(format!("{balance}.000000000")) + } else { + Cow::Borrowed(balance) + }; + account.balance = Balance::of_mina_string_exn(&balance); + } + if let Some(delegate) = account_value + .remove("delegate") + .and_then(|a| a.as_str().map(ToOwned::to_owned)) + { + account.delegate = Some(CompressedPubKey::from_address(&delegate)?); + } else { + account.delegate = Some(account.public_key.clone()); + } + if let Some(timing) = account_value.remove("timing") { + #[derive(Deserialize, Debug)] + struct Timed { + initial_minimum_balance: String, + cliff_time: [String; 2], + cliff_amount: String, + vesting_period: [String; 2], + vesting_increment: String, + } + + let Timed { + mut initial_minimum_balance, + cliff_time, + mut cliff_amount, + vesting_period, + mut vesting_increment, + } = serde_json::from_value(timing.clone())?; + + if !initial_minimum_balance.contains('.') { + initial_minimum_balance.extend(".000000000".chars()); + } + if !cliff_amount.contains('.') { + cliff_amount.extend(".000000000".chars()); + } + if !vesting_increment.contains('.') { + vesting_increment.extend(".000000000".chars()); + } + + account.timing = Timing::Timed { + initial_minimum_balance: Balance::of_mina_string_exn(&initial_minimum_balance), + cliff_time: Slot::from_u32(cliff_time[1].parse()?), + cliff_amount: Balance::of_mina_string_exn(&cliff_amount).to_amount(), + vesting_period: SlotSpan::from_u32(vesting_period[1].parse()?), + vesting_increment: Balance::of_mina_string_exn(&vesting_increment).to_amount(), + }; + } + account_value.remove("sk"); + + if !account_value.is_empty() { + return Err(anyhow::anyhow!("the object contains unprocessed fields")); + } + + Ok(account) +} + +fn main() -> anyhow::Result<()> { + let Args { input, url, output } = Args::from_args(); + + let value = if let Some(input) = input { + let ledger_file = File::open(&input)?; + serde_json::from_reader::<_, serde_json::Value>(ledger_file)? + } else if let Some(url) = url { + reqwest::blocking::get(url)?.json()? + } else { + anyhow::bail!("must provide either `--input` or `--url`"); + }; + + let list = value + .as_object() + .ok_or_else(|| anyhow::anyhow!("expected object"))? + .get("ledger") + .ok_or_else(|| anyhow::anyhow!("expected field `ledger`"))? + .as_object() + .ok_or_else(|| anyhow::anyhow!("expected object"))? + .get("accounts") + .ok_or_else(|| anyhow::anyhow!("expected field `accounts`"))? + .as_array() + .ok_or_else(|| anyhow::anyhow!("expected array"))?; + + let genesis_winner_account = { + let mut account = Account::empty(); + account.public_key = CompressedPubKey::from_address( + "B62qiy32p8kAKnny8ZFwoMhYpBppM1DWVCqAPBYNcXnsAHhnfAAuXgg", + ) + .expect("the constant is valid"); + + account.balance = Balance::of_nanomina_int_exn(1000); + account.delegate = Some(account.public_key.clone()); + account + }; + + let mut accounts = vec![genesis_winner_account]; + let mut mask = Mask::new_root(Database::create(35)); + + for (n, item) in list.iter().enumerate() { + accounts.push( + parse_account(item.clone()) + .map_err(|err| anyhow::anyhow!("account: {n}, err: {err}"))?, + ); + } + + for account in &accounts { + let account_id = account.id(); + mask.get_or_create_account(account_id, account.clone()) + .expect("must not be full"); + } + + let root = mask.merkle_root(); + let top_hash = v2::LedgerHash::from(v2::MinaBaseLedgerHash0StableV1(root.into())); + println!("{top_hash}"); + + let mut output = File::create(&output)?; + Some(top_hash).binprot_write(&mut output)?; + accounts.binprot_write(&mut output)?; + + Ok(()) +} diff --git a/vrf/Cargo.toml b/vrf/Cargo.toml index 8c6d42691..d0265e5ec 100644 --- a/vrf/Cargo.toml +++ b/vrf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "vrf" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "Apache-2.0" diff --git a/vrf/src/lib.rs b/vrf/src/lib.rs index b5ab2b049..469d7728f 100644 --- a/vrf/src/lib.rs +++ b/vrf/src/lib.rs @@ -1,3 +1,6 @@ +// TODO: remove after finalization (once the num::* rexports have been removed) +#![allow(hidden_glob_reexports)] + use ark_ec::AffineCurve; use ark_ff::{BigInteger, BigInteger256, One, PrimeField, SquareRootField, Zero}; use ledger::AccountIndex; @@ -20,7 +23,7 @@ mod message; mod output; mod threshold; -// TODO: remove after finalization +// TODO: remove after finalization, and `hidden_glob_reexports` lint attribute at beginning of file pub use num::*; type VrfResult = std::result::Result;