diff --git a/Cargo.lock b/Cargo.lock index e375d903a3..3e1bea34cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -999,18 +999,19 @@ dependencies = [ [[package]] name = "async-tungstenite" -version = "0.20.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0388bb7a400072bbb41ceb75d65c3baefb2ea99672fa22e85278452cd9b58b" +checksum = "3609af4bbf701ddaf1f6bb4e6257dff4ff8932327d0e685d3f653724c258b1ac" dependencies = [ "futures-io", "futures-util", "log", "pin-project-lite", - "rustls-native-certs 0.6.3", + "rustls-native-certs 0.7.3", + "rustls-pki-types", "tokio", - "tokio-rustls 0.23.4", - "tungstenite 0.18.0", + "tokio-rustls 0.25.0", + "tungstenite 0.21.0", ] [[package]] @@ -2673,15 +2674,6 @@ dependencies = [ "serde", ] -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct 0.6.1", -] - [[package]] name = "ctor" version = "0.1.26" @@ -3874,10 +3866,11 @@ version = "0.1.0" dependencies = [ "async-stm", "async-trait", + "bytes", "futures", "im", "structopt", - "tendermint 0.31.1", + "tendermint", "tokio", "tower 0.4.13", "tower-abci", @@ -4267,7 +4260,7 @@ dependencies = [ "paste", "prometheus", "prometheus_exporter", - "prost 0.11.9", + "prost 0.13.5", "quickcheck", "quickcheck_macros", "rand_chacha 0.3.1", @@ -4275,9 +4268,9 @@ dependencies = [ "serde_json", "serde_with 2.3.3", "tempfile", - "tendermint 0.31.1", - "tendermint-config 0.33.2", - "tendermint-proto 0.31.1", + "tendermint", + "tendermint-config", + "tendermint-proto", "tendermint-rpc", "tokio", "tokio-util 0.7.16", @@ -4430,7 +4423,7 @@ dependencies = [ "regex", "serde", "serde_json", - "tendermint 0.31.1", + "tendermint", "tendermint-rpc", "thiserror 1.0.69", "tokio", @@ -4567,11 +4560,11 @@ dependencies = [ "fvm_shared", "hex", "lazy_static", - "prost 0.11.9", + "prost 0.13.5", "serde", "serde_json", - "tendermint 0.31.1", - "tendermint-proto 0.31.1", + "tendermint", + "tendermint-proto", "tendermint-rpc", "tokio", "tracing", @@ -4738,7 +4731,7 @@ dependencies = [ "serde", "serde_json", "serde_with 2.3.3", - "tendermint 0.31.1", + "tendermint", ] [[package]] @@ -4819,7 +4812,7 @@ dependencies = [ "snap", "strum 0.26.3", "tempfile", - "tendermint 0.31.1", + "tendermint", "tendermint-rpc", "thiserror 1.0.69", "tokio", @@ -4907,7 +4900,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "tempfile", - "tendermint 0.31.1", + "tendermint", "tendermint-rpc", "thiserror 1.0.69", "tokio", @@ -6714,43 +6707,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-proxy" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" -dependencies = [ - "bytes", - "futures", - "headers", - "http 0.2.12", - "hyper 0.14.32", - "hyper-rustls 0.22.1", - "rustls-native-certs 0.5.0", - "tokio", - "tokio-rustls 0.22.0", - "tower-service", - "webpki 0.21.4", -] - -[[package]] -name = "hyper-rustls" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" -dependencies = [ - "ct-logs", - "futures-util", - "hyper 0.14.32", - "log", - "rustls 0.19.1", - "rustls-native-certs 0.5.0", - "tokio", - "tokio-rustls 0.22.0", - "webpki 0.21.4", - "webpki-roots 0.21.1", -] - [[package]] name = "hyper-rustls" version = "0.24.2" @@ -7466,7 +7422,7 @@ dependencies = [ "serde_with 2.3.3", "strum 0.26.3", "tempfile", - "tendermint 0.31.1", + "tendermint", "tendermint-rpc", "thiserror 1.0.69", "tokio", @@ -8523,7 +8479,7 @@ dependencies = [ "libp2p", "multihash 0.18.1", "prometheus", - "prost 0.11.9", + "prost 0.13.5", "prost-build", "thiserror 1.0.69", "tracing", @@ -10363,9 +10319,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "peg" -version = "0.7.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +checksum = "9928cfca101b36ec5163e70049ee5368a8a1c3c6efc9ca9c5f9cc2f816152477" dependencies = [ "peg-macros", "peg-runtime", @@ -10373,9 +10329,9 @@ dependencies = [ [[package]] name = "peg-macros" -version = "0.7.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +checksum = "6298ab04c202fa5b5d52ba03269fb7b74550b150323038878fe6c372d8280f71" dependencies = [ "peg-runtime", "proc-macro2", @@ -10384,9 +10340,9 @@ dependencies = [ [[package]] name = "peg-runtime" -version = "0.7.0" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" +checksum = "132dca9b868d927b35b5dd728167b2dee150eb1ad686008fc71ccb298b776fca" [[package]] name = "pem" @@ -11183,12 +11139,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.9" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" dependencies = [ "bytes", - "prost-derive 0.11.9", + "prost-derive 0.13.5", ] [[package]] @@ -11226,15 +11182,15 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.108", ] [[package]] @@ -11249,11 +11205,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.11.9" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" dependencies = [ - "prost 0.11.9", + "prost 0.13.5", ] [[package]] @@ -11815,7 +11771,8 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.12", - "rustls-pemfile", + "rustls-native-certs 0.6.3", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -12209,39 +12166,28 @@ dependencies = [ [[package]] name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring 0.16.20", - "sct 0.6.1", - "webpki 0.21.4", -] - -[[package]] -name = "rustls" -version = "0.20.9" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring 0.16.20", - "sct 0.7.1", - "webpki 0.22.4", + "ring 0.17.14", + "rustls-webpki 0.101.7", + "sct", ] [[package]] name = "rustls" -version = "0.21.12" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", "ring 0.17.14", - "rustls-webpki 0.101.7", - "sct 0.7.1", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", ] [[package]] @@ -12261,24 +12207,25 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.5.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls 0.19.1", + "rustls-pemfile 1.0.4", "schannel", "security-framework 2.11.1", ] [[package]] name = "rustls-native-certs" -version = "0.6.3" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.2.0", + "rustls-pki-types", "schannel", "security-framework 2.11.1", ] @@ -12304,6 +12251,15 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "rustls-pki-types" version = "1.12.0" @@ -12525,16 +12481,6 @@ dependencies = [ "sha2 0.10.9", ] -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "sct" version = "0.7.1" @@ -13887,9 +13833,9 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.31.1" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b58bdb6c44a2621b8b6bd0585d5912ba32546317604130a42410bcc813ef16" +checksum = "505d9d6ffeb83b1de47c307c6e0d2dff56c6256989299010ad03cd80a8491e97" dependencies = [ "bytes", "digest 0.10.7", @@ -13900,8 +13846,8 @@ dependencies = [ "k256 0.13.4", "num-traits", "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", + "prost 0.13.5", + "prost-types 0.13.5", "ripemd", "serde", "serde_bytes", @@ -13911,98 +13857,35 @@ dependencies = [ "signature 2.2.0", "subtle", "subtle-encoding", - "tendermint-proto 0.31.1", - "time", - "zeroize", -] - -[[package]] -name = "tendermint" -version = "0.33.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c35fe4fd24a7715571814c22416dbc40ec0f2a6e3cce75d73e19699faecd246" -dependencies = [ - "bytes", - "digest 0.10.7", - "ed25519", - "ed25519-consensus", - "flex-error", - "futures", - "num-traits", - "once_cell", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.9", - "signature 2.2.0", - "subtle", - "subtle-encoding", - "tendermint-proto 0.33.2", + "tendermint-proto", "time", "zeroize", ] [[package]] name = "tendermint-config" -version = "0.31.1" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "088bac81db392e66eedb508c400ebb2096d1e21cc40d71e3739a9bbd6838809a" +checksum = "9de111ea653b2adaef627ac2452b463c77aa615c256eaaddf279ec5a1cf9775f" dependencies = [ "flex-error", "serde", "serde_json", - "tendermint 0.31.1", - "toml 0.5.11", - "url", -] - -[[package]] -name = "tendermint-config" -version = "0.33.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a213a026dfc1c68468160bee24bf128e26002170abc123678ecfbe5ff37f91d" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.33.2", - "toml 0.5.11", + "tendermint", + "toml 0.8.23", "url", ] [[package]] name = "tendermint-proto" -version = "0.31.1" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f15666993e193fa4d2b2479aa1e4f1bbe41283c820812df8dd618f41ca3f7a" +checksum = "8ed14abe3b0502a3afe21ca74ca5cdd6c7e8d326d982c26f98a394445eb31d6e" dependencies = [ "bytes", "flex-error", - "num-derive 0.3.3", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.33.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639e5adffd77220d238a800a72c74c98d7e869290a6e4494c10b6b4e8f702f02" -dependencies = [ - "bytes", - "flex-error", - "num-derive 0.3.3", - "num-traits", - "prost 0.11.9", - "prost-types 0.11.9", + "prost 0.13.5", + "prost-types 0.13.5", "serde", "serde_bytes", "subtle-encoding", @@ -14011,9 +13894,9 @@ dependencies = [ [[package]] name = "tendermint-rpc" -version = "0.31.1" +version = "0.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120ccb296a0ec4485ddb78eb842e481d7a859d5659e0f1881456f8c127d5e950" +checksum = "02f96a2b8a0d3d0b59e4024b1a6bdc1589efc6af4709d08a480a20cc4ba90f63" dependencies = [ "async-trait", "async-tungstenite", @@ -14021,26 +13904,25 @@ dependencies = [ "flex-error", "futures", "getrandom 0.2.16", - "http 0.2.12", - "hyper 0.14.32", - "hyper-proxy", - "hyper-rustls 0.22.1", "peg", "pin-project", + "rand 0.8.5", + "reqwest 0.11.27", "semver 1.0.27", "serde", "serde_bytes", "serde_json", "subtle", "subtle-encoding", - "tendermint 0.31.1", - "tendermint-config 0.31.1", + "tendermint", + "tendermint-config", + "tendermint-proto", "thiserror 1.0.69", "time", "tokio", "tracing", "url", - "uuid 0.8.2", + "uuid 1.18.1", "walkdir", ] @@ -14256,33 +14138,22 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls 0.19.1", - "tokio", - "webpki 0.21.4", -] - -[[package]] -name = "tokio-rustls" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.20.9", + "rustls 0.21.12", "tokio", - "webpki 0.22.4", ] [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.21.12", + "rustls 0.22.4", + "rustls-pki-types", "tokio", ] @@ -14577,16 +14448,16 @@ dependencies = [ [[package]] name = "tower-abci" -version = "0.7.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaddfcab2a1c77ba634491e710b04653c4b53ae1a541c56a02c5c3fc9facc80c" +checksum = "64c31da2537c5f13b67d3f6aa9e5552a1a81a681debbcb3ce9ac6a34876cbcb2" dependencies = [ "bytes", "futures", "pin-project", - "prost 0.11.9", - "tendermint 0.31.1", - "tendermint-proto 0.31.1", + "prost 0.13.5", + "tendermint", + "tendermint-proto", "tokio", "tokio-stream", "tokio-util 0.6.10", @@ -14837,12 +14708,10 @@ dependencies = [ "log", "native-tls", "rand 0.8.5", - "rustls 0.20.9", "sha1", "thiserror 1.0.69", "url", "utf-8", - "webpki 0.22.4", ] [[package]] @@ -14878,6 +14747,8 @@ dependencies = [ "httparse", "log", "rand 0.8.5", + "rustls 0.22.4", + "rustls-pki-types", "sha1", "thiserror 1.0.69", "url", @@ -15543,26 +15414,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - -[[package]] -name = "webpki" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" -dependencies = [ - "ring 0.17.14", - "untrusted 0.9.0", -] - [[package]] name = "webpki-root-certs" version = "0.26.11" @@ -15581,15 +15432,6 @@ dependencies = [ "rustls-pki-types", ] -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki 0.21.4", -] - [[package]] name = "webpki-roots" version = "0.25.4" diff --git a/Cargo.toml b/Cargo.toml index 63be6a3da6..4f3941858d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -183,7 +183,7 @@ paste = "1" pin-project = "1.1.2" prometheus = { version = "0.13", features = ["process"] } prometheus_exporter = "0.8" -prost = { version = "0.11" } +prost = { version = "0.13" } quickcheck = "1" quickcheck_async = "0.1" quickcheck_macros = "1" @@ -294,17 +294,17 @@ netwatch = { path = "patches/netwatch" } frc42_dispatch = { path = "./ext/frc42_dispatch" } -# Using the same tendermint-rs dependency as tower-abci. From both we are interested in v037 modules. -tower-abci = { version = "0.7" } +# Using the same tendermint-rs dependency as tower-abci. +tower-abci = { version = "0.16" } tower = { version = "0.4" } -tendermint = { version = "0.31", features = ["secp256k1"] } -tendermint-config = "0.33.0" -tendermint-rpc = { version = "0.31", features = [ +tendermint = { version = "0.38.1", features = ["secp256k1"] } +tendermint-config = "0.38.1" +tendermint-rpc = { version = "0.38.1", features = [ "secp256k1", "http-client", "websocket-client", ] } -tendermint-proto = { version = "0.31" } +tendermint-proto = { version = "0.38.1" } rust-f3 = { git = "https://github.com/ChainSafe/rust-f3.git", branch = "main" } filecoin-proofs = { git = "https://github.com/consensus-shipyard/ipc-filecoin-proofs.git", branch = "main" } diff --git a/fendermint/abci/Cargo.toml b/fendermint/abci/Cargo.toml index e3388d04b3..d62a94e8e9 100644 --- a/fendermint/abci/Cargo.toml +++ b/fendermint/abci/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true [dependencies] async-trait = { workspace = true } +bytes = { workspace = true } futures = { workspace = true } tower = "0.4" tracing = { workspace = true } diff --git a/fendermint/abci/examples/kvstore.rs b/fendermint/abci/examples/kvstore.rs index 7b7d255a69..b7058e7dd9 100644 --- a/fendermint/abci/examples/kvstore.rs +++ b/fendermint/abci/examples/kvstore.rs @@ -10,7 +10,8 @@ use fendermint_abci::{ use structopt::StructOpt; use tendermint::abci::{request, response, Event, EventAttributeIndexExt}; use tower::ServiceBuilder; -use tower_abci::{split, v037::Server}; +use tower_abci::v038::split; +use tower_abci::v038::Server; use tracing::{info, Level}; // For the sake of example, sho the relationship between buffering, concurrency and block size. @@ -95,33 +96,56 @@ impl Application for KVStore { } } - async fn deliver_tx(&self, request: request::DeliverTx) -> Result { - let tx = String::from_utf8(request.tx.to_vec()).unwrap(); - let (key, value) = match tx.split('=').collect::>() { - k if k.len() == 1 => (k[0], k[0]), - kv => (kv[0], kv[1]), - }; - - atomically(|| { - self.store.update(|mut store| { - store.insert(key.into(), value.into()); - store + async fn finalize_block( + &self, + request: request::FinalizeBlock, + ) -> Result { + let mut tx_results = Vec::with_capacity(request.txs.len()); + + for tx in request.txs { + let tx = String::from_utf8(tx.to_vec()).unwrap(); + let (key, value) = match tx.split('=').collect::>() { + k if k.len() == 1 => (k[0], k[0]), + kv => (kv[0], kv[1]), + }; + + atomically(|| { + self.store.update(|mut store| { + store.insert(key.into(), value.into()); + store + }) }) - }) - .await; + .await; - info!(?key, ?value, "update"); + info!(?key, ?value, "update"); - Ok(response::DeliverTx { - events: vec![Event::new( + let events = vec![Event::new( "app", vec![ ("key", key).index(), ("index_key", "index is working").index(), ("noindex_key", "index is working").no_index(), ], - )], - ..Default::default() + )]; + + tx_results.push(tendermint::abci::types::ExecTxResult { + code: tendermint::abci::Code::Ok, + data: Default::default(), + log: Default::default(), + info: Default::default(), + gas_wanted: 0, + gas_used: 0, + events, + codespace: Default::default(), + }); + } + + Ok(response::FinalizeBlock { + events: Vec::new(), + tx_results, + validator_updates: Vec::new(), + consensus_param_updates: None, + app_hash: Default::default(), }) } @@ -204,7 +228,7 @@ async fn main() { // Run the ABCI server. server - .listen(format!("{}:{}", opt.host, opt.port)) + .listen_tcp(format!("{}:{}", opt.host, opt.port)) .await .unwrap(); } diff --git a/fendermint/abci/src/application.rs b/fendermint/abci/src/application.rs index 58d3b33aee..8598842ec1 100644 --- a/fendermint/abci/src/application.rs +++ b/fendermint/abci/src/application.rs @@ -7,7 +7,7 @@ use std::{ pin::Pin, task::{Context, Poll}, }; -use tendermint::abci::{request, response, Request, Response}; +use tendermint::v0_38::abci::{request, response, Request, Response}; use tower::Service; use tower_abci::BoxError; @@ -81,19 +81,33 @@ pub trait Application { Ok(response::ProcessProposal::Accept) } - /// Signals the beginning of a new block, prior to any `DeliverTx` calls. - async fn begin_block(&self, request: request::BeginBlock) -> AbciResult { - Ok(Default::default()) + /// Opportunity for the application to add arbitrary extension data to precommit votes. + async fn extend_vote(&self, _request: request::ExtendVote) -> AbciResult { + Ok(response::ExtendVote { + vote_extension: bytes::Bytes::new(), + }) } - /// Apply a transaction to the application's state. - async fn deliver_tx(&self, request: request::DeliverTx) -> AbciResult { - Ok(Default::default()) + /// Verify vote extensions from peer validators. + async fn verify_vote_extension( + &self, + _request: request::VerifyVoteExtension, + ) -> AbciResult { + Ok(response::VerifyVoteExtension::Accept) } - /// Signals the end of a block. - async fn end_block(&self, request: request::EndBlock) -> AbciResult { - Ok(Default::default()) + /// Execute and finalize an entire block. + async fn finalize_block( + &self, + _request: request::FinalizeBlock, + ) -> AbciResult { + Ok(response::FinalizeBlock { + events: Vec::new(), + tx_results: Vec::new(), + validator_updates: Vec::new(), + consensus_param_updates: None, + app_hash: tendermint::AppHash::default(), + }) } /// Commit the current state at the current height. @@ -174,11 +188,15 @@ where Request::ProcessProposal(r) => { Response::ProcessProposal(log_error(app.process_proposal(r).await)?) } - Request::BeginBlock(r) => { - Response::BeginBlock(log_error(app.begin_block(r).await)?) + Request::ExtendVote(r) => { + Response::ExtendVote(log_error(app.extend_vote(r).await)?) + } + Request::VerifyVoteExtension(r) => { + Response::VerifyVoteExtension(log_error(app.verify_vote_extension(r).await)?) + } + Request::FinalizeBlock(r) => { + Response::FinalizeBlock(log_error(app.finalize_block(r).await)?) } - Request::DeliverTx(r) => Response::DeliverTx(log_error(app.deliver_tx(r).await)?), - Request::EndBlock(r) => Response::EndBlock(log_error(app.end_block(r).await)?), Request::Commit => Response::Commit(log_error(app.commit().await)?), Request::ListSnapshots => { Response::ListSnapshots(log_error(app.list_snapshots().await)?) @@ -192,7 +210,8 @@ where Request::ApplySnapshotChunk(r) => { Response::ApplySnapshotChunk(log_error(app.apply_snapshot_chunk(r).await)?) } - Request::Flush => panic!("Flush should be handled by the Server!"), + // Some clients still send explicit Flush requests; never panic on protocol input. + Request::Flush => Response::Flush, }; Ok(res) }; diff --git a/fendermint/actors-custom-car/build.rs b/fendermint/actors-custom-car/build.rs index 11ef2b5e88..44c83b8e65 100644 --- a/fendermint/actors-custom-car/build.rs +++ b/fendermint/actors-custom-car/build.rs @@ -152,9 +152,10 @@ fn create_metadata_command(path: impl Into) -> MetadataCommand { metadata_command } -/// Find the `Cargo.lock` relative to the `OUT_DIR` environment variable. +/// Find the `Cargo.lock` by walking parent directories from known anchors. /// -/// If the `Cargo.lock` cannot be found, we emit a warning and return `None`. +/// We first try `OUT_DIR`, then fall back to `CARGO_MANIFEST_DIR`. +/// The fallback is needed when `CARGO_TARGET_DIR` points outside the workspace. fn find_cargo_lock(out_dir: &Path) -> Option { fn find_impl(mut path: PathBuf) -> Option { loop { @@ -172,6 +173,12 @@ fn find_cargo_lock(out_dir: &Path) -> Option { return Some(path); } + if let Some(manifest_dir) = std::env::var_os("CARGO_MANIFEST_DIR") { + if let Some(path) = find_impl(PathBuf::from(manifest_dir)) { + return Some(path); + } + } + None } diff --git a/fendermint/app/src/app.rs b/fendermint/app/src/app.rs index 4bcfccae8a..694672526d 100644 --- a/fendermint/app/src/app.rs +++ b/fendermint/app/src/app.rs @@ -1,6 +1,5 @@ // Copyright 2022-2024 Protocol Labs // SPDX-License-Identifier: Apache-2.0, MIT -use std::future::Future; use std::sync::Arc; use crate::observe::{ @@ -407,34 +406,41 @@ where Ok(Some(updated)) } + /// Build the post-execution state projection used by both `FinalizeBlock` and `Commit`. + fn project_post_exec_state( + &self, + block_height: ChainEpoch, + timestamp: Timestamp, + state_root: Cid, + params: FvmUpdatableParams, + state_commitments: Option, + ) -> Result { + let mut state = self.committed_state()?; + state.app_state.block_height = block_height.try_into()?; + state.app_state.state_params.timestamp = timestamp; + state.app_state.state_params.state_root = state_root; + state.app_state.state_params.app_version = params.app_version; + state.app_state.state_params.base_fee = params.base_fee; + state.app_state.state_params.circ_supply = params.circ_supply; + state.app_state.state_params.power_scale = params.power_scale; + state.state_commitments = state_commitments; + Ok(state) + } + /// Put the execution state during block execution. Has to be empty. - async fn put_exec_state(&self, state: FvmExecState) { + async fn put_exec_state(&self, state: FvmExecState) -> Result<()> { let mut guard = self.exec_state.lock().await; - assert!(guard.is_none(), "exec state not empty"); + if guard.is_some() { + return Err(anyhow!("exec state not empty")); + } *guard = Some(state); + Ok(()) } /// Take the execution state during block execution. Has to be non-empty. - async fn take_exec_state(&self) -> FvmExecState { + async fn take_exec_state(&self) -> Result> { let mut guard = self.exec_state.lock().await; - guard.take().expect("exec state empty") - } - - /// Update the execution state using the provided closure. - /// - /// Note: Deals with panics in the user provided closure as well. - async fn modify_exec_state(&self, generator: G) -> Result - where - G: for<'s> FnOnce(&'s mut FvmExecState) -> F, - F: Future>, - T: 'static, - { - let mut guard = self.exec_state.lock().await; - let maybe_state = guard.as_mut(); - let state = maybe_state.expect("exec state empty"); - let ret = generator(state).await?; - - Ok(ret) + guard.take().ok_or_else(|| anyhow!("exec state empty")) } /// Get a read-only view from the current FVM execution state, optionally passing a new BlockContext. @@ -511,28 +517,6 @@ where } } - /// Replaces the current validators cache with a new one. - async fn refresh_validators_cache(&self) -> Result<()> { - // TODO: This should be read only state, but we can't use the read-only view here - // because it hasn't been committed to state store yet. - let mut cache = self.validators_cache.lock().await; - self.modify_exec_state(|s| { - // we need to leave this outside the closure - // otherwise `s`' lifetime would be captured by the - // closure causing unresolvable liftetime conflicts - // this is fine since we execute the future directly - // after calling the generator closure. - let x = ValidatorCache::new_from_state(s); - async { - *cache = Some(x?); - Ok(()) - } - }) - .await?; - - Ok(()) - } - /// Retrieves a validator from the cache, initializing it if necessary. async fn get_validator_from_cache(&self, id: &tendermint::account::Id) -> Result { let mut cache = self.validators_cache.lock().await; @@ -856,9 +840,12 @@ where } } - /// Signals the beginning of a new block, prior to any `DeliverTx` calls. - async fn begin_block(&self, request: request::BeginBlock) -> AbciResult { - let block_height = request.header.height.into(); + /// Execute and finalize an entire block (ABCI 2.0). + async fn finalize_block( + &self, + request: request::FinalizeBlock, + ) -> AbciResult { + let block_height = request.height.into(); let block_hash = match request.hash { tendermint::Hash::Sha256(h) => h, tendermint::Hash::None => return Err(anyhow!("empty block hash").into()), @@ -875,162 +862,132 @@ where let db = self.state_store_clone(); let state = self.committed_state()?; let mut state_params = state.app_state.state_params.clone(); - - tracing::debug!( - height = block_height, - timestamp = request.header.time.unix_timestamp(), - app_hash = request.header.app_hash.to_string(), - //app_state_hash = to_app_hash(&state_params).to_string(), // should be the same as `app_hash` - "begin block" - ); - - state_params.timestamp = to_timestamp(request.header.time); + state_params.timestamp = to_timestamp(request.time); let validator = self - .get_validator_from_cache(&request.header.proposer_address) + .get_validator_from_cache(&request.proposer_address) .await?; - let mut state = + let mut exec_state = FvmExecState::new(db, self.multi_engine.as_ref(), block_height, state_params) .context("error creating new state")? .with_block_hash(block_hash) .with_block_producer(validator); - tracing::debug!("initialized new exec state"); - - let response = self + let begin_response = self .messages_interpreter - .begin_block(&mut state) + .begin_block(&mut exec_state) .await .context("failed to begin block")?; + let mut events = to_begin_block(begin_response.applied_cron_message).events; - self.put_exec_state(state).await; - - Ok(to_begin_block(response.applied_cron_message)) - } - - /// Apply a transaction to the application's state. - async fn deliver_tx(&self, request: request::DeliverTx) -> AbciResult { - let msg = request.tx.to_vec(); - - let (result, block_hash) = { - let mut guard = self.exec_state.lock().await; - let mut state = guard.take().expect("exec state empty"); - + let mut tx_results = Vec::with_capacity(request.txs.len()); + for tx in request.txs { + let msg = tx.to_vec(); let result = self .messages_interpreter - .apply_message(&mut state, msg) + .apply_message(&mut exec_state, msg) .await; - let block_hash = state.block_hash(); - - *guard = Some(state); - (result, block_hash) - }; - - let response = match result { - Ok(ApplyMessageResponse { - applied_message, - domain_hash, - }) => to_deliver_tx(applied_message, domain_hash, block_hash), - Err(ApplyMessageError::InvalidSignature(err)) => { - invalid_deliver_tx(AppError::InvalidSignature, err.to_string()) - } - Err(ApplyMessageError::InvalidMessage(s)) => { - invalid_deliver_tx(AppError::InvalidEncoding, s) - } - Err(ApplyMessageError::Other(e)) => Err(e).context("failed to apply message")?, - }; + let deliver_tx = match result { + Ok(ApplyMessageResponse { + applied_message, + domain_hash, + }) => to_deliver_tx(applied_message, domain_hash, exec_state.block_hash()), + Err(ApplyMessageError::InvalidSignature(err)) => { + invalid_deliver_tx(AppError::InvalidSignature, err.to_string()) + } + Err(ApplyMessageError::InvalidMessage(s)) => { + invalid_deliver_tx(AppError::InvalidEncoding, s) + } + Err(ApplyMessageError::Other(e)) => Err(e).context("failed to apply message")?, + }; - if response.code != 0.into() { - tracing::info!( - "deliver_tx failed: {:?} - {:?}", - response.code, - response.info - ); + tx_results.push(tendermint::abci::types::ExecTxResult { + code: deliver_tx.code, + data: deliver_tx.data, + log: deliver_tx.log, + info: deliver_tx.info, + gas_wanted: deliver_tx.gas_wanted, + gas_used: deliver_tx.gas_used, + events: deliver_tx.events, + codespace: deliver_tx.codespace, + }); } - Ok(response) - } - - /// Signals the end of a block. - async fn end_block(&self, request: request::EndBlock) -> AbciResult { - tracing::debug!(height = request.height, "end block"); - - let response = { - let mut guard = self.exec_state.lock().await; - let mut state = guard.take().expect("exec state empty"); - - let result = self.messages_interpreter.end_block(&mut state).await; - *guard = Some(state); - - result? - }; - let EndBlockResponse { power_updates, gas_market, light_client_commitments, end_block_events, - } = response; + } = self.messages_interpreter.end_block(&mut exec_state).await?; let mut c = self.light_client_commitments.lock().await; - *c = light_client_commitments; + *c = light_client_commitments.clone(); - // Convert the incoming power updates to Tendermint validator updates. let validator_updates = to_validator_updates(power_updates.0).context("failed to convert validator updates")?; - - // Replace the validator cache if the validator set has changed. if !validator_updates.is_empty() { - self.refresh_validators_cache().await?; + // Refresh the cache from the in-flight execution state, which isn't + // stored in `self.exec_state` until FinalizeBlock completes. + let mut cache = self.validators_cache.lock().await; + *cache = Some( + ValidatorCache::new_from_state(&mut exec_state) + .context("failed to refresh validator cache")?, + ); } - // Maybe update the app state with the new block gas limit. let consensus_param_updates = self .maybe_update_app_state(&gas_market) .context("failed to update block gas limit")?; - let ret = response::EndBlock { - validator_updates, - consensus_param_updates, - events: end_block_events + events.extend( + end_block_events .into_iter() - .flat_map(|(stamped, emitters)| to_events("event", stamped, emitters)) - .collect::>(), - }; + .flat_map(|(stamped, emitters)| to_events("event", stamped, emitters)), + ); + + // In ABCI 2.0 the app hash is returned from FinalizeBlock, so compute the same + // post-state hash that commit() will persist. + let state_root = exec_state + .flush_state_root() + .context("failed to flush finalized state root")?; + let projected_state = self.project_post_exec_state( + exec_state.block_height(), + exec_state.timestamp(), + state_root, + exec_state.updatable_params(), + light_client_commitments, + )?; + let app_hash = projected_state.app_hash(); + + self.put_exec_state(exec_state) + .await + .context("failed to store execution state")?; - Ok(ret) + Ok(response::FinalizeBlock { + events, + tx_results, + validator_updates, + consensus_param_updates, + app_hash, + }) } /// Commit the current state at the current height. async fn commit(&self) -> AbciResult { - let exec_state = self.take_exec_state().await; - - // Commit the execution state to the datastore. - let mut state = self.committed_state()?; - state.app_state.block_height = exec_state.block_height().try_into()?; - state.app_state.state_params.timestamp = exec_state.timestamp(); - - let ( - state_root, - FvmUpdatableParams { - app_version, - base_fee, - circ_supply, - power_scale, - }, - _, - ) = exec_state.commit().context("failed to commit FVM")?; + let exec_state = self + .take_exec_state() + .await + .context("failed to load execution state")?; - state.app_state.state_params.state_root = state_root; - state.app_state.state_params.app_version = app_version; - state.app_state.state_params.base_fee = base_fee; - state.app_state.state_params.circ_supply = circ_supply; - state.app_state.state_params.power_scale = power_scale; + let block_height = exec_state.block_height(); + let timestamp = exec_state.timestamp(); + let (state_root, params, _) = exec_state.commit().context("failed to commit FVM")?; let mut c = self.light_client_commitments.lock().await; // because of the take, no need to *c = None - state.state_commitments = c.take(); + let state = + self.project_post_exec_state(block_height, timestamp, state_root, params, c.take())?; let app_hash = state.app_hash(); let block_height = state.app_state.block_height; @@ -1044,7 +1001,7 @@ where tracing::debug!( block_height, - state_root = state_root.to_string(), + state_root = state.app_state.state_params.state_root.to_string(), app_hash = app_hash.to_string(), timestamp = state.app_state.state_params.timestamp.0, "commit state" diff --git a/fendermint/app/src/cmd/genesis.rs b/fendermint/app/src/cmd/genesis.rs index 34ddaf4d88..303322fc1b 100644 --- a/fendermint/app/src/cmd/genesis.rs +++ b/fendermint/app/src/cmd/genesis.rs @@ -275,6 +275,7 @@ pub fn into_tendermint( pub_key_types: vec![tendermint::public_key::Algorithm::Secp256k1], }, version: Some(tendermint::consensus::params::VersionParams { app: 0 }), + abci: tendermint::consensus::params::AbciParams::default(), }, // Validators will be returnd from `init_chain`. validators: Vec::new(), diff --git a/fendermint/app/src/service/node.rs b/fendermint/app/src/service/node.rs index 7550c3fc0b..a9c2848ae3 100644 --- a/fendermint/app/src/service/node.rs +++ b/fendermint/app/src/service/node.rs @@ -189,11 +189,11 @@ pub async fn run( // Split it into components. let (consensus, mempool, snapshot, info) = - tower_abci::split::service(service, settings.abci.bound); + tower_abci::v038::split::service(service, settings.abci.bound); // Hand those components to the ABCI server. This is where tower layers could be added. // TODO: Check out the examples about load shedding in `info` requests. - let server = tower_abci::v037::Server::builder() + let server = tower_abci::v038::Server::builder() .consensus( // Limiting the concurrency to 1 here because the `AplicationService::poll_ready` always // reports `Ready`, because it doesn't know which request it's going to get. @@ -217,7 +217,7 @@ pub async fn run( // Run the ABCI server. if let Some(token) = cancel_token { select! { - res = server.listen(settings.abci.listen.to_string()) => { + res = server.listen_tcp(settings.abci.listen.to_string()) => { res.map_err(|e| anyhow!("error listening: {e}"))? } _ = token.cancelled() => { @@ -226,7 +226,7 @@ pub async fn run( } } else { server - .listen(settings.abci.listen.to_string()) + .listen_tcp(settings.abci.listen.to_string()) .await .map_err(|e| anyhow!("error listening: {e}"))? } diff --git a/fendermint/app/src/tmconv.rs b/fendermint/app/src/tmconv.rs index c6b732ab81..3ac7e7eb93 100644 --- a/fendermint/app/src/tmconv.rs +++ b/fendermint/app/src/tmconv.rs @@ -15,7 +15,7 @@ use fvm_shared::{address::Address, error::ExitCode, event::StampedEvent, ActorID use prost::Message; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, num::NonZeroU32}; -use tendermint::abci::{response, Code, Event, EventAttribute}; +use tendermint::abci::{response, Code, Event, EventAttributeIndexExt}; #[derive(Serialize, Deserialize, Debug, Clone)] struct SnapshotMetadata { @@ -87,11 +87,7 @@ pub fn to_deliver_tx( if let Some(h) = block_hash { events.push(Event::new( "block", - vec![EventAttribute { - key: "hash".to_string(), - value: hex::encode(h), - index: true, - }], + vec![("hash".to_string(), hex::encode(h)).index()], )); } @@ -178,27 +174,19 @@ pub fn to_events( .map(|se| { let mut attrs = Vec::new(); - attrs.push(EventAttribute { - key: "emitter.id".to_string(), - value: se.emitter.to_string(), - index: true, - }); + attrs.push(("emitter.id".to_string(), se.emitter.to_string()).index()); // This is emitted because some clients might want to subscribe to events // based on the deterministic Ethereum address even before a contract is created. if let Some(deleg_addr) = emitters.get(&se.emitter) { - attrs.push(EventAttribute { - key: "emitter.deleg".to_string(), - value: deleg_addr.to_string(), - index: true, - }); + attrs.push(("emitter.deleg".to_string(), deleg_addr.to_string()).index()); } for e in se.event.entries { - attrs.push(EventAttribute { - key: e.key, - value: hex::encode(e.value), - index: !e.flags.is_empty(), + attrs.push(if !e.flags.is_empty() { + (e.key, hex::encode(e.value)).index() + } else { + (e.key, hex::encode(e.value)).no_index() }); } @@ -212,23 +200,12 @@ pub fn to_domain_hash_event(domain_hash: &DomainHash) -> Event { let (k, v) = match domain_hash { DomainHash::Eth(h) => ("eth", hex::encode(h)), }; - Event::new( - k, - vec![EventAttribute { - key: "hash".to_string(), - value: v, - index: true, - }], - ) + Event::new(k, vec![("hash".to_string(), v).index()]) } /// Event about the message itself. pub fn to_message_event(from: Address, to: Address) -> Event { - let attr = |k: &str, v: Address| EventAttribute { - key: k.to_string(), - value: v.to_string(), - index: true, - }; + let attr = |k: &str, v: Address| (k.to_string(), v.to_string()).index(); Event::new( "message".to_string(), vec![attr("from", from), attr("to", to)], @@ -265,7 +242,7 @@ pub fn to_query(ret: QueryResponse, block_height: BlockHeight) -> anyhow::Result // This is so there is a single representation of a call result, instead // of a normal delivery being one way and a query exposing `ApplyResponse`. let dtx = to_deliver_tx(*ret, None, None); - let dtx = tendermint_proto::abci::ResponseDeliverTx::from(dtx); + let dtx = tendermint_proto::v0_37::abci::ResponseDeliverTx::from(dtx); let mut buf = bytes::BytesMut::new(); dtx.encode(&mut buf)?; let bz = buf.to_vec(); diff --git a/fendermint/eth/api/src/conv/from_tm.rs b/fendermint/eth/api/src/conv/from_tm.rs index f68e455de2..9841686a8c 100644 --- a/fendermint/eth/api/src/conv/from_tm.rs +++ b/fendermint/eth/api/src/conv/from_tm.rs @@ -86,10 +86,9 @@ fn block_zero() -> tendermint::Block { tendermint::Block::new( header, Vec::new(), - tendermint::evidence::Data::default(), + tendermint::evidence::List::default(), Some(commit), ) - .unwrap() } pub fn is_block_zero(block: &tendermint::Block) -> bool { @@ -285,7 +284,8 @@ pub async fn to_eth_receipt( let contract_address = if result.tx_result.code.is_err() { None } else { - maybe_contract_address(&result.tx_result).map(|ca| et::H160::from_slice(&ca.0)) + maybe_contract_address_from_exec_tx_result(&result.tx_result) + .map(|ca| et::H160::from_slice(&ca.0)) }; let receipt = et::TransactionReceipt { @@ -413,8 +413,10 @@ pub fn to_eth_block_zero(block: tendermint::Block) -> anyhow::Result().ok()); + .find(|a| attr_key(a) == Some("emitter.deleg")) + .and_then(|a| attr_value(a)) + .and_then(|v| v.parse::
().ok()); let actor_id = event .attributes .iter() - .find(|a| a.key == "emitter.id") - .and_then(|a| a.value.parse::().ok()) + .find(|a| attr_key(a) == Some("emitter.id")) + .and_then(|a| attr_value(a)) + .and_then(|v| v.parse::().ok()) .ok_or_else(|| anyhow!("cannot find the 'emitter.id' key"))?; let address = addr @@ -489,19 +493,21 @@ fn to_topics_and_data(attrs: &Vec) -> anyhow::Result<(Vec { let bz = decode_value()?; if bz.len() != 32 { return Err(anyhow!("unexpected topic value: {attr:?}")); } let h = et::H256::from_slice(&bz); - let i = attr.key[1..].parse::().unwrap().saturating_sub(1); + let i = key[1..].parse::().unwrap().saturating_sub(1); while topics.len() <= i { topics.push(et::H256::default()) } @@ -535,8 +541,9 @@ pub fn find_hash_event(kind: &str, events: &[abci::Event]) -> Option { events .iter() .find(|e| e.kind == kind) - .and_then(|e| e.attributes.iter().find(|a| a.key == "hash")) - .and_then(|a| hex::decode(&a.value).ok()) + .and_then(|e| e.attributes.iter().find(|a| attr_key(a) == Some("hash"))) + .and_then(|a| attr_value(a)) + .and_then(|v| hex::decode(v).ok()) .filter(|bz| bz.len() == 32) .map(|bz| et::H256::from_slice(&bz)) } @@ -559,13 +566,15 @@ pub fn collect_emitters(events: &[abci::Event]) -> HashSet
{ event .attributes .iter() - .find(|a| a.key == "emitter.deleg") - .and_then(|a| a.value.parse::
().ok()), + .find(|a| attr_key(a) == Some("emitter.deleg")) + .and_then(|a| attr_value(a)) + .and_then(|v| v.parse::
().ok()), event .attributes .iter() - .find(|a| a.key == "emitter.id") - .and_then(|a| a.value.parse::().ok()) + .find(|a| attr_key(a) == Some("emitter.id")) + .and_then(|a| attr_value(a)) + .and_then(|v| v.parse::().ok()) .map(Address::new_id), ] .into_iter() @@ -577,6 +586,30 @@ pub fn collect_emitters(events: &[abci::Event]) -> HashSet
{ emitters } +fn attr_key(attr: &EventAttribute) -> Option<&str> { + attr.key_str().ok() +} + +fn attr_value(attr: &EventAttribute) -> Option<&str> { + attr.value_str().ok() +} + +fn maybe_contract_address_from_exec_tx_result( + tx_result: &tendermint::abci::types::ExecTxResult, +) -> Option { + let deliver_tx = DeliverTx { + code: tx_result.code, + data: tx_result.data.clone(), + log: tx_result.log.clone(), + info: tx_result.info.clone(), + gas_wanted: tx_result.gas_wanted, + gas_used: tx_result.gas_used, + events: tx_result.events.clone(), + codespace: tx_result.codespace.clone(), + }; + maybe_contract_address(&deliver_tx) +} + #[cfg(test)] mod tests { use crate::conv::from_tm::is_block_zero; diff --git a/fendermint/eth/api/src/filters.rs b/fendermint/eth/api/src/filters.rs index d4934c1f4c..61b2d9fc90 100644 --- a/fendermint/eth/api/src/filters.rs +++ b/fendermint/eth/api/src/filters.rs @@ -246,7 +246,7 @@ where block: Some(block), .. }, ) => { - let b: B = to_block(block).await?; + let b: B = to_block(*block).await?; blocks.push(b); } ( diff --git a/fendermint/rpc/examples/transfer.rs b/fendermint/rpc/examples/transfer.rs index 3c4e9ca206..03feaf9e34 100644 --- a/fendermint/rpc/examples/transfer.rs +++ b/fendermint/rpc/examples/transfer.rs @@ -116,7 +116,7 @@ async fn main() { .expect("transfer failed"); assert!(res.response.check_tx.code.is_ok(), "check is ok"); - assert!(res.response.deliver_tx.code.is_ok(), "deliver is ok"); + assert!(res.response.tx_result.code.is_ok(), "deliver is ok"); assert!(res.return_data.is_some()); } diff --git a/fendermint/rpc/src/client.rs b/fendermint/rpc/src/client.rs index cca674c837..c85d57599a 100644 --- a/fendermint/rpc/src/client.rs +++ b/fendermint/rpc/src/client.rs @@ -245,12 +245,22 @@ where .broadcast_tx_commit(data) .await .context("broadcast_tx_commit failed")?; + let deliver_tx = tendermint::abci::response::DeliverTx { + code: response.tx_result.code, + data: response.tx_result.data.clone(), + log: response.tx_result.log.clone(), + info: response.tx_result.info.clone(), + gas_wanted: response.tx_result.gas_wanted, + gas_used: response.tx_result.gas_used, + events: response.tx_result.events.clone(), + codespace: response.tx_result.codespace.clone(), + }; // We have a fully `DeliverTx` with default fields even if `CheckTx` indicates failure. - let return_data = if response.check_tx.code.is_err() || response.deliver_tx.code.is_err() { + let return_data = if response.check_tx.code.is_err() || deliver_tx.code.is_err() { None } else { let return_data = - f(&response.deliver_tx).context("error decoding data from deliver_tx in commit")?; + f(&deliver_tx).context("error decoding data from tx_result in commit")?; Some(return_data) }; let response = CommitResponse { diff --git a/fendermint/rpc/src/query.rs b/fendermint/rpc/src/query.rs index a958eeb4da..ad143a1b79 100644 --- a/fendermint/rpc/src/query.rs +++ b/fendermint/rpc/src/query.rs @@ -233,7 +233,7 @@ fn parse_deliver_tx(res: AbciQuery) -> anyhow::Result { let bz: Vec = fvm_ipld_encoding::from_slice(&res.value).context("failed to decode IPLD as bytes")?; - let deliver_tx = tendermint_proto::abci::ResponseDeliverTx::decode(bz.as_ref()) + let deliver_tx = tendermint_proto::v0_37::abci::ResponseDeliverTx::decode(bz.as_ref()) .context("failed to deserialize ResponseDeliverTx from proto bytes")?; let mut deliver_tx = tendermint::abci::response::DeliverTx::try_from(deliver_tx) diff --git a/fendermint/testing/materializer/src/docker/mod.rs b/fendermint/testing/materializer/src/docker/mod.rs index 6a38bbadc0..6794bc3d99 100644 --- a/fendermint/testing/materializer/src/docker/mod.rs +++ b/fendermint/testing/materializer/src/docker/mod.rs @@ -68,7 +68,7 @@ pub use relayer::DockerRelayer; use self::{dropper::DropHandle, network::NetworkName, runner::DockerRunner}; // TODO: Add these to the materializer. -const COMETBFT_IMAGE: &str = "cometbft/cometbft:v0.37.x"; +const COMETBFT_IMAGE: &str = "cometbft/cometbft:v0.38.x"; const FENDERMINT_IMAGE: &str = "fendermint:latest"; const STATE_JSON_FILE_NAME: &str = "materializer-state.json"; diff --git a/fendermint/testing/scripts/common.env b/fendermint/testing/scripts/common.env index 8c52cc4af0..c520eaaa5e 100644 --- a/fendermint/testing/scripts/common.env +++ b/fendermint/testing/scripts/common.env @@ -1,4 +1,4 @@ -CMT_DOCKER_IMAGE="cometbft/cometbft:v0.37.x" +CMT_DOCKER_IMAGE="cometbft/cometbft:v0.38.x" FM_DOCKER_IMAGE="fendermint:latest" PROMTAIL_DOCKER_IMAGE="grafana/promtail:latest" CMT_CONTAINER_NAME="${NETWORK_NAME}-cometbft" diff --git a/fendermint/testing/scripts/common.toml b/fendermint/testing/scripts/common.toml index 73cfe9023d..c792bb7d36 100644 --- a/fendermint/testing/scripts/common.toml +++ b/fendermint/testing/scripts/common.toml @@ -61,6 +61,9 @@ clear = true dependencies = [] [tasks.teardown] +# Cleanup should be best-effort; CI failures should reflect test/setup failures, +# not post-failure cleanup noise. +ignore_errors = true # `dependencies` doesn't seem to work with `cleanup_task`. run_task = { name = [ "cometbft-destroy", diff --git a/fendermint/vm/interpreter/src/fvm/state/exec.rs b/fendermint/vm/interpreter/src/fvm/state/exec.rs index 7a6372ffa3..d38d2bef7a 100644 --- a/fendermint/vm/interpreter/src/fvm/state/exec.rs +++ b/fendermint/vm/interpreter/src/fvm/state/exec.rs @@ -109,7 +109,7 @@ impl fmt::Debug for FvmStateParams { /// This is just a technical thing to help us not forget about saving something. /// /// TODO: `base_fee` should surely be here. -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct FvmUpdatableParams { /// The application protocol version, which changes during upgrades. pub app_version: u64, @@ -311,6 +311,16 @@ where Ok((cid, self.params, self.params_dirty)) } + /// Flush and return the current state root without consuming the execution state. + pub fn flush_state_root(&mut self) -> anyhow::Result { + self.executor.flush() + } + + /// Return a copy of currently tracked mutable parameters. + pub fn updatable_params(&self) -> FvmUpdatableParams { + self.params.clone() + } + /// The height of the currently executing block. pub fn block_height(&self) -> ChainEpoch { self.executor.context().epoch diff --git a/infra/fendermint/Makefile.toml b/infra/fendermint/Makefile.toml index 42962658e3..82cb6db7dd 100644 --- a/infra/fendermint/Makefile.toml +++ b/infra/fendermint/Makefile.toml @@ -92,7 +92,7 @@ ETHAPI_CONTAINER_NAME = "${NODE_NAME}-ethapi" PROMTAIL_CONTAINER_NAME="${NODE_NAME}-promtail" -CMT_DOCKER_IMAGE = "cometbft/cometbft:v0.37.x" +CMT_DOCKER_IMAGE = "cometbft/cometbft:v0.38.x" FM_DOCKER_TAG = "latest" FM_DOCKER_IMAGE = "fendermint:${FM_DOCKER_TAG}" FM_REMOTE_DOCKER_IMAGE = "ghcr.io/consensus-shipyard/fendermint:${FM_DOCKER_TAG}" diff --git a/ipc-storage/ipc-decentralized-storage/src/bin/node.rs b/ipc-storage/ipc-decentralized-storage/src/bin/node.rs index d70f6ebd5a..acd28994b7 100644 --- a/ipc-storage/ipc-decentralized-storage/src/bin/node.rs +++ b/ipc-storage/ipc-decentralized-storage/src/bin/node.rs @@ -380,13 +380,13 @@ async fn register_operator(args: RegisterOperatorArgs) -> Result<()> { ); } - if res.response.deliver_tx.code.is_err() { + if res.response.tx_result.code.is_err() { anyhow::bail!( "RegisterNodeOperator deliver_tx failed: code={:?}, log={}, info={}, gas_used={}", - res.response.deliver_tx.code, - res.response.deliver_tx.log, - res.response.deliver_tx.info, - res.response.deliver_tx.gas_used + res.response.tx_result.code, + res.response.tx_result.log, + res.response.tx_result.info, + res.response.tx_result.gas_used ); } diff --git a/ipc-storage/ipc-decentralized-storage/src/gateway/mod.rs b/ipc-storage/ipc-decentralized-storage/src/gateway/mod.rs index db1a163784..928e6b87a0 100644 --- a/ipc-storage/ipc-decentralized-storage/src/gateway/mod.rs +++ b/ipc-storage/ipc-decentralized-storage/src/gateway/mod.rs @@ -802,10 +802,10 @@ where ); } - if res.response.deliver_tx.code.is_err() { + if res.response.tx_result.code.is_err() { anyhow::bail!( "FinalizeBlob deliver_tx failed: {}", - res.response.deliver_tx.log + res.response.tx_result.log ); } diff --git a/ipc/cli/build.rs b/ipc/cli/build.rs index 59a33f824e..bc7d11fd61 100644 --- a/ipc/cli/build.rs +++ b/ipc/cli/build.rs @@ -30,41 +30,41 @@ struct Asset { const OWNER: &str = "cometbft"; const REPO: &str = "cometbft"; -const VERSION: &str = "v0.37.15"; +const VERSION: &str = "v0.38.17"; -// SHA-256 sums for v0.37.15 assets +// SHA-256 sums for v0.38.17 assets const CHECKSUMS: &[(&str, &str)] = &[ ( - "cometbft_0.37.15_darwin_amd64.tar.gz", - "693958a935325eb21269ccf89c39e9feb88e5be663cfb9510deae5e41af5acb7", + "cometbft_0.38.17_darwin_amd64.tar.gz", + "5a69c2c0f26a65a3b3b17ba62da0615a552ea897449e63d0d5ec62997b901eae", ), ( - "cometbft_0.37.15_darwin_arm64.tar.gz", - "933b97c4ea40eba0d41f71654a276774535cbc54400e4b361d73545246d60b23", + "cometbft_0.38.17_darwin_arm64.tar.gz", + "0809221df1ed6b1471b266a8bbdc673331c7ac45f26c20af91bb383e3e6457a5", ), ( - "cometbft_0.37.15_linux_amd64.tar.gz", - "617846c4d146323564d2c2759592d30b9357b3c8e126e9e066ac95d16e146d4d", + "cometbft_0.38.17_linux_amd64.tar.gz", + "ca4d7ca0df296e092462edc92a3f07a4cd1e6c0366516e382a0726b522806f38", ), ( - "cometbft_0.37.15_linux_arm64.tar.gz", - "b25aab414c64183aa401752cba4b03609cf035f5b587376eeac840895c1e36c1", + "cometbft_0.38.17_linux_arm64.tar.gz", + "5a6a4bf655a84d9463932ff93ac373ea68327c14c26d65a497a3907c45c65144", ), ( - "cometbft_0.37.15_linux_armv6.tar.gz", - "63b98b93a7708dc6a0b1798b8b186d575a2787da158d67bc787aac3de00e0da8", + "cometbft_0.38.17_linux_armv6.tar.gz", + "95fae10f5fc5c0ff8176d9497f684c2a0a27c15fc0f96bb3e131489db14d0c1a", ), ( - "cometbft_0.37.15_windows_amd64.tar.gz", - "e42cf4e1d84b056630248dcaecb1bddea43b668e121ee4ea19587494a3367187", + "cometbft_0.38.17_windows_amd64.tar.gz", + "3523d602f355ef73380d91db335f86daa4d6e0848f54a09cdbc918defb38281c", ), ( - "cometbft_0.37.15_windows_arm64.tar.gz", - "880fb704519b7005a5f395f10b0dcc4fbc7dd4936acacd8b1a373ae76e775572", + "cometbft_0.38.17_windows_arm64.tar.gz", + "1bfe9a6e2bceccee679a9917363bbb3b167c1387be821f3f4c661d226a38b749", ), ( - "cometbft_0.37.15_windows_armv6.tar.gz", - "5041df72a5ec2ceb3d0f3dbec7272c507c2f92e0d22cfb1e04b26370e32f6de4", + "cometbft_0.38.17_windows_armv6.tar.gz", + "cf70cdcabd82e9b7080054d06665d286a026469162715057b7ab458cf693fcb0", ), ]; @@ -103,14 +103,14 @@ fn main() { let os = env::var("CARGO_CFG_TARGET_OS").unwrap(); let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); let asset_name = match (os.as_str(), arch.as_str()) { - ("macos", "x86_64") => "cometbft_0.37.15_darwin_amd64.tar.gz", - ("macos", "aarch64") => "cometbft_0.37.15_darwin_arm64.tar.gz", - ("linux", "x86_64") => "cometbft_0.37.15_linux_amd64.tar.gz", - ("linux", "aarch64") => "cometbft_0.37.15_linux_arm64.tar.gz", - ("linux", "arm") => "cometbft_0.37.15_linux_armv6.tar.gz", - ("windows", "x86_64") => "cometbft_0.37.15_windows_amd64.tar.gz", - ("windows", "aarch64") => "cometbft_0.37.15_windows_arm64.tar.gz", - ("windows", "arm") => "cometbft_0.37.15_windows_armv6.tar.gz", + ("macos", "x86_64") => "cometbft_0.38.17_darwin_amd64.tar.gz", + ("macos", "aarch64") => "cometbft_0.38.17_darwin_arm64.tar.gz", + ("linux", "x86_64") => "cometbft_0.38.17_linux_amd64.tar.gz", + ("linux", "aarch64") => "cometbft_0.38.17_linux_arm64.tar.gz", + ("linux", "arm") => "cometbft_0.38.17_linux_armv6.tar.gz", + ("windows", "x86_64") => "cometbft_0.38.17_windows_amd64.tar.gz", + ("windows", "aarch64") => "cometbft_0.38.17_windows_arm64.tar.gz", + ("windows", "arm") => "cometbft_0.38.17_windows_armv6.tar.gz", _ => { eprintln!("Unsupported target: {}-{}", os, arch); exit(1)