diff --git a/.gitignore b/.gitignore index 9f04a5ed6..06b207bf7 100644 --- a/.gitignore +++ b/.gitignore @@ -14,17 +14,16 @@ target/ *.pdb # Default database location for the ledger -ledger.db +/*ledger.db/ # Default database location for the consensus -chain.db +/*chain.db/ # Insta not-yet reviewed snapshots *.snap.new # Files downloaded for the demo -snapshots/ -!crates/amaru/tests/snapshots +/snapshots/ # Files for local coverage reports coverage/ @@ -36,3 +35,6 @@ coverage/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. .idea/ *~ + +# Cardano node support files +/cardano-node-config/ diff --git a/Cargo.lock b/Cargo.lock index 436895921..4398e88e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,20 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "acto" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52632fc65e2b2dac7eb4f62e94c494a48ceecc8d2b81c5748dd19694850b548b" +dependencies = [ + "parking_lot", + "pin-project-lite", + "rustc_version", + "smol_str", + "tokio", + "tracing", +] + [[package]] name = "addr2line" version = "0.24.2" @@ -30,6 +44,7 @@ dependencies = [ name = "amaru" version = "0.1.0" dependencies = [ + "acto", "amaru-consensus", "amaru-kernel", "amaru-ledger", @@ -44,6 +59,7 @@ dependencies = [ "indicatif", "indoc", "insta", + "minicbor", "opentelemetry", "opentelemetry-otlp", "opentelemetry_sdk", @@ -54,6 +70,8 @@ dependencies = [ "pallas-traverse", "proptest", "rand 0.9.0", + "serde_json", + "slot-arithmetic", "sysinfo", "tempfile", "test-case", @@ -75,17 +93,20 @@ dependencies = [ "envpath", "hex", "insta", + "minicbor", "pallas-codec", "pallas-crypto", "pallas-math", "proptest", "rand 0.9.0", "rayon", + "serde_json", "slot-arithmetic", "tempfile", "thiserror 2.0.12", "tokio", "tracing", + "tracing-subscriber", ] [[package]] @@ -273,9 +294,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "assert-json-diff" @@ -462,9 +483,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.17" +version = "1.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "8e3a13707ac958681c13b39b458c073d0d9bc8a22cb1b2f4c8e55eb72c13f362" dependencies = [ "jobserver", "libc", @@ -499,9 +520,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +checksum = "2df961d8c8a0d08aa9945718ccf584145eee3f3aa06cddbeac12933781102e04" dependencies = [ "clap_builder", "clap_derive", @@ -509,9 +530,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.35" +version = "4.5.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +checksum = "132dbda40fb6753878316a489d5a1242a8ef2f0d9e47ba01c951ea8aa7d013a5" dependencies = [ "anstream", "anstyle", @@ -601,9 +622,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -893,9 +914,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1099,9 +1120,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "h2" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +checksum = "75249d144030531f8dee69fe9cea04d3edf809a017ae445e2abdff6629e86633" dependencies = [ "atomic-waker", "bytes", @@ -1109,7 +1130,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.8.0", + "indexmap 2.9.0", "slab", "tokio", "tokio-util", @@ -1118,9 +1139,9 @@ dependencies = [ [[package]] name = "half" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -1225,9 +1246,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-channel", @@ -1235,6 +1256,7 @@ dependencies = [ "http", "http-body", "hyper", + "libc", "pin-project-lite", "socket2", "tokio", @@ -1283,9 +1305,9 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" @@ -1307,9 +1329,9 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" @@ -1328,9 +1350,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" @@ -1393,9 +1415,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -1488,10 +1510,11 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" dependencies = [ + "getrandom 0.3.2", "libc", ] @@ -1540,9 +1563,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libgit2-sys" @@ -1615,9 +1638,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" @@ -1625,11 +1648,21 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "matchers" @@ -1681,9 +1714,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] @@ -1843,9 +1876,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "opaque-debug" @@ -2049,6 +2082,29 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + [[package]] name = "paste" version = "1.0.15" @@ -2126,9 +2182,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -2295,6 +2351,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "redox_syscall" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.6" @@ -2420,9 +2485,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags", "errno", @@ -2455,6 +2520,12 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "semver" version = "1.0.26" @@ -2610,15 +2681,21 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "smol_str" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2810,9 +2887,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.1" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", "bytes", @@ -3624,18 +3701,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 2d3b52abe..458ccf702 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ default-members = ["crates/*"] resolver = "2" [workspace.dependencies] +acto = { version = "0.7.2", features = ["tokio"] } anyhow = "1.0.95" async-trait = "0.1.83" bech32 = "0.11.0" diff --git a/Makefile b/Makefile index fc4d49ae5..5835c6767 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ DEMO_TARGET_EPOCH ?= 174 HASKELL_NODE_CONFIG_SOURCE := https://book.world.dev.cardano.org/environments COVERAGE_DIR ?= coverage COVERAGE_CRATES ?= +LISTEN_ADDRESS ?= 0.0.0.0:0 +LEDGER_DIR ?= ./ledger.db +CHAIN_DIR ?= ./chain.db .PHONY: help bootstrap run import-snapshots import-headers import-nonces download-haskell-config coverage-html coverage-lconv check-llvm-cov @@ -37,32 +40,44 @@ download-haskell-config: ## Download Cardano Haskell configuration for $NETWORK import-snapshots: snapshots ## Import PreProd snapshots for demo cargo run -- import-ledger-state \ + --ledger-dir $(LEDGER_DIR) \ --snapshot $^/69206375.6f99b5f3deaeae8dc43fce3db2f3cd36ad8ed174ca3400b5b1bed76fdf248912.cbor \ --snapshot $^/69638382.5da6ba37a4a07df015c4ea92c880e3600d7f098b97e73816f8df04bbb5fad3b7.cbor \ --snapshot $^/70070379.d6fe6439aed8bddc10eec22c1575bf0648e4a76125387d9e985e9a3f8342870d.cbor import-headers: ## Import headers from $AMARU_PEER_ADDRESS for demo cargo run -- import-headers \ + --chain-dir $(CHAIN_DIR) \ --peer-address ${AMARU_PEER_ADDRESS} \ --starting-point 69638365.4ec0f5a78431fdcc594eab7db91aff7dfd91c13cc93e9fbfe70cd15a86fadfb2 \ --count 2 cargo run -- import-headers \ + --chain-dir $(CHAIN_DIR) \ --peer-address ${AMARU_PEER_ADDRESS} \ --starting-point 70070331.076218aa483344e34620d3277542ecc9e7b382ae2407a60e177bc3700548364c \ --count 2 import-nonces: ## Import PreProd nonces for demo cargo run -- import-nonces \ + --chain-dir $(CHAIN_DIR) \ --at 70070379.d6fe6439aed8bddc10eec22c1575bf0648e4a76125387d9e985e9a3f8342870d \ --active a7c4477e9fcfd519bf7dcba0d4ffe35a399125534bc8c60fa89ff6b50a060a7a \ --candidate 74fe03b10c4f52dd41105a16b5f6a11015ec890a001a5253db78a779fe43f6b6 \ --evolving 24bb737ee28652cd99ca41f1f7be568353b4103d769c6e1ddb531fc874dd6718 \ --tail 5da6ba37a4a07df015c4ea92c880e3600d7f098b97e73816f8df04bbb5fad3b7 -bootstrap: import-headers import-nonces import-snapshots ## Bootstrap the node +clear-db: ## Clear the database + rm -rf $(LEDGER_DIR) $(CHAIN_DIR) + +bootstrap: clear-db import-headers import-nonces import-snapshots ## Bootstrap the node dev: ## Compile and run for development with default options - cargo run -- daemon --peer-address=$(AMARU_PEER_ADDRESS) --network=$(NETWORK) + cargo run -- daemon \ + --ledger-dir $(LEDGER_DIR) \ + --chain-dir $(CHAIN_DIR) \ + --peer-address $(AMARU_PEER_ADDRESS) \ + --network=$(NETWORK) \ + --listen-address $(LISTEN_ADDRESS) test-e2e: ## Run snapshot tests, assuming snapshots are available. cargo test -p amaru -- --ignored @@ -77,19 +92,19 @@ check-llvm-cov: ## Check if cargo-llvm-cov is installed, install if not coverage-html: check-llvm-cov ## Run test coverage for Amaru cargo llvm-cov \ - --no-cfg-coverage \ - --html \ + --no-cfg-coverage \ + --html \ --output-dir $(COVERAGE_DIR) $(foreach package,$(COVERAGE_CRATES), --package $(package)) coverage-lconv: ## Run test coverage for CI to upload to Codecov cargo llvm-cov \ - --all-features \ + --all-features \ --workspace \ --lcov \ --output-path lcov.info demo: ## Synchronize Amaru until a target epoch $DEMO_TARGET_EPOCH - ./scripts/demo.sh $(AMARU_PEER_ADDRESS) $(DEMO_TARGET_EPOCH) $(NETWORK) + LEDGER_DIR=$(LEDGER_DIR) CHAIN_DIR=$(CHAIN_DIR) ./scripts/demo.sh $(AMARU_PEER_ADDRESS) $(DEMO_TARGET_EPOCH) $(NETWORK) build-examples: ## Build all examples @for dir in $(wildcard examples/*/.); do \ diff --git a/README.md b/README.md index 3b1407a05..2a39486d8 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ cargo build --release > [!IMPORTANT] > These instructions assume one starts from scratch, and has access to a running [cardano-node](https://github.com/IntersectMBO/cardano-node/) -on the [preprod](https://book.world.dev.cardano.org/env-preprod.html) network. +on the [preprod](https://book.world.dev.cardano.org/env-preprod.html) network (see bottom of page for more info). 1. Download at least three [ledger snapshots](./data/README.md#cardano-ledger-snapshots): @@ -127,3 +127,22 @@ Amaru is the integration point of several other projects / repositories. Amongst | Discord Discord

+ +## Spinning up a Cardano node on `preprod` + +One option to do this is by using the docker image mentioned above: + +```sh +docker pull ghcr.io/intersectmbo/cardano-node:8.9.1 +``` + +(you may want to check available versions) +This image requires two volumes: + +- `cardano-data:/data` for the blockchain db +- `cardano-ipc:/ipc` for IPC with other tools + +Since we want to use network connections to interact with this node, you’ll want to expose port 3001, at least on `localhost`. + +The final and crucial ingredient is to supply the environment variable `NETWORK=preprod`. +With this, the node with start up, fetch the required config files, and then start syncing blocks from the network; this will take some time. diff --git a/crates/amaru-consensus/Cargo.lock b/crates/amaru-consensus/Cargo.lock deleted file mode 100644 index 80f93c270..000000000 --- a/crates/amaru-consensus/Cargo.lock +++ /dev/null @@ -1,2060 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "amaru" -version = "0.1.0" -dependencies = [ - "async-trait", - "clap", - "gasket", - "hex", - "miette 7.2.0", - "ouroboros", - "ouroboros-praos", - "pallas-codec", - "pallas-crypto", - "pallas-math", - "pallas-network", - "pallas-primitives", - "pallas-traverse", - "thiserror", - "tokio", - "tokio-util", - "tracing", - "tracing-subscriber", - "uplc", -] - -[[package]] -name = "anstream" -version = "0.6.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" - -[[package]] -name = "anstyle-parse" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" -dependencies = [ - "anstyle", - "windows-sys", -] - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "async-trait" -version = "0.1.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blst" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" -dependencies = [ - "cc", - "glob", - "threadpool", - "zeroize", -] - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" - -[[package]] -name = "cc" -version = "1.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "clap" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "clap_lex" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" - -[[package]] -name = "colorchoice" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crc" -version = "3.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" - -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "cryptoxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382ce8820a5bb815055d3553a610e8cb542b2d767bbacea99038afda96cd760d" - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "git+https://github.com/txpipe/curve25519-dalek?branch=ietf03_vrf_compat_ell2#70a36f41cfc3fbb7357ec3062201b911787decba" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek 4.1.3", - "ed25519", - "serde", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff", - "generic-array", - "group", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "fragile" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "gasket" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b60154514ed9e060f0b2b78819602fa5d68746d6b618efb2ea2fecc6f89f32" -dependencies = [ - "async-trait", - "crossbeam", - "gasket-derive", - "serde", - "signal-hook", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "gasket-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16f3b9da5c685c55178b9749f79bf6a6c62d1bd07656a0c8eeddadb80ef29c8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "half" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "k256" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2 0.10.8", - "signature", -] - -[[package]] -name = "kes-summed-ed25519" -version = "0.2.1" -source = "git+https://github.com/txpipe/kes?rev=f69fb357d46f6a18925543d785850059569d7e78#f69fb357d46f6a18925543d785850059569d7e78" -dependencies = [ - "blake2", - "ed25519-dalek", - "rand_core 0.6.4", - "thiserror", - "zeroize", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.159" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" - -[[package]] -name = "libm" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" - -[[package]] -name = "malachite" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5616515d632967cd329b6f6db96be9a03ea0b3a49cdbc45b0016803dad8a77b7" -dependencies = [ - "malachite-base", - "malachite-nz", - "malachite-q", -] - -[[package]] -name = "malachite-base" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46059721011b0458b7bd6d9179be5d0b60294281c23320c207adceaecc54d13b" -dependencies = [ - "hashbrown 0.14.5", - "itertools 0.11.0", - "libm", - "ryu", -] - -[[package]] -name = "malachite-nz" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1503b27e825cabd1c3d0ff1e95a39fb2ec9eab6fd3da6cfa41aec7091d273e78" -dependencies = [ - "itertools 0.11.0", - "libm", - "malachite-base", -] - -[[package]] -name = "malachite-q" -version = "0.4.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a475503a70a3679dbe3b9b230a23622516742528ba614a7b2490f180ea9cb514" -dependencies = [ - "itertools 0.11.0", - "malachite-base", - "malachite-nz", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "miette" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" -dependencies = [ - "miette-derive 5.10.0", - "once_cell", - "thiserror", - "unicode-width", -] - -[[package]] -name = "miette" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" -dependencies = [ - "cfg-if", - "miette-derive 7.2.0", - "thiserror", - "unicode-width", -] - -[[package]] -name = "miette-derive" -version = "5.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "miette-derive" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "minicbor" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d15f4203d71fdf90903c2696e55426ac97a363c67b218488a73b534ce7aca10" -dependencies = [ - "half", - "minicbor-derive", -] - -[[package]] -name = "minicbor-derive" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1154809406efdb7982841adb6311b3d095b46f78342dd646736122fe6b19e267" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", -] - -[[package]] -name = "mockall" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c28b3fb6d753d28c20e826cd46ee611fda1cf3cde03a443a974043247c065a" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "341014e7f530314e9a1fdbc7400b244efea7122662c96bfa248c31da5bfb2020" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.36.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "ouroboros" -version = "0.1.0" -source = "git+https://github.com/pragma-org/ouroboros?rev=5d914a7e8435a1860cf7747d15db9692c2a06110#5d914a7e8435a1860cf7747d15db9692c2a06110" -dependencies = [ - "async-trait", - "hex", - "mockall", - "pallas-codec", - "pallas-crypto", - "serde", - "thiserror", -] - -[[package]] -name = "ouroboros-praos" -version = "0.1.0" -source = "git+https://github.com/pragma-org/ouroboros?rev=5d914a7e8435a1860cf7747d15db9692c2a06110#5d914a7e8435a1860cf7747d15db9692c2a06110" -dependencies = [ - "hex", - "ouroboros", - "pallas-crypto", - "pallas-math", - "pallas-primitives", - "rayon", - "tracing", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "pallas-addresses" -version = "0.30.2" -source = "git+https://github.com/txpipe/pallas?rev=4871342a8deffaceafb5e0f771e1623dfe57e25f#4871342a8deffaceafb5e0f771e1623dfe57e25f" -dependencies = [ - "base58", - "bech32", - "crc", - "cryptoxide", - "hex", - "pallas-codec", - "pallas-crypto", - "thiserror", -] - -[[package]] -name = "pallas-codec" -version = "0.30.2" -source = "git+https://github.com/txpipe/pallas?rev=4871342a8deffaceafb5e0f771e1623dfe57e25f#4871342a8deffaceafb5e0f771e1623dfe57e25f" -dependencies = [ - "hex", - "minicbor", - "num-bigint", - "serde", - "thiserror", -] - -[[package]] -name = "pallas-crypto" -version = "0.30.2" -source = "git+https://github.com/txpipe/pallas?rev=4871342a8deffaceafb5e0f771e1623dfe57e25f#4871342a8deffaceafb5e0f771e1623dfe57e25f" -dependencies = [ - "cryptoxide", - "hex", - "kes-summed-ed25519", - "pallas-codec", - "rand_core 0.6.4", - "serde", - "thiserror", - "vrf_dalek", - "zeroize", -] - -[[package]] -name = "pallas-math" -version = "0.30.2" -source = "git+https://github.com/txpipe/pallas?rev=4871342a8deffaceafb5e0f771e1623dfe57e25f#4871342a8deffaceafb5e0f771e1623dfe57e25f" -dependencies = [ - "malachite", - "malachite-base", - "once_cell", - "regex", - "thiserror", -] - -[[package]] -name = "pallas-network" -version = "0.30.2" -source = "git+https://github.com/txpipe/pallas?rev=4871342a8deffaceafb5e0f771e1623dfe57e25f#4871342a8deffaceafb5e0f771e1623dfe57e25f" -dependencies = [ - "byteorder", - "hex", - "itertools 0.13.0", - "pallas-codec", - "pallas-crypto", - "rand", - "socket2", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "pallas-primitives" -version = "0.30.2" -source = "git+https://github.com/txpipe/pallas?rev=4871342a8deffaceafb5e0f771e1623dfe57e25f#4871342a8deffaceafb5e0f771e1623dfe57e25f" -dependencies = [ - "base58", - "bech32", - "hex", - "log", - "pallas-codec", - "pallas-crypto", - "serde", - "serde_json", -] - -[[package]] -name = "pallas-traverse" -version = "0.30.2" -source = "git+https://github.com/txpipe/pallas?rev=4871342a8deffaceafb5e0f771e1623dfe57e25f#4871342a8deffaceafb5e0f771e1623dfe57e25f" -dependencies = [ - "hex", - "itertools 0.13.0", - "pallas-addresses", - "pallas-codec", - "pallas-crypto", - "pallas-primitives", - "paste", - "serde", - "thiserror", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "peg" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a" - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "predicates" -version = "3.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" -dependencies = [ - "anstyle", - "predicates-core", -] - -[[package]] -name = "predicates-core" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" - -[[package]] -name = "predicates-tree" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "pretty" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f3aa1e3ca87d3b124db7461265ac176b40c277f37e503eaa29c9c75c037846" -dependencies = [ - "arrayvec", - "log", - "typed-arena", - "unicode-segmentation", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] - -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "regex" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata 0.4.8", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "secp256k1" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" -dependencies = [ - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" -dependencies = [ - "cc", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "serde" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "serde_json" -version = "1.0.128" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "termtree" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" - -[[package]] -name = "thiserror" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "thread_local" -version = "1.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "threadpool" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" -dependencies = [ - "num_cpus", -] - -[[package]] -name = "tokio" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "tokio-util" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "uplc" -version = "1.1.4" -source = "git+https://github.com/aiken-lang/aiken?branch=amaru-demo#310e0717a10670da57ff9923f6c78fddd1e16116" -dependencies = [ - "blst", - "cryptoxide", - "hex", - "indexmap", - "itertools 0.10.5", - "k256", - "miette 5.10.0", - "num-bigint", - "num-integer", - "num-traits", - "once_cell", - "pallas-addresses", - "pallas-codec", - "pallas-crypto", - "pallas-primitives", - "pallas-traverse", - "peg", - "pretty", - "secp256k1", - "serde", - "serde_json", - "strum", - "strum_macros", - "thiserror", -] - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vrf_dalek" -version = "0.1.0" -source = "git+https://github.com/txpipe/vrf?rev=044b45a1a919ba9d9c2471fc5c4d441f13086676#044b45a1a919ba9d9c2471fc5c4d441f13086676" -dependencies = [ - "curve25519-dalek 3.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "curve25519-dalek 3.2.0 (git+https://github.com/txpipe/curve25519-dalek?branch=ietf03_vrf_compat_ell2)", - "rand_core 0.5.1", - "sha2 0.9.9", - "thiserror", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", -] diff --git a/crates/amaru-consensus/Cargo.toml b/crates/amaru-consensus/Cargo.toml index 9745b7d58..485cb0197 100644 --- a/crates/amaru-consensus/Cargo.toml +++ b/crates/amaru-consensus/Cargo.toml @@ -30,6 +30,9 @@ slot-arithmetic.workspace = true envpath.workspace = true hex.workspace = true insta.workspace = true +minicbor.workspace = true proptest.workspace = true rand.workspace = true +serde_json.workspace = true tempfile.workspace = true +tracing-subscriber.workspace = true diff --git a/crates/amaru/Cargo.toml b/crates/amaru/Cargo.toml index 20ebb65e2..5e20b6efc 100644 --- a/crates/amaru/Cargo.toml +++ b/crates/amaru/Cargo.toml @@ -14,12 +14,14 @@ rust-version.workspace = true build = "build.rs" [dependencies] +acto.workspace = true async-trait.workspace = true clap.workspace = true gasket.workspace = true hex.workspace = true indicatif.workspace = true indoc.workspace = true +minicbor.workspace = true opentelemetry-otlp.workspace = true opentelemetry.workspace = true opentelemetry_sdk.workspace = true @@ -28,6 +30,8 @@ pallas-crypto.workspace = true pallas-network.workspace = true pallas-primitives.workspace = true pallas-traverse.workspace = true +serde_json.workspace = true +slot-arithmetic.workspace = true sysinfo.workspace = true thiserror.workspace = true tokio = { workspace = true, features = ["rt", "rt-multi-thread", "signal"] } diff --git a/crates/amaru/src/bin/amaru/cmd/daemon.rs b/crates/amaru/src/bin/amaru/cmd/daemon.rs index 17b2d4666..944a414bd 100644 --- a/crates/amaru/src/bin/amaru/cmd/daemon.rs +++ b/crates/amaru/src/bin/amaru/cmd/daemon.rs @@ -50,6 +50,14 @@ pub struct Args { /// Path of the chain on-disk storage. #[arg(long, value_name = "DIR", default_value = super::DEFAULT_CHAIN_DB_DIR)] chain_dir: PathBuf, + + /// The address to listen on for incoming connections. + #[arg(long, value_name = "LISTEN_ADDRESS", default_value = super::DEFAULT_LISTEN_ADDRESS)] + listen_address: String, + + /// The maximum number of downstream peers to connect to. + #[arg(long, value_name = "MAX_DOWNSTREAM_PEERS", default_value_t = 10)] + max_downstream_peers: usize, } pub async fn run( @@ -106,5 +114,8 @@ fn parse_args(args: Args) -> Result> { chain_dir: args.chain_dir, upstream_peers: args.peer_address, network: args.network, + network_magic: args.network.to_network_magic(), + listen_address: args.listen_address, + max_downstream_peers: args.max_downstream_peers, }) } diff --git a/crates/amaru/src/bin/amaru/cmd/mod.rs b/crates/amaru/src/bin/amaru/cmd/mod.rs index d37f02711..2b08cf096 100644 --- a/crates/amaru/src/bin/amaru/cmd/mod.rs +++ b/crates/amaru/src/bin/amaru/cmd/mod.rs @@ -25,6 +25,9 @@ pub(crate) const DEFAULT_LEDGER_DB_DIR: &str = "./ledger.db"; /// Default path to the on-disk chain storage. pub(crate) const DEFAULT_CHAIN_DB_DIR: &str = "./chain.db"; +/// Default address to listen on for incoming connections. +pub(crate) const DEFAULT_LISTEN_ADDRESS: &str = "0.0.0.0:3000"; + /// Utility function to parse a point from a string. /// /// Expects the input to be of the form '.', where `` is a number and `` diff --git a/crates/amaru/src/stages/consensus/chain_forward.rs b/crates/amaru/src/stages/consensus/chain_forward.rs index 1e96bb9f0..0ea58e0fa 100644 --- a/crates/amaru/src/stages/consensus/chain_forward.rs +++ b/crates/amaru/src/stages/consensus/chain_forward.rs @@ -12,13 +12,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -use amaru_consensus::consensus::store::ChainStore; +use crate::stages::PallasPoint; +use acto::{AcTokio, ActoCell, ActoMsgSuper, ActoRef, ActoRuntime}; +use amaru_consensus::{consensus::store::ChainStore, IsHeader}; use amaru_kernel::{Hash, Header}; use amaru_ledger::BlockValidationResult; +use client_protocol::{client_protocols, ClientProtocolMsg}; use gasket::framework::*; -use std::sync::Arc; -use tokio::sync::Mutex; -use tracing::trace_span; +use pallas_network::{ + facades::PeerServer, + miniprotocols::{chainsync::Tip, Point}, +}; +use std::{cell::RefCell, collections::HashMap, sync::Arc}; +use tokio::{ + net::TcpListener, + sync::{ + mpsc::{self, Receiver}, + Mutex, + }, + task::JoinHandle, +}; +use tracing::{error, info, trace_span}; pub type UpstreamPort = gasket::messaging::InputPort; @@ -26,54 +40,213 @@ pub const EVENT_TARGET: &str = "amaru::consensus::chain_forward"; /// Forwarding stage of the consensus where blocks are stored and made /// available to downstream peers. -/// -/// TODO: currently does nothing, should store block, update chain state, and -/// forward new chain downstream #[derive(Stage)] -#[stage( - name = "consensus.forward", - unit = "BlockValidationResult", - worker = "Worker" -)] +#[stage(name = "consensus.forward", unit = "Unit", worker = "Worker")] pub struct ForwardStage { pub store: Arc>>, pub upstream: UpstreamPort, + pub network_magic: u64, + pub runtime: AcTokio, + pub listen_address: String, + pub downstream: ActoRef, + pub max_peers: usize, + pub our_tip: Tip, +} + +#[derive(Debug, Clone)] +pub enum ForwardEvent { + Listening(u16), + Forward(Point), + Backward(Point), } impl ForwardStage { - pub fn new(store: Arc>>) -> Self { + pub fn new( + downstream: Option>, + store: Arc>>, + network_magic: u64, + listen_address: &str, + max_peers: usize, + our_tip: Tip, + ) -> Self { + #[allow(clippy::expect_used)] + let runtime = + AcTokio::new("consensus.forward", 1).expect("failed to create AcTokio runtime"); Self { store, upstream: Default::default(), + network_magic, + runtime, + listen_address: listen_address.to_string(), + downstream: downstream.unwrap_or_else(ActoRef::blackhole), + max_peers, + our_tip, } } } -pub struct Worker {} +pub enum Unit { + Peer(RefCell>), + Block(BlockValidationResult), +} + +pub struct Worker { + server: JoinHandle<()>, + incoming_peers: Receiver, + our_tip: Tip, + clients: ActoRef, +} + +impl Drop for Worker { + fn drop(&mut self) { + self.server.abort(); + } +} + +#[allow(clippy::large_enum_variant)] +#[derive(Clone)] +enum ClientOp { + /// the tip to go back to + Backward(Tip), + /// the header to go forward to and the tip we will be at after sending this header + Forward(Header, Tip), +} + +impl std::fmt::Debug for ClientOp { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Backward(tip) => f + .debug_struct("Backward") + .field("tip", &(tip.1, PrettyPoint(&tip.0))) + .finish(), + Self::Forward(header, tip) => f + .debug_struct("Forward") + .field( + "header", + &(header.block_height(), PrettyPoint(&header.pallas_point())), + ) + .field("tip", &(tip.1, PrettyPoint(&tip.0))) + .finish(), + } + } +} + +struct PrettyPoint<'a>(&'a Point); + +impl std::fmt::Debug for PrettyPoint<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "({}, {})", + self.0.slot_or_default(), + hex::encode(hash_point(self.0)) + ) + } +} + +fn hash_point(point: &Point) -> Hash<32> { + match point { + Point::Origin => Hash::from([0; 32]), + Point::Specific(_slot, hash) => Hash::from(hash.as_slice()), + } +} + +impl PartialEq for ClientOp { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Backward(l0), Self::Backward(r0)) => (&l0.0, l0.1) == (&r0.0, r0.1), + (Self::Forward(l0, l1), Self::Forward(r0, r1)) => { + l0 == r0 && (&l1.0, l1.1) == (&r1.0, r1.1) + } + _ => false, + } + } +} + +impl Eq for ClientOp {} + +impl ClientOp { + pub fn tip(&self) -> Tip { + match self { + ClientOp::Backward(tip) => tip.clone(), + ClientOp::Forward(_, tip) => tip.clone(), + } + } +} #[async_trait::async_trait(?Send)] impl gasket::framework::Worker for Worker { - async fn bootstrap(_stage: &ForwardStage) -> Result { - Ok(Self {}) + async fn bootstrap(stage: &ForwardStage) -> Result { + let server = TcpListener::bind(&stage.listen_address).await.or_panic()?; + tracing::debug!("sending listening event"); + stage.downstream.send(ForwardEvent::Listening( + server.local_addr().or_panic()?.port(), + )); + + let (tx, incoming_peers) = mpsc::channel(10); + + let clients = stage + .runtime + .spawn_actor("chain_forward", |cell| { + client_supervisor(cell, stage.store.clone(), stage.max_peers) + }) + .me; + + let network_magic = stage.network_magic; + let server = tokio::spawn(async move { + loop { + // due to the signature of TcpListener::accept, this is the only way to use this API + // in particular, it isn’t possible to poll for new peers within the `schedule` method + let peer = match PeerServer::accept(&server, network_magic).await { + Ok(peer) => peer, + Err(e) => { + tracing::warn!( + target: EVENT_TARGET, + "error accepting peer: {e}", + ); + continue; + } + }; + + match tx.send(peer).await { + Ok(_) => {} + Err(e) => { + tracing::info!( + target: EVENT_TARGET, + "dropping incoming connection: {e}" + ); + } + } + } + }); + + Ok(Self { + server, + incoming_peers, + our_tip: stage.our_tip.clone(), + clients, + }) } async fn schedule( &mut self, stage: &mut ForwardStage, - ) -> Result, WorkerError> { - let unit = stage.upstream.recv().await.or_panic()?; - - Ok(WorkSchedule::Unit(unit.payload)) + ) -> Result, WorkerError> { + tokio::select! { + block = stage.upstream.recv() => Ok(WorkSchedule::Unit(Unit::Block(block.or_panic()?.payload))), + peer = self.incoming_peers.recv() => { + match peer { + Some(peer) => Ok(WorkSchedule::Unit(Unit::Peer(RefCell::new(Some(peer))))), + None => Err(WorkerError::Panic), + } + } + } } - async fn execute( - &mut self, - unit: &BlockValidationResult, - _stage: &mut ForwardStage, - ) -> Result<(), WorkerError> { + async fn execute(&mut self, unit: &Unit, stage: &mut ForwardStage) -> Result<(), WorkerError> { match unit { - BlockValidationResult::BlockValidated(point, span) => { + Unit::Block(BlockValidationResult::BlockValidated(point, span)) => { // FIXME: this span is just a placeholder to hold a link to t // the parent, it will be filled once we had the storage and // forwarding logic. @@ -85,30 +258,134 @@ impl gasket::framework::Worker for Worker { hash = %Hash::<32>::from(point), ); + // FIXME: block height should be part of BlockValidated message + let store = stage.store.lock().await; + if let Some(header) = store.load_header(&Hash::from(point)) { + // assert that the new tip is a direct successor of the old tip + assert_eq!(header.block_height(), self.our_tip.1 + 1); + match header.parent() { + Some(parent) => assert_eq!( + Point::new(self.our_tip.0.slot_or_default(), parent.as_ref().to_vec()), + self.our_tip.0 + ), + None => assert_eq!(self.our_tip.0, Point::Origin), + } + + self.our_tip = Tip(point.pallas_point(), header.block_height()); + self.clients.send(ClientMsg::Op(ClientOp::Forward( + header, + self.our_tip.clone(), + ))); + + stage + .downstream + .send(ForwardEvent::Forward(point.pallas_point())); + } + Ok(()) } - BlockValidationResult::BlockValidationFailed(point, span) => { - let _span = trace_span!( + Unit::Block(BlockValidationResult::RolledBackTo(point, span)) => { + info!( target: EVENT_TARGET, parent: span, - "forward.block_validation_failed", slot = ?point.slot_or_default(), hash = %Hash::<32>::from(point), + "rolled_back_to" ); - Err(WorkerError::Panic) + // FIXME: block height should be part of BlockValidated message + let store = stage.store.lock().await; + if let Some(header) = store.load_header(&Hash::from(point)) { + self.our_tip = Tip(point.pallas_point(), header.block_height()); + self.clients + .send(ClientMsg::Op(ClientOp::Backward(self.our_tip.clone()))); + + stage + .downstream + .send(ForwardEvent::Backward(point.pallas_point())); + } + + Ok(()) } - BlockValidationResult::RolledBackTo(point, span) => { - let _span = trace_span!( + Unit::Block(BlockValidationResult::BlockValidationFailed(point, span)) => { + error!( target: EVENT_TARGET, parent: span, - "rolled_back_to", slot = ?point.slot_or_default(), hash = %Hash::<32>::from(point), + "block_validation_failed" ); Ok(()) } + Unit::Peer(peer) => { + // FIXME: gasket design bug that we only get &Unit and thus cannot take values from it without internal mutability + let peer = peer.borrow_mut().take(); + if let Some(peer) = peer { + self.clients + .send(ClientMsg::Peer(peer, self.our_tip.clone())); + } else { + tracing::error!(target: EVENT_TARGET, "Unit::Peer was empty in execute"); + } + Ok(()) + } + } + } +} + +#[allow(clippy::large_enum_variant)] +enum ClientMsg { + /// A new peer has connected to us. + /// + /// Our tip is included to get the connection handlers started correctly. + Peer(PeerServer, Tip), + /// An operation to be executed on all clients. + Op(ClientOp), +} + +async fn client_supervisor( + mut cell: ActoCell>, + store: Arc>>, + max_peers: usize, +) { + let mut clients = HashMap::new(); + while let Some(msg) = cell.recv().await.has_senders() { + match msg { + ActoMsgSuper::Message(ClientMsg::Peer(peer, tip)) => { + let addr = peer + .accepted_address() + .map(|a| a.to_string()) + .unwrap_or_default(); + + if clients.len() >= max_peers { + tracing::warn!(target: EVENT_TARGET, "max peers reached, dropping peer from {addr}"); + continue; + } + + let client = cell.spawn_supervised(&addr, { + let store = store.clone(); + move |cell| client_protocols(cell, peer, store, tip) + }); + clients.insert(client.id(), client); + } + ActoMsgSuper::Message(ClientMsg::Op(op)) => { + for client in clients.values() { + client.send(ClientProtocolMsg::Op(op.clone())); + } + } + ActoMsgSuper::Supervision { id, name, result } => { + tracing::info!(target: EVENT_TARGET, "client {} terminated: {:?}", name, result); + clients.remove(&id); + } } } } + +mod client_protocol; +mod client_state; + +#[cfg(test)] +mod tests; + +#[cfg(test)] +mod test_infra; diff --git a/crates/amaru/src/stages/consensus/chain_forward/README.md b/crates/amaru/src/stages/consensus/chain_forward/README.md new file mode 100644 index 000000000..3507ed0e4 --- /dev/null +++ b/crates/amaru/src/stages/consensus/chain_forward/README.md @@ -0,0 +1,38 @@ +# chain_forward: Downstream Server + +![diagram](./chain_forward.png) + +This stage needs to handle a high degree of concurrency due to + +- getting block validation results +- receiving new client connections +- receiving various requests from those clients + +Placing all these functions into one state machine is impractical due to the multiplicative state complexity explosion. +The current design therefore splits up the state into non-concurrent pieces and places each piece within an [`acto`](https://docs.rs/acto) actor. +Currently, only the chain sync and keep alive protocols are fully implemented. + +## Accepting client connections + +This functionality is given by the `PeerServer::accept` async function from Pallas, which in turn inherits its API design constraints from the Tokio [`TcpListener`](https://docs.rs/tokio/latest/tokio/net/struct.TcpListener.html). +Since its `accept` method borrows `self`, this async function cannot be spawned as a separate task, nor can its `Future` be stored within the `ForwardStage` without using `unsafe`; this API can only be used within another async function calling `accept` in a loop. +Therefore, such a task is spawned from the worker’s `bootstrap` hook and will send received connections to the worker via a bounded queue. + +## Handling client requests + +The `PeerServer` API bundles miniprotocol instances for each of the supported protocols, but unfortunately, using these instances via the `PeerServer` requires an exclusive reference, so the `PeerServer` needs to be deconstructed in order to allow concurrent usage of the protocols (like concurrently waiting for requests). +Each of the protocol instances is managed by one actor whose sole responsibility is to react to client requests as appropriate. +For `keepalive` this is trivial because no further information is needed to answer a request. +In the case of `chainsync` this actor needs to obtain information regarding the current best chain and consequently the list of outstanding header operations (roll forward or backward) in order to respond to requests for the next header. +Since it is impossible to await the next client request while staying responsive to incoming block validation updates, these two responsibilities need to be separated into two actors: + +- `chain_sync` handles block validation updates and tracks them relative to the latest communicated state with the client +- `chain_sync_handler` handles client requests + +Since `chain_sync` has no otherwise forbidding responsibilities, it stays responsive to requests from the `chain_sync_handler`. +This concurrency is the minimum required complexity to solve this problem, i.e. the split into these two actors should yield optimal readability and maintainability of the resulting code. +A further simplification of the communication between these two actors is achieved by performing the intersect part of the protocol — which must happen first — within the `chain_sync` actor before handing off the header requests part to the `chain_sync_handler`; +this is possible because I presume one intersection request to be a precondition for the first header request. + +Between the level of per-protocol actors for one client and the overall client supervisor there is an additional level of per-client supervision in the `client_protocols` actors that serves to bundle the miniprotocols spoken over one client connection. +The effect is that failure in one protocol will tear down the others and the connection as well. diff --git a/crates/amaru/src/stages/consensus/chain_forward/chain_forward.d2 b/crates/amaru/src/stages/consensus/chain_forward/chain_forward.d2 new file mode 100644 index 000000000..34f7e881d --- /dev/null +++ b/crates/amaru/src/stages/consensus/chain_forward/chain_forward.d2 @@ -0,0 +1,126 @@ +title: { + label: "internal design of the chain_forward stage" + near: top-center + shape: text + style.font-size: 24 + style.bold: true +} + +# Styles +classes: { + component: { + style: { + stroke: "#2a2a2a" + fill: "#ffffff" + font-color: "#2a2a2a" + border-radius: 10 + shadow: true + } + } + container: { + style: { + stroke: "#2a2a2a" + fill: "#f5f5f5" + font-color: "#2a2a2a" + border-radius: 10 + shadow: true + } + } + subcomponent: { + style: { + stroke: "#666666" + fill: "#ffffff" + font-color: "#2a2a2a" + border-radius: 5 + shadow: false + } + } +} + +prev: { + class: component + label: "BlockValidationResult" +} + +chain_forward: { + class: container + label: "chain_forward" + + accept: { + class: component + label: "TcpListener accept task" + } + + stage: { + class: component + label: "" + t: |md + ### ForwardStage / Worker + tracks current `tip` + | + } + + AcTokio: { + class: component + + client_supervisor: { + class: subcomponent + label: "" + t: |md + ### client_supervisor + maintains a map of live client actors + | + } + + client_protocols: { + class: subcomponent + label: "" + t: |md + ### client_protocols + supervises the per-miniprotocol actors + | + } + + chain_sync: { + class: subcomponent + label: "" + t: |md + ### chain_sync + performs initial intersection and
+ tracks outstanding messages to be sent to the client + | + } + chain_sync_handler: { + class: subcomponent + label: "" + t: |md + ### chain_sync_handler + runs the `chainsync::Server` mini-protocol + | + } + + block_fetch: {class: subcomponent} + tx_submission: {class: subcomponent} + keep_alive: { + class: subcomponent + label: "" + t: |md + ### keep_alive + runs the `keepalive` ping pong protocol + | + } + + client_supervisor -> client_protocols: "spawns for each client connection\nand forwards block updates to all" + client_protocols -> chain_sync: "forwards block updates" + chain_sync -> chain_sync_handler: "sends server responses" + chain_sync_handler -> chain_sync: "requests headers" + client_protocols -> block_fetch + client_protocols -> tx_submission + client_protocols -> keep_alive + } + + accept -> stage: "new connections as `PeerServer`" + stage -> AcTokio.client_supervisor: "forwards block updates or received connections" +} + +prev -> chain_forward.stage diff --git a/crates/amaru/src/stages/consensus/chain_forward/chain_forward.png b/crates/amaru/src/stages/consensus/chain_forward/chain_forward.png new file mode 100644 index 000000000..65b8342f4 Binary files /dev/null and b/crates/amaru/src/stages/consensus/chain_forward/chain_forward.png differ diff --git a/crates/amaru/src/stages/consensus/chain_forward/client_protocol.rs b/crates/amaru/src/stages/consensus/chain_forward/client_protocol.rs new file mode 100644 index 000000000..058363e68 --- /dev/null +++ b/crates/amaru/src/stages/consensus/chain_forward/client_protocol.rs @@ -0,0 +1,250 @@ +use super::{ + client_state::{find_headers_between, ClientState}, + ClientOp, +}; +use acto::{ActoCell, ActoInput, ActoRef, ActoRuntime}; +use amaru_consensus::consensus::store::ChainStore; +use amaru_kernel::{to_cbor, Header}; +use pallas_network::{ + facades::PeerServer, + miniprotocols::{ + blockfetch, + chainsync::{self, ClientRequest, HeaderContent, Tip}, + keepalive, txsubmission, + }, +}; +use std::sync::Arc; +use tokio::sync::Mutex; + +#[derive(Debug, thiserror::Error)] +pub enum ClientError { + #[error("client asked for headers before intersection was found")] + EarlyRequestNext, + #[error("no intersection found")] + NoIntersection, + #[error("client asked for intersection after it was already found")] + LateIntersection, + #[error("client terminated")] + ClientTerminated, + #[error("handler failure: {0}")] + HandlerFailure(String), +} + +pub enum ClientProtocolMsg { + Op(ClientOp), +} + +pub async fn client_protocols( + mut cell: ActoCell>, + server: PeerServer, + store: Arc>>, + our_tip: Tip, +) -> anyhow::Result<()> { + let _block_fetch = cell.spawn_supervised("block_fetch", { + let store = store.clone(); + move |cell| block_fetch(cell, server.blockfetch, store) + }); + let _tx_submission = cell.spawn_supervised("tx_submission", move |cell| { + tx_submission(cell, server.txsubmission) + }); + let _keep_alive = + cell.spawn_supervised("keep_alive", move |cell| keep_alive(cell, server.keepalive)); + + let chain_sync = cell.spawn_supervised("chain_sync", move |cell| { + chain_sync(cell, server.chainsync, our_tip, store) + }); + + while let ActoInput::Message(msg) = cell.recv().await { + match msg { + ClientProtocolMsg::Op(op) => chain_sync.send(ChainSyncMsg::Op(op)), + }; + } + + Ok(()) +} + +#[allow(clippy::large_enum_variant)] +pub enum ChainSyncMsg { + /// An operation coming in from the ledger + Op(ClientOp), + /// A request for data from the client + ReqNext, +} + +async fn chain_sync( + mut cell: ActoCell>, + mut server: chainsync::Server, + our_tip: Tip, + store: Arc>>, +) -> anyhow::Result<()> { + // TODO: do we need to handle validation updates already here in case the client is really slow to ask for intersection? + let Some(ClientRequest::Intersect(req)) = server.recv_while_idle().await? else { + // need an intersection point to start + return Err(ClientError::EarlyRequestNext.into()); + }; + + tracing::debug!("finding headers between {:?} and {:?}", our_tip.0, req); + let Some((catch_up, client_at)) = find_headers_between(&*store.lock().await, &our_tip.0, &req) + else { + tracing::debug!("no intersection found"); + server.send_intersect_not_found(our_tip).await?; + return Err(ClientError::NoIntersection.into()); + }; + tracing::debug!("intersection found: {client_at:?}"); + server + .send_intersect_found(client_at.0.clone(), our_tip.clone()) + .await?; + + let parent = cell.me(); + let handler = cell.spawn_supervised("chainsync_handler", move |cell| { + chain_sync_handler(cell, server, parent) + }); + + let mut state = ClientState::new(catch_up.into()); + let mut our_tip = our_tip; + let mut waiting = false; + loop { + let input = cell.recv().await; + match input { + ActoInput::Message(ChainSyncMsg::Op(op)) => { + tracing::debug!("got op {op:?}"); + our_tip = op.tip(); + state.add_op(op); + if waiting { + if let Some(op) = state.next_op() { + tracing::debug!("sending op {op:?} to waiting handler"); + waiting = false; + handler.send(Some((op, our_tip.clone()))); + } + } + } + ActoInput::Message(ChainSyncMsg::ReqNext) => { + tracing::debug!("got req next"); + if let Some(op) = state.next_op() { + tracing::debug!("sending op {op:?} to handler"); + handler.send(Some((op, our_tip.clone()))); + } else { + tracing::debug!("sending await reply"); + handler.send(None); + waiting = true; + } + } + ActoInput::NoMoreSenders => { + tracing::debug!("no more senders"); + return Ok(()); + } + ActoInput::Supervision { result, .. } => { + tracing::debug!("supervision result: {result:?}"); + return result + .map_err(|e| anyhow::Error::from(ClientError::HandlerFailure(e.to_string()))) + .and_then(|x| x); + } + } + } +} + +/// This actor handles the ReqNext part of the chainsync protocol. +/// It will ask the parent for the next operation whenever needed. +/// The parent may respond with None to indicate the need to await, then it will eventually send the next operation. +async fn chain_sync_handler( + mut cell: ActoCell, impl ActoRuntime>, + mut server: chainsync::Server, + parent: ActoRef, +) -> anyhow::Result<()> { + loop { + let Some(req) = server.recv_while_idle().await? else { + tracing::debug!("client terminated"); + return Err(ClientError::ClientTerminated.into()); + }; + if !matches!(req, ClientRequest::RequestNext) { + tracing::debug!("late intersection"); + return Err(ClientError::LateIntersection.into()); + }; + tracing::debug!("got req next"); + parent.send(ChainSyncMsg::ReqNext); + + if let ActoInput::Message(op) = cell.recv().await { + match op { + Some((ClientOp::Forward(header, _), tip)) => { + tracing::debug!("sending roll forward"); + server + .send_roll_forward(to_header_content(header), tip) + .await?; + } + Some((ClientOp::Backward(point), tip)) => { + tracing::debug!("sending roll backward"); + server.send_roll_backward(point.0, tip).await?; + } + None => { + tracing::debug!("sending await reply"); + server.send_await_reply().await?; + let ActoInput::Message(Some((op, tip))) = cell.recv().await else { + return Ok(()); + }; + match op { + ClientOp::Forward(header, _) => { + server + .send_roll_forward(to_header_content(header), tip) + .await?; + } + ClientOp::Backward(point) => { + server.send_roll_backward(point.0, tip).await?; + } + } + } + } + } else { + tracing::debug!("parent terminated"); + // parent terminated + return Ok(()); + } + } +} + +pub(super) fn to_header_content(header: Header) -> HeaderContent { + HeaderContent { + variant: 1, + byron_prefix: None, + cbor: to_cbor(&header), + } +} + +enum BlockFetchMsg {} + +async fn block_fetch( + _cell: ActoCell, + mut server: blockfetch::Server, + _store: Arc>>, // TODO: need a block store here +) -> anyhow::Result<()> { + while let Some(req) = server.recv_while_idle().await? { + tracing::info!("block fetch request: {:?}", req); + // TODO: Implement block fetch + server.send_no_blocks().await?; + } + + Ok(()) +} + +enum TxSubmissionMsg {} + +async fn tx_submission( + _cell: ActoCell, + mut server: txsubmission::Server, +) -> anyhow::Result<()> { + server.wait_for_init().await?; + + // TODO: Implement tx submission + + Ok(()) +} + +enum KeepAliveMsg {} + +async fn keep_alive( + _cell: ActoCell, + mut server: keepalive::Server, +) -> anyhow::Result<()> { + loop { + server.keepalive_roundtrip().await?; + } +} diff --git a/crates/amaru/src/stages/consensus/chain_forward/client_state.rs b/crates/amaru/src/stages/consensus/chain_forward/client_state.rs new file mode 100644 index 000000000..08f09de05 --- /dev/null +++ b/crates/amaru/src/stages/consensus/chain_forward/client_state.rs @@ -0,0 +1,92 @@ +use super::{hash_point, ClientOp}; +use crate::stages::AsTip; +use amaru_consensus::{consensus::store::ChainStore, IsHeader}; +use amaru_kernel::Header; +use pallas_network::miniprotocols::{chainsync::Tip, Point}; +use std::collections::VecDeque; + +/// The state we track for one client. +/// +/// The `ops` list may contain up to one rollback at the front only. +pub(super) struct ClientState { + /// The list of operations to send to the client. + ops: VecDeque, +} + +impl ClientState { + pub fn new(ops: VecDeque) -> Self { + Self { ops } + } + + pub fn next_op(&mut self) -> Option { + tracing::debug!("next_op: {:?}", self.ops.front()); + self.ops.pop_front() + } + + pub fn add_op(&mut self, op: ClientOp) { + tracing::debug!("add_op: {:?}", op); + match op { + ClientOp::Backward(tip) => { + if let Some((index, _)) = + self.ops.iter().enumerate().rfind( + |(_, op)| matches!(op, ClientOp::Forward(_, tip2) if tip2.0 == tip.0), + ) + { + tracing::debug!("found backward op at index {index} in {:?}", self.ops); + self.ops.truncate(index + 1); + tracing::debug!("last after truncate: {:?}", self.ops.back()); + } else { + tracing::debug!("clearing ops"); + self.ops.clear(); + self.ops.push_back(ClientOp::Backward(tip)); + } + } + op @ ClientOp::Forward(..) => { + tracing::debug!("adding forward op"); + self.ops.push_back(op); + } + } + } +} + +/// Find headers between points in the chain store. +/// Returns None if the local chain is broken. +/// Otherwise returns Some(headers) where headers is a list of headers leading from +/// the tallest point from the list that lies in the past of `start_point`. +pub(super) fn find_headers_between( + store: &dyn ChainStore
, + start_point: &Point, + points: &[Point], +) -> Option<(Vec, Tip)> { + let start_header = store.load_header(&hash_point(start_point))?; + + if points.contains(start_point) { + return Some((vec![], start_header.as_tip())); + } + + // Find the first point that is in the past of start_point + let mut current_header = start_header; + let mut headers = vec![ClientOp::Forward( + current_header.clone(), + current_header.as_tip(), + )]; + + while let Some(parent_hash) = current_header.parent() { + match store.load_header(&parent_hash) { + Some(header) => { + if points.iter().any(|p| hash_point(p) == parent_hash) { + // Found a matching point, return the collected headers + headers.reverse(); + return Some((headers, header.as_tip())); + } + headers.push(ClientOp::Forward(header.clone(), header.as_tip())); + current_header = header; + } + None => return None, // Broken chain + } + } + + // Reached genesis without finding any matching point + headers.reverse(); + Some((headers, Tip(Point::Origin, 0))) +} diff --git a/crates/amaru/src/stages/consensus/chain_forward/test_infra.rs b/crates/amaru/src/stages/consensus/chain_forward/test_infra.rs new file mode 100644 index 000000000..462a5aa05 --- /dev/null +++ b/crates/amaru/src/stages/consensus/chain_forward/test_infra.rs @@ -0,0 +1,351 @@ +#![allow(dead_code)] + +use super::{ForwardEvent, ForwardStage, PrettyPoint}; +use crate::stages::PallasPoint; +use acto::{AcTokio, AcTokioRuntime, ActoCell, ActoInput, ActoRuntime}; +use amaru_consensus::consensus::store::{ChainStore, Nonces, StoreError}; +use amaru_consensus::IsHeader; +use amaru_kernel::{from_cbor, Hash, Header}; +use amaru_ledger::BlockValidationResult; +use gasket::messaging::tokio::ChannelRecvAdapter; +use gasket::runtime::{spawn_stage, Tether}; +use pallas_network::facades::PeerClient; +use pallas_network::miniprotocols::chainsync::{NextResponse, Tip}; +use pallas_network::miniprotocols::Point; +use std::future::Future; +use std::sync::Arc; +use std::time::Duration; +use std::{collections::HashMap, fs::File, path::Path, str::FromStr}; +use tokio::sync::{mpsc, Mutex}; +use tokio::time::timeout; +use tracing_subscriber::EnvFilter; + +#[derive(Debug, Clone)] +pub struct TestStore(HashMap, Header>); + +impl TestStore { + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn get(&self, hash: &Hash<32>) -> Option<&Header> { + self.0.get(hash) + } + + pub fn get_chain(&self, h: &str) -> Vec
{ + let mut chain = Vec::new(); + let mut current = hash(h); + while let Some(header) = self.get(¤t) { + chain.push(header.clone()); + let Some(parent) = header.parent() else { + break; + }; + current = parent; + } + chain.reverse(); + chain + } + + pub fn get_tip(&self, h: &str) -> Tip { + let header = self.get(&hash(h)).unwrap(); + Tip(header.pallas_point(), header.block_height()) + } + + pub fn get_point(&self, h: &str) -> Point { + let header = self.get(&hash(h)).unwrap(); + header.pallas_point() + } + + pub fn get_height(&self, h: &str) -> u64 { + let header = self.get(&hash(h)).unwrap(); + header.block_height() + } +} + +impl ChainStore
for TestStore { + fn load_header(&self, hash: &Hash<32>) -> Option
{ + self.0.get(hash).cloned() + } + + fn store_header(&mut self, hash: &Hash<32>, header: &Header) -> Result<(), StoreError> { + self.0.insert(*hash, header.clone()); + Ok(()) + } + + fn get_nonces(&self, _header: &Hash<32>) -> Option { + unimplemented!() + } + + fn put_nonces(&mut self, _header: &Hash<32>, _nonces: Nonces) -> Result<(), StoreError> { + unimplemented!() + } + + fn era_history(&self) -> &slot_arithmetic::EraHistory { + unimplemented!() + } +} + +pub const CHAIN_47: &str = "tests/data/chain41.json"; +pub const TIP_47: &str = "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6"; +pub const LOST_47: &str = "bd41b102018a21e068d504e64b282512a3b7d5c3883b743aa070ad9244691125"; +pub const BRANCH_47: &str = "64565f22fb23476baaa6f82e0e2d68636ceadabded697099fb376c23226bdf03"; +pub const WINNER_47: &str = "66c90f54f9073cfc03a334f5b15b1617f6bf6fe6c892fad8368e16abe20b0f4f"; + +pub fn mk_store(path: impl AsRef) -> TestStore { + let f = File::open(path).unwrap(); + let json: serde_json::Value = serde_json::from_reader(f).unwrap(); + let headers = json + .pointer("/stakePools/chains") + .unwrap() + .as_array() + .unwrap(); + + let mut store = HashMap::new(); + + for header in headers { + let hash = header.pointer("/hash").unwrap().as_str().unwrap(); + let header = header.pointer("/header").unwrap().as_str().unwrap(); + let header = hex::decode(header).unwrap(); + store.insert(hash.parse().unwrap(), minicbor::decode(&header).unwrap()); + } + + TestStore(store) +} + +pub fn hash(s: &str) -> Hash<32> { + Hash::<32>::from_str(s).unwrap() +} + +pub fn hex(s: &str) -> Vec { + hex::decode(s).unwrap() +} + +pub fn point(slot: u64, hash: &str) -> Point { + Point::Specific(slot, hex(hash)) +} + +pub fn amaru_point(slot: u64, hash: &str) -> amaru_kernel::Point { + amaru_kernel::Point::Specific(slot, hex(hash)) +} + +pub struct Setup { + pub store: TestStore, + runtime: AcTokio, + event: mpsc::Receiver, + block: mpsc::Sender>, + _tether: Tether, + port: u16, +} + +impl Setup { + pub fn new(our_tip: &str) -> Setup { + let _ = tracing_subscriber::fmt() + .with_env_filter(EnvFilter::from_default_env()) + .with_test_writer() + .try_init(); + + let store = mk_store(CHAIN_47); + let runtime = AcTokio::new("test", 1).unwrap(); + let (port_tx, mut port_rx) = mpsc::channel(8); + let downstream = runtime + .spawn_actor( + "test", + |mut cell: ActoCell| async move { + while let ActoInput::Message(msg) = cell.recv().await { + port_tx.send(msg).await.unwrap(); + } + }, + ) + .me; + let (block_tx, block_rx) = mpsc::channel(8); + let mut stage = ForwardStage::new( + Some(downstream), + Arc::new(Mutex::new(store.clone())), + 42, + "127.0.0.1:0", + 1, + store.get_tip(our_tip), + ); + stage.upstream.connect(ChannelRecvAdapter::Mpsc(block_rx)); + let tether = spawn_stage(stage, Default::default()); + + tracing::info!("stage state: {:?}", tether.check_state()); + let port = block_on(&runtime, port_rx.recv()).unwrap(); + let ForwardEvent::Listening(port) = port else { + panic!("expected listening event, got {:?}", port); + }; + assert_ne!(port, 0); + tracing::info!( + "stage ({:?}) listening on port {}", + tether.check_state(), + port + ); + + Setup { + store, + runtime, + event: port_rx, + block: block_tx, + _tether: tether, + port, + } + } + + pub fn send_validated(&mut self, s: &str) { + let point = self.store.get(&hash(s)).unwrap().point(); + let span = tracing::debug_span!("whatever"); + let f = self + .block + .send(BlockValidationResult::BlockValidated(point.clone(), span).into()); + tracing::info!("sending block validated"); + block_on(&self.runtime, f).unwrap(); + tracing::info!("waiting for forward event"); + let p = block_on(&self.runtime, self.event.recv()).unwrap(); + let ForwardEvent::Forward(p) = p else { + panic!("expected forward event, got {:?}", p); + }; + assert_eq!(p, point.pallas_point()); + } + + pub fn send_backward(&mut self, s: &str) { + let point = self.store.get(&hash(s)).unwrap().point(); + let span = tracing::debug_span!("whatever"); + let f = self + .block + .send(BlockValidationResult::RolledBackTo(point.clone(), span).into()); + tracing::info!("sending block roll backward"); + block_on(&self.runtime, f).unwrap(); + tracing::info!("waiting for backward event"); + let p = block_on(&self.runtime, self.event.recv()).unwrap(); + let ForwardEvent::Backward(p) = p else { + panic!("expected backward event, got {:?}", p); + }; + assert_eq!(p, point.pallas_point()); + } + + pub fn connect(&self) -> Client { + let client = block_on( + &self.runtime, + PeerClient::connect(&format!("127.0.0.1:{}", self.port), 42), + ) + .unwrap(); + Client { + runtime: self.runtime.clone(), + client, + } + } + + pub fn check_header(&self, s: &str, h: &Header) { + let header = self.store.get(&hash(s)).unwrap(); + assert_eq!(header.header_body, h.header_body); + } +} + +pub struct Client { + runtime: AcTokioRuntime, + client: PeerClient, +} + +impl Client { + pub fn find_intersect(&mut self, points: Vec) -> (Option, Tip) { + block_on( + &self.runtime, + self.client.chainsync().find_intersect(points), + ) + .unwrap() + } + + pub fn recv_until_await(&mut self) -> Vec { + let mut ops = Vec::new(); + while let Ok(response) = block_on(&self.runtime, self.client.chainsync().request_next()) { + match response { + NextResponse::RollForward(header, tip) => { + ops.push(ClientMsg::Forward(from_cbor(&header.cbor).unwrap(), tip)) + } + NextResponse::RollBackward(point, tip) => ops.push(ClientMsg::Backward(point, tip)), + NextResponse::Await => break, + } + } + ops + } + + pub fn recv_n(&mut self) -> [ClientMsg; N] { + let mut ops = Vec::new(); + for _ in 0..N { + let msg = block_on(&self.runtime, self.client.chainsync().request_next()).unwrap(); + match msg { + NextResponse::RollForward(header, tip) => { + ops.push(ClientMsg::Forward(from_cbor(&header.cbor).unwrap(), tip)) + } + NextResponse::RollBackward(point, tip) => ops.push(ClientMsg::Backward(point, tip)), + NextResponse::Await => break, + } + } + ops.try_into().unwrap() + } + + pub fn recv_after_await(&mut self) -> ClientMsg { + let msg = block_on( + &self.runtime, + self.client.chainsync().recv_while_can_await(), + ) + .unwrap(); + match msg { + NextResponse::RollForward(header, tip) => { + ClientMsg::Forward(from_cbor(&header.cbor).unwrap(), tip) + } + NextResponse::RollBackward(point, tip) => ClientMsg::Backward(point, tip), + NextResponse::Await => panic!("unexpected await"), + } + } +} + +#[derive(Clone)] +#[allow(clippy::large_enum_variant)] +pub enum ClientMsg { + Forward(Header, Tip), + Backward(Point, Tip), +} + +impl std::fmt::Debug for ClientMsg { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Forward(header, tip) => f + .debug_struct("Forward") + .field( + "header", + &(header.block_height(), PrettyPoint(&header.pallas_point())), + ) + .field("tip", &(tip.1, PrettyPoint(&tip.0))) + .finish(), + Self::Backward(point, tip) => f + .debug_struct("Backward") + .field("point", &PrettyPoint(point)) + .field("tip", &(tip.1, PrettyPoint(&tip.0))) + .finish(), + } + } +} + +impl PartialEq for ClientMsg { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (ClientMsg::Forward(lh, lt), ClientMsg::Forward(rh, rt)) => { + lh == rh && (<.0, lt.1) == (&rt.0, rt.1) + } + (ClientMsg::Backward(lp, lt), ClientMsg::Backward(rp, rt)) => { + lp == rp && (<.0, lt.1) == (&rt.0, rt.1) + } + _ => false, + } + } +} +fn block_on(runtime: &AcTokioRuntime, f: F) -> F::Output { + runtime + .with_rt(|rt| { + let _x = rt.enter(); + rt.block_on(timeout(Duration::from_secs(1), f)) + }) + .unwrap() + .unwrap() +} diff --git a/crates/amaru/src/stages/consensus/chain_forward/tests.rs b/crates/amaru/src/stages/consensus/chain_forward/tests.rs new file mode 100644 index 000000000..4c2d95415 --- /dev/null +++ b/crates/amaru/src/stages/consensus/chain_forward/tests.rs @@ -0,0 +1,172 @@ +use super::{ + client_state::find_headers_between, + test_infra::{ + hash, mk_store, ClientMsg, Setup, BRANCH_47, CHAIN_47, LOST_47, TIP_47, WINNER_47, + }, +}; +use crate::stages::{AsTip, PallasPoint}; +use amaru_consensus::IsHeader; +use pallas_network::miniprotocols::chainsync::Tip; +use pallas_network::miniprotocols::Point; + +#[test] +fn test_mk_store() { + let store = mk_store(CHAIN_47); + assert_eq!(store.len(), 48); + let chain = store.get_chain(TIP_47); + assert_eq!(chain.len(), 47); + assert_eq!(chain[0].header_body.slot, 31); + assert_eq!(chain[46].header_body.slot, 990); + assert_eq!(chain[6].block_height(), 7); +} + +#[test] +fn find_headers_between_tip_and_tip() { + let store = mk_store(CHAIN_47); + + let tip = store.get_point(TIP_47); + let points = [store.get_point(TIP_47)]; + + let (ops, Tip(p, h)) = find_headers_between(&store, &tip, &points).unwrap(); + assert_eq!((ops, p, h), (vec![], tip, 47)); +} + +#[test] +fn find_headers_between_tip_and_branch() { + let store = mk_store(CHAIN_47); + + let tip = store.get_point(TIP_47); + let points = [store.get_point(BRANCH_47)]; + let peer = store.get_point(BRANCH_47); + + let (ops, Tip(p, h)) = find_headers_between(&store, &tip, &points).unwrap(); + assert_eq!( + (ops.len() as u64, p, h), + ( + store.get_height(TIP_47) - store.get_height(BRANCH_47), + peer, + store.get_height(BRANCH_47) + ) + ); +} + +#[test] +fn find_headers_between_tip_and_branches() { + let store = mk_store(CHAIN_47); + + let tip = store.get_point(TIP_47); + // Note that the below scheme does not match the documented behaviour, which shall pick the first from + // the list that is on the same chain. But that doesn't make sense to me at all. + let points = [ + store.get_point(BRANCH_47), // this will lose to the (taller) winner + store.get_point(LOST_47), // this is not on the same chain + store.get_point(WINNER_47), // this is the winner after the branch + ]; + let peer = store.get_point(WINNER_47); + + let (ops, Tip(p, h)) = find_headers_between(&store, &tip, &points).unwrap(); + assert_eq!( + (ops.len() as u64, p, h), + ( + store.get_height(TIP_47) - store.get_height(WINNER_47), + peer, + store.get_height(WINNER_47) + ) + ); +} + +#[test] +fn find_headers_between_tip_and_lost() { + let store = mk_store(CHAIN_47); + + let tip = store.get_point(TIP_47); + let points = [store.get_point(LOST_47)]; + + let result = find_headers_between(&store, &tip, &points).unwrap(); + assert_eq!(result.0.len() as u64, store.get_height(TIP_47)); + assert_eq!(result.1 .0, Point::Origin); + assert_eq!(result.1 .1, 0); +} + +#[test] +fn test_chain_sync() { + let mut setup = Setup::new(LOST_47); + let chain = setup.store.get_chain(TIP_47); + let lost = setup.store.get(&hash(LOST_47)).unwrap().clone(); + + let mut client = setup.connect(); + + let (p, t) = client.find_intersect(vec![chain[6].pallas_point()]); + + assert_eq!(p, Some(setup.store.get_point(BRANCH_47))); + assert_eq!(t.0, lost.pallas_point()); + assert_eq!(t.1, lost.block_height()); + + let headers = client.recv_until_await(); + assert_eq!( + headers, + vec![ClientMsg::Forward(lost.clone(), lost.as_tip())] + ); + + setup.send_backward(BRANCH_47); + setup.send_validated(WINNER_47); + setup.send_validated(&chain[8].hash().to_string()); + let msg = client.recv_after_await(); + assert_eq!( + msg, + // out tip comes out as chain[6] here because previously client.recv_until_await already + // asked for the next op, which means the Backward got sent before the BlockValidated + // updated the `our_tip` pointer + ClientMsg::Backward(chain[6].pallas_point(), chain[6].as_tip()) + ); + + let headers = client.recv_until_await(); + assert_eq!( + headers, + vec![ + ClientMsg::Forward(chain[7].clone(), chain[8].as_tip()), + ClientMsg::Forward(chain[8].clone(), chain[8].as_tip()), + ] + ); + + // Note: there’s no way to shut down the gasket stage without logging to ERRORs, sorry +} + +#[test] +fn test_sync_optimising_rollback() { + let mut setup = Setup::new(LOST_47); + let chain = setup.store.get_chain(TIP_47); + let lost = setup.store.get(&hash(LOST_47)).unwrap().clone(); + + let mut client = setup.connect(); + client.find_intersect(vec![]).0.expect("no intersection"); + + let msgs = client.recv_n::<4>(); + assert_eq!( + msgs, + [ + ClientMsg::Forward(chain[0].clone(), lost.as_tip()), + ClientMsg::Forward(chain[1].clone(), lost.as_tip()), + ClientMsg::Forward(chain[2].clone(), lost.as_tip()), + ClientMsg::Forward(chain[3].clone(), lost.as_tip()), + ] + ); + + setup.send_backward(BRANCH_47); + setup.send_validated(&chain[7].hash().to_string()); + setup.send_validated(&chain[8].hash().to_string()); + setup.send_validated(&chain[9].hash().to_string()); + + let msgs = client.recv_until_await(); + assert_eq!( + msgs, + [ + ClientMsg::Forward(chain[4].clone(), chain[9].as_tip()), + ClientMsg::Forward(chain[5].clone(), chain[9].as_tip()), + ClientMsg::Forward(chain[6].clone(), chain[9].as_tip()), + ClientMsg::Forward(chain[7].clone(), chain[9].as_tip()), + ClientMsg::Forward(chain[8].clone(), chain[9].as_tip()), + ClientMsg::Forward(chain[9].clone(), chain[9].as_tip()), + ] + ); +} diff --git a/crates/amaru/src/stages/mod.rs b/crates/amaru/src/stages/mod.rs index e86e99c22..fe6a6e6f4 100644 --- a/crates/amaru/src/stages/mod.rs +++ b/crates/amaru/src/stages/mod.rs @@ -19,9 +19,9 @@ use amaru_consensus::{ store::ChainStore, }, peer::Peer, - ConsensusError, + ConsensusError, IsHeader, }; -use amaru_kernel::{network::NetworkName, EraHistory, Hash, Header, Point}; +use amaru_kernel::{network::NetworkName, EraHistory, Hash, Header}; use amaru_stores::rocksdb::{consensus::RocksDBStore, RocksDB}; use consensus::{ chain_forward::ForwardStage, @@ -32,7 +32,10 @@ use gasket::{ messaging::{tokio::funnel_ports, OutputPort}, runtime::Tether, }; -use pallas_network::facades::PeerClient; +use pallas_network::{ + facades::PeerClient, + miniprotocols::{chainsync::Tip, Point}, +}; use std::{path::PathBuf, sync::Arc}; use tokio::sync::Mutex; @@ -47,6 +50,9 @@ pub struct Config { pub chain_dir: PathBuf, pub upstream_peers: Vec, pub network: NetworkName, + pub network_magic: u32, + pub listen_address: String, + pub max_downstream_peers: usize, } /// A session with a peer, including the peer itself and a client to communicate with it. @@ -86,7 +92,18 @@ pub fn bootstrap( .map(|session| pull::Stage::new(session.clone(), vec![tip.clone()])) .collect::>(); let chain_store = RocksDBStore::new(config.chain_dir.clone(), era_history)?; - let chain_selector = make_chain_selector(tip, &chain_store, &peer_sessions)?; + + let our_tip = if let amaru_kernel::Point::Specific(_slot, hash) = &tip { + #[allow(clippy::expect_used)] + let header: Header = chain_store + .load_header(&Hash::from(&**hash)) + .expect("Tip not found"); + Tip(header.pallas_point(), header.block_height()) + } else { + Tip(Point::Origin, 0) + }; + + let chain_selector = make_chain_selector(tip.clone(), &chain_store, &peer_sessions)?; let chain_ref = Arc::new(Mutex::new(chain_store)); let consensus = Consensus::new( Box::new(ledger.state.view_stake_distribution()), @@ -95,7 +112,14 @@ pub fn bootstrap( ); let mut consensus_stage = HeaderStage::new(consensus); - let mut block_forward = ForwardStage::new(chain_ref.clone()); + let mut block_forward = ForwardStage::new( + None, + chain_ref.clone(), + config.network_magic as u64, + &config.listen_address, + config.max_downstream_peers, + our_tip, + ); let (to_block_fetch, from_consensus_stage) = gasket::messaging::tokio::mpsc_channel(50); let (to_ledger, from_block_fetch) = gasket::messaging::tokio::mpsc_channel(50); @@ -134,7 +158,7 @@ pub fn bootstrap( } fn make_chain_selector( - tip: Point, + tip: amaru_kernel::Point, chain_store: &impl ChainStore
, peers: &Vec, ) -> Result>>, ConsensusError> { @@ -152,3 +176,38 @@ fn make_chain_selector( Ok(Arc::new(Mutex::new(builder.build()?))) } + +pub trait PallasPoint { + fn pallas_point(&self) -> pallas_network::miniprotocols::Point; +} + +impl PallasPoint for Header { + fn pallas_point(&self) -> pallas_network::miniprotocols::Point { + to_pallas_point(&self.point()) + } +} + +impl PallasPoint for amaru_kernel::Point { + fn pallas_point(&self) -> pallas_network::miniprotocols::Point { + to_pallas_point(self) + } +} + +fn to_pallas_point(point: &amaru_kernel::Point) -> pallas_network::miniprotocols::Point { + match point { + amaru_kernel::Point::Origin => pallas_network::miniprotocols::Point::Origin, + amaru_kernel::Point::Specific(slot, hash) => { + pallas_network::miniprotocols::Point::Specific(*slot, hash.clone()) + } + } +} + +pub trait AsTip { + fn as_tip(&self) -> Tip; +} + +impl AsTip for Header { + fn as_tip(&self) -> Tip { + Tip(self.pallas_point(), self.block_height()) + } +} diff --git a/crates/amaru/tests/data/chain41.json b/crates/amaru/tests/data/chain41.json new file mode 100644 index 000000000..729bd3ea1 --- /dev/null +++ b/crates/amaru/tests/data/chain41.json @@ -0,0 +1,574 @@ +{ + "context": { + "activeSlotCoeff": 5.0e-2, + "nonce": "ec08f270a044fb94bf61f9870e928a96cf75027d1f0e9f5dead0651b40849a89", + "praosMaxKESEvo": 63, + "praosSlotsPerKESPeriod": 2048 + }, + "stakePools": { + "chains": [ + { + "hash": "2487bd4f49c89e59bb3d2166510d3d49017674d3c3b430b95db2e260fedce45e", + "header": "828a01181ff6582022ff37595005fa65ad731d4fb112de050aa0ca910d9a3110f56f3879d449f88e5820da90997ba81483b3f2b4de751ba3ece6ba6d50f96598eb0940cc7d29452cdcb9825840d350e19abe11a25b28d4d1a846faa8f7792b6dc4a19679780dcdd3d98baf4e9738d82764c59b1c76f80b5ddbff2e145aa26f1652ab83f1f930fc430d1be960305850b444cc452b3fbc01a267ff526ea8a66cb57202303b4b1c22557cad8c1d8afbb47a34e55c5e0bee497f58c812e8b2fed95b40cb1f966ad77445ef573f289910debf5dcb4924cecce47d181f325b4d21040058200a9aa01fbdfe2cff3e49a3c02c2610691966075092f76bd26f5bddf85489ffd3845820499fc5dada1544be26d7cd3b2851fe955b44e560b50901abc71333d5d449eac9182e005840595a9a329b2637b8f2cb501aa793a159acc928a27c01e1ef586508492a68cabeae6ced714421be1f648bb05c7196f38e7aa4a8f616ad46e32c84e67951657a038200005901c0c00b0daf83dfc61a23fa9f6e4db5ad31428a7e98839aba420dbdbdc5ad90b72185cb03b5373b73fcd9c0128b3afcc7d14e5b51f4d5592d55a5d222314b590101472338fcc8b178f0ba10f8683725c5df444b7fc6a5afc3c7fbab82e00e7df2d247c673d066eacc1dc7860c10b134c413d71c5a073a5f3e66a17f0d25dabae2699d7b4a969e129d627cd7839995ddf40a3e6672b6d03936de782f5e0dc31bfafdccc5d5d2e5e9a5b3414bface59a824e3a574250474d633115af821b63232de753fddb638606b93b853144dd75692b02e73b2ef8621eb1bfa307cfda8acaa2c43f8b673c9ed749e472cdf2fced20c063a2507ccb985d2b5a9bc77699f42379fb349e1e3a1ab86d1bd510c6ee89720f860d55c208dd262f49746d8fb2a7817d038262a6b266f98f427fc8b958f11adb8c84cc96444b1f5f9d994a4fd1adae2f2be87d8c1dbc0206ace7871da50cc92476d3fced6a4fc2809c8bb47dff992b06259c21f78cd6e72b49b8fe101065aaf243003af67a11d5aabcebf1059b3c92493f954507573a01bf92047ef68f4e980df914b360307b78b3371138b4c1504e155f704df9fabf1bc87ac47b3d5cd563cee6017380e4df6529face9cf39b36277068e", + "height": 1, + "parent": null, + "slot": 31 + }, + { + "hash": "4fcd1d0fccd869c632d4af171b7f3011f51b11bd2e9870bebe8990cad4c5b8ba", + "header": "828a02182658202487bd4f49c89e59bb3d2166510d3d49017674d3c3b430b95db2e260fedce45e5820cf1d41b669559e9d30eaf310408a8dea605e3629c0dfd7b6d649d4861514d1bf582083f3206635b9182a411e2a9e870cc13f5974507b1f84476c8519ad9215ae4678825840e8cf431cf549890a0a9bc8203524e5722b7fe156f03d51386e4c0f58d18892df6b1349581935b299e0ef77db4ea00f06481e5430ddb5404562f6ebab6eaba868585035f6b33676d464d482f112d220d7bd4be183d1e6eecec8d68c876b624bc47fc51e7687d02651807ae63076f66bd1b964cf1ff2bcd99bbb7f7e769f835ba99fd5fe4c835a70ecb3ebcb7789d52a661c0c0058206cfbcf0fd018168133b31fa9b1ec0fe810f372004467f8ebbc444a78281ddb578458205474aa415f322607b193704e4c4c0554ec74fe68f7a0c880d65660a75c092e9d0d005840bbd78899a963f57f958f23ee2113f5acf830ce54a3733f7f5e9ec66459997dbbe4837e7706f415b8435ded9bedc37cf51e60177ff5d8e753c2638349cf01bf0d8200005901c0dc42cdf7c5f1b38716efafe1fc24449fee11f5b454d9e2b7c889a69a4b4bea23fbee709cce6a3873ae252f34840f3df5a4d155cd5445ed26398015b86f67a80ec240bf2a1681adcda82378b0cd9f0211c9f7ee6eb26e57ee2b0b92547793e5faa7f183ed48ff763de91c6324f355449b2d96e4f37efde9dc377751844b3314bb8d0e3c59befe2f1a5b7bc0045a164b8b9e1c5c9ee285bf6c2f6152826ef1252ab39577992ce208e5b172e9d03e46c268454a1502697162f175c586821d0fb5a8c0ffd4c56fb8c5cce2e1f7a0efc77a38277faa82580e983c87d4081dd8b5226bc8994114ec7a95f8be871726a6998dce138fc55377f022f84cc97eccdd18e7d61b557d7daea41d1d021e34aab3dac320758ba4f9c2d5fddc5a8072097be37af8f2e5fb4037a11632c6fd9d42c62a2e8263af2db7c83d992c933548e0f5d2593bface422b543cb5c1eb68fab55f0a77683d4532df74468dee8e18a1b32b92fde2dd6a8dad63af74be2f9c4d3a1d7b57711d09e38e97fb72551eedf3c215beb1c0cac6a938ca375bcb5ab7037955122f116659927bdbb741aec609c2c27e3d18c4d5751b52460d0914e68d40014f179d8400db188be2c34a7f98872070b86ad764", + "height": 2, + "parent": "2487bd4f49c89e59bb3d2166510d3d49017674d3c3b430b95db2e260fedce45e", + "slot": 38 + }, + { + "hash": "7393071a515238dec04e86ee45329121ae6a38051642d6548790ac3325b592ee", + "header": "828a03182958204fcd1d0fccd869c632d4af171b7f3011f51b11bd2e9870bebe8990cad4c5b8ba5820cf1d41b669559e9d30eaf310408a8dea605e3629c0dfd7b6d649d4861514d1bf582083f3206635b9182a411e2a9e870cc13f5974507b1f84476c8519ad9215ae4678825840c62b011f810bc9f6ed4ee0388463bead89231b2634c432824a388ed87f70b41d83ae5773c8fd02ca59954d0e3406eeae320bb5cc1ae456a8bee4933a32c2b2405850f328c6556b2ef586ef7743551bb02b272b39b4268aa0844caa1787a7bbc35a7e81cdc17fafb485217e71d24dda797df7d3b254dd3bd923a7c5d2db9e1240732602de00682ea42eebb8668d1b4e3b770f0058201ade370a2f2a38a9a82dce6ab97b8bee7c0c380e37ff23134d664a38a32e2ccc8458205474aa415f322607b193704e4c4c0554ec74fe68f7a0c880d65660a75c092e9d0d005840bbd78899a963f57f958f23ee2113f5acf830ce54a3733f7f5e9ec66459997dbbe4837e7706f415b8435ded9bedc37cf51e60177ff5d8e753c2638349cf01bf0d8200005901c0d65a20ebb86aa86a47ec2852babb715aea3dc0080cb845ac51a798bbf50909d999995811153da2c6a2d6cf569347098139e78f118979f1e5735671e382b1df0cc240bf2a1681adcda82378b0cd9f0211c9f7ee6eb26e57ee2b0b92547793e5faa7f183ed48ff763de91c6324f355449b2d96e4f37efde9dc377751844b3314bb8d0e3c59befe2f1a5b7bc0045a164b8b9e1c5c9ee285bf6c2f6152826ef1252ab39577992ce208e5b172e9d03e46c268454a1502697162f175c586821d0fb5a8c0ffd4c56fb8c5cce2e1f7a0efc77a38277faa82580e983c87d4081dd8b5226bc8994114ec7a95f8be871726a6998dce138fc55377f022f84cc97eccdd18e7d61b557d7daea41d1d021e34aab3dac320758ba4f9c2d5fddc5a8072097be37af8f2e5fb4037a11632c6fd9d42c62a2e8263af2db7c83d992c933548e0f5d2593bface422b543cb5c1eb68fab55f0a77683d4532df74468dee8e18a1b32b92fde2dd6a8dad63af74be2f9c4d3a1d7b57711d09e38e97fb72551eedf3c215beb1c0cac6a938ca375bcb5ab7037955122f116659927bdbb741aec609c2c27e3d18c4d5751b52460d0914e68d40014f179d8400db188be2c34a7f98872070b86ad764", + "height": 3, + "parent": "4fcd1d0fccd869c632d4af171b7f3011f51b11bd2e9870bebe8990cad4c5b8ba", + "slot": 41 + }, + { + "hash": "726ef3afa0721efd9f0b42103b45379869c859d3f20c62f9aeae99b557cbdfa4", + "header": "828a04183758207393071a515238dec04e86ee45329121ae6a38051642d6548790ac3325b592ee58209f6a9a363089819a4a011406addcd84e984210ca43f1f0b93f014bf4246b0fd05820349fa6de24709731a7f27d0e4f711d73018f285d2bf91fd0bcc67559c478a2e7825840b09f6a13c3f09e122605486c5a9bbbbde28bf88335006b0d3d980b4cd84852ff319c3ba4c5c1af4e333212b74744bc30a9eae9ca6ef2d19d676bd09a5adc7fab5850b53b6f4e2d0493976a580c32190628b876549b89163fe23d798cc2bb495ce7b72ed7638f00acb1361b67ffb2ecac7489ab8c639db6890a0f2809edd3171930877c25166fe2c6a84ea22cf2a553a43703005820102b9198f78d8dd2a7317bc9ea538806cfd6ae5588b29210cd9554ea904657da845820740dc0a0c3ab031ec83d2737df245cf634f5bb52c30e3f10d5784b498dceaa09184c0058402e844d232e5697feeb57d0e1e24f46f8de86f56d0bf7c984deb5130262fb3bc3119ddeb09933664ff423f419109154efe6bf5f2e30d7f59704fed09f178452078200005901c0ec7ead9e182a4043c8a04117761a9d8c0c4354ea7c9369ff69de42fb61373bbf25ba31aadbb8b5456eb70798f2c0abed98b489aacfebc6b76ad396a9696a2f045f172dc4077a26ab4fc58ef6de644079bcd76e7553b4468e3ec64a52c2bf5ccda05395e1cf6acb1d2b11d88202930f17e17e3233e55f2cc60fdccf05174901d5c655273b8dec2d0665a7473a84b905410e17a1f19a853d25b32f341e11e66e53f61b5bbbdce9419ff8b4a3438dc5f959cb3066161b4f51f848aca11fbaaa98afced6f3eb73033175d25410cdd7a018c8e15da090dd1d8cc71f36408ad6f69797b70eb348856734bfc2e11c083d84a92f997cc1a7399b6dd6ea38e1c82a535e9e64aa39875ef67c21415f076a39f22cb8b7607ff0c5e4d60dc393a7593bbfff567e3db58d6de8fe25f153d654184e24e8e3e71faffaca0fd480c83f96d6b66657c490b49bd76a543df7855949494093c385db0104f6f8711a163e2a9fae72841fb9eae2261808fb1436203b948a4a4b29be573a00fdea79962087ccc70e60fc368a254c6b20bc0f7ce151585fcd2ba76ae8ffdc4744204b5bc354f12b00927718c357791e112a4c26a02831faae28508f708944423e2a1d0c5c9c7a471ed30225", + "height": 4, + "parent": "7393071a515238dec04e86ee45329121ae6a38051642d6548790ac3325b592ee", + "slot": 55 + }, + { + "hash": "597ea69c905c502e35ea5bd693c74b3a0f6a1aab241ea117147588c2da1743fe", + "header": "828a05185d5820726ef3afa0721efd9f0b42103b45379869c859d3f20c62f9aeae99b557cbdfa4582022ff37595005fa65ad731d4fb112de050aa0ca910d9a3110f56f3879d449f88e5820da90997ba81483b3f2b4de751ba3ece6ba6d50f96598eb0940cc7d29452cdcb98258407f9c8e79dc3f5107b7f6848b6cc6840edc7460f62a77cd89d181688cf4bf72e060b4e18b9b4081ce7d87e9db14447722b18fedac8c14a1eeaafc8e5ac3bfdfcc5850e02240162fc946c3ab1bd96a1cbcec528012c133a7e53a485843749c9a58532728ea1ca792b4b1520cc9df28d6cddb85c1de90cfe728f891ed3ae37587b84fbf584be9d27bfa1e84fde943e1b6addc00005820dc6872b1b852fcf748b814ef7322e478f43f9ea5ce36cd55dc3c2969c9b8a336845820499fc5dada1544be26d7cd3b2851fe955b44e560b50901abc71333d5d449eac9182e005840595a9a329b2637b8f2cb501aa793a159acc928a27c01e1ef586508492a68cabeae6ced714421be1f648bb05c7196f38e7aa4a8f616ad46e32c84e67951657a038200005901c06317ac6fe141f1acc49ae94aecca9f48d74bd7e95feedaf9bf4ecb26e4e43ba5041cdd94cf53c57beb2fc819058c1183bf3c392e8bc1632368779be022222501472338fcc8b178f0ba10f8683725c5df444b7fc6a5afc3c7fbab82e00e7df2d247c673d066eacc1dc7860c10b134c413d71c5a073a5f3e66a17f0d25dabae2699d7b4a969e129d627cd7839995ddf40a3e6672b6d03936de782f5e0dc31bfafdccc5d5d2e5e9a5b3414bface59a824e3a574250474d633115af821b63232de753fddb638606b93b853144dd75692b02e73b2ef8621eb1bfa307cfda8acaa2c43f8b673c9ed749e472cdf2fced20c063a2507ccb985d2b5a9bc77699f42379fb349e1e3a1ab86d1bd510c6ee89720f860d55c208dd262f49746d8fb2a7817d038262a6b266f98f427fc8b958f11adb8c84cc96444b1f5f9d994a4fd1adae2f2be87d8c1dbc0206ace7871da50cc92476d3fced6a4fc2809c8bb47dff992b06259c21f78cd6e72b49b8fe101065aaf243003af67a11d5aabcebf1059b3c92493f954507573a01bf92047ef68f4e980df914b360307b78b3371138b4c1504e155f704df9fabf1bc87ac47b3d5cd563cee6017380e4df6529face9cf39b36277068e", + "height": 5, + "parent": "726ef3afa0721efd9f0b42103b45379869c859d3f20c62f9aeae99b557cbdfa4", + "slot": 93 + }, + { + "hash": "bfa96cd376052c78a93d1941f68bdfcf5abf51c1988091f52f2c568f0916eca8", + "header": "828a0618795820597ea69c905c502e35ea5bd693c74b3a0f6a1aab241ea117147588c2da1743fe58205a177476c40bb96ea1f9d241d0d1651ae08104bfc54337d356f951d59404a4d2582037264127bcb2df028319e576fbe8727a7d9b2d1cdcda8b30c6cd377f0630bbd882584001f839b792df22baccbf707c0e35f93e470ec6151039c50c0c97100f652657dfb71005376bbe41eca2610e539760427c664f236b4880d2e392bff3e21a5e079f5850ed7dcdabc128ff41e0cca9e1c5d2a1ffd57be159655d5fe1644ebcd215f4bd0d88373042b9f782fb7fce206e24ae8fd3180ddb57a22099264b4e74a1e1c8db43a68d7beff733f4b4390823170e337003005820a5087cbb3f5882c880ed581fcf0d38b7b6909a2a1cf8eefd8ed26de602825a7f845820338f92308f2f1d0dcabc1f1e3ad061c8b6e32679fee51431a43dc32efec5a0fc1818005840b3bd852c4a9a2d8f740ba727594f91c227a9dc638d2f27edce75b140bce7a12d62c0dcca2c832e3c8904e0149d2bc62e20e42605f6e0444835a9ecf2f462000e8200005901c0dc33c2ecd2baa2840228846d4dc991bedf0f2a22074496e28c007ac7d0a31fbc241d214d73d7406dad96f7cc755aa01cf5c0de2a2a74328e840053c7c01f95072a33fd2dc4086d99d1309eee46f49e76b5d9f86465fb0ae9f1b3dec4c8e2c15dcb0120b19dd9e1496fd9350141f284d40e2350e86404f031597cefa7063a4a35e92b198a7888cb9397d81e563e067f3e0f5709159027827cc74fd3ea0583051a1cbcb8f3cdb6280b50138328292f33b6b7dd202214124507fde1789777f1737fd390cef46fb8ae253be49c8d3b43aa48387f0e50a32c3f2b6fe25613e06e4d3873903f3ddbef0d2d520380966869fcf11a1dd7275b1b6cccc313d2a718de1b2ed2e5fc55f72a46076eaf27598525fe452ace332397e8a2687d494b086256933ebfd955443d19d647a98c17f0472d136b4ae46d4548cc837ae9ea18449b259f3eea3820cc09fd0ee8dacd88f36ea31d266dbab5ee6ae55142594774498e7e3a3ff3fad6228c6e1fe23e3ef39e2edbe258351d9a1b8b50aa35a9f5e3e6c4f376d16948885aae058502fd5d51b5f6bafa8ec285d1cac641488bdaf90d99331da3edd4e2db2ac63975bb6791ba02822a7d25ea87aa5b3756ed3decb5ef8f09970600", + "height": 6, + "parent": "597ea69c905c502e35ea5bd693c74b3a0f6a1aab241ea117147588c2da1743fe", + "slot": 121 + }, + { + "hash": "64565f22fb23476baaa6f82e0e2d68636ceadabded697099fb376c23226bdf03", + "header": "828a07188e5820bfa96cd376052c78a93d1941f68bdfcf5abf51c1988091f52f2c568f0916eca85820be62f79f3cfcaa5e6986b864daff9debcfae34ad53a36df2faee406c67ac290d582088a86b524b9f5f6b5319f1a3171c0031fa97842df2ffc5d29ff7ec4c0ecc05f18258404f5d48647954a38346a51a7e6eaeb78c4507cf445dee612c2a9a61d6e97e8460e0ed5420c2b58194ad84a1a1c6e5094448aedebe46d1143112a6cdf2e73628ad5850ec2f6916cdb9f6b78f2b96f08c07d2477fe09faaeaa10066afa382980b58a2e3fad742b3fa05875eceaad3da9c3622ca28182fc77ad7f9df85d2bea26b125b81010fd6298a7fbf9fd11d6f4a6dcdf20f005820493d8d892a8ab8e5387849b34d7954153b334a8a677bf16187db0e926210a7cb84582020a37cd965acd0de0280f5e0718b30bfc3b1aceb8600e370b39c43427f66e391182c005840c681c005d6df951680b4b490fa801a62780d96e9f71c3c8e2ca23ae6d2ee05c5d0bf87365103292cad2a469db8289f7ac3e451a1151dd6c38892fb6cf12bd4048200005901c084aa0fd95adf481f4bb1ffee3358719255066f127a36bad60ef9f6ac6ff18fc8955223a020cb0d03f942c9d42065281b249485e341d6333255ec50064075060eb1b31c4c85c89b7ac3440fc9032b7a482bcd59a86bdb03806b96b8dacfe77ec03fc82c59fbc5fc91eeeb54dcf090bf32c704e1bb2137fa582499fea349099a4229933a23f86307a1e0bfabd3be96ce88e1d8301ae9496f90faac04d4566febbf3f8734df4cb9d8b6cf956144e0b62b27e004a86101c8fc366b95afc64577986fc07595d4fb4957032c05c2ba22d00e2f77bf13efcb87b77a432490009d8a03920be66cdf82ea3dec218a5d4a95636996b696b66ede98c1b25703f9d8143c8d09bfc76ebd9985b443812739fcd161fe01b49c25ede6df49fd0a838f8b531644c9ac8f35e3c2872576916098c31a26110952b2f076c216a512bcb18e6b2003c1aad1b1b155842af6fdc031af4edaadd576eab871368b8fdac1386878e7883340cfebdf82d43ebe2654608eefcbef56ecc8eaf8bcf56fe1461e866cb7a1a8ae3b10ed3883a99a29b842c65f6ffa391aaef7d5178eecb4319eef91048772d1cebbaf28d30e5d28357a08504ed0250d1ee71fe0aea705a0c686a3cedfc35961620bea", + "height": 7, + "parent": "bfa96cd376052c78a93d1941f68bdfcf5abf51c1988091f52f2c568f0916eca8", + "slot": 142 + }, + { + "hash": "66c90f54f9073cfc03a334f5b15b1617f6bf6fe6c892fad8368e16abe20b0f4f", + "header": "828a0818bb582064565f22fb23476baaa6f82e0e2d68636ceadabded697099fb376c23226bdf035820cf1d41b669559e9d30eaf310408a8dea605e3629c0dfd7b6d649d4861514d1bf582083f3206635b9182a411e2a9e870cc13f5974507b1f84476c8519ad9215ae46788258409f61612d55b8a980fb443aef29ec5ebb6867e56daeef5ae31221cbdbe0cc73052932dc200074ad1dd7766ca08758c946f726572d9da96ae83e83cf590beb1dd858503823baaf691584230676f935604c98f66335891d6e89bf9ffeda97caa388130478631b982355366dcc7b196d1ca0df4fb62b37591e4a1f009ec353598eb878ca8ff08ad7089800d39b72f6658d1d0706005820b26dce4633b152af05ed751b9e1db5ae740d561842c26e815942654bc5da24f38458205474aa415f322607b193704e4c4c0554ec74fe68f7a0c880d65660a75c092e9d0d005840bbd78899a963f57f958f23ee2113f5acf830ce54a3733f7f5e9ec66459997dbbe4837e7706f415b8435ded9bedc37cf51e60177ff5d8e753c2638349cf01bf0d8200005901c0cdff07ce69ea86d952d8af47a8bac61863ae5b0a3ac5dc041603c1b523dff52c03a9132c0d25b0a09365489fa96d864322f3fdbd4ae3e2d64815440fa68a5d04c240bf2a1681adcda82378b0cd9f0211c9f7ee6eb26e57ee2b0b92547793e5faa7f183ed48ff763de91c6324f355449b2d96e4f37efde9dc377751844b3314bb8d0e3c59befe2f1a5b7bc0045a164b8b9e1c5c9ee285bf6c2f6152826ef1252ab39577992ce208e5b172e9d03e46c268454a1502697162f175c586821d0fb5a8c0ffd4c56fb8c5cce2e1f7a0efc77a38277faa82580e983c87d4081dd8b5226bc8994114ec7a95f8be871726a6998dce138fc55377f022f84cc97eccdd18e7d61b557d7daea41d1d021e34aab3dac320758ba4f9c2d5fddc5a8072097be37af8f2e5fb4037a11632c6fd9d42c62a2e8263af2db7c83d992c933548e0f5d2593bface422b543cb5c1eb68fab55f0a77683d4532df74468dee8e18a1b32b92fde2dd6a8dad63af74be2f9c4d3a1d7b57711d09e38e97fb72551eedf3c215beb1c0cac6a938ca375bcb5ab7037955122f116659927bdbb741aec609c2c27e3d18c4d5751b52460d0914e68d40014f179d8400db188be2c34a7f98872070b86ad764", + "height": 8, + "parent": "64565f22fb23476baaa6f82e0e2d68636ceadabded697099fb376c23226bdf03", + "slot": 187 + }, + { + "hash": "bd41b102018a21e068d504e64b282512a3b7d5c3883b743aa070ad9244691125", + "header": "828a0818bc582064565f22fb23476baaa6f82e0e2d68636ceadabded697099fb376c23226bdf03582005aa1852c06d7490878d753ded251014a78bccec57a808a3b86ef3bd82a75a3858206ee3a36d9b941fcbb53e647468d10b0ae958d8a77b9f60d2ebd247a05a654c6d8258402a75f0ac75d5a93d6f5e5b24707e5403aabf3a1d88eb3a070a70c3c97949c12a85a8809e28d371ddc64e78ca7c3b59cee5ade5a4051521817ef654f0b3af24625850ae5fc258f45d205aedfdb3e2b0d1dd9bd7efaa96f2f2007cedc128cfc89f4c6f9292f097dba5f857b3ceb1329cd97ffe1bcf72610191df7915d5f6275a985495c75f843513258fd9151f3dec45e41606005820c3f0c9ec15cb5ea301f49032b9a84afbf361caf3f78e81ba6b37f4436f9551108458206fc52b672c123b52948bd394596278019413c1731cc335cc3a61bf3121e6305e1831005840f319400afc6a8848e9feeaf3c9128fe8a5a1c980dea1cabbbee777a95fef1fefbb3095e87e0bbc277e9a4c5baf6b21655b2a984e4507e3e12e68f697f15aab098200005901c007e82466ec742c66bf7a3501515a94e7c7e2e04cab17a2d724e28c829433abc02eaf56018ed6ff9205be9fcb9addf806d7f15ab2db159f6dca17dd31d594ca09ac24643578b384023b70d7a93e3f2435e4f9e38dc65c40df258d7379228b6ea42ea108ce0f27da1e113e3017311451c8972eaf8127f19b900fab6c241f06dccaf57cced81eb964eff669ef38c7e5036eb8d4f8d664bd7b5a50f03dd56e0435ec017e92b07be6ec30c20724593c79648978fbe94501ef85f261eb38209f8a2f829352981606a4c6d22d3f14a0b4f2f37c4b8085974aed296379d80e66f83506b7513a9e3c8b9ad6268994e42fa50be81faae29e8cf62bd7bd75b09a06652f9e0e30b0f898800be71e896a06a157e8ad8801887a2777e10d1d3eb6065b2712946f51b89bd9d239ed01417eef7f09a94eb286a1a4c08e6ad99a767346ec031c3797b4c48e149cb0b5dea39cdf1ba4977433afea1261a9992f207e0b8589e048e85abc751c50b717dc2f3ddc099109d6637cc881d59fd58c865305bae525fc84de10f5728e848bfd0722355748f9dfe3765aad64cccf0c030442258fd81a6dba936803bedc6096ff1d90072ef1a24e231f60c43c3d4b5f31776fe56287ecf228013c", + "height": 8, + "parent": "64565f22fb23476baaa6f82e0e2d68636ceadabded697099fb376c23226bdf03", + "slot": 188 + }, + { + "hash": "3dcc0a38ffead472ed06463f34338d0624c2c19f5117f908c54d98a30c0d8df9", + "header": "828a0918cc582066c90f54f9073cfc03a334f5b15b1617f6bf6fe6c892fad8368e16abe20b0f4f5820a01fafb0394b73269f0ba718760133346a76e8e590ae0b876670c8c4b31e1bbf582092411f9a1a29cab8b4ed1ab4357a25b230c014e3045c221b3346b5a5a243783a82584000f3001eb6f5e99bff9025fc8a06e7db6372381e2f759b20a47dc12267ff6f75a757fadc539f5a516dc98bb0e67e4f390a672198d8addc64308769dfbc68603158500a51fa3fac186fe9ddd55b37670a275735346191359ac4039309d7a49e26180e2ad92a523f3c9fcd3e0c73a2e3c046db0ecb2725839b77268f21e3fc2ea9f040eb5144af9edea3cc94fff9255c99820d0058209c2187596b43e20f304ca797b40645b37e2ad3e6ccccd319eb34fa5032fcaed58458203ccd81ccc58fc2adc69ac3cb20e6ee56598cf0603e9564cca9aface763d94c3c18500058400c4b28e1ae2bd14f9399384d45ef9267e5ff2a0e74c56bb6de6263bca3dd25c50852642b40e1fe9ad3f2f6ec2878401e9d93066723cba83d54a34a2e2a59e5038200005901c0b2509739b3bd938fc74e88a14c9541cd930d866c66926c8aed835d994e0a6ea14461a445300561f400e0f9e2444fd3e99779543c4c48647bedae4760f3ebc90149a9eb6f25c6175b6d603ee15b913013fb75f9f4a4c5ecedb5bcb3f288fadd520a015063b56cae186454b21f05060a616dcc3753a0fa963791666a3c2359fe5bdc13a77c64d7e5eb106f1d8d9da0968747066add30c07d12eb9ee7fee29f2b0f762464642c1d35adb980792baa73c3e3eece676c9c82858a1fdd34094e6680e037153e75a055c876a511ecd1731111f8512b4edcd831fb1e6013c0e485b4215a2c0fa5639f33ff62a2455e80b6cb5e3cf0ed721aac66bf14ead70fbcaecf89672fe3698a8bc53de555cba5e21a29179e9e2c2b410c1d4b0fd703387ef89fe7af5733e2549c699ec466c25727d72934d38add039c9713fe348a7468ba7f53f2e68a96bcfd25d1119c55f533be28a25e9bcf5ed7f96e57920358e6f78602351b270d70591707c6c1dbb926009a5b19d0ee96aeb92f09125242875f33d74e1fc2cfb72ee67291edee6e5dd11afad4788ac84b136b681cfe905260170a2088933e36be2607ac986a15546931e4f0bbc5ef0d5824bc53af6539a762cb490fa7b168e2", + "height": 9, + "parent": "66c90f54f9073cfc03a334f5b15b1617f6bf6fe6c892fad8368e16abe20b0f4f", + "slot": 204 + }, + { + "hash": "1900c6991f15a9f7bf20bcfe5a5c6ed71e4ae2aeb4a19611920f37b4ed089287", + "header": "828a0a18e158203dcc0a38ffead472ed06463f34338d0624c2c19f5117f908c54d98a30c0d8df9582022ff37595005fa65ad731d4fb112de050aa0ca910d9a3110f56f3879d449f88e5820da90997ba81483b3f2b4de751ba3ece6ba6d50f96598eb0940cc7d29452cdcb9825840b493b5a348d4660639cfa1dfe0edf50f1a21f6c2b5ecb3b9c572a47a077f4d8833ade725215bb0fd1608a0019e865ec30cf30fc2e567282709aaafba721af5f6585091374dbe76596cd34499b2ea2abeec7cf5db3c35ab1185a4a5ed0ee410e70aeaf4de0b7f8439b627d60e9dbe9a9449d6424c3eadb510879f2ebe40da0d78984e9eb58b50d3ab7bb71c179e0779afee01005820536be626675025dd9288c0c2ede06ee5efe88ae43306d1656c67977aaf635529845820499fc5dada1544be26d7cd3b2851fe955b44e560b50901abc71333d5d449eac9182e005840595a9a329b2637b8f2cb501aa793a159acc928a27c01e1ef586508492a68cabeae6ced714421be1f648bb05c7196f38e7aa4a8f616ad46e32c84e67951657a038200005901c03fd82976a4cefd1dbc88a6905ba36e6e8cf177bce55166808d5ac7ff2bf8a31f6a02b6b0fb5369539444cd3e783c58bce85e98dbd0cc0ab67c8ae0d5940fbf0d472338fcc8b178f0ba10f8683725c5df444b7fc6a5afc3c7fbab82e00e7df2d247c673d066eacc1dc7860c10b134c413d71c5a073a5f3e66a17f0d25dabae2699d7b4a969e129d627cd7839995ddf40a3e6672b6d03936de782f5e0dc31bfafdccc5d5d2e5e9a5b3414bface59a824e3a574250474d633115af821b63232de753fddb638606b93b853144dd75692b02e73b2ef8621eb1bfa307cfda8acaa2c43f8b673c9ed749e472cdf2fced20c063a2507ccb985d2b5a9bc77699f42379fb349e1e3a1ab86d1bd510c6ee89720f860d55c208dd262f49746d8fb2a7817d038262a6b266f98f427fc8b958f11adb8c84cc96444b1f5f9d994a4fd1adae2f2be87d8c1dbc0206ace7871da50cc92476d3fced6a4fc2809c8bb47dff992b06259c21f78cd6e72b49b8fe101065aaf243003af67a11d5aabcebf1059b3c92493f954507573a01bf92047ef68f4e980df914b360307b78b3371138b4c1504e155f704df9fabf1bc87ac47b3d5cd563cee6017380e4df6529face9cf39b36277068e", + "height": 10, + "parent": "3dcc0a38ffead472ed06463f34338d0624c2c19f5117f908c54d98a30c0d8df9", + "slot": 225 + }, + { + "hash": "38fbcc947003d8b5e31c5d83e20881add97f96df1131f782978e414a89de4d49", + "header": "828a0b19011058201900c6991f15a9f7bf20bcfe5a5c6ed71e4ae2aeb4a19611920f37b4ed0892875820df541b1fbd09fc825a48cd82ea1b2788553b2d72db86c4397b017db6fb4ee6e05820f80ce1e74d580c078c2e6cceeaaf2af18c87d72e85df14897ced396a9e803bf48258402c0670be0f61fae80eabd8b35421cc93161b9be6aa450320c5fa9af6ac50c8c8ff9af28338e27abd683ccb22d3923936453fa3201de03d7f0b66e6192c19212d58504d7f1025985a78254928935a194767583b87e0e7ce4a3ed8e2cc5fdae33976851ac9be64d45faec0114779481b4239cd842ea9d82785b059c92295c476c273932ec635be2ee68548102c08db9a1b5c050058209030940586f6027d7423d1f541d379c14f4d2ccb067366797154a39901c3fb1e845820e2dce0eb82d7bb4ca48269ebb93b70374185d6dc9e0e9f10de35ce2d8fd355000c005840d1dc8482d252de52a3e8868ad0325d50a10d2de4aa2fe8508a81edfe26897d93db3ee72346158f1b136db7ed754ac7a46354b6ae357dc8ec4be9857e35aa7e0e8200005901c04382921e630a6bc368755ff723b0aec652043f550a3fbfa42ffe16507b1a942f10695f24f4155d88547a9ac447a5ceba2c409ed31d0db6f75da346a40aabea04123f03f1ba839244e816272ddebfaccd07b396c7d4e7e8127b65e28a34be2af6d99954122949e55f47def97ae436cb9975b8a70ec77c4e57f48ceec0f4c19093a99991ea07b4b34129340df6cba7f4e2a99036c15e2309de61d20d77ba801603cd42f57f6fc3fd127dbb2923dc40375f1d11d0b6df7a73e6178c42fb62221a907e2126561b88861eb6d764dd5abd0a02cce6dd3baf659acd10c78bb17c48f7035a0c97618c6252664b9ce9541451047d47b888f01b92fb499940b9a5570c7b5b5e938563dd88a5483aafec9d89e92d14aea22a0a9b8dd77e7fcf14b4f58ea4b24be7a3866f9e9fd4646be578a2ba3baf516b6cf5b543267cd8bbd9684d4516733b782437363ef2bbcca05cb0de5d5163d29645b1f58be7307037ad8ea25494c204906d3df79b42e8529a7e9a98a51d9e31f116ec499ebbab55f0eba55bfc8763cc3d6a9824fb4514cd46aaed452cade04436f0c26c5e156e3d9d5d6524cc85dff4676d1eceb7cde887cb25345e7447b36d36f62ae2e497ebdc03b2f05f167604", + "height": 11, + "parent": "1900c6991f15a9f7bf20bcfe5a5c6ed71e4ae2aeb4a19611920f37b4ed089287", + "slot": 272 + }, + { + "hash": "a7bafdeab754f4636be9e4fd6c227fd083ecdea14e313738015827fe303283d5", + "header": "828a0c190135582038fbcc947003d8b5e31c5d83e20881add97f96df1131f782978e414a89de4d49582005442bb4e671ee9f6adb69c74ca5b3af6b3a407c97429856e80d8c4090d64d3f5820e0c61af1967457770433454c2b27cd6b922427f8ae13148c8b09f53ee7a56710825840ade63f510e852ec2bb4f0c37a8b47530fee73b9cb0068a0227ed541cfca2287dfe59dd9175c30f81f63ad8553fcce9ef1034ca08cb271c1c03638968d4f815ad5850308371ac0e3ad80c173da27a0643a90a5588070830f39e142ad3e52dc632ae02b44a7e6144bdaa302fd5de903affea0c5297a4c798bedc269686e14091f8f3119c078492c8a767d64d8262cf78bc0b0d005820a8743cc85987efb48c6052334a6c68fa34fae1d96683856b5bae643abcf4a20f845820dcfdf1559b3dcaea552e088d31e2225f3798b682571e8693d88e8437fd42110a184d005840c12b51de34fea0bbd6c4979d581669913bf95dc4f16d13857c752af53b31d4080e2ce0ec2fb289ec32bd82aad457750ce35698052309ba2c386f67d48c6c2a0c8200005901c0dcccca6e93e4b0357eca51d96f23d6b812c61d8be1929eca53ba5d92526792d1bdba10d2283f926c6c932d4fdef176f41379016f986150ab1db2a4b9b3d11e061a3631680c81fd0642ee45aeedefa4ae83ebf2c78a681a3f831e50c628929c8b5897e0f273ecfab8671cda14da4d1a5d44d9337270b394b4c0a03e1912eb755291a64261efd6984933d34e22e5267056bbcb58ac74362e3b9bec47024ac873539faa3cfe89bb91571cb1bf47f14445ae3a7734afe96d6f7c683b64683e1ac525f1a8bdaf43285cf8ff621478980cb756ba86019bdf1baddc904298c573015a8971d8215977d748c327d9dfc06c1a65539feeebb7898cbfca7903088818a96bafc14119ebba5b1afbdee35c292389ebd0bd318f4b7d48adca59cb2b7ed66113575cd3bf11be8549bced3cfac0c66b6ce83b28238e0de549d46aaa281a0d39784b7b46a29fff240c7aacfd49b7d4a0ec4dd0b6dab0f1a08a51c3fd796cd1bda647208509138b9278bd30b0208bcbc683d7f58db1568c6b06d0a9aca741fe39aeef7c253a04279ba7a367b2b4a870c3e2581add3e5824bcc9dd53bbaee2aedcbd58fa8ef76c7c11b3b6df977e036ce5cbfc1f7c974e70abf035ad72b8a5e0be09ae", + "height": 12, + "parent": "38fbcc947003d8b5e31c5d83e20881add97f96df1131f782978e414a89de4d49", + "slot": 309 + }, + { + "hash": "a45d606f75c663d8eac869c590ada997bd51442c2581098daa3859ac021efd59", + "header": "828a0d19013a5820a7bafdeab754f4636be9e4fd6c227fd083ecdea14e313738015827fe303283d5582009b54b526e6c5afb4a3c4362f199f243bda856e248c2de99156b5186562c08a1582021e64e133738bbee188311034a4f03103e0821a6c0e632f499e96d45d379b30082584065006a42cc18c9b07cc4bd66f70334f2b553e8305aad09d43b086c373e4d5c3683c1965fbb4b037b7c2c42afb24cb128a1d980c63937dffdd0ce847a36cf9ece58502dd6b642368e25c6cb73f094e7987b52e84cd575454b097a07da5b6f144058d58c3a8c62605e899be6691f2edf8bfe71f1a962c735e493bb4897efee47600d77c10ec90d7fb78c421a77221e5aee7800005820e25498225dd37f6cc3a86e34e06fe41444226737fe1d77b7c9adbfc90a8c064d845820a7d564335ced2b5ee9edd8ecb349f31822001a398d0ba5859e57715d696c6ebc1818005840c697536217d7492be9a280e147c5ae4a22dd0bb8ba765f45027927c587993dcb3e080df2aa3ac218d53a1afd5a4e9215cbe79b390e28cd9ff405464824f2710e8200005901c05d3bbcbd11e28469beb6b355329b836cd0367d6bf3517ce065689735eb7ac41ac47c2717c13c88cc55985ce598ccefa5bece0046e1e34a5f047bc4c04830c108fe9063bb6c7ffb23f3a85e936f906a1e1478be1b5d015c8d3d78ce5a536558ac25177143dcf1dc132c17d29d3cbf0021f048f9efd73d5d54313adcacdf010db9006c13807ac6128d25f2ab28b755abf844e50c1cf772ee5314a79ee8ac338b28e154499794b6477d7daafca6a41ee1c3a3bbd86cd860f1702ce69d25d10b46aa9ec5e31a2e91a8db0322ff68a383f14d2560ffd1144a020ba8ba7312e314932cb1137e21fde4ffff49e6352a932bf2772ea2ae98dfaf881a80d369caaa2db1dc25ebf19f2710cbc4ca12bfa7fe5978dbb0e6018745dabcad22091655e66ba15c3bedbab0ff7cd73107dca9e44cbd79f79f42f4e4babc9311157a0f48befea2e122a23e940b0420c2dbea9b710d5e1df7cbf1f65e6f6576209d6f676b91ee38f374e8e34da0c4897935fd62eaa4414678d133b6c3a819015707fbc1be3f35f3917ee924cff5f0ebe56cc4e90bbf76c4c80d7b8da18c2cf98005f54955499da7a8f581e4c935a0f5ba5c61f1717662e80d7b82c3a4ca01b1284ff95e0522f50878", + "height": 13, + "parent": "a7bafdeab754f4636be9e4fd6c227fd083ecdea14e313738015827fe303283d5", + "slot": 314 + }, + { + "hash": "75114e641531fa9a1025d03ece87e26607eba1f96eb67958523c8967f9cd3f0e", + "header": "828a0e1901575820a45d606f75c663d8eac869c590ada997bd51442c2581098daa3859ac021efd595820df541b1fbd09fc825a48cd82ea1b2788553b2d72db86c4397b017db6fb4ee6e05820f80ce1e74d580c078c2e6cceeaaf2af18c87d72e85df14897ced396a9e803bf4825840e3b47ae41c37c61f47dcc581b12536edb2696b0ff06fe3779a7a362f94ecd9413a59c0b8ced1e1689a11b1244562e3b428ce085f551c3627bad1d62c8e2235b258508fea74157df620c0f5c316e8219ffdc51a53596cfbe5b65a24454760b27a34fc8abd2fa4aed0ab0b7f75ea0970081a71f32a9207d15c01f3668b34e410b6a5e8cba62d6c9f62737f11345327489590030058205f74198f469ad28a72766552a4fe6d6fa80cf0404eb29f43ea7383418d87c442845820e2dce0eb82d7bb4ca48269ebb93b70374185d6dc9e0e9f10de35ce2d8fd355000c005840d1dc8482d252de52a3e8868ad0325d50a10d2de4aa2fe8508a81edfe26897d93db3ee72346158f1b136db7ed754ac7a46354b6ae357dc8ec4be9857e35aa7e0e8200005901c010b118010d227fed6a55f92b4291d6fa82e5e2a20f8ea256263ff965e1ef91ac779eea20799fb1cee391bb33c5b036da40a6773322128c9b59f3f5434c638409123f03f1ba839244e816272ddebfaccd07b396c7d4e7e8127b65e28a34be2af6d99954122949e55f47def97ae436cb9975b8a70ec77c4e57f48ceec0f4c19093a99991ea07b4b34129340df6cba7f4e2a99036c15e2309de61d20d77ba801603cd42f57f6fc3fd127dbb2923dc40375f1d11d0b6df7a73e6178c42fb62221a907e2126561b88861eb6d764dd5abd0a02cce6dd3baf659acd10c78bb17c48f7035a0c97618c6252664b9ce9541451047d47b888f01b92fb499940b9a5570c7b5b5e938563dd88a5483aafec9d89e92d14aea22a0a9b8dd77e7fcf14b4f58ea4b24be7a3866f9e9fd4646be578a2ba3baf516b6cf5b543267cd8bbd9684d4516733b782437363ef2bbcca05cb0de5d5163d29645b1f58be7307037ad8ea25494c204906d3df79b42e8529a7e9a98a51d9e31f116ec499ebbab55f0eba55bfc8763cc3d6a9824fb4514cd46aaed452cade04436f0c26c5e156e3d9d5d6524cc85dff4676d1eceb7cde887cb25345e7447b36d36f62ae2e497ebdc03b2f05f167604", + "height": 14, + "parent": "a45d606f75c663d8eac869c590ada997bd51442c2581098daa3859ac021efd59", + "slot": 343 + }, + { + "hash": "5401ead94d19a9375621adbd04ab2faf4f8435ffccc567750688071a5f90401f", + "header": "828a0f190159582075114e641531fa9a1025d03ece87e26607eba1f96eb67958523c8967f9cd3f0e5820be62f79f3cfcaa5e6986b864daff9debcfae34ad53a36df2faee406c67ac290d582088a86b524b9f5f6b5319f1a3171c0031fa97842df2ffc5d29ff7ec4c0ecc05f18258408bdcb127efec7dae9902f779e23ae96fbe1a1804cad82711a9807a3c79b4d5cb4ce930fc61573b3b9aa5501552ef4eee8ce826cadb73660b4e542b0818ee7ed35850b72058773c0003b5aa13f36bbfbc676e65d7077c2fca6e2ee1e88b71426a35f8b675bb3dafc879fb363ff5e5b35819c9950411f0a181c7588f473b546532133988c60c220e202dd3759127997a31270d00582066ffb9be8ca75f501b6ae07db6ee7f7355f15ac307001c6f30305f526b7cb7c584582020a37cd965acd0de0280f5e0718b30bfc3b1aceb8600e370b39c43427f66e391182c005840c681c005d6df951680b4b490fa801a62780d96e9f71c3c8e2ca23ae6d2ee05c5d0bf87365103292cad2a469db8289f7ac3e451a1151dd6c38892fb6cf12bd4048200005901c0b1f6e3b830b128de88df804e43a24437f1004a57d6c6e92e9d53f0b82c4b0918f2465fe35507ca166474634a33dca95c096e2af44c7d8346c74eaa855ff0920db1b31c4c85c89b7ac3440fc9032b7a482bcd59a86bdb03806b96b8dacfe77ec03fc82c59fbc5fc91eeeb54dcf090bf32c704e1bb2137fa582499fea349099a4229933a23f86307a1e0bfabd3be96ce88e1d8301ae9496f90faac04d4566febbf3f8734df4cb9d8b6cf956144e0b62b27e004a86101c8fc366b95afc64577986fc07595d4fb4957032c05c2ba22d00e2f77bf13efcb87b77a432490009d8a03920be66cdf82ea3dec218a5d4a95636996b696b66ede98c1b25703f9d8143c8d09bfc76ebd9985b443812739fcd161fe01b49c25ede6df49fd0a838f8b531644c9ac8f35e3c2872576916098c31a26110952b2f076c216a512bcb18e6b2003c1aad1b1b155842af6fdc031af4edaadd576eab871368b8fdac1386878e7883340cfebdf82d43ebe2654608eefcbef56ecc8eaf8bcf56fe1461e866cb7a1a8ae3b10ed3883a99a29b842c65f6ffa391aaef7d5178eecb4319eef91048772d1cebbaf28d30e5d28357a08504ed0250d1ee71fe0aea705a0c686a3cedfc35961620bea", + "height": 15, + "parent": "75114e641531fa9a1025d03ece87e26607eba1f96eb67958523c8967f9cd3f0e", + "slot": 345 + }, + { + "hash": "dec730545b2ff80c3e6e83cffa91d90025fdcf8d254e0dde29edaa145fa75627", + "header": "828a1019017658205401ead94d19a9375621adbd04ab2faf4f8435ffccc567750688071a5f90401f58205a177476c40bb96ea1f9d241d0d1651ae08104bfc54337d356f951d59404a4d2582037264127bcb2df028319e576fbe8727a7d9b2d1cdcda8b30c6cd377f0630bbd8825840ca2117324454dcabb6883ae978674532de943b8011baa89f57b7703fe780a04c33570b92d05b9ae288d57ce2c72e2e5a18076c83467fc31c9e6ccc35bfd4c90758506f0d58c4c19a303d11f86a7b63a5317537b9d0d603cbac51dd5479a65c5485bfcc94128cf5f3795826ed155166234bac202456c80bd441abb9ad3cb69290843ec58dd08da8c53839982120d1aa52920000582068e1ac2203c6d60ed68db32f586c3695a0277272b17822a9622d0f5980a256b8845820338f92308f2f1d0dcabc1f1e3ad061c8b6e32679fee51431a43dc32efec5a0fc1818005840b3bd852c4a9a2d8f740ba727594f91c227a9dc638d2f27edce75b140bce7a12d62c0dcca2c832e3c8904e0149d2bc62e20e42605f6e0444835a9ecf2f462000e8200005901c00f40e59a0f07a2aafb3cd75c862fb1f742748283f81e23f0fc9487ec31734e4390dbe570b9d0fc0f89c52c1dd7d04c2b68554106b664635f6ca5d77c11801b092a33fd2dc4086d99d1309eee46f49e76b5d9f86465fb0ae9f1b3dec4c8e2c15dcb0120b19dd9e1496fd9350141f284d40e2350e86404f031597cefa7063a4a35e92b198a7888cb9397d81e563e067f3e0f5709159027827cc74fd3ea0583051a1cbcb8f3cdb6280b50138328292f33b6b7dd202214124507fde1789777f1737fd390cef46fb8ae253be49c8d3b43aa48387f0e50a32c3f2b6fe25613e06e4d3873903f3ddbef0d2d520380966869fcf11a1dd7275b1b6cccc313d2a718de1b2ed2e5fc55f72a46076eaf27598525fe452ace332397e8a2687d494b086256933ebfd955443d19d647a98c17f0472d136b4ae46d4548cc837ae9ea18449b259f3eea3820cc09fd0ee8dacd88f36ea31d266dbab5ee6ae55142594774498e7e3a3ff3fad6228c6e1fe23e3ef39e2edbe258351d9a1b8b50aa35a9f5e3e6c4f376d16948885aae058502fd5d51b5f6bafa8ec285d1cac641488bdaf90d99331da3edd4e2db2ac63975bb6791ba02822a7d25ea87aa5b3756ed3decb5ef8f09970600", + "height": 16, + "parent": "5401ead94d19a9375621adbd04ab2faf4f8435ffccc567750688071a5f90401f", + "slot": 374 + }, + { + "hash": "05c824474e5239b7718632c065389f0f9b1a4120a44ef27e4d2065478c50cb7d", + "header": "828a111901c65820dec730545b2ff80c3e6e83cffa91d90025fdcf8d254e0dde29edaa145fa756275820be62f79f3cfcaa5e6986b864daff9debcfae34ad53a36df2faee406c67ac290d582088a86b524b9f5f6b5319f1a3171c0031fa97842df2ffc5d29ff7ec4c0ecc05f182584073df48d337d6fbf497354c60ce817fc8014b67141ad83cb749f238a29a64a77eefdf9f5de9ab51c59d36f4c3fd3693e3167aa27a8b59bed5fe1024121433a4f0585099c4803602526a2a6790b6b3813a10fa5c195cd96597fefac74af095d93efd99bd9dd309160ad5b610c18f2e423832938524e409ba382fc709696180cc49661bae91858ee2b14cf51f9d7d0401289b07005820b4e57e88aa2b820449e415ccc452bd521d12c6eb70b03e406d7dd8ef3aacb73384582020a37cd965acd0de0280f5e0718b30bfc3b1aceb8600e370b39c43427f66e391182c005840c681c005d6df951680b4b490fa801a62780d96e9f71c3c8e2ca23ae6d2ee05c5d0bf87365103292cad2a469db8289f7ac3e451a1151dd6c38892fb6cf12bd4048200005901c04595fd571a430146f33b6a46bb4acdcc74e1d5d37595bab8840c5735d1869dc439db24485598e53551e5be231748ed2e2a0e39571418437ffdc2c76f965c6609b1b31c4c85c89b7ac3440fc9032b7a482bcd59a86bdb03806b96b8dacfe77ec03fc82c59fbc5fc91eeeb54dcf090bf32c704e1bb2137fa582499fea349099a4229933a23f86307a1e0bfabd3be96ce88e1d8301ae9496f90faac04d4566febbf3f8734df4cb9d8b6cf956144e0b62b27e004a86101c8fc366b95afc64577986fc07595d4fb4957032c05c2ba22d00e2f77bf13efcb87b77a432490009d8a03920be66cdf82ea3dec218a5d4a95636996b696b66ede98c1b25703f9d8143c8d09bfc76ebd9985b443812739fcd161fe01b49c25ede6df49fd0a838f8b531644c9ac8f35e3c2872576916098c31a26110952b2f076c216a512bcb18e6b2003c1aad1b1b155842af6fdc031af4edaadd576eab871368b8fdac1386878e7883340cfebdf82d43ebe2654608eefcbef56ecc8eaf8bcf56fe1461e866cb7a1a8ae3b10ed3883a99a29b842c65f6ffa391aaef7d5178eecb4319eef91048772d1cebbaf28d30e5d28357a08504ed0250d1ee71fe0aea705a0c686a3cedfc35961620bea", + "height": 17, + "parent": "dec730545b2ff80c3e6e83cffa91d90025fdcf8d254e0dde29edaa145fa75627", + "slot": 454 + }, + { + "hash": "b967de1463e411fe5368b544c4943d23a1f534a8f07ed959d0c971c014894b40", + "header": "828a121901d9582005c824474e5239b7718632c065389f0f9b1a4120a44ef27e4d2065478c50cb7d58205a487ec06ac8f9f228e54a21d81f494eda87a990504f5a980b1f71aa13d905c05820d68a44bed117a61e737741fc787b26135ca7e0d802115d5f389e9f068b55196882584001d1fa15c1411fe591ae1469ad4b932c9d4d2d9665db2a6ccdaf3b735c77f8e1f738bf46ca229694ab3776c9aa1dbd6d9b3019cddce2d857784a6f9936120a0e5850397fcbab605dfe622631e50ad83af397ec5c579880dd927ae394866c7e4ceedbe569d04a8fabf914683a832ba0e271daa40512c8b4ec6e07c51c3e396e1a221dcc0573f11f349f9cd8fdeb62e75fa90d0058209f8279b99e3c4d557b976e4c1b925eb4b6a604c4c55a7f6af7be1b39a658b2fb84582005fdbf2c95125a438bdcd229101252502e108f05ac0870d65494526602a23f731845005840fbd7a9357529a5691c0579f2500b386fde041aadeef632b321b7b8b522012256387680ac3f5090b2f2d03dc27b43df686af2c4c8ee98fe050dd0ea7c96f00a088200005901c0179d9a105f1e411feaf66152095d3213f14d8ac6acfaa6ce23db3708974aeb4df90c6c0c17c1f2b878cbdcc596c47c85f0f6ef44d3ae8ce838f6435471e60e0cc13235d0eb8ca973053893d3588f771b59046cc03fec46e11742086377edec80a495daaa579a6de588deb6fa4a7c0809595f93d68fda859c0ccfb011181dd49bd5f2e67c5626df00ffdc5c1bec266e91682cbc57333c7327cc1d567596db4607e7964e58e6a1dc6f6c9c24ae72243cf9f193f966bee38cbef934863625dde01a8956610bfe98c89429ab2270df7742983eef20dbbd1504a137c00a556ee708a444426f733c152fe8b19d6af50dfda6b3efacde9b71b3c90043a99f216e462af69144576b49bd708cf5c67d93160adf3ad1a39f0b118ad8f78adc7af45dcd4f28c42657fb8cde01fbd496ab6ace5ed6607eb73b610965ddbb78a7fd6714c4ed087fd69f5b133aed19db36919606390333f145b6e44a4ffba76fcf503c19b5afa897a9448beb350fafa9c6aaf29e5e105444d5732445b97170e628462da8969a163587d05081ef2618fe056df94defc1c70d21b41903d8bd77a171c67eb481ec2037260dc8c5ae867a61af91966b30ee9734b0b0b38d63d33c114471cf8dd5fc09", + "height": 18, + "parent": "05c824474e5239b7718632c065389f0f9b1a4120a44ef27e4d2065478c50cb7d", + "slot": 473 + }, + { + "hash": "42c0a5fe638f069eea72b788c9a8c7deba5c40b9b3f4aea09b41cd405d1edf4e", + "header": "828a131901ec5820b967de1463e411fe5368b544c4943d23a1f534a8f07ed959d0c971c014894b40582018837df064b6125a111e33ea813bad260fefc9b358c9a6f593efe6d414f6b1855820b6a49a80648fd97b79c4658137a21896c2cb965c5bfb5341b6bbc1ebd309eb4982584051c31cbb7a7544c95c735df6caf4a53490f0427fa5ac923083268edf42722c66dbf2c267e16c89e0534e2acb1f5b573d818293499e7441b03a2bfc2b1ea554a3585072e4aa905e5dbce296967336041a560de5d803dd43505c333c9187940a8720cc5226aac0c9f85b71895fa14cfba52f95952d3eceba7c40296f9f847bd5d68ec0a2e6ffc655294c08d2a21811cd87650f005820c3f7892c234df731ff838487153b89b6eaf70fdeefe81d784750f9806bcd40b08458206e87b3f3231bc816ab79dbf7ef9631ffa9750c074d56276a9d3537817ac418ed1840005840a1a5f068dee1cea50ecd3206b2cde96c3ffcd9e7101e365fe2a7308274660caa20e69815d37cc4e9d7b93609d4f7787d499c1e54f838fd5c3b5fb6de0d229b088200005901c0af7fba93be00bc441a52fa4cfb278c925cfce8bd338b36c43e07514713478d37f94769a7f1ed3f4ff424690c34ddcd9548ba84ae28b6a0dca5970643061af707ebeb4c8dd448ce09d675ca6291ef83f2b82371cb4c904960430e40d120365011d31daef6cdc3e3896ae2ebce0400f566484c73de8810d337d3c80bc5ae3af9cc68fa7f55478b6b8d3d7e5ac61b2587184899ffd1314e8bc2911a0004fa506e9369ccc438aef33bd13cb6c27766f0e8339304da66df13094b2e31b383d4794bd21c14710d97ac55bbd942952d2511466b9d9cfd9f1035df8bf7f079b8dced90be77f3adf4bbfad6ad2f63befb230b8c7a8ca3771dc1783d1deb0cf6b369e03ec2aa38454f09e9e2fa975ece0ec6711e0370c7e816230adadef96b3a4d6694ef12c7c9002b8371a09994caff169639bfa4e07abc1341a6708a59940df51c155cc1aebf196d8cf3705c9f22764d0bec98b52aff7d4939621dd576568554b854ea3bb80e4292f56f76bf2f68a98fa6e17f6824ba839c2f60905b81d4987195c69e5dda32c884a7112465e00938275fbfba9d331d8b1258110d730bd9fbecd6b6952f69e346e8e4e37a7f7ad035a0ebd89ccd901fcc1ebc80672696861af7bb2050db", + "height": 19, + "parent": "b967de1463e411fe5368b544c4943d23a1f534a8f07ed959d0c971c014894b40", + "slot": 492 + }, + { + "hash": "fdd5fbfbb966ee2632f3a01237498ab06f50ae882dd1836ead57be19321fe85e", + "header": "828a14190209582042c0a5fe638f069eea72b788c9a8c7deba5c40b9b3f4aea09b41cd405d1edf4e5820af9da86d95be558880436e0e16150e759a13937e427dee52508c94d67ef80eba58201f16763f1e6898d544d7f9e569294b0960b2d2c0a9c5effaf1b81aed6feb3cbe8258405c412ba9f09655e77c5bc4fe966e0414b6022919e981c668734644c951c7a60eec35b08e16118447798939d7e9530102735c9a54b0d23ecce4f12e028191369158504c1f616c1ecc096a9b51d33efd5277fb9301d3209e6ebe0698e652ab5e342cce186645523b831b2a216950faabc5fb860c769af9655f0f24d89d8dd29d61f02b4d0dcebad8e751b1ee64b2c535adc408005820ec1586e4785c719bb85223de9bee4db54eda6d1ea73102e0e766bec7f486a19984582033b4783491e8204211596cee996a92865a2a00761c4972ee0f0ee1cbb07dcfc00a005840d03083f0c14c4b60af4642ab1d5530e1b396127c57db5767d671044fb2a92cd55795e3df673f1a68958813bdf4fa09fa2e8d3a6c9bea623479ae2cc8bcef180c8200005901c02fb8d8c276dea8ba48ff07f9cec314f1f6d11ee1b91316c5c171c630add0b43e40604799197235d2f1fd54132019c188a46a3a82fc211a4e2eb2276ca51eae06b32b954dc94768de9dd6931a9bc97c59dd74567448ac09f5228862e2fff750b97ae0f60f555d80843b304b9ca963720a599d0e43626161b5879259bd07c47c57ae3c711d7faa1896c58fc200ad7a3f39c3ca8b5e89814ad8fce112782b8779b4a5f89b45244d3efc05c73121c211d6d233cd82cfaf3e1573ada54adb0f887fc96c797d37c54aa5d232dc72f987cb717f09b0ca199cf84c5ac63ed24baace4a8b322b535330362773743b0946f562cc370cdbef122b242e8c24b1d079bec1733e0d21e7bfaa739a8708ddb99540491e7fbbea15c90fe3079bcc568ab56e07a74e73bc2fa589593f7db9a3298a928a6f0de4971fef3e4964e6c4da7eecbfa3850bdf8402c758c86d91c8e35c1c318f9e5a3f6eae7fcc456e117edf87341334286fc00e692abc03595af3753258ac024429868e89e4d24e7bdabce43676bf25e05c1f05f5973b87da15a2a754cc29f27db5707867d7c9185dc5b1bf5a1865324134cd7ca504dd6bedbf48394755f16e10feac173ce9eaba2620c6f4cd10d24d9b03", + "height": 20, + "parent": "42c0a5fe638f069eea72b788c9a8c7deba5c40b9b3f4aea09b41cd405d1edf4e", + "slot": 521 + }, + { + "hash": "03409d444148026901b853cdc01ccfc2494cd0f18adf6cfe14ec13607d1e3e1e", + "header": "828a151902175820fdd5fbfbb966ee2632f3a01237498ab06f50ae882dd1836ead57be19321fe85e58205a177476c40bb96ea1f9d241d0d1651ae08104bfc54337d356f951d59404a4d2582037264127bcb2df028319e576fbe8727a7d9b2d1cdcda8b30c6cd377f0630bbd8825840160829dcd413a0f203cf02586588c713763bac34d9cdfa0d37a7ffe56d906a86437298c54238c01203b954e0b20d39c3ad7a40d109c71b4b26447682060ee93f585002282850d66e9e5085c9a1ad55ccdcdd077c8c2b786d48e3b935ab8d86e04504d27d46becdf3a9870178bcd7bc219d94304adc6573b1b8f0973a280f249728b1f360be4367ca2e45c0346d00178e0c07005820507b0380c4a36c78e6c90d410421f7fd1a766a983e1bbac668e7df2f7236bb7c845820338f92308f2f1d0dcabc1f1e3ad061c8b6e32679fee51431a43dc32efec5a0fc1818005840b3bd852c4a9a2d8f740ba727594f91c227a9dc638d2f27edce75b140bce7a12d62c0dcca2c832e3c8904e0149d2bc62e20e42605f6e0444835a9ecf2f462000e8200005901c010adaaf43ea6a45b499ddf747b41d082197bf2ccc741a45bc74e2fd505b4623fbea03e5820fc9d145f22690a0ce2adb7256382fa132f99d9801b1b6b7d39b60b2a33fd2dc4086d99d1309eee46f49e76b5d9f86465fb0ae9f1b3dec4c8e2c15dcb0120b19dd9e1496fd9350141f284d40e2350e86404f031597cefa7063a4a35e92b198a7888cb9397d81e563e067f3e0f5709159027827cc74fd3ea0583051a1cbcb8f3cdb6280b50138328292f33b6b7dd202214124507fde1789777f1737fd390cef46fb8ae253be49c8d3b43aa48387f0e50a32c3f2b6fe25613e06e4d3873903f3ddbef0d2d520380966869fcf11a1dd7275b1b6cccc313d2a718de1b2ed2e5fc55f72a46076eaf27598525fe452ace332397e8a2687d494b086256933ebfd955443d19d647a98c17f0472d136b4ae46d4548cc837ae9ea18449b259f3eea3820cc09fd0ee8dacd88f36ea31d266dbab5ee6ae55142594774498e7e3a3ff3fad6228c6e1fe23e3ef39e2edbe258351d9a1b8b50aa35a9f5e3e6c4f376d16948885aae058502fd5d51b5f6bafa8ec285d1cac641488bdaf90d99331da3edd4e2db2ac63975bb6791ba02822a7d25ea87aa5b3756ed3decb5ef8f09970600", + "height": 21, + "parent": "fdd5fbfbb966ee2632f3a01237498ab06f50ae882dd1836ead57be19321fe85e", + "slot": 535 + }, + { + "hash": "5d3cbe4d673988e02fbf1f87de1111896286a78a46e82650ecd3444796100a52", + "header": "828a1619021f582003409d444148026901b853cdc01ccfc2494cd0f18adf6cfe14ec13607d1e3e1e58205a487ec06ac8f9f228e54a21d81f494eda87a990504f5a980b1f71aa13d905c05820d68a44bed117a61e737741fc787b26135ca7e0d802115d5f389e9f068b55196882584014d6299e4813ef7d9d45454e6bf168d032d94e76a0948282ce48badab275fa8a92ab8211e98875dec8d106ba1ef34264f41ba68dca694af3c4a62fbe06076fd55850b212719c6cdb85f04ca70428ed23e54945da3553e777209a0945af7c4348908f0de5752788acc60d467351a6c800c1e1720b3affff1d7d8d5a01edea991faec60025dcab667cc1edd8b4246ceef76d0f005820cb0a3366a57ab3d112db06bee13da4c30c68f9ec1425cc08ca52fd5db97f16cf84582005fdbf2c95125a438bdcd229101252502e108f05ac0870d65494526602a23f731845005840fbd7a9357529a5691c0579f2500b386fde041aadeef632b321b7b8b522012256387680ac3f5090b2f2d03dc27b43df686af2c4c8ee98fe050dd0ea7c96f00a088200005901c0a1d99e5976c609814a2bafd5d871e53bc0ca6975c28d5bb43a8a7c4c67501222f02ad9b7c4fa2bcd252e3b54fd69d79a95dc14552ac51186499f0f4234841c00c13235d0eb8ca973053893d3588f771b59046cc03fec46e11742086377edec80a495daaa579a6de588deb6fa4a7c0809595f93d68fda859c0ccfb011181dd49bd5f2e67c5626df00ffdc5c1bec266e91682cbc57333c7327cc1d567596db4607e7964e58e6a1dc6f6c9c24ae72243cf9f193f966bee38cbef934863625dde01a8956610bfe98c89429ab2270df7742983eef20dbbd1504a137c00a556ee708a444426f733c152fe8b19d6af50dfda6b3efacde9b71b3c90043a99f216e462af69144576b49bd708cf5c67d93160adf3ad1a39f0b118ad8f78adc7af45dcd4f28c42657fb8cde01fbd496ab6ace5ed6607eb73b610965ddbb78a7fd6714c4ed087fd69f5b133aed19db36919606390333f145b6e44a4ffba76fcf503c19b5afa897a9448beb350fafa9c6aaf29e5e105444d5732445b97170e628462da8969a163587d05081ef2618fe056df94defc1c70d21b41903d8bd77a171c67eb481ec2037260dc8c5ae867a61af91966b30ee9734b0b0b38d63d33c114471cf8dd5fc09", + "height": 22, + "parent": "03409d444148026901b853cdc01ccfc2494cd0f18adf6cfe14ec13607d1e3e1e", + "slot": 543 + }, + { + "hash": "6f582e017fb4a4f996f2ad1965bc7a557551d3a0dc71d3081be5a8ecaf9c4a0d", + "header": "828a1719025058205d3cbe4d673988e02fbf1f87de1111896286a78a46e82650ecd3444796100a52582005aa1852c06d7490878d753ded251014a78bccec57a808a3b86ef3bd82a75a3858206ee3a36d9b941fcbb53e647468d10b0ae958d8a77b9f60d2ebd247a05a654c6d82584088ed43f8dba3883daca173d2f38fb77c9a4188b968706c45efc08a764bb55604af0ee7f2f539cf142846272b787d18dcc67249bbc6a58be5a6c2403149b3038858501499e42d6f56cbbca8e6042a9cc204776e5889e21f52b68c069dabd3dd7b59f934d0345ae6a6b3f34d2a673f50a0c5834190eb5435447e1f821ec3bd6dd96ce693b86175df367b63607e0f8a357f550f005820fd24ea061eae4f024b33beb3a7c5d7114fdb92e4344c6c2b3edb2d2af5a142158458206fc52b672c123b52948bd394596278019413c1731cc335cc3a61bf3121e6305e1831005840f319400afc6a8848e9feeaf3c9128fe8a5a1c980dea1cabbbee777a95fef1fefbb3095e87e0bbc277e9a4c5baf6b21655b2a984e4507e3e12e68f697f15aab098200005901c0c54604328a4fe389365226a8a1cd44d3168dc8b1dada4070868f2611be4657aead0e0240a163aa697d74a14fed30a45870fa414f4e330a6ed1ef93b321d69202ac24643578b384023b70d7a93e3f2435e4f9e38dc65c40df258d7379228b6ea42ea108ce0f27da1e113e3017311451c8972eaf8127f19b900fab6c241f06dccaf57cced81eb964eff669ef38c7e5036eb8d4f8d664bd7b5a50f03dd56e0435ec017e92b07be6ec30c20724593c79648978fbe94501ef85f261eb38209f8a2f829352981606a4c6d22d3f14a0b4f2f37c4b8085974aed296379d80e66f83506b7513a9e3c8b9ad6268994e42fa50be81faae29e8cf62bd7bd75b09a06652f9e0e30b0f898800be71e896a06a157e8ad8801887a2777e10d1d3eb6065b2712946f51b89bd9d239ed01417eef7f09a94eb286a1a4c08e6ad99a767346ec031c3797b4c48e149cb0b5dea39cdf1ba4977433afea1261a9992f207e0b8589e048e85abc751c50b717dc2f3ddc099109d6637cc881d59fd58c865305bae525fc84de10f5728e848bfd0722355748f9dfe3765aad64cccf0c030442258fd81a6dba936803bedc6096ff1d90072ef1a24e231f60c43c3d4b5f31776fe56287ecf228013c", + "height": 23, + "parent": "5d3cbe4d673988e02fbf1f87de1111896286a78a46e82650ecd3444796100a52", + "slot": 592 + }, + { + "hash": "387d52ca09e6699422dde1090864cdf4d5a44e8eeff34d740701dd4ed9ddaa1c", + "header": "828a181819026058206f582e017fb4a4f996f2ad1965bc7a557551d3a0dc71d3081be5a8ecaf9c4a0d582022ff37595005fa65ad731d4fb112de050aa0ca910d9a3110f56f3879d449f88e5820da90997ba81483b3f2b4de751ba3ece6ba6d50f96598eb0940cc7d29452cdcb9825840b99815aebf7de3461ec3f488398d664a09a7c0b51890b1afb0fd666517a86b71cabe08a3cf3181b2e615e92a9e308eefa8537ec76ff081aaf6bad7985d56a90158504771afe5b062bc2e41a14516e67eb0ee0f63c75f30253ab1f3de3cdfae95f740d704336f43cb1c7707aacc0b52af7f1921ddb599ff9b046f688e4bed1c2f542f14828536b10f2d5c8234404987f0a203005820b3e8adaff1a454ea11853b10cd5a4c1092f5b7952f933c5f22ebcf30cbee8d2c845820499fc5dada1544be26d7cd3b2851fe955b44e560b50901abc71333d5d449eac9182e005840595a9a329b2637b8f2cb501aa793a159acc928a27c01e1ef586508492a68cabeae6ced714421be1f648bb05c7196f38e7aa4a8f616ad46e32c84e67951657a038200005901c09920368c1cdba7c25fb286617b22aa002ffdc6d1c98d1c1538236210b9dde16d3d9acfd0cbe101918f090e6381ed1a20105a072216a1e31b4a0d3e90334d380a472338fcc8b178f0ba10f8683725c5df444b7fc6a5afc3c7fbab82e00e7df2d247c673d066eacc1dc7860c10b134c413d71c5a073a5f3e66a17f0d25dabae2699d7b4a969e129d627cd7839995ddf40a3e6672b6d03936de782f5e0dc31bfafdccc5d5d2e5e9a5b3414bface59a824e3a574250474d633115af821b63232de753fddb638606b93b853144dd75692b02e73b2ef8621eb1bfa307cfda8acaa2c43f8b673c9ed749e472cdf2fced20c063a2507ccb985d2b5a9bc77699f42379fb349e1e3a1ab86d1bd510c6ee89720f860d55c208dd262f49746d8fb2a7817d038262a6b266f98f427fc8b958f11adb8c84cc96444b1f5f9d994a4fd1adae2f2be87d8c1dbc0206ace7871da50cc92476d3fced6a4fc2809c8bb47dff992b06259c21f78cd6e72b49b8fe101065aaf243003af67a11d5aabcebf1059b3c92493f954507573a01bf92047ef68f4e980df914b360307b78b3371138b4c1504e155f704df9fabf1bc87ac47b3d5cd563cee6017380e4df6529face9cf39b36277068e", + "height": 24, + "parent": "6f582e017fb4a4f996f2ad1965bc7a557551d3a0dc71d3081be5a8ecaf9c4a0d", + "slot": 608 + }, + { + "hash": "fe7f705538bbf48aea35c51805fedce1ab3d295efd7f398e781f1747f1a01edf", + "header": "828a18191902635820387d52ca09e6699422dde1090864cdf4d5a44e8eeff34d740701dd4ed9ddaa1c582005aa1852c06d7490878d753ded251014a78bccec57a808a3b86ef3bd82a75a3858206ee3a36d9b941fcbb53e647468d10b0ae958d8a77b9f60d2ebd247a05a654c6d82584050f7566b01840ba8b28bd7d2fc6ff854f09ab9b3b4570df1f5caac623ca16c09b7e89c606337dbd69ceb11a1ee00ea0db87e3b8e57986db758391f14ea18d7a75850e34a2f719fd88cefb5a5af14ebf82c84a9003fbb3944e5e0dbe4fb9ce54c3cca54ef99069b730801f67dfa83df24fc41be19580842dfd902f90d678465b6a275242b32d464779000283947cc2c5efa0a005820d2a307e16f147ca219a0c2b9568b7dc5637bd970a522ef95544e153f8c296a548458206fc52b672c123b52948bd394596278019413c1731cc335cc3a61bf3121e6305e1831005840f319400afc6a8848e9feeaf3c9128fe8a5a1c980dea1cabbbee777a95fef1fefbb3095e87e0bbc277e9a4c5baf6b21655b2a984e4507e3e12e68f697f15aab098200005901c0d85fa7332293687ee12aded02622ffbce9e28b1fa70e910ecfa65c1375c3259f7ca7aaa1513bc10e1c268801063a5997770d6ee35872808405ab2e10bda3260bac24643578b384023b70d7a93e3f2435e4f9e38dc65c40df258d7379228b6ea42ea108ce0f27da1e113e3017311451c8972eaf8127f19b900fab6c241f06dccaf57cced81eb964eff669ef38c7e5036eb8d4f8d664bd7b5a50f03dd56e0435ec017e92b07be6ec30c20724593c79648978fbe94501ef85f261eb38209f8a2f829352981606a4c6d22d3f14a0b4f2f37c4b8085974aed296379d80e66f83506b7513a9e3c8b9ad6268994e42fa50be81faae29e8cf62bd7bd75b09a06652f9e0e30b0f898800be71e896a06a157e8ad8801887a2777e10d1d3eb6065b2712946f51b89bd9d239ed01417eef7f09a94eb286a1a4c08e6ad99a767346ec031c3797b4c48e149cb0b5dea39cdf1ba4977433afea1261a9992f207e0b8589e048e85abc751c50b717dc2f3ddc099109d6637cc881d59fd58c865305bae525fc84de10f5728e848bfd0722355748f9dfe3765aad64cccf0c030442258fd81a6dba936803bedc6096ff1d90072ef1a24e231f60c43c3d4b5f31776fe56287ecf228013c", + "height": 25, + "parent": "387d52ca09e6699422dde1090864cdf4d5a44e8eeff34d740701dd4ed9ddaa1c", + "slot": 611 + }, + { + "hash": "b30bf23d2954ac28a952a024a4a5619e137fce29eb908f3a2dcc6b4abb0fc0e6", + "header": "828a181a1902885820fe7f705538bbf48aea35c51805fedce1ab3d295efd7f398e781f1747f1a01edf582018837df064b6125a111e33ea813bad260fefc9b358c9a6f593efe6d414f6b1855820b6a49a80648fd97b79c4658137a21896c2cb965c5bfb5341b6bbc1ebd309eb49825840afc404865e2a40dd11009ddde20dbcaa52c66b8c9284fa25740df1abcfb43358de09de2f45ac56286ed273ff028974493e126ebff02107d2e1bf6e1c243737f558507b1d2bc98b7d45635735795105f52db9bf6516e152ef06a1a1622249d48fa3be42330bd3b0a6f723562b769c28645e8e825ae0814ff447a2b58bbb7227097fe146b91ef5962fc376cfa4608bbda28f01005820499fa283933d8cc6f31edc89ede3979762b26731caf022f8628e4f595f6222de8458206e87b3f3231bc816ab79dbf7ef9631ffa9750c074d56276a9d3537817ac418ed1840005840a1a5f068dee1cea50ecd3206b2cde96c3ffcd9e7101e365fe2a7308274660caa20e69815d37cc4e9d7b93609d4f7787d499c1e54f838fd5c3b5fb6de0d229b088200005901c05e0929974db62958d3b73a3387bec54b636b3682db1568d1313946c74b59724ecc930c0fe8148e314149cd8e62bbd9130029740ef08ced84f68774143ff74205ebeb4c8dd448ce09d675ca6291ef83f2b82371cb4c904960430e40d120365011d31daef6cdc3e3896ae2ebce0400f566484c73de8810d337d3c80bc5ae3af9cc68fa7f55478b6b8d3d7e5ac61b2587184899ffd1314e8bc2911a0004fa506e9369ccc438aef33bd13cb6c27766f0e8339304da66df13094b2e31b383d4794bd21c14710d97ac55bbd942952d2511466b9d9cfd9f1035df8bf7f079b8dced90be77f3adf4bbfad6ad2f63befb230b8c7a8ca3771dc1783d1deb0cf6b369e03ec2aa38454f09e9e2fa975ece0ec6711e0370c7e816230adadef96b3a4d6694ef12c7c9002b8371a09994caff169639bfa4e07abc1341a6708a59940df51c155cc1aebf196d8cf3705c9f22764d0bec98b52aff7d4939621dd576568554b854ea3bb80e4292f56f76bf2f68a98fa6e17f6824ba839c2f60905b81d4987195c69e5dda32c884a7112465e00938275fbfba9d331d8b1258110d730bd9fbecd6b6952f69e346e8e4e37a7f7ad035a0ebd89ccd901fcc1ebc80672696861af7bb2050db", + "height": 26, + "parent": "fe7f705538bbf48aea35c51805fedce1ab3d295efd7f398e781f1747f1a01edf", + "slot": 648 + }, + { + "hash": "03d2a8882e3b68fa3b5322d9561929132acdd0816d2f65435b6556683ef88bc5", + "header": "828a181b1902995820b30bf23d2954ac28a952a024a4a5619e137fce29eb908f3a2dcc6b4abb0fc0e65820e851ed72bf223065330da4b4c1aa9cdd64acf009e2ce9ccc3ec825c2598efd075820a8b99efbe8bd8fb6f1af06648ef394acda09d5f3acd65d22b316489b52691da7825840e2a33d385dae63a88debbd2cd327ffa056eb51a35058dbd9eb057f1e8e3e468cf41d4c407b8ac298873297bd5478adbbf7c7fdc405b9e3a914db313bddab7bd75850874bdae38ce5f51625cc11561235b601325f6d897b160f0e94d87b88f204f9b937cea019239f1020d4e2744f94f2bb05c06abc6b795213751cecc298f98cce284086bbd05b47aa7c2a2b273446da1b0d0058205b4b2f292da3a3b8f6b5a13be66c97884acdeb9345e5839a2c2a54234c9447b68458206b9f9a45e7ed4d48b431262d90180acc013d4cac89419a907fa280d3aeaca1f3183400584074e51331594815a1d2f549f667cab1aa88c9d0ad0dce619a5a3a1d5a714e5c5247b4bd9e3f8a84ea60f42fc9b326842ba000ce9eeb24b173685c86a3206944078200005901c0ec71e71b534faccfd0e7f688f9ddd425ec1143f5f2691627de0635ae22dfb21883123ca072ea81682d49ea3552a357ae124e6eef9d110eb189cc4f487665340f49e52e9b1d0ead0e54d857c5815ddda8179a71d8d7b8545e04f753d9b7e6d0f5ba91ad9b33beaf1e83d2afef9e37e3786639e16be5e953a1239a1c8323ecd721480e6b8494a0676c5da2745c2aa9dfeda302d8c284f528fcc41229a39455257cb667f4a3e728c95b38b0191bdaa14ffde3dd5c743ff7fd22ee1d5192dbf28722715f9f7a5657c06b1fd73e0da46f660020680004e9b76703f82bc36d6382363ad2ec04425c6e9031b2e1a19188f36b4d2dae71afb8b94fa27e129ede608b9d4628db96efee84ba8a4582f9c0a619807de4ace773edda4570f8021db7cc2c74a7c8a57d7dadfe159b3a52f2d478497a720535d348cf436857a6a55c610946b2a56563daf041aedbeeb426ba200bed4faf746a0361003e60cec7be069a0ad6e03444e0039a6124686c8f4df0fd22225f8ae00a86868cef64dc68d582307f23ed22964050c244e4241be08e766798496e0b6968e290c1ef50ef1805323e6ed9fe7a5bd78215e32b55b817b45145731de78b10f9afb4df0a89713b80a43b5dd8abe4", + "height": 27, + "parent": "b30bf23d2954ac28a952a024a4a5619e137fce29eb908f3a2dcc6b4abb0fc0e6", + "slot": 665 + }, + { + "hash": "52564738bc7b6cf07090cf658ddc4ba5fde59dce8f33ea3cc3f77217172d0e80", + "header": "828a181c19029e582003d2a8882e3b68fa3b5322d9561929132acdd0816d2f65435b6556683ef88bc5582022ff37595005fa65ad731d4fb112de050aa0ca910d9a3110f56f3879d449f88e5820da90997ba81483b3f2b4de751ba3ece6ba6d50f96598eb0940cc7d29452cdcb982584078d72213fb35e9a68e76fca7801267fab896033e15c596c9c280f82b2cba1d4423a9e11587f31651572d6dc2043ed7be2365bbdcc5d0a9adc55404208d79bf62585001c11f31d459a12dc282c59f52b74888283a25101b831b530076ed54159f2a27f23e949162b04e0a9b079ea33f2785f281293c5102b9a0a82ad421f0a1066e1c7abb9e13006490e7d2c27a66af39230d0058200f3dab2a48d0f344531e4aee3f38145a37c090e4e26fbeea82cd3519a23ae964845820499fc5dada1544be26d7cd3b2851fe955b44e560b50901abc71333d5d449eac9182e005840595a9a329b2637b8f2cb501aa793a159acc928a27c01e1ef586508492a68cabeae6ced714421be1f648bb05c7196f38e7aa4a8f616ad46e32c84e67951657a038200005901c06ccbd496300eb388da832f12af878753b5aff2d81b5aef2944ab2e406084665b9ee759440d1f785806de65a9861cbc23c2886f616a81da631ce7134fddb22b01472338fcc8b178f0ba10f8683725c5df444b7fc6a5afc3c7fbab82e00e7df2d247c673d066eacc1dc7860c10b134c413d71c5a073a5f3e66a17f0d25dabae2699d7b4a969e129d627cd7839995ddf40a3e6672b6d03936de782f5e0dc31bfafdccc5d5d2e5e9a5b3414bface59a824e3a574250474d633115af821b63232de753fddb638606b93b853144dd75692b02e73b2ef8621eb1bfa307cfda8acaa2c43f8b673c9ed749e472cdf2fced20c063a2507ccb985d2b5a9bc77699f42379fb349e1e3a1ab86d1bd510c6ee89720f860d55c208dd262f49746d8fb2a7817d038262a6b266f98f427fc8b958f11adb8c84cc96444b1f5f9d994a4fd1adae2f2be87d8c1dbc0206ace7871da50cc92476d3fced6a4fc2809c8bb47dff992b06259c21f78cd6e72b49b8fe101065aaf243003af67a11d5aabcebf1059b3c92493f954507573a01bf92047ef68f4e980df914b360307b78b3371138b4c1504e155f704df9fabf1bc87ac47b3d5cd563cee6017380e4df6529face9cf39b36277068e", + "height": 28, + "parent": "03d2a8882e3b68fa3b5322d9561929132acdd0816d2f65435b6556683ef88bc5", + "slot": 670 + }, + { + "hash": "65e5aaf928fe53e1e8a0774452a7bff4e984e8d17e77f76206b0112e1f657b85", + "header": "828a181d1902b6582052564738bc7b6cf07090cf658ddc4ba5fde59dce8f33ea3cc3f77217172d0e805820be62f79f3cfcaa5e6986b864daff9debcfae34ad53a36df2faee406c67ac290d582088a86b524b9f5f6b5319f1a3171c0031fa97842df2ffc5d29ff7ec4c0ecc05f1825840ddf7170a17e292cbc0eb2eda67fb197b078dba301e7a8a1169ad57d2866141e6a06124426b871e7086238725e26a2dfee5d5c818d789fd2e3cd60b3db7e138f75850776fb37ea5f8d889a63a66699747fac2f28e40b2402a5992894caea31abdb3d102fb65b787c1d19076424dbf054bf00f4bb9930cc5e2eeeb9eec53e213d1fe2386b8e3047e159ff0409dbbb6106a9100005820545118ff6db71ad2927564b10c2ce70bb5863c63d31fe72a59051440d9d4afbe84582020a37cd965acd0de0280f5e0718b30bfc3b1aceb8600e370b39c43427f66e391182c005840c681c005d6df951680b4b490fa801a62780d96e9f71c3c8e2ca23ae6d2ee05c5d0bf87365103292cad2a469db8289f7ac3e451a1151dd6c38892fb6cf12bd4048200005901c0b0ea9ce0cd4c7110ffe2375c8655dd18cb08d561e093e3af433ee65c12b652b725550929bdfd2b14e1d12ac13956927e9986dbdd7e1d1eb6836f1ec338f5760cb1b31c4c85c89b7ac3440fc9032b7a482bcd59a86bdb03806b96b8dacfe77ec03fc82c59fbc5fc91eeeb54dcf090bf32c704e1bb2137fa582499fea349099a4229933a23f86307a1e0bfabd3be96ce88e1d8301ae9496f90faac04d4566febbf3f8734df4cb9d8b6cf956144e0b62b27e004a86101c8fc366b95afc64577986fc07595d4fb4957032c05c2ba22d00e2f77bf13efcb87b77a432490009d8a03920be66cdf82ea3dec218a5d4a95636996b696b66ede98c1b25703f9d8143c8d09bfc76ebd9985b443812739fcd161fe01b49c25ede6df49fd0a838f8b531644c9ac8f35e3c2872576916098c31a26110952b2f076c216a512bcb18e6b2003c1aad1b1b155842af6fdc031af4edaadd576eab871368b8fdac1386878e7883340cfebdf82d43ebe2654608eefcbef56ecc8eaf8bcf56fe1461e866cb7a1a8ae3b10ed3883a99a29b842c65f6ffa391aaef7d5178eecb4319eef91048772d1cebbaf28d30e5d28357a08504ed0250d1ee71fe0aea705a0c686a3cedfc35961620bea", + "height": 29, + "parent": "52564738bc7b6cf07090cf658ddc4ba5fde59dce8f33ea3cc3f77217172d0e80", + "slot": 694 + }, + { + "hash": "8bd65ad6c00dd635aaf4afc45d5d2c3d51dcf7b4b5bdaac18e54ef37bc808da7", + "header": "828a181e1902bf582065e5aaf928fe53e1e8a0774452a7bff4e984e8d17e77f76206b0112e1f657b855820d134281383884d5fd42f0696fa7560fa620220d5e88a176681789151d760199b5820e2428fc1694882b7632ab35a7a9de5d7ca208299fd887d234857ea8061a65c72825840b8a3ff90649017c660f0470405ef2ec995e0906f0a5bafe369795b1a90d950f12b4436576f3863ca8117ab497b6134f71aac906dec5d87be6309a97d3d14593d5850f8e0e20646415fe0f427ba2932bdae556356c5c0eb80413af3a085f6c3d9158f960d9c06768a8146ae685426ab60d6a75ba5d5d04ce79ee4d6c1e5c317210cdf0672f3a579d93f91f32451399788270000582060bd9ab5ea07348183e0284481853a7d57635e0f5d910547ba755c54a148dc878458208caa0b3145e81f2c444a845a92cc804fb6306528822cc30ac3b61badac55a0d2184a005840787abc533e8c1cdbb12b576339670745848c6817502f5a29d35fa394a8ef564f1a661756129c705a0dd08be5c96b07a19ab31eed4dc4b1bf0a5a24469627e90e8200005901c09e9619f1719278993cedea436ad00172d6ad88e4bda3b1120fc62e9dd6c90baf944b13dd8860d83504456886ad92c6f0106f03f4efa953292ee6beab21db4200da41abb7a69d5448046d4741d0e195b91d7c984fb09f33bdd2f2a97ef4fa9e8922a2b0a7dda60412ec3224262779dbf5afbd6cc5c867dc1b36e19b72948f0b8102191d79de24ad6a5c32ac2c2aa03c75988f41b66ef9ebf2e5417c69857c8ab66422a18462fef15e424c2fc57fa8614a95318c3154e30c46b075f8e2724a6bd6aa8396e7791f24bf9dfc977e03899b8b89ed5c2a3cc994ac11823a9ec9ab81a13eddbe46298c27cf8ba29429e7e3372a57a6ef70c716e1126df589892c22f66938e009c0971bc3aafae05b88c7f6d127cc0d651b51c1b5bb79ae359815802dec45b6d750f9415fbc45a612aceb51fc9a8dc9ff2263810acb29a331a3fca427706f0a3192cdc22b23963fd1a315c774de8285b1adee80c609a4d5aceff8c27f86d37da061d6fdde1d35a4902a87d64f62a2f171a66351a88e34493850306eb81dbdf5f1c4ca39c567d3e12b2751d508abca8b94091b64d5e32e943777a961e236dce006446489d579811b83b0279d8f34454c64a266ccd66c188ef242970f96e1", + "height": 30, + "parent": "65e5aaf928fe53e1e8a0774452a7bff4e984e8d17e77f76206b0112e1f657b85", + "slot": 703 + }, + { + "hash": "a8e8db8fc5698b34a1c26889504af2df02c197dd42dfca6d17c3b8227fa06056", + "header": "828a181f1902d958208bd65ad6c00dd635aaf4afc45d5d2c3d51dcf7b4b5bdaac18e54ef37bc808da75820be62f79f3cfcaa5e6986b864daff9debcfae34ad53a36df2faee406c67ac290d582088a86b524b9f5f6b5319f1a3171c0031fa97842df2ffc5d29ff7ec4c0ecc05f1825840e81beb2b668992405f73268dd8217217d5ed1a170cc4e50fe5892df647d5b7e3372f8cc97febf3ad2f8d1cbadac836762fd0c27f7e94fd1fcad7adc42bb12cf45850c3a41e0f6dcdf4ddd2525b4ca9eb3ae46dc05ee848df521d991dac0a949b10181d61ef87eb41e3949304b32be836211ee856c97df9488596ee78500aed06ad934154de0e1c8b6cac578e4109621212010058208f1c87cd9ad29c9c5d6176dd5fd8a4c562c27eadfb7ba213f12002e7e98f7ea184582020a37cd965acd0de0280f5e0718b30bfc3b1aceb8600e370b39c43427f66e391182c005840c681c005d6df951680b4b490fa801a62780d96e9f71c3c8e2ca23ae6d2ee05c5d0bf87365103292cad2a469db8289f7ac3e451a1151dd6c38892fb6cf12bd4048200005901c0682b00ef48a3ff251805304e338c90c558360718ea1c9062ae27d9121fc9faf04154e866497403dd83c1029dec79acccb45baa9e522039f30845fd98525d5301b1b31c4c85c89b7ac3440fc9032b7a482bcd59a86bdb03806b96b8dacfe77ec03fc82c59fbc5fc91eeeb54dcf090bf32c704e1bb2137fa582499fea349099a4229933a23f86307a1e0bfabd3be96ce88e1d8301ae9496f90faac04d4566febbf3f8734df4cb9d8b6cf956144e0b62b27e004a86101c8fc366b95afc64577986fc07595d4fb4957032c05c2ba22d00e2f77bf13efcb87b77a432490009d8a03920be66cdf82ea3dec218a5d4a95636996b696b66ede98c1b25703f9d8143c8d09bfc76ebd9985b443812739fcd161fe01b49c25ede6df49fd0a838f8b531644c9ac8f35e3c2872576916098c31a26110952b2f076c216a512bcb18e6b2003c1aad1b1b155842af6fdc031af4edaadd576eab871368b8fdac1386878e7883340cfebdf82d43ebe2654608eefcbef56ecc8eaf8bcf56fe1461e866cb7a1a8ae3b10ed3883a99a29b842c65f6ffa391aaef7d5178eecb4319eef91048772d1cebbaf28d30e5d28357a08504ed0250d1ee71fe0aea705a0c686a3cedfc35961620bea", + "height": 31, + "parent": "8bd65ad6c00dd635aaf4afc45d5d2c3d51dcf7b4b5bdaac18e54ef37bc808da7", + "slot": 729 + }, + { + "hash": "3d9b4c5e8641fd386a115c53db3bb787123499682b38305e7ad166a5b1701244", + "header": "828a18201902ec5820a8e8db8fc5698b34a1c26889504af2df02c197dd42dfca6d17c3b8227fa060565820cf1d41b669559e9d30eaf310408a8dea605e3629c0dfd7b6d649d4861514d1bf582083f3206635b9182a411e2a9e870cc13f5974507b1f84476c8519ad9215ae4678825840c94198126e4434d15ca953d8f6eb7c4bb057ec4131d39216d6d8029e7a28e0edbcfa29feec00b88fdd7f9a6ddf560678d4b0f1eef333989ea0f03cbdab0fface585028098fb55c61fc06699d7132f8f759cac10eff66b9b0decd32d5853874ea2613224f8d506cce331e0d9b605271639637cc106c70102257e12be12cc200a0538f549bf5dab20193489020040a28370f070058207ef3e6fabb5eb64558bef484c22acf3c87c915df675ec257d07586cddd14450c8458205474aa415f322607b193704e4c4c0554ec74fe68f7a0c880d65660a75c092e9d0d005840bbd78899a963f57f958f23ee2113f5acf830ce54a3733f7f5e9ec66459997dbbe4837e7706f415b8435ded9bedc37cf51e60177ff5d8e753c2638349cf01bf0d8200005901c0da4814e9ea15ed24b3421ec6b648ea5f5a1f84a9dcd1c8afe59ef59bb94fa43eb074da1ba288680090c1ad248fec97061ca612f3bbdc4d3ef380ac8f2b75f005c240bf2a1681adcda82378b0cd9f0211c9f7ee6eb26e57ee2b0b92547793e5faa7f183ed48ff763de91c6324f355449b2d96e4f37efde9dc377751844b3314bb8d0e3c59befe2f1a5b7bc0045a164b8b9e1c5c9ee285bf6c2f6152826ef1252ab39577992ce208e5b172e9d03e46c268454a1502697162f175c586821d0fb5a8c0ffd4c56fb8c5cce2e1f7a0efc77a38277faa82580e983c87d4081dd8b5226bc8994114ec7a95f8be871726a6998dce138fc55377f022f84cc97eccdd18e7d61b557d7daea41d1d021e34aab3dac320758ba4f9c2d5fddc5a8072097be37af8f2e5fb4037a11632c6fd9d42c62a2e8263af2db7c83d992c933548e0f5d2593bface422b543cb5c1eb68fab55f0a77683d4532df74468dee8e18a1b32b92fde2dd6a8dad63af74be2f9c4d3a1d7b57711d09e38e97fb72551eedf3c215beb1c0cac6a938ca375bcb5ab7037955122f116659927bdbb741aec609c2c27e3d18c4d5751b52460d0914e68d40014f179d8400db188be2c34a7f98872070b86ad764", + "height": 32, + "parent": "a8e8db8fc5698b34a1c26889504af2df02c197dd42dfca6d17c3b8227fa06056", + "slot": 748 + }, + { + "hash": "ed6142c5bcd2afb0c012fdb4d2ffaf2979244a244e387cf4738c10c1a786ab07", + "header": "828a18211902fe58203d9b4c5e8641fd386a115c53db3bb787123499682b38305e7ad166a5b170124458205a177476c40bb96ea1f9d241d0d1651ae08104bfc54337d356f951d59404a4d2582037264127bcb2df028319e576fbe8727a7d9b2d1cdcda8b30c6cd377f0630bbd88258405385e7e8416ed813706e222920aed7484709f55cc379bebef8bb26e8f93d7e0fa4b52ced1104e39319752a6013486b1d6c06f39cb1ad68cb7c7b856513b91b21585028a407bfe464469740a7d65e268625a669db60bd2dce38af72a1d8e1cf064be88fcecc56c416df695488278e16b328ba6fd3fce5f0e77963ac0aeee6a79f6e8672f84a06e00c9b8a109a66b8f9a6d10e005820cd401ebeb304f27a56bfb5f1ad6fb94e986fcaaaf5a6fc9ab5eb6cd726199e9e845820338f92308f2f1d0dcabc1f1e3ad061c8b6e32679fee51431a43dc32efec5a0fc1818005840b3bd852c4a9a2d8f740ba727594f91c227a9dc638d2f27edce75b140bce7a12d62c0dcca2c832e3c8904e0149d2bc62e20e42605f6e0444835a9ecf2f462000e8200005901c07e89f83786748ce4c77eb2edb61a602c4b0c15d39e5e34c0cd91e811afd78223eef4692f0ede5291ac0666d98ea7b7f7eb0c8d64cf19c7e9c883552b4a74d1052a33fd2dc4086d99d1309eee46f49e76b5d9f86465fb0ae9f1b3dec4c8e2c15dcb0120b19dd9e1496fd9350141f284d40e2350e86404f031597cefa7063a4a35e92b198a7888cb9397d81e563e067f3e0f5709159027827cc74fd3ea0583051a1cbcb8f3cdb6280b50138328292f33b6b7dd202214124507fde1789777f1737fd390cef46fb8ae253be49c8d3b43aa48387f0e50a32c3f2b6fe25613e06e4d3873903f3ddbef0d2d520380966869fcf11a1dd7275b1b6cccc313d2a718de1b2ed2e5fc55f72a46076eaf27598525fe452ace332397e8a2687d494b086256933ebfd955443d19d647a98c17f0472d136b4ae46d4548cc837ae9ea18449b259f3eea3820cc09fd0ee8dacd88f36ea31d266dbab5ee6ae55142594774498e7e3a3ff3fad6228c6e1fe23e3ef39e2edbe258351d9a1b8b50aa35a9f5e3e6c4f376d16948885aae058502fd5d51b5f6bafa8ec285d1cac641488bdaf90d99331da3edd4e2db2ac63975bb6791ba02822a7d25ea87aa5b3756ed3decb5ef8f09970600", + "height": 33, + "parent": "3d9b4c5e8641fd386a115c53db3bb787123499682b38305e7ad166a5b1701244", + "slot": 766 + }, + { + "hash": "b4d19482383e055ec6d76faa41e95a982b7c53152c78fa3872a95ae200a446b7", + "header": "828a18221903095820ed6142c5bcd2afb0c012fdb4d2ffaf2979244a244e387cf4738c10c1a786ab075820d134281383884d5fd42f0696fa7560fa620220d5e88a176681789151d760199b5820e2428fc1694882b7632ab35a7a9de5d7ca208299fd887d234857ea8061a65c728258404a8cdec01f0815c90a2e1fbdf12a4e2b6179a0317c8dc813314f108b441d3e0cba79fc78c29a3e3c43d00952d2aca52eb996cbe444ce6bd02885db22c46aec5b5850fa1948dc933172d26e456221cd1c2da2dd783e1e4d87de024d3d54ab1eb5da9bec42edee9f1443855442cb44633218cb9d2de3eabc6944642c32d25d2be7a839ba4bf211620a1725ed7570a660d44d0900582070d7f2dbff4c24f725c52d373816314b18bb55bb38bc0f9cb64717ac9b474d9a8458208caa0b3145e81f2c444a845a92cc804fb6306528822cc30ac3b61badac55a0d2184a005840787abc533e8c1cdbb12b576339670745848c6817502f5a29d35fa394a8ef564f1a661756129c705a0dd08be5c96b07a19ab31eed4dc4b1bf0a5a24469627e90e8200005901c08ee6b63afb06dc3590019a826ddd70f38b88641ccb520a1a82f6c973db7db0c684228ee15149facbfc11c0546b9f9243a0c2e605bc911263e533ff7777fc490fda41abb7a69d5448046d4741d0e195b91d7c984fb09f33bdd2f2a97ef4fa9e8922a2b0a7dda60412ec3224262779dbf5afbd6cc5c867dc1b36e19b72948f0b8102191d79de24ad6a5c32ac2c2aa03c75988f41b66ef9ebf2e5417c69857c8ab66422a18462fef15e424c2fc57fa8614a95318c3154e30c46b075f8e2724a6bd6aa8396e7791f24bf9dfc977e03899b8b89ed5c2a3cc994ac11823a9ec9ab81a13eddbe46298c27cf8ba29429e7e3372a57a6ef70c716e1126df589892c22f66938e009c0971bc3aafae05b88c7f6d127cc0d651b51c1b5bb79ae359815802dec45b6d750f9415fbc45a612aceb51fc9a8dc9ff2263810acb29a331a3fca427706f0a3192cdc22b23963fd1a315c774de8285b1adee80c609a4d5aceff8c27f86d37da061d6fdde1d35a4902a87d64f62a2f171a66351a88e34493850306eb81dbdf5f1c4ca39c567d3e12b2751d508abca8b94091b64d5e32e943777a961e236dce006446489d579811b83b0279d8f34454c64a266ccd66c188ef242970f96e1", + "height": 34, + "parent": "ed6142c5bcd2afb0c012fdb4d2ffaf2979244a244e387cf4738c10c1a786ab07", + "slot": 777 + }, + { + "hash": "58be40ac0159d5183f10f2f528dc6c4b1282c82fb140569b4811c12b74d020e0", + "header": "828a182319030e5820b4d19482383e055ec6d76faa41e95a982b7c53152c78fa3872a95ae200a446b75820a01fafb0394b73269f0ba718760133346a76e8e590ae0b876670c8c4b31e1bbf582092411f9a1a29cab8b4ed1ab4357a25b230c014e3045c221b3346b5a5a243783a825840ffd9fd9b3a4ac612f64b9a0fed892cb06e637d7ad0c4ca8e4369a85830ea43d1695b9ced906684c1cc48d07a074b789d41f69c6cc4cfe413f51dd733729341f45850077067992e571f816e9da4d1b463d9b1430b6092afdb530c3332ee48ff8b4ea97248371005f1b3f8426751003ef3f357c1581e09f70167e55de3308584b7116907b276b00a51ec99cd9c140394e7670600582018ee24c7ebe294dd70f0ee0c53f959fe654e29ee3ace75e28996aa0aea0d208b8458203ccd81ccc58fc2adc69ac3cb20e6ee56598cf0603e9564cca9aface763d94c3c18500058400c4b28e1ae2bd14f9399384d45ef9267e5ff2a0e74c56bb6de6263bca3dd25c50852642b40e1fe9ad3f2f6ec2878401e9d93066723cba83d54a34a2e2a59e5038200005901c0676316a3a2417337c11c3b78b0b7cdfe3208d9e36b00e8ff87b7634352fdea67ec90e4c743ed039a7cbfc9b89b26dfca91765c21f80942e4e83f2b4c29bc0e0249a9eb6f25c6175b6d603ee15b913013fb75f9f4a4c5ecedb5bcb3f288fadd520a015063b56cae186454b21f05060a616dcc3753a0fa963791666a3c2359fe5bdc13a77c64d7e5eb106f1d8d9da0968747066add30c07d12eb9ee7fee29f2b0f762464642c1d35adb980792baa73c3e3eece676c9c82858a1fdd34094e6680e037153e75a055c876a511ecd1731111f8512b4edcd831fb1e6013c0e485b4215a2c0fa5639f33ff62a2455e80b6cb5e3cf0ed721aac66bf14ead70fbcaecf89672fe3698a8bc53de555cba5e21a29179e9e2c2b410c1d4b0fd703387ef89fe7af5733e2549c699ec466c25727d72934d38add039c9713fe348a7468ba7f53f2e68a96bcfd25d1119c55f533be28a25e9bcf5ed7f96e57920358e6f78602351b270d70591707c6c1dbb926009a5b19d0ee96aeb92f09125242875f33d74e1fc2cfb72ee67291edee6e5dd11afad4788ac84b136b681cfe905260170a2088933e36be2607ac986a15546931e4f0bbc5ef0d5824bc53af6539a762cb490fa7b168e2", + "height": 35, + "parent": "b4d19482383e055ec6d76faa41e95a982b7c53152c78fa3872a95ae200a446b7", + "slot": 782 + }, + { + "hash": "b0f841fd1b23611950338511eaa3f2a2118d11465e36231e6aa4269e1d511c11", + "header": "828a182419031e582058be40ac0159d5183f10f2f528dc6c4b1282c82fb140569b4811c12b74d020e058209f6a9a363089819a4a011406addcd84e984210ca43f1f0b93f014bf4246b0fd05820349fa6de24709731a7f27d0e4f711d73018f285d2bf91fd0bcc67559c478a2e7825840e6b2f05ae80e8e7ef504aece5e52f18170ecd14ae0b6336b2bf2895b52e9f3f817b639059e4c6142716427387a3aec71f3ed1225eaf1addc71f973ad2d7fd3c85850652c84469ce0205fc612b7886008ed2b641912b11ccf0361d9f370e2f6a23d1496366714ede28fd4306c9178120614ddbf266a89b5bc4fd7009663e2bb87f1a96536789b160a92959906072b234d8d08005820af21468b8ed2a8a88b5b4c1fa94f3c3b79acad6441c20e4b9edc5ba33b7c086e845820740dc0a0c3ab031ec83d2737df245cf634f5bb52c30e3f10d5784b498dceaa09184c0058402e844d232e5697feeb57d0e1e24f46f8de86f56d0bf7c984deb5130262fb3bc3119ddeb09933664ff423f419109154efe6bf5f2e30d7f59704fed09f178452078200005901c0d070b8e9d61264e7806239c9c1e8497e47f7fa82b6a9e772b6b97384cf0addaaeff44a6a01132c8fad52d9fc69e56c5d41bcd4d9a9cd33c3187af984f43fa4095f172dc4077a26ab4fc58ef6de644079bcd76e7553b4468e3ec64a52c2bf5ccda05395e1cf6acb1d2b11d88202930f17e17e3233e55f2cc60fdccf05174901d5c655273b8dec2d0665a7473a84b905410e17a1f19a853d25b32f341e11e66e53f61b5bbbdce9419ff8b4a3438dc5f959cb3066161b4f51f848aca11fbaaa98afced6f3eb73033175d25410cdd7a018c8e15da090dd1d8cc71f36408ad6f69797b70eb348856734bfc2e11c083d84a92f997cc1a7399b6dd6ea38e1c82a535e9e64aa39875ef67c21415f076a39f22cb8b7607ff0c5e4d60dc393a7593bbfff567e3db58d6de8fe25f153d654184e24e8e3e71faffaca0fd480c83f96d6b66657c490b49bd76a543df7855949494093c385db0104f6f8711a163e2a9fae72841fb9eae2261808fb1436203b948a4a4b29be573a00fdea79962087ccc70e60fc368a254c6b20bc0f7ce151585fcd2ba76ae8ffdc4744204b5bc354f12b00927718c357791e112a4c26a02831faae28508f708944423e2a1d0c5c9c7a471ed30225", + "height": 36, + "parent": "58be40ac0159d5183f10f2f528dc6c4b1282c82fb140569b4811c12b74d020e0", + "slot": 798 + }, + { + "hash": "2d628da6ea1e4e1353c1c40aa914f00285e2b375cb94b6a9fbd37f0a156a7efb", + "header": "828a18251903395820b0f841fd1b23611950338511eaa3f2a2118d11465e36231e6aa4269e1d511c11582009b54b526e6c5afb4a3c4362f199f243bda856e248c2de99156b5186562c08a1582021e64e133738bbee188311034a4f03103e0821a6c0e632f499e96d45d379b3008258407111558f92824242fbbceeb62f2b4dd7afe5f9e9137494c6d8f339c38ddf877ec8cc27d08e36a0754e55e7b98f19b1a91ae387a1bfdb532e0e6a57948ad1eeef58501fb69117ba4a5d0f91340100b5a0dc0d4704aee14fc9254dbee430e23f1b357d03a264bb5bc8d9a5dd867c3439ae610a74c639261d970f1c61289f63b4b57c4bd8ca4960348d7c16d5678b9261b5d90f00582060b2e00c99b11a3f2c5c6a6d92727b854a0081c1b43115141f73c264ed243e57845820a7d564335ced2b5ee9edd8ecb349f31822001a398d0ba5859e57715d696c6ebc1818005840c697536217d7492be9a280e147c5ae4a22dd0bb8ba765f45027927c587993dcb3e080df2aa3ac218d53a1afd5a4e9215cbe79b390e28cd9ff405464824f2710e8200005901c01de839fa901e64254c84bc9bcae0d606c7f7d138e30e86ebf24a234f7632716536f929a68d1929e5a2c4a40640d9d00c85db125428c9feb71eb7f59e38060403fe9063bb6c7ffb23f3a85e936f906a1e1478be1b5d015c8d3d78ce5a536558ac25177143dcf1dc132c17d29d3cbf0021f048f9efd73d5d54313adcacdf010db9006c13807ac6128d25f2ab28b755abf844e50c1cf772ee5314a79ee8ac338b28e154499794b6477d7daafca6a41ee1c3a3bbd86cd860f1702ce69d25d10b46aa9ec5e31a2e91a8db0322ff68a383f14d2560ffd1144a020ba8ba7312e314932cb1137e21fde4ffff49e6352a932bf2772ea2ae98dfaf881a80d369caaa2db1dc25ebf19f2710cbc4ca12bfa7fe5978dbb0e6018745dabcad22091655e66ba15c3bedbab0ff7cd73107dca9e44cbd79f79f42f4e4babc9311157a0f48befea2e122a23e940b0420c2dbea9b710d5e1df7cbf1f65e6f6576209d6f676b91ee38f374e8e34da0c4897935fd62eaa4414678d133b6c3a819015707fbc1be3f35f3917ee924cff5f0ebe56cc4e90bbf76c4c80d7b8da18c2cf98005f54955499da7a8f581e4c935a0f5ba5c61f1717662e80d7b82c3a4ca01b1284ff95e0522f50878", + "height": 37, + "parent": "b0f841fd1b23611950338511eaa3f2a2118d11465e36231e6aa4269e1d511c11", + "slot": 825 + }, + { + "hash": "8c54fee05c72dc31a08dd57d9c6252ea542197db2e8d7088e44cf709554c6483", + "header": "828a182619033b58202d628da6ea1e4e1353c1c40aa914f00285e2b375cb94b6a9fbd37f0a156a7efb5820df541b1fbd09fc825a48cd82ea1b2788553b2d72db86c4397b017db6fb4ee6e05820f80ce1e74d580c078c2e6cceeaaf2af18c87d72e85df14897ced396a9e803bf4825840d8b17cfecc2c5eae8e0ecdbb3ed957edd5ada9cb38a2cf3068a609ee8be83480a3fe2852be91364f41520d61b803a860a2914b26c0f362368b992d8e609e8e3d58505161f63d9f922c9961f8fac57c147121b1453c6211c6a81a81865e8d627a0487740731e8c9df9a3f35d56156b20bedd94598e00c8b239051dfb5eb18a70d2e64bf86e85d081d0bfd4f2ecfc72a475f0e0058201929d15a4eb2a70470f9304a27a4936327687cd9325ab68ae812c4abd6622c64845820e2dce0eb82d7bb4ca48269ebb93b70374185d6dc9e0e9f10de35ce2d8fd355000c005840d1dc8482d252de52a3e8868ad0325d50a10d2de4aa2fe8508a81edfe26897d93db3ee72346158f1b136db7ed754ac7a46354b6ae357dc8ec4be9857e35aa7e0e8200005901c0bea06a14b92d021a9c895b88926b94fe1b5b8d7673c3ef117dbd45230d360c4b543dc766c7057cf3d0e0986c0b050d74e9d13b76608cf8d5ee39a0d8b4f38401123f03f1ba839244e816272ddebfaccd07b396c7d4e7e8127b65e28a34be2af6d99954122949e55f47def97ae436cb9975b8a70ec77c4e57f48ceec0f4c19093a99991ea07b4b34129340df6cba7f4e2a99036c15e2309de61d20d77ba801603cd42f57f6fc3fd127dbb2923dc40375f1d11d0b6df7a73e6178c42fb62221a907e2126561b88861eb6d764dd5abd0a02cce6dd3baf659acd10c78bb17c48f7035a0c97618c6252664b9ce9541451047d47b888f01b92fb499940b9a5570c7b5b5e938563dd88a5483aafec9d89e92d14aea22a0a9b8dd77e7fcf14b4f58ea4b24be7a3866f9e9fd4646be578a2ba3baf516b6cf5b543267cd8bbd9684d4516733b782437363ef2bbcca05cb0de5d5163d29645b1f58be7307037ad8ea25494c204906d3df79b42e8529a7e9a98a51d9e31f116ec499ebbab55f0eba55bfc8763cc3d6a9824fb4514cd46aaed452cade04436f0c26c5e156e3d9d5d6524cc85dff4676d1eceb7cde887cb25345e7447b36d36f62ae2e497ebdc03b2f05f167604", + "height": 38, + "parent": "2d628da6ea1e4e1353c1c40aa914f00285e2b375cb94b6a9fbd37f0a156a7efb", + "slot": 827 + }, + { + "hash": "1c093639fdd9784a171dcb6f7cb0f99916b22fd554ee9cfabe79275ea79aae18", + "header": "828a182719034158208c54fee05c72dc31a08dd57d9c6252ea542197db2e8d7088e44cf709554c64835820af9da86d95be558880436e0e16150e759a13937e427dee52508c94d67ef80eba58201f16763f1e6898d544d7f9e569294b0960b2d2c0a9c5effaf1b81aed6feb3cbe825840d12db8df5ab22d567757ba1e4e642303dcc8ad3846a6e3d722f120bd087b61d9848cf8c6b8fbeb6b7685b12595b46bbd3614412c5972842ac50a074f9f8c3aa258503aac92505fde6972dae822cd3c8168b30b2b450b0e628f0f41cdb3504ad9af8f91bf59dd552fc48cc6d013a4e7a3d3d06da5b3b87e7e3ea8ae0b6e8bf3d19932c37c2d6b6204bb1f45a0c92af2491e0c0058209253a0de7eb629e3b125a0c2a1f31ad8c774e8279e26357ba8ada9dab4222fdb84582033b4783491e8204211596cee996a92865a2a00761c4972ee0f0ee1cbb07dcfc00a005840d03083f0c14c4b60af4642ab1d5530e1b396127c57db5767d671044fb2a92cd55795e3df673f1a68958813bdf4fa09fa2e8d3a6c9bea623479ae2cc8bcef180c8200005901c070210aa344a401dd2343c3004bad750d0671721951df836c84b051a49888a812816174a3ab396844d3b83725064ffd4112a46b78ab6cbf25f68a0b9d7daaf406b32b954dc94768de9dd6931a9bc97c59dd74567448ac09f5228862e2fff750b97ae0f60f555d80843b304b9ca963720a599d0e43626161b5879259bd07c47c57ae3c711d7faa1896c58fc200ad7a3f39c3ca8b5e89814ad8fce112782b8779b4a5f89b45244d3efc05c73121c211d6d233cd82cfaf3e1573ada54adb0f887fc96c797d37c54aa5d232dc72f987cb717f09b0ca199cf84c5ac63ed24baace4a8b322b535330362773743b0946f562cc370cdbef122b242e8c24b1d079bec1733e0d21e7bfaa739a8708ddb99540491e7fbbea15c90fe3079bcc568ab56e07a74e73bc2fa589593f7db9a3298a928a6f0de4971fef3e4964e6c4da7eecbfa3850bdf8402c758c86d91c8e35c1c318f9e5a3f6eae7fcc456e117edf87341334286fc00e692abc03595af3753258ac024429868e89e4d24e7bdabce43676bf25e05c1f05f5973b87da15a2a754cc29f27db5707867d7c9185dc5b1bf5a1865324134cd7ca504dd6bedbf48394755f16e10feac173ce9eaba2620c6f4cd10d24d9b03", + "height": 39, + "parent": "8c54fee05c72dc31a08dd57d9c6252ea542197db2e8d7088e44cf709554c6483", + "slot": 833 + }, + { + "hash": "c5a715ddede8aa7d824c98dc955bd63ba599ac30f8fe6c09914ae891466cad56", + "header": "828a182819035658201c093639fdd9784a171dcb6f7cb0f99916b22fd554ee9cfabe79275ea79aae185820cf1d41b669559e9d30eaf310408a8dea605e3629c0dfd7b6d649d4861514d1bf582083f3206635b9182a411e2a9e870cc13f5974507b1f84476c8519ad9215ae4678825840b826c538af9e69a0e7d4413e2319524fb1e71c8b547803370c611424449aadaa5c841a8acd0f3f2acb119948c0e8d53efc94fa1a55b1d4d7c027b9a896b2d75b5850909d06c330d44db47b4b0d85ba43d15a14199eed103aa572380d6851ebb49e9febfdf738210820ee9b26399f3e2a64e3ead6aecf844109d8c2fa42bea3911034c4d72e8a042a3aac3b5af4f78e604306005820743eea4e6ac4b9c880b522cf358dc5818ba69a23d01137bb88c8d080f9eb67368458205474aa415f322607b193704e4c4c0554ec74fe68f7a0c880d65660a75c092e9d0d005840bbd78899a963f57f958f23ee2113f5acf830ce54a3733f7f5e9ec66459997dbbe4837e7706f415b8435ded9bedc37cf51e60177ff5d8e753c2638349cf01bf0d8200005901c009dbf31ad03a5497e3529c13016ef5b4de61bc2283ea4aa8d6a72b2aa662eb634c1adbbbc21bf00b275a06ed2899ea5c26be0f45fbde05420bb1d58c544b7a06c240bf2a1681adcda82378b0cd9f0211c9f7ee6eb26e57ee2b0b92547793e5faa7f183ed48ff763de91c6324f355449b2d96e4f37efde9dc377751844b3314bb8d0e3c59befe2f1a5b7bc0045a164b8b9e1c5c9ee285bf6c2f6152826ef1252ab39577992ce208e5b172e9d03e46c268454a1502697162f175c586821d0fb5a8c0ffd4c56fb8c5cce2e1f7a0efc77a38277faa82580e983c87d4081dd8b5226bc8994114ec7a95f8be871726a6998dce138fc55377f022f84cc97eccdd18e7d61b557d7daea41d1d021e34aab3dac320758ba4f9c2d5fddc5a8072097be37af8f2e5fb4037a11632c6fd9d42c62a2e8263af2db7c83d992c933548e0f5d2593bface422b543cb5c1eb68fab55f0a77683d4532df74468dee8e18a1b32b92fde2dd6a8dad63af74be2f9c4d3a1d7b57711d09e38e97fb72551eedf3c215beb1c0cac6a938ca375bcb5ab7037955122f116659927bdbb741aec609c2c27e3d18c4d5751b52460d0914e68d40014f179d8400db188be2c34a7f98872070b86ad764", + "height": 40, + "parent": "1c093639fdd9784a171dcb6f7cb0f99916b22fd554ee9cfabe79275ea79aae18", + "slot": 854 + }, + { + "hash": "e2fdff3ced0d6414f4a29cd197f7c2ce6534637b86979353a3f19ff88782deb7", + "header": "828a182919035d5820c5a715ddede8aa7d824c98dc955bd63ba599ac30f8fe6c09914ae891466cad565820be62f79f3cfcaa5e6986b864daff9debcfae34ad53a36df2faee406c67ac290d582088a86b524b9f5f6b5319f1a3171c0031fa97842df2ffc5d29ff7ec4c0ecc05f1825840eee9d942c495bfd9a9ea9f44ace37fc51edae65598031f28dfbf937c36b92fc7380640db7eabd0f4a179e1fa09fde16ba921d9db08d22fe6df8e41f0f5e768dc585021ee742a2eac054c760fe1f1e0867a106ccbc224a80b916a1e90aeb6413126544a48b7d0db504df6949f3bdeb0226a69365e1b790cd6613f9300528d72b2d092aa688ccf2122dd7a6e79de14eb134f030058209d86547a7ee9b0b6ce01833870cc3b62df0d9dd1bd324bbaddd915105a98cccb84582020a37cd965acd0de0280f5e0718b30bfc3b1aceb8600e370b39c43427f66e391182c005840c681c005d6df951680b4b490fa801a62780d96e9f71c3c8e2ca23ae6d2ee05c5d0bf87365103292cad2a469db8289f7ac3e451a1151dd6c38892fb6cf12bd4048200005901c014d9532e338e079654d7016fefa33cb5de612614013f692fc427b7d030bf09ea0dc9f987e94ad42a8d8f615e91b98785646407e841e4171e297b54cdb846ce00b1b31c4c85c89b7ac3440fc9032b7a482bcd59a86bdb03806b96b8dacfe77ec03fc82c59fbc5fc91eeeb54dcf090bf32c704e1bb2137fa582499fea349099a4229933a23f86307a1e0bfabd3be96ce88e1d8301ae9496f90faac04d4566febbf3f8734df4cb9d8b6cf956144e0b62b27e004a86101c8fc366b95afc64577986fc07595d4fb4957032c05c2ba22d00e2f77bf13efcb87b77a432490009d8a03920be66cdf82ea3dec218a5d4a95636996b696b66ede98c1b25703f9d8143c8d09bfc76ebd9985b443812739fcd161fe01b49c25ede6df49fd0a838f8b531644c9ac8f35e3c2872576916098c31a26110952b2f076c216a512bcb18e6b2003c1aad1b1b155842af6fdc031af4edaadd576eab871368b8fdac1386878e7883340cfebdf82d43ebe2654608eefcbef56ecc8eaf8bcf56fe1461e866cb7a1a8ae3b10ed3883a99a29b842c65f6ffa391aaef7d5178eecb4319eef91048772d1cebbaf28d30e5d28357a08504ed0250d1ee71fe0aea705a0c686a3cedfc35961620bea", + "height": 41, + "parent": "c5a715ddede8aa7d824c98dc955bd63ba599ac30f8fe6c09914ae891466cad56", + "slot": 861 + }, + { + "hash": "00f0252e56298d1c18cf5e9854a44cafd1db98ccb2d21ee749d63799d6124e15", + "header": "828a182a19035f5820e2fdff3ced0d6414f4a29cd197f7c2ce6534637b86979353a3f19ff88782deb7582005442bb4e671ee9f6adb69c74ca5b3af6b3a407c97429856e80d8c4090d64d3f5820e0c61af1967457770433454c2b27cd6b922427f8ae13148c8b09f53ee7a56710825840f6ba404971c93680b4050c0494de5c11acc61c70178d70efcd17c4f3e513cb8c8977f69fca7ed269bc16f550240fa4210f0a5ac75406d7143b92346e2aed557e5850a67d6974c3124290e9381023d9aefbe9679fe15676df5d7ff007454c107598431d9fad33f6bb4a662ffc9b3cd9c703128f5c248eba9186e6da1403ab183b91070084dde320a636d866cf289111d95a010058200ef62ce43d0a3fa0018173f726ba62892cbe27cac4d0bfdc74eb7714935e82f5845820dcfdf1559b3dcaea552e088d31e2225f3798b682571e8693d88e8437fd42110a184d005840c12b51de34fea0bbd6c4979d581669913bf95dc4f16d13857c752af53b31d4080e2ce0ec2fb289ec32bd82aad457750ce35698052309ba2c386f67d48c6c2a0c8200005901c07c0a3b6ddb639bcf2cb4569c1522c01e44e2dc88313a75ad0bb349c189131bfd5ef40ed78ad2115c2ab7716cd540367db8a388baf6c193c4e8c2f657ae526a051a3631680c81fd0642ee45aeedefa4ae83ebf2c78a681a3f831e50c628929c8b5897e0f273ecfab8671cda14da4d1a5d44d9337270b394b4c0a03e1912eb755291a64261efd6984933d34e22e5267056bbcb58ac74362e3b9bec47024ac873539faa3cfe89bb91571cb1bf47f14445ae3a7734afe96d6f7c683b64683e1ac525f1a8bdaf43285cf8ff621478980cb756ba86019bdf1baddc904298c573015a8971d8215977d748c327d9dfc06c1a65539feeebb7898cbfca7903088818a96bafc14119ebba5b1afbdee35c292389ebd0bd318f4b7d48adca59cb2b7ed66113575cd3bf11be8549bced3cfac0c66b6ce83b28238e0de549d46aaa281a0d39784b7b46a29fff240c7aacfd49b7d4a0ec4dd0b6dab0f1a08a51c3fd796cd1bda647208509138b9278bd30b0208bcbc683d7f58db1568c6b06d0a9aca741fe39aeef7c253a04279ba7a367b2b4a870c3e2581add3e5824bcc9dd53bbaee2aedcbd58fa8ef76c7c11b3b6df977e036ce5cbfc1f7c974e70abf035ad72b8a5e0be09ae", + "height": 42, + "parent": "e2fdff3ced0d6414f4a29cd197f7c2ce6534637b86979353a3f19ff88782deb7", + "slot": 863 + }, + { + "hash": "5bb6b1804289c3528ce98913efb45644151d9a2c67f0cc4ee9472fab9dd46671", + "header": "828a182b19036a582000f0252e56298d1c18cf5e9854a44cafd1db98ccb2d21ee749d63799d6124e15582047fd0765b53736b30a6a5f08acdf816c52130e14d412fe6a68eee1709220eb895820a638c3df66df6a9d9848e807d5c640848f85d8e81d4c3adb0a549048a5fd445a8258408f7d0932cd15f7d0ff4d90ff8f2ef64ad0a0f49a49d94f4d87609263954bbab5ddf9fa0db43444f987dffb3648fdd533cc74bf393ec9c8d920a270f35882855b585043e64be9a837b8fa06ed28e182b03b992ba882a2b146f98b4fc79f28947d01c423c603102927d14100ac9506f0b3f43f9035b325c6f4b80c3cd6c99c3353af37373bd9b145385272f0d3fa62d90c8705005820a482141df7468c6574ce398d0e82d9964bd946d780140a87950ff196e7705243845820b0bd254dcd7defd5fd897ccfc8baac962918185d9beb01cc30c058b609b99ad21838005840baa184ff5ad3089cb1bb4cd6e3aa597da07898ceded22fcdc17a7df515057a8705b97441ab73ed8cd88b73bba7eb766595c0415ed60906cc9cd6b59be542ea0a8200005901c05f81b14d69c041416be10a79f93d2c1aed9652157c4e9aff97d59d9bacfdecfdf7a6099a076faf54d076253806b5ae962001c3136fc47d3064807aeff56d570a2a8a69d73897cb341ab6e2f71dacefee5f4f9a4bfd51c5b3e752c0548d86f1100c95b7b1f1f7f121f7f34f7e8fa2648cadb37e49e073f627e7d7f3172f9726d3703161fc3f826832df4112f9edf6c56fa82dbd6f3fa1b9b84329ef9522e1643ef335b41d01f1e032b48daff34323b0bf928c83e6b8ca0fe8966a99058bdcc71e4735027eb910b9b3ce08541855b5dd728a015eae8655bbd81f2741ff0ebea6a3d3129d520190357814d719ee4f34b2e952034e1f9c3a768fac1c3e7f113e45ec0e852475f16779f84fa8c007a2d3370ff9b424d2c0bdd1946599d85543fc1d519a44b1efe71391ec68a76c7ca9f6bdf103041bad0c5141c2af718d14f17b2ac74f6763c9deb8a0810deae879e7289b81ad159481ad0bef759a0ba3bfb64ec9c98b53df21b3869d488556ded542742a6cb702f1e1a5f7948510d544702909b256134afa1738d7509b7f1cd68fd1b7ef3fd078429c5433b0dcbbbe40c363b8516772311390ac6bdedee0a4347008b958e4570c7f81d5bf21e148195d583ee14593", + "height": 43, + "parent": "00f0252e56298d1c18cf5e9854a44cafd1db98ccb2d21ee749d63799d6124e15", + "slot": 874 + }, + { + "hash": "2a348c5a9ccb1648b70e9a3aa2e9cfadb262acf59f79ccd160528f23e8004736", + "header": "828a182c19039358205bb6b1804289c3528ce98913efb45644151d9a2c67f0cc4ee9472fab9dd4667158205a177476c40bb96ea1f9d241d0d1651ae08104bfc54337d356f951d59404a4d2582037264127bcb2df028319e576fbe8727a7d9b2d1cdcda8b30c6cd377f0630bbd8825840bef69f7a985a52d3e5cee244ae15fece386829607e07e41d86720a376b886d06e0ad95c4de3521ca5085556f72598d7e488c2c7b9b57e5dba28a4947f16fc0c1585002a8c844af45a7e04ca7992ed4764acbbc0a22ec116f5a3d001636999e8310af14e64f16fbc0b741c921c207cab80347242d2f8a420be5350e8c4b53b7b0579f327c9a76d1c65cc3f0206e5c03c3510d005820b0baa39f76bbbdb15dcf688bcf535a59b12c9a25a80c3bcb1b0a3cdda57c5f6a845820338f92308f2f1d0dcabc1f1e3ad061c8b6e32679fee51431a43dc32efec5a0fc1818005840b3bd852c4a9a2d8f740ba727594f91c227a9dc638d2f27edce75b140bce7a12d62c0dcca2c832e3c8904e0149d2bc62e20e42605f6e0444835a9ecf2f462000e8200005901c041860435d36c54c1d7f37ef98cd6d589805be9c65a14c0e9d2a2ba510e422aa7473122e3e6291d50253a77354a26db982860167c0d5a030c8f0589592cf502072a33fd2dc4086d99d1309eee46f49e76b5d9f86465fb0ae9f1b3dec4c8e2c15dcb0120b19dd9e1496fd9350141f284d40e2350e86404f031597cefa7063a4a35e92b198a7888cb9397d81e563e067f3e0f5709159027827cc74fd3ea0583051a1cbcb8f3cdb6280b50138328292f33b6b7dd202214124507fde1789777f1737fd390cef46fb8ae253be49c8d3b43aa48387f0e50a32c3f2b6fe25613e06e4d3873903f3ddbef0d2d520380966869fcf11a1dd7275b1b6cccc313d2a718de1b2ed2e5fc55f72a46076eaf27598525fe452ace332397e8a2687d494b086256933ebfd955443d19d647a98c17f0472d136b4ae46d4548cc837ae9ea18449b259f3eea3820cc09fd0ee8dacd88f36ea31d266dbab5ee6ae55142594774498e7e3a3ff3fad6228c6e1fe23e3ef39e2edbe258351d9a1b8b50aa35a9f5e3e6c4f376d16948885aae058502fd5d51b5f6bafa8ec285d1cac641488bdaf90d99331da3edd4e2db2ac63975bb6791ba02822a7d25ea87aa5b3756ed3decb5ef8f09970600", + "height": 44, + "parent": "5bb6b1804289c3528ce98913efb45644151d9a2c67f0cc4ee9472fab9dd46671", + "slot": 915 + }, + { + "hash": "218266f20942ccf7d0dba7e1a9ac9a5b6e168b27ead7dcb1ef4424e1764d5241", + "header": "828a182d1903b558202a348c5a9ccb1648b70e9a3aa2e9cfadb262acf59f79ccd160528f23e8004736582022ff37595005fa65ad731d4fb112de050aa0ca910d9a3110f56f3879d449f88e5820da90997ba81483b3f2b4de751ba3ece6ba6d50f96598eb0940cc7d29452cdcb98258403677f5fe36a0182a8a041c80472b982f3ce83618962013bf2bfed9ca2a9ccc5b25ec82188fc6179869b80254028fb5234f4902a8dec7c68b46fb3cd2ba96ffe85850e3f7be2a47360159ea331d8eb031586ec0a3fe396ba22a94eb7c5923292405ae78ff22ab2df0deba59272c111c466098b83b880bddf9d630e1fc9c94b89e71daf1f84135d67e7952befc8cc9af10b8080058206fc8296e6d7c07cf17975769769795020b480acb1a8a0dbd832a39faf1e9d984845820499fc5dada1544be26d7cd3b2851fe955b44e560b50901abc71333d5d449eac9182e005840595a9a329b2637b8f2cb501aa793a159acc928a27c01e1ef586508492a68cabeae6ced714421be1f648bb05c7196f38e7aa4a8f616ad46e32c84e67951657a038200005901c076879b387d02f961e8c989df1d5cc6016116240a3a55eb1ae03ccbabac31cc1a0412ed8efe34b09903e1a8be4815d2b076f38f7b335b095257a52612c694f40c472338fcc8b178f0ba10f8683725c5df444b7fc6a5afc3c7fbab82e00e7df2d247c673d066eacc1dc7860c10b134c413d71c5a073a5f3e66a17f0d25dabae2699d7b4a969e129d627cd7839995ddf40a3e6672b6d03936de782f5e0dc31bfafdccc5d5d2e5e9a5b3414bface59a824e3a574250474d633115af821b63232de753fddb638606b93b853144dd75692b02e73b2ef8621eb1bfa307cfda8acaa2c43f8b673c9ed749e472cdf2fced20c063a2507ccb985d2b5a9bc77699f42379fb349e1e3a1ab86d1bd510c6ee89720f860d55c208dd262f49746d8fb2a7817d038262a6b266f98f427fc8b958f11adb8c84cc96444b1f5f9d994a4fd1adae2f2be87d8c1dbc0206ace7871da50cc92476d3fced6a4fc2809c8bb47dff992b06259c21f78cd6e72b49b8fe101065aaf243003af67a11d5aabcebf1059b3c92493f954507573a01bf92047ef68f4e980df914b360307b78b3371138b4c1504e155f704df9fabf1bc87ac47b3d5cd563cee6017380e4df6529face9cf39b36277068e", + "height": 45, + "parent": "2a348c5a9ccb1648b70e9a3aa2e9cfadb262acf59f79ccd160528f23e8004736", + "slot": 949 + }, + { + "hash": "dc6018a6ca7f09656ca4202218dbddc60e624a91568484838cfcd56bd11eb524", + "header": "828a182e1903b75820218266f20942ccf7d0dba7e1a9ac9a5b6e168b27ead7dcb1ef4424e1764d52415820af9da86d95be558880436e0e16150e759a13937e427dee52508c94d67ef80eba58201f16763f1e6898d544d7f9e569294b0960b2d2c0a9c5effaf1b81aed6feb3cbe82584043b1bf0aa912c6f3096c92d4aacb9b20a313926ad46fcc711dc3558b0a5ed3b88048661a00ce0be7008a1c4bc03dc87517df34357848650dab057cc5ff0bbfa2585014afd91148344b24bba2d2e646d28190c15b7b403cacf7688bc864b23fc97402141ffa0a3bc4f913648248910d2dbd180d7ac712123f7b3c85023f7a1e7c546b02e3e70e059c56d9d899512ebdba5006005820b13e507bc808f3f3ce316288fdb5cb4c269f76d6c88f175a3ee9647fe61b225184582033b4783491e8204211596cee996a92865a2a00761c4972ee0f0ee1cbb07dcfc00a005840d03083f0c14c4b60af4642ab1d5530e1b396127c57db5767d671044fb2a92cd55795e3df673f1a68958813bdf4fa09fa2e8d3a6c9bea623479ae2cc8bcef180c8200005901c0c764aa7327643bad5d63c47b782c9558a4f6f62b0f7139959cb1f087660270cb72ab869360414cfcd3b5cf03af3337aa824bbfda3c97de9008ad8b882db0910db32b954dc94768de9dd6931a9bc97c59dd74567448ac09f5228862e2fff750b97ae0f60f555d80843b304b9ca963720a599d0e43626161b5879259bd07c47c57ae3c711d7faa1896c58fc200ad7a3f39c3ca8b5e89814ad8fce112782b8779b4a5f89b45244d3efc05c73121c211d6d233cd82cfaf3e1573ada54adb0f887fc96c797d37c54aa5d232dc72f987cb717f09b0ca199cf84c5ac63ed24baace4a8b322b535330362773743b0946f562cc370cdbef122b242e8c24b1d079bec1733e0d21e7bfaa739a8708ddb99540491e7fbbea15c90fe3079bcc568ab56e07a74e73bc2fa589593f7db9a3298a928a6f0de4971fef3e4964e6c4da7eecbfa3850bdf8402c758c86d91c8e35c1c318f9e5a3f6eae7fcc456e117edf87341334286fc00e692abc03595af3753258ac024429868e89e4d24e7bdabce43676bf25e05c1f05f5973b87da15a2a754cc29f27db5707867d7c9185dc5b1bf5a1865324134cd7ca504dd6bedbf48394755f16e10feac173ce9eaba2620c6f4cd10d24d9b03", + "height": 46, + "parent": "218266f20942ccf7d0dba7e1a9ac9a5b6e168b27ead7dcb1ef4424e1764d5241", + "slot": 951 + }, + { + "hash": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "header": "828a182f1903de5820dc6018a6ca7f09656ca4202218dbddc60e624a91568484838cfcd56bd11eb5245820e851ed72bf223065330da4b4c1aa9cdd64acf009e2ce9ccc3ec825c2598efd075820a8b99efbe8bd8fb6f1af06648ef394acda09d5f3acd65d22b316489b52691da782584084be7c06e16b8b2376eeda0c4f23afc695caf112f9b857b15f2cb45573cb458ce53ec2d98eaec1c6b40ca649ed0cf526aae16194b98ba329ec7987e9b57bfc36585075e8d1cf9e2266026877d3cfaef5d480b0afa0e1a5c5af66db8d1e1a58d8d0c5e4a6483553deff46ec96aa49d7739a9f00adf7bb70691b829a06570f208a23fdbb703a64de4a0729b9d98775883aa40200582013d623a8faad46e44e62e021993a948f0e2631be624d5f54856001a3427f8cca8458206b9f9a45e7ed4d48b431262d90180acc013d4cac89419a907fa280d3aeaca1f3183400584074e51331594815a1d2f549f667cab1aa88c9d0ad0dce619a5a3a1d5a714e5c5247b4bd9e3f8a84ea60f42fc9b326842ba000ce9eeb24b173685c86a3206944078200005901c0153651db8408ed31ebdc7fb6bb68d560394a4a5376531dd709d72229aed89fdc579ad5f1ef4967dfe4a0d082ef242d996bc5d9a0a45f983a9c5a9282560d2f0049e52e9b1d0ead0e54d857c5815ddda8179a71d8d7b8545e04f753d9b7e6d0f5ba91ad9b33beaf1e83d2afef9e37e3786639e16be5e953a1239a1c8323ecd721480e6b8494a0676c5da2745c2aa9dfeda302d8c284f528fcc41229a39455257cb667f4a3e728c95b38b0191bdaa14ffde3dd5c743ff7fd22ee1d5192dbf28722715f9f7a5657c06b1fd73e0da46f660020680004e9b76703f82bc36d6382363ad2ec04425c6e9031b2e1a19188f36b4d2dae71afb8b94fa27e129ede608b9d4628db96efee84ba8a4582f9c0a619807de4ace773edda4570f8021db7cc2c74a7c8a57d7dadfe159b3a52f2d478497a720535d348cf436857a6a55c610946b2a56563daf041aedbeeb426ba200bed4faf746a0361003e60cec7be069a0ad6e03444e0039a6124686c8f4df0fd22225f8ae00a86868cef64dc68d582307f23ed22964050c244e4241be08e766798496e0b6968e290c1ef50ef1805323e6ed9fe7a5bd78215e32b55b817b45145731de78b10f9afb4df0a89713b80a43b5dd8abe4", + "height": 47, + "parent": "dc6018a6ca7f09656ca4202218dbddc60e624a91568484838cfcd56bd11eb524", + "slot": 990 + } + ], + "spos": [ + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "7d69f26449fea78dd035fd88a360205ee15fe03d4e3f019814fc12cce0fac334", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "5e32e78311c07da914ac925dbfc4aecbb874245a72f94c2253dd64e39340b085", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "cba58fe1e36fbe608d047ba4f1774efebad8fbac39b53d9b73bc80a8f8dd4c44e8eb434c62d143454d85f5ece2a675cade637e20fe4cff3f11556ecde7ad2ff0ac24643578b384023b70d7a93e3f2435e4f9e38dc65c40df258d7379228b6ea42ea108ce0f27da1e113e3017311451c8972eaf8127f19b900fab6c241f06dcca4d1f153541b7cd87d47144f44c9bf945501f3ccb9de9e7664b473eedb7710a3af57cced81eb964eff669ef38c7e5036eb8d4f8d664bd7b5a50f03dd56e0435ec017e92b07be6ec30c20724593c79648978fbe94501ef85f261eb38209f8a2f8260b794ec16692996a80f7620b0e256c0bb45da1e701ce21bfd3edfaf908f1f6d9352981606a4c6d22d3f14a0b4f2f37c4b8085974aed296379d80e66f83506b7513a9e3c8b9ad6268994e42fa50be81faae29e8cf62bd7bd75b09a06652f9e0e5b0e52068251c13bdb85261d4aa9c22f18235f019c4e2cf4e94cb49c38f2eea330b0f898800be71e896a06a157e8ad8801887a2777e10d1d3eb6065b2712946f51b89bd9d239ed01417eef7f09a94eb286a1a4c08e6ad99a767346ec031c3797d9a18aef202ac7782b91a08fe3075afb79b4880613aa78210de4c5ba7a20c699b4c48e149cb0b5dea39cdf1ba4977433afea1261a9992f207e0b8589e048e85abc751c50b717dc2f3ddc099109d6637cc881d59fd58c865305bae525fc84de10c9aefa0f0b8a83da104138bd998daf300dad244a8ad10a42c2a61b372c34cb1ff5728e848bfd0722355748f9dfe3765aad64cccf0c030442258fd81a6dba936803bedc6096ff1d90072ef1a24e231f60c43c3d4b5f31776fe56287ecf228013c", + "ocertCounter": 49, + "poolId": "a0664cae7b12c6c64f08c08e9affef46b8d096c18bc7c3adba382f0f", + "poolIdx": 16, + "vrfSignKey": "82c7e81244a3bce96904feaeabaffc4270245f77b0d26e89ed0ce42a2a89b2af6ee3a36d9b941fcbb53e647468d10b0ae958d8a77b9f60d2ebd247a05a654c6d" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "c303bdd3b05c573acb624965c7ce2a5f0e144354fe4db65d643fbb477329446e", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "a54e9186510d3a0c046b7118fc288d2f28722d24350453d8eb149fdeccbcbb3c", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "5a2a5ea10aa2d95ca4bbf2e8def658624df5171224d89d25c62f901fe4658efef43217ed873c1b5c033e03e3f10c7179be68bb022a8f804a3c22d074fe5da817b1b31c4c85c89b7ac3440fc9032b7a482bcd59a86bdb03806b96b8dacfe77ec03fc82c59fbc5fc91eeeb54dcf090bf32c704e1bb2137fa582499fea349099a427fa67ab309b4db393742e9ec4fde0c85fddd8c651950819d0c023c919282b75529933a23f86307a1e0bfabd3be96ce88e1d8301ae9496f90faac04d4566febbf3f8734df4cb9d8b6cf956144e0b62b27e004a86101c8fc366b95afc64577986fe9f17bcac2422bb28ece7a4eb89a9f1391481ae485225b3c188e69c226f9d333c07595d4fb4957032c05c2ba22d00e2f77bf13efcb87b77a432490009d8a03920be66cdf82ea3dec218a5d4a95636996b696b66ede98c1b25703f9d8143c8d09ad74b201e3497617f11ffe522d539540048cb0cd00ca8002ecafbdff6ecf2c43bfc76ebd9985b443812739fcd161fe01b49c25ede6df49fd0a838f8b531644c9ac8f35e3c2872576916098c31a26110952b2f076c216a512bcb18e6b2003c1aa36674100e58677dca57569de9b6344117c059f25082806132e3527405716410cd1b1b155842af6fdc031af4edaadd576eab871368b8fdac1386878e7883340cfebdf82d43ebe2654608eefcbef56ecc8eaf8bcf56fe1461e866cb7a1a8ae3b10ba54941f55a390f518544e002748527f8ba0ce05800559f33a2c13c2ad6e555eed3883a99a29b842c65f6ffa391aaef7d5178eecb4319eef91048772d1cebbaf28d30e5d28357a08504ed0250d1ee71fe0aea705a0c686a3cedfc35961620bea", + "ocertCounter": 44, + "poolId": "c898e16a709c609c68b283377a6eeb67dabca025aae15c7ddb7d8705", + "poolIdx": 15, + "vrfSignKey": "bdf0b43993777d56f7c38c9b3b03fe6edecbe0455842e89104138e15f41624b188a86b524b9f5f6b5319f1a3171c0031fa97842df2ffc5d29ff7ec4c0ecc05f1" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "a7efd56ba64e9b07ca053d1d4d93f44cfdd1d41e0dc72222d1d97ebf0144f361", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "ae06f98f58ff9e92feda8df3468198828b0bbb8ced67a45577b880b3da1efa85", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "caac8524a1fbfb25d00949d0632caa3e80c77e1d1869e0f821be8d6b3d01527197325600ada480001a471ce443a619c60536a20e2eee814785d3bf5a3aa8f45d2a8a69d73897cb341ab6e2f71dacefee5f4f9a4bfd51c5b3e752c0548d86f1100c95b7b1f1f7f121f7f34f7e8fa2648cadb37e49e073f627e7d7f3172f9726d3fe0415a2b27f235bea1d1dd79299658a5db87e41b9755d4f568e8e4d83cb9160703161fc3f826832df4112f9edf6c56fa82dbd6f3fa1b9b84329ef9522e1643ef335b41d01f1e032b48daff34323b0bf928c83e6b8ca0fe8966a99058bdcc71e8ed56cc0cdb2a798bde06a79f286859a70e556215f40562808f21f59fcaefe384735027eb910b9b3ce08541855b5dd728a015eae8655bbd81f2741ff0ebea6a3d3129d520190357814d719ee4f34b2e952034e1f9c3a768fac1c3e7f113e45ecc5a3e0736611f3a23ea17f2729b8a6a29832a2aa60dd418500dd199e984f18190e852475f16779f84fa8c007a2d3370ff9b424d2c0bdd1946599d85543fc1d519a44b1efe71391ec68a76c7ca9f6bdf103041bad0c5141c2af718d14f17b2ac7a087eeea3cfe694bb02e5c2f14822f4e7a44e1a26acf749bcd738e77d359fd914f6763c9deb8a0810deae879e7289b81ad159481ad0bef759a0ba3bfb64ec9c98b53df21b3869d488556ded542742a6cb702f1e1a5f7948510d544702909b256239bccd2e2684e6f4db0923cbebe7d2de661ffc87e0e43956eb397738fb7b8f2134afa1738d7509b7f1cd68fd1b7ef3fd078429c5433b0dcbbbe40c363b8516772311390ac6bdedee0a4347008b958e4570c7f81d5bf21e148195d583ee14593", + "ocertCounter": 56, + "poolId": "355a834a2d1a42e8724f0bbf23b7ac561a30cac77ec82302509a4eaf", + "poolIdx": 14, + "vrfSignKey": "bff58e19c24ea2c85adcadf327f2aba0c1d08650ce57d4669bd408041a85e555a638c3df66df6a9d9848e807d5c640848f85d8e81d4c3adb0a549048a5fd445a" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "46e3d352ae36d796b04a46ab49e808aefdeb562281dc92f68d0be4d921f0ffcc", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "d1557bfbd616f7125e0b3a32ec77982ee05841d662f5d48f3da4d7a6fbd3b83b", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "dada054ec7b8dae7407daf65692b63353e6b822b948cf722bbf2dabaa71702936fa7c0fd5e05ff763d918ef1109fe993fe03044e5faae88914190c30dc969ebf472338fcc8b178f0ba10f8683725c5df444b7fc6a5afc3c7fbab82e00e7df2d247c673d066eacc1dc7860c10b134c413d71c5a073a5f3e66a17f0d25dabae269dfd458d342080da106e60e900e2a554c9a9bc90c6136b7e27eda1def7bed961d9d7b4a969e129d627cd7839995ddf40a3e6672b6d03936de782f5e0dc31bfafdccc5d5d2e5e9a5b3414bface59a824e3a574250474d633115af821b63232de754fc2207cb11ae82f8894d7b941683f30f02c8cccec44eca93ad50b21944b2f093fddb638606b93b853144dd75692b02e73b2ef8621eb1bfa307cfda8acaa2c43f8b673c9ed749e472cdf2fced20c063a2507ccb985d2b5a9bc77699f42379fb3c8535c22177e87df965f39d9d66d6c622b07b4122ebc5a5b1c14e3d55c89868f49e1e3a1ab86d1bd510c6ee89720f860d55c208dd262f49746d8fb2a7817d038262a6b266f98f427fc8b958f11adb8c84cc96444b1f5f9d994a4fd1adae2f2bef55cc4e8918740bb3335a14747e178b8c4f704cdf3bb0213583d78b74ee0bc4187d8c1dbc0206ace7871da50cc92476d3fced6a4fc2809c8bb47dff992b06259c21f78cd6e72b49b8fe101065aaf243003af67a11d5aabcebf1059b3c92493f9b3a5938c03eae42385cf38da53d3b472ae6c1460807b3b49025e7c38050d0c9554507573a01bf92047ef68f4e980df914b360307b78b3371138b4c1504e155f704df9fabf1bc87ac47b3d5cd563cee6017380e4df6529face9cf39b36277068e", + "ocertCounter": 46, + "poolId": "851c6131fa082970f7d3c6c8aef5a64653f3777fbf727040401e091b", + "poolIdx": 13, + "vrfSignKey": "b446304939ae34c7d9ee979903846cfab952b0b89bf46cdcb13847289f73fe9ada90997ba81483b3f2b4de751ba3ece6ba6d50f96598eb0940cc7d29452cdcb9" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "e9367b2aad550a0454072ece2183843bf492bb8dcbaf5120a17a462e884d290b", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "e53628f5b750706df604e38a76d9c71dd136cb50bef406b4597375f5b1183f02", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "4b5875ad14ece8e6fa3339cb8cc57b31b7252d4969940bd7df0a23ebe45eba8552559ba9613953227546efa5d15c5c386002231000ca84b62ec3f1660b903b48b32b954dc94768de9dd6931a9bc97c59dd74567448ac09f5228862e2fff750b97ae0f60f555d80843b304b9ca963720a599d0e43626161b5879259bd07c47c577dfdb3c8436b214781adfb201ed88099808acd9b1637574e4886e40fee1b6bffae3c711d7faa1896c58fc200ad7a3f39c3ca8b5e89814ad8fce112782b8779b4a5f89b45244d3efc05c73121c211d6d233cd82cfaf3e1573ada54adb0f887fc9c4a800d094474319367e1f393ed55f93615f09dc521f525a613606728305ad5f6c797d37c54aa5d232dc72f987cb717f09b0ca199cf84c5ac63ed24baace4a8b322b535330362773743b0946f562cc370cdbef122b242e8c24b1d079bec1733e2b22cdbbc1a4e9faa155d9c7579f8fe5b98b90830c43cd21dfd5ad7909e8f6b60d21e7bfaa739a8708ddb99540491e7fbbea15c90fe3079bcc568ab56e07a74e73bc2fa589593f7db9a3298a928a6f0de4971fef3e4964e6c4da7eecbfa3850b2f53b482617aced0246870702f6c08143d50fc6367a8fdcfa9e610d2ac5ebb30df8402c758c86d91c8e35c1c318f9e5a3f6eae7fcc456e117edf87341334286fc00e692abc03595af3753258ac024429868e89e4d24e7bdabce43676bf25e05c7cd39b1af9d88728da72093e67cbcd214708fde9314f4e99e53c83c7ffbf16731f05f5973b87da15a2a754cc29f27db5707867d7c9185dc5b1bf5a1865324134cd7ca504dd6bedbf48394755f16e10feac173ce9eaba2620c6f4cd10d24d9b03", + "ocertCounter": 10, + "poolId": "a455bec8c63c9243544206d36e291ff2660e3356d876620395e2d016", + "poolIdx": 12, + "vrfSignKey": "7e9fbc3710ed80fe663e619de3c8b3cd40890fa29eb6536cbd1bf45684cba8b01f16763f1e6898d544d7f9e569294b0960b2d2c0a9c5effaf1b81aed6feb3cbe" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "c28b125c2ddab91d96853b5bc6e26e118d6889ee46dc1987e7a8e67b06374900", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "52dbcac049ed285f823e6f9767b0bbf4eeb038409815ce6a8bfa322472c23e76", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "ff1178c924afc1360e50ea2a2007c9ac6cc9c74825bf1d794eca12e611c29a3dd14093c8b104f62a3704fd5d2fc847a0ede7509d4f17f19c96fc21efa144e759ebeb4c8dd448ce09d675ca6291ef83f2b82371cb4c904960430e40d120365011d31daef6cdc3e3896ae2ebce0400f566484c73de8810d337d3c80bc5ae3af9ccc3a9f58cc4bd7642e6825d30e4078844c71daca23a5f2a4b10eb16fa9dc3769668fa7f55478b6b8d3d7e5ac61b2587184899ffd1314e8bc2911a0004fa506e9369ccc438aef33bd13cb6c27766f0e8339304da66df13094b2e31b383d4794bd226157f46d2206683e1d35b3b1d2edb9b8e9dbcd9a054afc1d1d59dc8771180351c14710d97ac55bbd942952d2511466b9d9cfd9f1035df8bf7f079b8dced90be77f3adf4bbfad6ad2f63befb230b8c7a8ca3771dc1783d1deb0cf6b369e03ec2d78089f86e9a37521f583d5b8ac2fa7ff3ab6c1bae68374cd32a97db83e8030eaa38454f09e9e2fa975ece0ec6711e0370c7e816230adadef96b3a4d6694ef12c7c9002b8371a09994caff169639bfa4e07abc1341a6708a59940df51c155cc19bf2e3bd7e34af75245e61126a195302a53404109ee4416169d2fc53e8c11604aebf196d8cf3705c9f22764d0bec98b52aff7d4939621dd576568554b854ea3bb80e4292f56f76bf2f68a98fa6e17f6824ba839c2f60905b81d4987195c69e5d48a54278ebc0124eeef20ece974765fba5845a79e8a964aea7890a27a04dfc1bda32c884a7112465e00938275fbfba9d331d8b1258110d730bd9fbecd6b6952f69e346e8e4e37a7f7ad035a0ebd89ccd901fcc1ebc80672696861af7bb2050db", + "ocertCounter": 64, + "poolId": "51b564454672b17ade8e4da10428e570098f51867895eb59cfb157f1", + "poolIdx": 11, + "vrfSignKey": "0aec41be5ec325c2c7022a47c7b71a78e39d9b54dba4cac3d0350cf4c3ad0555b6a49a80648fd97b79c4658137a21896c2cb965c5bfb5341b6bbc1ebd309eb49" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "1c4e72a4c138eb96cb38c44531e17a25d00412851b427963e214a9ae4d19a4c7", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "cc6f41a4a721169f3547ca27d098a1b8475474cfb35b45319ca7e68c0cd35292", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "27442c7fa4ecdd1b0d855a1cb0f0efe35f05fa0bac7f4be77b65d15c9554f76701fd013d5b1197e018199ce3ef1366b9e188b6082645b23f03513dbfaeac678eda41abb7a69d5448046d4741d0e195b91d7c984fb09f33bdd2f2a97ef4fa9e8922a2b0a7dda60412ec3224262779dbf5afbd6cc5c867dc1b36e19b72948f0b81fc6ae3b5e2e24939195525c65815af80ffcb9954d3b9bdbc011ebfada1f53fe902191d79de24ad6a5c32ac2c2aa03c75988f41b66ef9ebf2e5417c69857c8ab66422a18462fef15e424c2fc57fa8614a95318c3154e30c46b075f8e2724a6bd6f22a93af773675cb4204025e6127eadbc6f09f38efa8d049987752a9184046e4aa8396e7791f24bf9dfc977e03899b8b89ed5c2a3cc994ac11823a9ec9ab81a13eddbe46298c27cf8ba29429e7e3372a57a6ef70c716e1126df589892c22f6690bebd27924f7b032658e53fa2c53675048604e93454c9108e2ea0553f991ba7238e009c0971bc3aafae05b88c7f6d127cc0d651b51c1b5bb79ae359815802dec45b6d750f9415fbc45a612aceb51fc9a8dc9ff2263810acb29a331a3fca42770dd59b3d32ddaad51932652eb9708f6262713adbe4ad56b9b772fe5464a357d376f0a3192cdc22b23963fd1a315c774de8285b1adee80c609a4d5aceff8c27f86d37da061d6fdde1d35a4902a87d64f62a2f171a66351a88e34493850306eb81d46686ea956db5d77294e4a07cbbc415b87b022de746380412751b22c41e4eaaebdf5f1c4ca39c567d3e12b2751d508abca8b94091b64d5e32e943777a961e236dce006446489d579811b83b0279d8f34454c64a266ccd66c188ef242970f96e1", + "ocertCounter": 74, + "poolId": "4a52e060a4c96d74c9f8a3e6e186f0ee3f8c2f53ec69acc2d1df8410", + "poolIdx": 10, + "vrfSignKey": "cd2348615836009788f7ee7b73ef524fe7376ba0492e9143d3ebad395d8c60bae2428fc1694882b7632ab35a7a9de5d7ca208299fd887d234857ea8061a65c72" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "fb0562769c453c9dd94f4c819ffb81fd2de9a069b230e8a75393483d3ac8b3d5", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "124c0c5a1ac018357710bee0e29e4d6f3084019fe7732c0f4159afa3bf465abf", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "baacd7b4c82b7fa86db135bfcd4dfef7f41396e4294545c3d7be1b11dfc884cfeaca79d6a3746e159b307b8bf886ef0b1584f6d3ffa70bfe4c37d28745753757c13235d0eb8ca973053893d3588f771b59046cc03fec46e11742086377edec80a495daaa579a6de588deb6fa4a7c0809595f93d68fda859c0ccfb011181dd49ba2999b0df8ea4dd899169f5b84ac91ea28785961e3ce74404818aed4cc0e685ad5f2e67c5626df00ffdc5c1bec266e91682cbc57333c7327cc1d567596db4607e7964e58e6a1dc6f6c9c24ae72243cf9f193f966bee38cbef934863625dde01aeba0999a6f192a679080e5e6118bce77436a48179ff6d68f0b80d202f8645bc58956610bfe98c89429ab2270df7742983eef20dbbd1504a137c00a556ee708a444426f733c152fe8b19d6af50dfda6b3efacde9b71b3c90043a99f216e462af6c7961bb06b97f71831d09852c9566840654324be8ada6ab6a4a83da6bca5e10e9144576b49bd708cf5c67d93160adf3ad1a39f0b118ad8f78adc7af45dcd4f28c42657fb8cde01fbd496ab6ace5ed6607eb73b610965ddbb78a7fd6714c4ed087314ade68accdd1ceb8d3d65f5c400140ddfcc0967d7f3ada05a2659a298a5667fd69f5b133aed19db36919606390333f145b6e44a4ffba76fcf503c19b5afa897a9448beb350fafa9c6aaf29e5e105444d5732445b97170e628462da8969a16de18975582ea03f9294acf8b097771c013203b8418885a7212d0344f7173b01f3587d05081ef2618fe056df94defc1c70d21b41903d8bd77a171c67eb481ec2037260dc8c5ae867a61af91966b30ee9734b0b0b38d63d33c114471cf8dd5fc09", + "ocertCounter": 69, + "poolId": "1e54471e137575c8463db3f7630cfae1bdd6387e9532fff846ca0eaa", + "poolIdx": 9, + "vrfSignKey": "20eee7bca6299f7f9eaaa8c94a2b873cfc78deb92052262ef08838884c8b3342d68a44bed117a61e737741fc787b26135ca7e0d802115d5f389e9f068b551968" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "3b94a4b2f286987f64e958d703d16011061e71353cef418e8cf9537f0d7cfb54", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "8f3983a01f458ba6256ee1c740b86416ffe02fb3cf45945911828626851e8446", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "a3014d408b3b34f73e10e0a971d5a5a710f5db97e5b9c97fa5b3221457cfc81a022e38331e03f95bf8069854afa5b932ce77c35673722425d719502520e68d5549a9eb6f25c6175b6d603ee15b913013fb75f9f4a4c5ecedb5bcb3f288fadd520a015063b56cae186454b21f05060a616dcc3753a0fa963791666a3c2359fe5be6d1c54c42bcf82a87aef1583b34df05bd98f23014dc9f61ac6197e0127ce996dc13a77c64d7e5eb106f1d8d9da0968747066add30c07d12eb9ee7fee29f2b0f762464642c1d35adb980792baa73c3e3eece676c9c82858a1fdd34094e6680e0ed050681c4bf39742849d2e8ea0337f4dce636d2e78b5449c365a269d82dc4e337153e75a055c876a511ecd1731111f8512b4edcd831fb1e6013c0e485b4215a2c0fa5639f33ff62a2455e80b6cb5e3cf0ed721aac66bf14ead70fbcaecf896775a4cca54fff0d04abedc36b6b809a8124b7887f8f81fd9f9ddcf19e163f2c002fe3698a8bc53de555cba5e21a29179e9e2c2b410c1d4b0fd703387ef89fe7af5733e2549c699ec466c25727d72934d38add039c9713fe348a7468ba7f53f2e696d28bfff3697234d1301764ef035c29e32a059d714a56b8c31469f2c6d6c1128a96bcfd25d1119c55f533be28a25e9bcf5ed7f96e57920358e6f78602351b270d70591707c6c1dbb926009a5b19d0ee96aeb92f09125242875f33d74e1fc2cf1bf847893bf853c75c4fc1c2bc38643c141600a103b0aa36a8bc86bc599bfe21b72ee67291edee6e5dd11afad4788ac84b136b681cfe905260170a2088933e36be2607ac986a15546931e4f0bbc5ef0d5824bc53af6539a762cb490fa7b168e2", + "ocertCounter": 80, + "poolId": "164b266eedc357d6d61081f90afa085228ea414c0d5ff83ebeee4cc2", + "poolIdx": 8, + "vrfSignKey": "7efb4ebec47faaded633f189a46d7de72468c70e7bb042f5f7d4cea86b6e9e9092411f9a1a29cab8b4ed1ab4357a25b230c014e3045c221b3346b5a5a243783a" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "09ae3d5b734dafaaec4efd982f44b6b2a48eff91380aca8cb854c46bae77d4df", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "adba69c9f91efff97763795c454d8e8c7777a19f467a46cda030880d4b9eae2d", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "62dfd14792df9f6f027997943f1659164839bb35a2ee29ca271d971327a556417b1cf4bff4325ad5a8675f9286253779386aea3a22ed9269382a458978465470c240bf2a1681adcda82378b0cd9f0211c9f7ee6eb26e57ee2b0b92547793e5faa7f183ed48ff763de91c6324f355449b2d96e4f37efde9dc377751844b3314bb196df3e75c4f9ace46f893902c60a911668ad1bc1e93d6a62ed4253594d49d098d0e3c59befe2f1a5b7bc0045a164b8b9e1c5c9ee285bf6c2f6152826ef1252ab39577992ce208e5b172e9d03e46c268454a1502697162f175c586821d0fb5a8f779e38845460603b27a0c2481be83f5613bc192cf58ba2c6ef0c71d20b38c65c0ffd4c56fb8c5cce2e1f7a0efc77a38277faa82580e983c87d4081dd8b5226bc8994114ec7a95f8be871726a6998dce138fc55377f022f84cc97eccdd18e7d6d57fed1211d5c1760ecb4af9b5b47cae934a122baaa6ad7c384219602a21bd2f1b557d7daea41d1d021e34aab3dac320758ba4f9c2d5fddc5a8072097be37af8f2e5fb4037a11632c6fd9d42c62a2e8263af2db7c83d992c933548e0f5d2593b872073cc6e81fe10de7db0508fe7cb27328ac021fd538e8f7254d8d6bda62472face422b543cb5c1eb68fab55f0a77683d4532df74468dee8e18a1b32b92fde2dd6a8dad63af74be2f9c4d3a1d7b57711d09e38e97fb72551eedf3c215beb1c002cd40718c24fe8ed816bd85595083783fa0cb54c0927fef761e74f12b3246eecac6a938ca375bcb5ab7037955122f116659927bdbb741aec609c2c27e3d18c4d5751b52460d0914e68d40014f179d8400db188be2c34a7f98872070b86ad764", + "ocertCounter": 13, + "poolId": "4b1f54a1437906009d347348126cbccf7a0651d67755d22187968e0d", + "poolIdx": 7, + "vrfSignKey": "c2eff0079b54054d22a0888443a45b44f32ef12e8c62679368d1c5128625820e83f3206635b9182a411e2a9e870cc13f5974507b1f84476c8519ad9215ae4678" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "5df347530a5de3f310ebd88248acc2c8683016dc6b18f2e3a7bbf52791a099b4", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "44d44e2a7c17cac92a3d8d3ea711c1a9e10f30e16049b5fa0bd6ea91b7e62719", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "407279cbdaaeb21b358e4392d4aa37938971bb09063a2ced069a5f13a6c6364607b56defde779469a8e58cb3158d879675b9d60f1cf7bf79a8a423439adec16bfe9063bb6c7ffb23f3a85e936f906a1e1478be1b5d015c8d3d78ce5a536558ac25177143dcf1dc132c17d29d3cbf0021f048f9efd73d5d54313adcacdf010db9ace2dd015006dd2ab3660bb567a5ce89cb67ba85e503388ec2c8e9052792f044006c13807ac6128d25f2ab28b755abf844e50c1cf772ee5314a79ee8ac338b28e154499794b6477d7daafca6a41ee1c3a3bbd86cd860f1702ce69d25d10b46aac512667a67f3a0e8c51cc9855dbce4e80c16edc9397f7eeb5ea5f8376d74b9f99ec5e31a2e91a8db0322ff68a383f14d2560ffd1144a020ba8ba7312e314932cb1137e21fde4ffff49e6352a932bf2772ea2ae98dfaf881a80d369caaa2db1dc20a9f0db4e49d0b68167d407b4b400b1327e15ff06c5f41ea131fc9f9c033fb325ebf19f2710cbc4ca12bfa7fe5978dbb0e6018745dabcad22091655e66ba15c3bedbab0ff7cd73107dca9e44cbd79f79f42f4e4babc9311157a0f48befea2e142fb5746f55b71d442ccc304370cdfedc1874f3e6548d8752f50c1c532b408d922a23e940b0420c2dbea9b710d5e1df7cbf1f65e6f6576209d6f676b91ee38f374e8e34da0c4897935fd62eaa4414678d133b6c3a819015707fbc1be3f35f391d84d3614299ab74f2dac5ef942c6930b66b065d2c6f946e9f706ee2a3494f1687ee924cff5f0ebe56cc4e90bbf76c4c80d7b8da18c2cf98005f54955499da7a8f581e4c935a0f5ba5c61f1717662e80d7b82c3a4ca01b1284ff95e0522f50878", + "ocertCounter": 24, + "poolId": "be13ccb4ce55235fe294a6494a3744766e8b2d5e076995fe55ea6f18", + "poolIdx": 6, + "vrfSignKey": "747ba8ee1211024ddac2e9a646ec6e9625667b17b8ee7e8b7f36724a197bbf1d21e64e133738bbee188311034a4f03103e0821a6c0e632f499e96d45d379b300" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "381bcef95d9a62eab8958977b119f57b688451e76855bd1387c7bd1f1fa44f32", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "138c33ffb1f6e3e22115d4b064b5481967c3c3aae52d7e82ea9ef0a8b49cba26", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "8354aa6cfef3fd254204e512d7bac1f2f5cad9648d44630db621b8c30d995b06f89e70c3247938cf8620946f228a641eddeff1006df949b7766fd4a2ddc51ff2123f03f1ba839244e816272ddebfaccd07b396c7d4e7e8127b65e28a34be2af6d99954122949e55f47def97ae436cb9975b8a70ec77c4e57f48ceec0f4c19093b16bccd77319595d472379e17132544772c6ba4c4e4fdde9beb3925353826544a99991ea07b4b34129340df6cba7f4e2a99036c15e2309de61d20d77ba801603cd42f57f6fc3fd127dbb2923dc40375f1d11d0b6df7a73e6178c42fb62221a9095ba2f062465e72d4f344fa3603c2b3eca3a734be85b70820c4c8e8bf91a47217e2126561b88861eb6d764dd5abd0a02cce6dd3baf659acd10c78bb17c48f7035a0c97618c6252664b9ce9541451047d47b888f01b92fb499940b9a5570c7b5b5f6ed566457eebde8295149c67a119da55d05d0d6ea888ae0ee6674420b806b05e938563dd88a5483aafec9d89e92d14aea22a0a9b8dd77e7fcf14b4f58ea4b24be7a3866f9e9fd4646be578a2ba3baf516b6cf5b543267cd8bbd9684d451673fa5a92583c2025c7213b2d0f5e3f6e99109691d043e4660b8a421a0b812aa6c63b782437363ef2bbcca05cb0de5d5163d29645b1f58be7307037ad8ea25494c204906d3df79b42e8529a7e9a98a51d9e31f116ec499ebbab55f0eba55bfc876320fd2f8d1ac593ea39020267f2a928b044458d85a5a2741dfdccee723650dff5cc3d6a9824fb4514cd46aaed452cade04436f0c26c5e156e3d9d5d6524cc85dff4676d1eceb7cde887cb25345e7447b36d36f62ae2e497ebdc03b2f05f167604", + "ocertCounter": 12, + "poolId": "7bb1305489fc4e4d22ead2b66c15faae1a45757deab7aec3d5729f31", + "poolIdx": 5, + "vrfSignKey": "00ac7a952c7872593dc50b04b0f4d9b7ee60fd89c52debe062c984a1e06d8f4ff80ce1e74d580c078c2e6cceeaaf2af18c87d72e85df14897ced396a9e803bf4" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "ac5898dccc3a60abec9582972f2354dabc89fe621bfde78ecc89e1abd40caa51", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "e46e61e80d2ab5699d2c16ba84d98e779826fec6dfeda7306f24a7a05c7f153d", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "970a71c9c861b207b2d68500e44967ab3b0e968d425dd89edd78415a045953383a58cb156c9bc19e4a54f4216cef2a8b49dbe70de3f32d8b90b046b6fce5291c2a33fd2dc4086d99d1309eee46f49e76b5d9f86465fb0ae9f1b3dec4c8e2c15dcb0120b19dd9e1496fd9350141f284d40e2350e86404f031597cefa7063a4a35f8963dcdeed26383d4f8ab03e0375232f2b3294a627536f1de626c915f5d736ae92b198a7888cb9397d81e563e067f3e0f5709159027827cc74fd3ea0583051a1cbcb8f3cdb6280b50138328292f33b6b7dd202214124507fde1789777f1737f0ed6715708fde69ed403fdc25320819b3aadccc490250c2ffef1097b8835e00bd390cef46fb8ae253be49c8d3b43aa48387f0e50a32c3f2b6fe25613e06e4d3873903f3ddbef0d2d520380966869fcf11a1dd7275b1b6cccc313d2a718de1b2ec97e97ade97d8c224f3b977911a6912791e9b69657a55f92e1db1df03ac7b6dfd2e5fc55f72a46076eaf27598525fe452ace332397e8a2687d494b086256933ebfd955443d19d647a98c17f0472d136b4ae46d4548cc837ae9ea18449b259f3ef4d10e5e9660595ba7403b4bd8b3719c8eb6bad093aaa5d53b88525bb442fd56ea3820cc09fd0ee8dacd88f36ea31d266dbab5ee6ae55142594774498e7e3a3ff3fad6228c6e1fe23e3ef39e2edbe258351d9a1b8b50aa35a9f5e3e6c4f376d1c3e7f55dbc2415f86bd23c1e720da6ee0b2f318900a16161c0f50fb90b75f98a6948885aae058502fd5d51b5f6bafa8ec285d1cac641488bdaf90d99331da3edd4e2db2ac63975bb6791ba02822a7d25ea87aa5b3756ed3decb5ef8f09970600", + "ocertCounter": 24, + "poolId": "3fcc6db066b66f2c99e9370d9730d142b79ba5653be961ca635ca1d9", + "poolIdx": 4, + "vrfSignKey": "6da9d197f081ab89f2087fd25035d6283df57da359bb9b6435110cb9ba86892d37264127bcb2df028319e576fbe8727a7d9b2d1cdcda8b30c6cd377f0630bbd8" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "6f56d355d2730d73d79e28d3d665571f7b49613d17e1517a8265b85df8a33a71", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "12bee8075ae5cc4989eaacefe9eed20778cf30d98b1cc23cd1624e441c1ce856", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "4c7087d0b7dfa86c4cbc585f83c469a9baad3963cbbc3bd2929580d33a8c7e4575aef5a63ef95c0ed641f54be124a45784b534a09ceb233ce864e49c22eb059f49e52e9b1d0ead0e54d857c5815ddda8179a71d8d7b8545e04f753d9b7e6d0f5ba91ad9b33beaf1e83d2afef9e37e3786639e16be5e953a1239a1c8323ecd721faaded26ce11bedbe08cd5946fc2142f0888464d394f3f17734d03de635cb1eb480e6b8494a0676c5da2745c2aa9dfeda302d8c284f528fcc41229a39455257cb667f4a3e728c95b38b0191bdaa14ffde3dd5c743ff7fd22ee1d5192dbf287225083759d8045a904fc9dfbdfabdba331cd4ce74ce4d7c0a02454c7bcf9532873715f9f7a5657c06b1fd73e0da46f660020680004e9b76703f82bc36d6382363ad2ec04425c6e9031b2e1a19188f36b4d2dae71afb8b94fa27e129ede608b9d4687768c78c7597b8204f60e91b43c8979883de8bfbbe85172e87af8122e02609528db96efee84ba8a4582f9c0a619807de4ace773edda4570f8021db7cc2c74a7c8a57d7dadfe159b3a52f2d478497a720535d348cf436857a6a55c610946b2a51ea170ddc9b6b6c0d8af59afccb2f7049f70be744277b84288d959936b98d13c6563daf041aedbeeb426ba200bed4faf746a0361003e60cec7be069a0ad6e03444e0039a6124686c8f4df0fd22225f8ae00a86868cef64dc68d582307f23ed220dd52fc17095d7d7d50658942a08d1525b1ba119715edf3d4d0a3cf003c3f0c2964050c244e4241be08e766798496e0b6968e290c1ef50ef1805323e6ed9fe7a5bd78215e32b55b817b45145731de78b10f9afb4df0a89713b80a43b5dd8abe4", + "ocertCounter": 52, + "poolId": "9f90fbe8b41ba352aafa77475f9e6dce79baf79491526e0696a0a7d8", + "poolIdx": 3, + "vrfSignKey": "d7fc9765f0284073f4e99615274bc11d2d2b6c06411e303d6c24f00cfda484e1a8b99efbe8bd8fb6f1af06648ef394acda09d5f3acd65d22b316489b52691da7" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "2e17e8915ffbdf9405e47a6b51ffde2d4b5c6ed19066ffe9895754da5875b54d", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "203ceb6a4565e4d27df332143319019aeeb48a8c4ebf6be4786711104e99e978", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "ae05f381a0fed52437dffcd02d0265bc09edfc40067c0da453108f9f595a9a5b7ade31ca8b1405caeb3d186449b6aeecf5a2c9a8eb7743b02d328e448759341b1a3631680c81fd0642ee45aeedefa4ae83ebf2c78a681a3f831e50c628929c8b5897e0f273ecfab8671cda14da4d1a5d44d9337270b394b4c0a03e1912eb75520304aec4ebad13e36c73f33121c7d2971cd37457541fd08804dabf6067eb57f191a64261efd6984933d34e22e5267056bbcb58ac74362e3b9bec47024ac873539faa3cfe89bb91571cb1bf47f14445ae3a7734afe96d6f7c683b64683e1ac5256a264dcd61f5b4d089e011825329ee0b0a8844340653c05d7e4864ca566fd1cdf1a8bdaf43285cf8ff621478980cb756ba86019bdf1baddc904298c573015a8971d8215977d748c327d9dfc06c1a65539feeebb7898cbfca7903088818a96baff4a5e2f5a645ec161eef5d98892c128286b49dd33d5412f2b3d37a6ea39b77cdc14119ebba5b1afbdee35c292389ebd0bd318f4b7d48adca59cb2b7ed66113575cd3bf11be8549bced3cfac0c66b6ce83b28238e0de549d46aaa281a0d39784b1277b6dcd403512cc55e34db3feffe145a6797dc967749679c595d154f5be7467b46a29fff240c7aacfd49b7d4a0ec4dd0b6dab0f1a08a51c3fd796cd1bda647208509138b9278bd30b0208bcbc683d7f58db1568c6b06d0a9aca741fe39aeef56bfaa8b67b17443b166cc94661135ebf6adb384380ae82dd0e80f3bfbebef8c7c253a04279ba7a367b2b4a870c3e2581add3e5824bcc9dd53bbaee2aedcbd58fa8ef76c7c11b3b6df977e036ce5cbfc1f7c974e70abf035ad72b8a5e0be09ae", + "ocertCounter": 77, + "poolId": "d4073ef01e18eed9bac3165a5268ae7229be38f5bc2360dc2830c603", + "poolIdx": 2, + "vrfSignKey": "0c2471a9c3208a3939aa9cc401d17371fd85567cf08e50944fceb560537b4b13e0c61af1967457770433454c2b27cd6b922427f8ae13148c8b09f53ee7a56710" + }, + { + "chain": "fcb4a51804f14f3f5b5ad841199b557aed0187280f7855736bdb153b0d202bb6", + "coldSignKey": "a34ec398be1915ed731aff6fb6f4318383920bc9ae1f4fa87ace771e54d32383", + "individualStake": { + "individualPoolStake": { "denominator": 16, "numerator": 1 }, + "individualPoolStakeVrf": "65833b6a5fcd19f118f260922a0685620bcdead5b40753557aa7ff30bc9ec796", + "individualTotalPoolStake": 625000000000000 + }, + "kesSignKey": "6c493eaf81a3cb0b38e53ec237d7c3f297a891d5d87da1f6cc3ddb027fd6062b90f84030c57c607f6e45e7486e490318c02797394ccac496080a95a11102eec85f172dc4077a26ab4fc58ef6de644079bcd76e7553b4468e3ec64a52c2bf5ccda05395e1cf6acb1d2b11d88202930f17e17e3233e55f2cc60fdccf05174901d534b7b56896934558db7bfe245774f639fa5cc1683b241cc8aaca6a16efb5c5abc655273b8dec2d0665a7473a84b905410e17a1f19a853d25b32f341e11e66e53f61b5bbbdce9419ff8b4a3438dc5f959cb3066161b4f51f848aca11fbaaa98afadd3ace098ed97baa0105a3949bffe6a7f511c564c674aca7019121763ac7184ced6f3eb73033175d25410cdd7a018c8e15da090dd1d8cc71f36408ad6f69797b70eb348856734bfc2e11c083d84a92f997cc1a7399b6dd6ea38e1c82a535e9eef7881f194390cc1174ab17736fb4d3d24f229d4276219c3aed5e7bfaf2faaaf64aa39875ef67c21415f076a39f22cb8b7607ff0c5e4d60dc393a7593bbfff567e3db58d6de8fe25f153d654184e24e8e3e71faffaca0fd480c83f96d6b666577be9a37ddc646152aadc8de77508ecc5583ab2c2420640c82878b90ddb528bc2c490b49bd76a543df7855949494093c385db0104f6f8711a163e2a9fae72841fb9eae2261808fb1436203b948a4a4b29be573a00fdea79962087ccc70e60fc368e1b72d191d1acf8021a4570bc66395994a7ee10b6e22cb38e99831a2c2c119a8a254c6b20bc0f7ce151585fcd2ba76ae8ffdc4744204b5bc354f12b00927718c357791e112a4c26a02831faae28508f708944423e2a1d0c5c9c7a471ed30225", + "ocertCounter": 76, + "poolId": "50484a702b93327308d85f51f1831940fdddcb751bf43bc3376c42b9", + "poolIdx": 1, + "vrfSignKey": "ddd17f518daebb08a25d00b3913eb00777978b473d42f0b637eae26a41fb9c8c349fa6de24709731a7f27d0e4f711d73018f285d2bf91fd0bcc67559c478a2e7" + } + ] + } +} diff --git a/examples/Cargo.lock b/examples/Cargo.lock index 0846b01e2..78197288a 100644 --- a/examples/Cargo.lock +++ b/examples/Cargo.lock @@ -56,12 +56,10 @@ dependencies = [ "iter-borrow", "num", "serde", - "serde_json", "slot-arithmetic", "thiserror 2.0.12", "tracing", "tracing-json", - "tracing-subscriber", ] [[package]] diff --git a/scripts/demo.sh b/scripts/demo.sh index 64f445ade..d5f12dd99 100755 --- a/scripts/demo.sh +++ b/scripts/demo.sh @@ -19,9 +19,17 @@ fi NETWORK=${3:-preprod} +LEDGER_DIR=${LEDGER_DIR:-./ledger.db} + +CHAIN_DIR=${CHAIN_DIR:-./chain.db} + echo -e " \033[1;32mTarget\033[00m epoch $TARGET_EPOCH" set -eo pipefail -AMARU_TRACE="amaru=info" cargo run -- --with-json-traces daemon --peer-address=$PEER_ADDRESS --network=$NETWORK | while read line; do +AMARU_TRACE="amaru=info" cargo run -- --with-json-traces daemon \ + --peer-address="${PEER_ADDRESS}" \ + --network="${NETWORK}" \ + --chain-dir="${CHAIN_DIR}" \ + --ledger-dir="${LEDGER_DIR}" | while read line; do EVENT=$(echo $line | jq -r '.fields.message' 2>/dev/null) SPAN=$(echo $line | jq -r '.span.name' 2>/dev/null) if [ "$EVENT" == "exit" ] && [ "$SPAN" == "epoch_transition" ]; then