diff --git a/Cargo.Bazel.Fuzzing.json.lock b/Cargo.Bazel.Fuzzing.json.lock index 62b92f3b732..5674e431743 100644 --- a/Cargo.Bazel.Fuzzing.json.lock +++ b/Cargo.Bazel.Fuzzing.json.lock @@ -1,5 +1,5 @@ { - "checksum": "e2f0c9fb8047d4200e8e14e235a3d28792aef48b70952cf21a1f849ff9ea495d", + "checksum": "36e09e87bac1920bd5b5bc018f856f8ddc1eea92392cd7d468d47664ee335dfc", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -5610,6 +5610,12 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "std" + ], + "selects": {} + }, "deps": { "common": [ { @@ -6042,7 +6048,8 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "std" ], "selects": {} }, @@ -6985,14 +6992,14 @@ ], "license_file": null }, - "bitcoin 0.32.2": { + "bitcoin 0.32.5": { "name": "bitcoin", - "version": "0.32.2", + "version": "0.32.5", "package_url": "https://github.com/rust-bitcoin/rust-bitcoin/", "repository": { "Http": { - "url": "https://static.crates.io/crates/bitcoin/0.32.2/download", - "sha256": "ea507acc1cd80fc084ace38544bbcf7ced7c2aa65b653b102de0ce718df668f6" + "url": "https://static.crates.io/crates/bitcoin/0.32.5/download", + "sha256": "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" } }, "targets": [ @@ -7026,6 +7033,18 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "actual-serde", + "default", + "rand", + "rand-std", + "secp-recovery", + "serde", + "std" + ], + "selects": {} + }, "deps": { "common": [ { @@ -7038,7 +7057,7 @@ "target": "bech32" }, { - "id": "bitcoin 0.32.2", + "id": "bitcoin 0.32.5", "target": "build_script_build" }, { @@ -7073,6 +7092,11 @@ { "id": "secp256k1 0.29.0", "target": "secp256k1" + }, + { + "id": "serde 1.0.217", + "target": "serde", + "alias": "actual_serde" } ], "selects": {} @@ -7099,7 +7123,7 @@ ], "selects": {} }, - "version": "0.32.2" + "version": "0.32.5" }, "build_script_attrs": { "compile_data_glob": [ @@ -7159,7 +7183,9 @@ "crate_features": { "common": [ "alloc", - "default" + "default", + "serde", + "std" ], "selects": {} }, @@ -7168,6 +7194,10 @@ { "id": "bitcoin-internals 0.3.0", "target": "build_script_build" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -7220,7 +7250,8 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "std" ], "selects": {} }, @@ -7339,7 +7370,9 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "serde", + "std" ], "selects": {} }, @@ -7349,6 +7382,10 @@ "id": "bitcoin-internals 0.3.0", "target": "bitcoin_internals", "alias": "internals" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -7509,7 +7546,9 @@ "common": [ "alloc", "bitcoin-io", - "io" + "io", + "serde", + "std" ], "selects": {} }, @@ -7523,6 +7562,10 @@ "id": "hex-conservative 0.2.1", "target": "hex_conservative", "alias": "hex" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -7536,14 +7579,14 @@ ], "license_file": null }, - "bitcoincore-rpc 0.15.0": { + "bitcoincore-rpc 0.19.0": { "name": "bitcoincore-rpc", - "version": "0.15.0", + "version": "0.19.0", "package_url": "https://github.com/rust-bitcoin/rust-bitcoincore-rpc/", "repository": { "Http": { - "url": "https://static.crates.io/crates/bitcoincore-rpc/0.15.0/download", - "sha256": "dd0e67dbf7a9971e7f4276f6089e9e814ce0f624a03216b7d92d00351ae7fb3e" + "url": "https://static.crates.io/crates/bitcoincore-rpc/0.19.0/download", + "sha256": "aedd23ae0fd321affb4bbbc36126c6f49a32818dc6b979395d24da8c9d4e80ee" } }, "targets": [ @@ -7565,14 +7608,21 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "default", + "rand" + ], + "selects": {} + }, "deps": { "common": [ { - "id": "bitcoincore-rpc-json 0.15.0", + "id": "bitcoincore-rpc-json 0.19.0", "target": "bitcoincore_rpc_json" }, { - "id": "jsonrpc 0.12.1", + "id": "jsonrpc 0.18.0", "target": "jsonrpc" }, { @@ -7590,8 +7640,8 @@ ], "selects": {} }, - "edition": "2015", - "version": "0.15.0" + "edition": "2018", + "version": "0.19.0" }, "license": "CC0-1.0", "license_ids": [ @@ -7599,14 +7649,14 @@ ], "license_file": "LICENSE" }, - "bitcoincore-rpc-json 0.15.0": { + "bitcoincore-rpc-json 0.19.0": { "name": "bitcoincore-rpc-json", - "version": "0.15.0", + "version": "0.19.0", "package_url": "https://github.com/rust-bitcoin/rust-bitcoincore-rpc/", "repository": { "Http": { - "url": "https://static.crates.io/crates/bitcoincore-rpc-json/0.15.0/download", - "sha256": "2e2ae16202721ba8c3409045681fac790a5ddc791f05731a2df22c0c6bffc0f1" + "url": "https://static.crates.io/crates/bitcoincore-rpc-json/0.19.0/download", + "sha256": "d8909583c5fab98508e80ef73e5592a651c954993dc6b7739963257d19f0e71a" } }, "targets": [ @@ -7628,10 +7678,17 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "default", + "rand" + ], + "selects": {} + }, "deps": { "common": [ { - "id": "bitcoin 0.28.2", + "id": "bitcoin 0.32.5", "target": "bitcoin" }, { @@ -7645,8 +7702,8 @@ ], "selects": {} }, - "edition": "2015", - "version": "0.15.0" + "edition": "2021", + "version": "0.19.0" }, "license": "CC0-1.0", "license_ids": [ @@ -18458,15 +18515,15 @@ }, { "id": "bitcoin 0.28.2", - "target": "bitcoin" + "target": "bitcoin", + "alias": "bitcoin_0_28" }, { - "id": "bitcoin 0.32.2", - "target": "bitcoin", - "alias": "bitcoin_0_32" + "id": "bitcoin 0.32.5", + "target": "bitcoin" }, { - "id": "bitcoincore-rpc 0.15.0", + "id": "bitcoincore-rpc 0.19.0", "target": "bitcoincore_rpc" }, { @@ -27352,7 +27409,8 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "std" ], "selects": {} }, @@ -36132,16 +36190,14 @@ "license_ids": [], "license_file": "LICENSE" }, - "jsonrpc 0.12.1": { + "jsonrpc 0.13.0": { "name": "jsonrpc", - "version": "0.12.1", + "version": "0.13.0", "package_url": "https://github.com/apoelstra/rust-jsonrpc/", "repository": { - "Git": { - "remote": "https://github.com/apoelstra/rust-jsonrpc", - "commitish": { - "Rev": "e42044d8e0896317488dfbd65eb5563d76e937fe" - } + "Http": { + "url": "https://static.crates.io/crates/jsonrpc/0.13.0/download", + "sha256": "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" } }, "targets": [ @@ -36190,7 +36246,7 @@ "selects": {} }, "edition": "2018", - "version": "0.12.1" + "version": "0.13.0" }, "license": "CC0-1.0", "license_ids": [ @@ -36198,14 +36254,14 @@ ], "license_file": "LICENSE" }, - "jsonrpc 0.13.0": { + "jsonrpc 0.18.0": { "name": "jsonrpc", - "version": "0.13.0", + "version": "0.18.0", "package_url": "https://github.com/apoelstra/rust-jsonrpc/", "repository": { "Http": { - "url": "https://static.crates.io/crates/jsonrpc/0.13.0/download", - "sha256": "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" + "url": "https://static.crates.io/crates/jsonrpc/0.18.0/download", + "sha256": "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf" } }, "targets": [ @@ -36231,6 +36287,8 @@ "common": [ "base64", "default", + "minreq", + "minreq_http", "simple_http", "simple_tcp" ], @@ -36242,6 +36300,10 @@ "id": "base64 0.13.1", "target": "base64" }, + { + "id": "minreq 2.13.0", + "target": "minreq" + }, { "id": "serde 1.0.217", "target": "serde" @@ -36254,7 +36316,7 @@ "selects": {} }, "edition": "2018", - "version": "0.13.0" + "version": "0.18.0" }, "license": "CC0-1.0", "license_ids": [ @@ -41716,6 +41778,93 @@ ], "license_file": "LICENSE" }, + "minreq 2.13.0": { + "name": "minreq", + "version": "2.13.0", + "package_url": "https://github.com/neonmoe/minreq", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/minreq/2.13.0/download", + "sha256": "36a8e50e917e18a37d500d27d40b7bc7d127e71c0c94fb2d83f43b4afd308390" + } + }, + "targets": [ + { + "Library": { + "crate_name": "minreq", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "minreq", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "json-using-serde", + "serde", + "serde_json" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "log 0.4.20", + "target": "log" + }, + { + "id": "minreq 2.13.0", + "target": "build_script_build" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_json 1.0.132", + "target": "serde_json" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "2.13.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "ISC", + "license_ids": [ + "ISC" + ], + "license_file": null + }, "mio 0.8.10": { "name": "mio", "version": "0.8.10", @@ -63634,7 +63783,12 @@ "crate_features": { "common": [ "alloc", - "hashes" + "hashes", + "rand", + "rand-std", + "recovery", + "serde", + "std" ], "selects": {} }, @@ -63645,9 +63799,17 @@ "target": "bitcoin_hashes", "alias": "hashes" }, + { + "id": "rand 0.8.5", + "target": "rand" + }, { "id": "secp256k1-sys 0.10.0", "target": "secp256k1_sys" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -63873,7 +64035,9 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "recovery", + "std" ], "selects": {} }, @@ -87403,8 +87567,8 @@ "bip32 0.5.1", "bit-vec 0.6.3", "bitcoin 0.28.2", - "bitcoin 0.32.2", - "bitcoincore-rpc 0.15.0", + "bitcoin 0.32.5", + "bitcoincore-rpc 0.19.0", "bitcoind 0.32.0", "bitflags 1.3.2", "bs58 0.5.0", @@ -87713,5 +87877,11 @@ "zstd 0.13.2" ], "direct_dev_deps": [], - "unused_patches": [] + "unused_patches": [ + { + "name": "jsonrpc", + "version": "0.12.1", + "source": "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" + } + ] } diff --git a/Cargo.Bazel.Fuzzing.toml.lock b/Cargo.Bazel.Fuzzing.toml.lock index 36b66b3cf23..6f1408a30af 100644 --- a/Cargo.Bazel.Fuzzing.toml.lock +++ b/Cargo.Bazel.Fuzzing.toml.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "abnf" @@ -1206,9 +1206,9 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.32.2" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea507acc1cd80fc084ace38544bbcf7ced7c2aa65b653b102de0ce718df668f6" +checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" dependencies = [ "base58ck", "bech32 0.11.0", @@ -1219,6 +1219,7 @@ dependencies = [ "hex-conservative", "hex_lit", "secp256k1 0.29.0", + "serde", ] [[package]] @@ -1226,6 +1227,9 @@ name = "bitcoin-internals" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" +dependencies = [ + "serde", +] [[package]] name = "bitcoin-io" @@ -1246,6 +1250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" dependencies = [ "bitcoin-internals", + "serde", ] [[package]] @@ -1275,16 +1280,17 @@ checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ "bitcoin-io", "hex-conservative", + "serde", ] [[package]] name = "bitcoincore-rpc" -version = "0.15.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0e67dbf7a9971e7f4276f6089e9e814ce0f624a03216b7d92d00351ae7fb3e" +checksum = "aedd23ae0fd321affb4bbbc36126c6f49a32818dc6b979395d24da8c9d4e80ee" dependencies = [ "bitcoincore-rpc-json", - "jsonrpc 0.12.1", + "jsonrpc 0.18.0", "log", "serde", "serde_json", @@ -1292,11 +1298,11 @@ dependencies = [ [[package]] name = "bitcoincore-rpc-json" -version = "0.15.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2ae16202721ba8c3409045681fac790a5ddc791f05731a2df22c0c6bffc0f1" +checksum = "d8909583c5fab98508e80ef73e5592a651c954993dc6b7739963257d19f0e71a" dependencies = [ - "bitcoin 0.28.2", + "bitcoin 0.32.5", "serde", "serde_json", ] @@ -2999,7 +3005,7 @@ dependencies = [ "bip32", "bit-vec", "bitcoin 0.28.2", - "bitcoin 0.32.2", + "bitcoin 0.32.5", "bitcoincore-rpc", "bitcoind", "bitflags 1.3.2", @@ -6076,8 +6082,9 @@ dependencies = [ [[package]] name = "jsonrpc" -version = "0.12.1" -source = "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" dependencies = [ "base64 0.13.1", "serde", @@ -6086,11 +6093,12 @@ dependencies = [ [[package]] name = "jsonrpc" -version = "0.13.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" +checksum = "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf" dependencies = [ "base64 0.13.1", + "minreq", "serde", "serde_json", ] @@ -6897,6 +6905,17 @@ dependencies = [ "adler", ] +[[package]] +name = "minreq" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a8e50e917e18a37d500d27d40b7bc7d127e71c0c94fb2d83f43b4afd308390" +dependencies = [ + "log", + "serde", + "serde_json", +] + [[package]] name = "mio" version = "0.8.10" @@ -9937,7 +9956,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" dependencies = [ "bitcoin_hashes 0.14.0", + "rand 0.8.5", "secp256k1-sys 0.10.0", + "serde", ] [[package]] @@ -13388,3 +13409,9 @@ dependencies = [ "cc", "pkg-config", ] + +[[patch.unused]] +name = "jsonrpc" +version = "0.12.1" +source = "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" + diff --git a/Cargo.Bazel.json.lock b/Cargo.Bazel.json.lock index ae3a6e269f4..d8e862314e7 100644 --- a/Cargo.Bazel.json.lock +++ b/Cargo.Bazel.json.lock @@ -1,5 +1,5 @@ { - "checksum": "c940ed0c71e779f38de47e366662d71cd883022d89016936e1952a55719fe089", + "checksum": "91a2715ca41916b4ecfa31b91e2184f3d68e77139b436717fb06f3372126fa40", "crates": { "abnf 0.12.0": { "name": "abnf", @@ -5611,6 +5611,12 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "std" + ], + "selects": {} + }, "deps": { "common": [ { @@ -6043,7 +6049,8 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "std" ], "selects": {} }, @@ -6923,14 +6930,14 @@ ], "license_file": null }, - "bitcoin 0.32.2": { + "bitcoin 0.32.5": { "name": "bitcoin", - "version": "0.32.2", + "version": "0.32.5", "package_url": "https://github.com/rust-bitcoin/rust-bitcoin/", "repository": { "Http": { - "url": "https://static.crates.io/crates/bitcoin/0.32.2/download", - "sha256": "ea507acc1cd80fc084ace38544bbcf7ced7c2aa65b653b102de0ce718df668f6" + "url": "https://static.crates.io/crates/bitcoin/0.32.5/download", + "sha256": "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" } }, "targets": [ @@ -6964,6 +6971,18 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "actual-serde", + "default", + "rand", + "rand-std", + "secp-recovery", + "serde", + "std" + ], + "selects": {} + }, "deps": { "common": [ { @@ -6976,7 +6995,7 @@ "target": "bech32" }, { - "id": "bitcoin 0.32.2", + "id": "bitcoin 0.32.5", "target": "build_script_build" }, { @@ -7011,12 +7030,17 @@ { "id": "secp256k1 0.29.0", "target": "secp256k1" + }, + { + "id": "serde 1.0.217", + "target": "serde", + "alias": "actual_serde" } ], "selects": {} }, "edition": "2021", - "version": "0.32.2" + "version": "0.32.5" }, "build_script_attrs": { "compile_data_glob": [ @@ -7076,7 +7100,9 @@ "crate_features": { "common": [ "alloc", - "default" + "default", + "serde", + "std" ], "selects": {} }, @@ -7085,6 +7111,10 @@ { "id": "bitcoin-internals 0.3.0", "target": "build_script_build" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -7137,7 +7167,8 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "std" ], "selects": {} }, @@ -7256,7 +7287,9 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "serde", + "std" ], "selects": {} }, @@ -7266,6 +7299,10 @@ "id": "bitcoin-internals 0.3.0", "target": "bitcoin_internals", "alias": "internals" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -7426,7 +7463,9 @@ "common": [ "alloc", "bitcoin-io", - "io" + "io", + "serde", + "std" ], "selects": {} }, @@ -7440,6 +7479,10 @@ "id": "hex-conservative 0.2.1", "target": "hex_conservative", "alias": "hex" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -7453,14 +7496,14 @@ ], "license_file": null }, - "bitcoincore-rpc 0.15.0": { + "bitcoincore-rpc 0.19.0": { "name": "bitcoincore-rpc", - "version": "0.15.0", + "version": "0.19.0", "package_url": "https://github.com/rust-bitcoin/rust-bitcoincore-rpc/", "repository": { "Http": { - "url": "https://static.crates.io/crates/bitcoincore-rpc/0.15.0/download", - "sha256": "dd0e67dbf7a9971e7f4276f6089e9e814ce0f624a03216b7d92d00351ae7fb3e" + "url": "https://static.crates.io/crates/bitcoincore-rpc/0.19.0/download", + "sha256": "aedd23ae0fd321affb4bbbc36126c6f49a32818dc6b979395d24da8c9d4e80ee" } }, "targets": [ @@ -7482,14 +7525,21 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "default", + "rand" + ], + "selects": {} + }, "deps": { "common": [ { - "id": "bitcoincore-rpc-json 0.15.0", + "id": "bitcoincore-rpc-json 0.19.0", "target": "bitcoincore_rpc_json" }, { - "id": "jsonrpc 0.12.1", + "id": "jsonrpc 0.18.0", "target": "jsonrpc" }, { @@ -7507,8 +7557,8 @@ ], "selects": {} }, - "edition": "2015", - "version": "0.15.0" + "edition": "2018", + "version": "0.19.0" }, "license": "CC0-1.0", "license_ids": [ @@ -7516,14 +7566,14 @@ ], "license_file": "LICENSE" }, - "bitcoincore-rpc-json 0.15.0": { + "bitcoincore-rpc-json 0.19.0": { "name": "bitcoincore-rpc-json", - "version": "0.15.0", + "version": "0.19.0", "package_url": "https://github.com/rust-bitcoin/rust-bitcoincore-rpc/", "repository": { "Http": { - "url": "https://static.crates.io/crates/bitcoincore-rpc-json/0.15.0/download", - "sha256": "2e2ae16202721ba8c3409045681fac790a5ddc791f05731a2df22c0c6bffc0f1" + "url": "https://static.crates.io/crates/bitcoincore-rpc-json/0.19.0/download", + "sha256": "d8909583c5fab98508e80ef73e5592a651c954993dc6b7739963257d19f0e71a" } }, "targets": [ @@ -7545,10 +7595,17 @@ "compile_data_glob": [ "**" ], + "crate_features": { + "common": [ + "default", + "rand" + ], + "selects": {} + }, "deps": { "common": [ { - "id": "bitcoin 0.28.2", + "id": "bitcoin 0.32.5", "target": "bitcoin" }, { @@ -7562,8 +7619,8 @@ ], "selects": {} }, - "edition": "2015", - "version": "0.15.0" + "edition": "2021", + "version": "0.19.0" }, "license": "CC0-1.0", "license_ids": [ @@ -18286,15 +18343,15 @@ }, { "id": "bitcoin 0.28.2", - "target": "bitcoin" + "target": "bitcoin", + "alias": "bitcoin_0_28" }, { - "id": "bitcoin 0.32.2", - "target": "bitcoin", - "alias": "bitcoin_0_32" + "id": "bitcoin 0.32.5", + "target": "bitcoin" }, { - "id": "bitcoincore-rpc 0.15.0", + "id": "bitcoincore-rpc 0.19.0", "target": "bitcoincore_rpc" }, { @@ -27207,7 +27264,8 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "std" ], "selects": {} }, @@ -35966,16 +36024,14 @@ "license_ids": [], "license_file": "LICENSE" }, - "jsonrpc 0.12.1": { + "jsonrpc 0.13.0": { "name": "jsonrpc", - "version": "0.12.1", + "version": "0.13.0", "package_url": "https://github.com/apoelstra/rust-jsonrpc/", "repository": { - "Git": { - "remote": "https://github.com/apoelstra/rust-jsonrpc", - "commitish": { - "Rev": "e42044d8e0896317488dfbd65eb5563d76e937fe" - } + "Http": { + "url": "https://static.crates.io/crates/jsonrpc/0.13.0/download", + "sha256": "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" } }, "targets": [ @@ -36024,7 +36080,7 @@ "selects": {} }, "edition": "2018", - "version": "0.12.1" + "version": "0.13.0" }, "license": "CC0-1.0", "license_ids": [ @@ -36032,14 +36088,14 @@ ], "license_file": "LICENSE" }, - "jsonrpc 0.13.0": { + "jsonrpc 0.18.0": { "name": "jsonrpc", - "version": "0.13.0", + "version": "0.18.0", "package_url": "https://github.com/apoelstra/rust-jsonrpc/", "repository": { "Http": { - "url": "https://static.crates.io/crates/jsonrpc/0.13.0/download", - "sha256": "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" + "url": "https://static.crates.io/crates/jsonrpc/0.18.0/download", + "sha256": "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf" } }, "targets": [ @@ -36065,6 +36121,8 @@ "common": [ "base64", "default", + "minreq", + "minreq_http", "simple_http", "simple_tcp" ], @@ -36076,6 +36134,10 @@ "id": "base64 0.13.1", "target": "base64" }, + { + "id": "minreq 2.13.0", + "target": "minreq" + }, { "id": "serde 1.0.217", "target": "serde" @@ -36088,7 +36150,7 @@ "selects": {} }, "edition": "2018", - "version": "0.13.0" + "version": "0.18.0" }, "license": "CC0-1.0", "license_ids": [ @@ -41556,6 +41618,93 @@ ], "license_file": "LICENSE" }, + "minreq 2.13.0": { + "name": "minreq", + "version": "2.13.0", + "package_url": "https://github.com/neonmoe/minreq", + "repository": { + "Http": { + "url": "https://static.crates.io/crates/minreq/2.13.0/download", + "sha256": "36a8e50e917e18a37d500d27d40b7bc7d127e71c0c94fb2d83f43b4afd308390" + } + }, + "targets": [ + { + "Library": { + "crate_name": "minreq", + "crate_root": "src/lib.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + }, + { + "BuildScript": { + "crate_name": "build_script_build", + "crate_root": "build.rs", + "srcs": { + "allow_empty": true, + "include": [ + "**/*.rs" + ] + } + } + } + ], + "library_target_name": "minreq", + "common_attrs": { + "compile_data_glob": [ + "**" + ], + "crate_features": { + "common": [ + "json-using-serde", + "serde", + "serde_json" + ], + "selects": {} + }, + "deps": { + "common": [ + { + "id": "log 0.4.20", + "target": "log" + }, + { + "id": "minreq 2.13.0", + "target": "build_script_build" + }, + { + "id": "serde 1.0.217", + "target": "serde" + }, + { + "id": "serde_json 1.0.132", + "target": "serde_json" + } + ], + "selects": {} + }, + "edition": "2018", + "version": "2.13.0" + }, + "build_script_attrs": { + "compile_data_glob": [ + "**" + ], + "data_glob": [ + "**" + ] + }, + "license": "ISC", + "license_ids": [ + "ISC" + ], + "license_file": null + }, "mio 0.8.10": { "name": "mio", "version": "0.8.10", @@ -63480,7 +63629,12 @@ "crate_features": { "common": [ "alloc", - "hashes" + "hashes", + "rand", + "rand-std", + "recovery", + "serde", + "std" ], "selects": {} }, @@ -63491,9 +63645,17 @@ "target": "bitcoin_hashes", "alias": "hashes" }, + { + "id": "rand 0.8.5", + "target": "rand" + }, { "id": "secp256k1-sys 0.10.0", "target": "secp256k1_sys" + }, + { + "id": "serde 1.0.217", + "target": "serde" } ], "selects": {} @@ -63719,7 +63881,9 @@ ], "crate_features": { "common": [ - "alloc" + "alloc", + "recovery", + "std" ], "selects": {} }, @@ -87283,8 +87447,8 @@ "bip32 0.5.1", "bit-vec 0.6.3", "bitcoin 0.28.2", - "bitcoin 0.32.2", - "bitcoincore-rpc 0.15.0", + "bitcoin 0.32.5", + "bitcoincore-rpc 0.19.0", "bitcoind 0.32.0", "bitflags 1.3.2", "bs58 0.5.0", @@ -87593,5 +87757,11 @@ "zstd 0.13.2" ], "direct_dev_deps": [], - "unused_patches": [] + "unused_patches": [ + { + "name": "jsonrpc", + "version": "0.12.1", + "source": "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" + } + ] } diff --git a/Cargo.Bazel.toml.lock b/Cargo.Bazel.toml.lock index a81cc6d2d52..c1e87d83dd6 100644 --- a/Cargo.Bazel.toml.lock +++ b/Cargo.Bazel.toml.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "abnf" @@ -1207,9 +1207,9 @@ dependencies = [ [[package]] name = "bitcoin" -version = "0.32.2" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea507acc1cd80fc084ace38544bbcf7ced7c2aa65b653b102de0ce718df668f6" +checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" dependencies = [ "base58ck", "bech32 0.11.0", @@ -1220,6 +1220,7 @@ dependencies = [ "hex-conservative", "hex_lit", "secp256k1 0.29.0", + "serde", ] [[package]] @@ -1227,6 +1228,9 @@ name = "bitcoin-internals" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" +dependencies = [ + "serde", +] [[package]] name = "bitcoin-io" @@ -1247,6 +1251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" dependencies = [ "bitcoin-internals", + "serde", ] [[package]] @@ -1276,16 +1281,17 @@ checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ "bitcoin-io", "hex-conservative", + "serde", ] [[package]] name = "bitcoincore-rpc" -version = "0.15.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0e67dbf7a9971e7f4276f6089e9e814ce0f624a03216b7d92d00351ae7fb3e" +checksum = "aedd23ae0fd321affb4bbbc36126c6f49a32818dc6b979395d24da8c9d4e80ee" dependencies = [ "bitcoincore-rpc-json", - "jsonrpc 0.12.1", + "jsonrpc 0.18.0", "log", "serde", "serde_json", @@ -1293,11 +1299,11 @@ dependencies = [ [[package]] name = "bitcoincore-rpc-json" -version = "0.15.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2ae16202721ba8c3409045681fac790a5ddc791f05731a2df22c0c6bffc0f1" +checksum = "d8909583c5fab98508e80ef73e5592a651c954993dc6b7739963257d19f0e71a" dependencies = [ - "bitcoin 0.28.2", + "bitcoin 0.32.5", "serde", "serde_json", ] @@ -2988,7 +2994,7 @@ dependencies = [ "bip32", "bit-vec", "bitcoin 0.28.2", - "bitcoin 0.32.2", + "bitcoin 0.32.5", "bitcoincore-rpc", "bitcoind", "bitflags 1.3.2", @@ -6066,8 +6072,9 @@ dependencies = [ [[package]] name = "jsonrpc" -version = "0.12.1" -source = "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" dependencies = [ "base64 0.13.1", "serde", @@ -6076,11 +6083,12 @@ dependencies = [ [[package]] name = "jsonrpc" -version = "0.13.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" +checksum = "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf" dependencies = [ "base64 0.13.1", + "minreq", "serde", "serde_json", ] @@ -6888,6 +6896,17 @@ dependencies = [ "adler", ] +[[package]] +name = "minreq" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a8e50e917e18a37d500d27d40b7bc7d127e71c0c94fb2d83f43b4afd308390" +dependencies = [ + "log", + "serde", + "serde_json", +] + [[package]] name = "mio" version = "0.8.10" @@ -9933,7 +9952,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" dependencies = [ "bitcoin_hashes 0.14.0", + "rand 0.8.5", "secp256k1-sys 0.10.0", + "serde", ] [[package]] @@ -13402,3 +13423,9 @@ dependencies = [ "cc", "pkg-config", ] + +[[patch.unused]] +name = "jsonrpc" +version = "0.12.1" +source = "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" + diff --git a/Cargo.lock b/Cargo.lock index 66492550925..40acea29dd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1203,7 +1203,6 @@ dependencies = [ "bech32 0.8.1", "bitcoin_hashes 0.10.0", "secp256k1 0.22.2", - "serde", ] [[package]] @@ -1235,6 +1234,7 @@ dependencies = [ "hex-conservative", "hex_lit", "secp256k1 0.29.1", + "serde", ] [[package]] @@ -1242,6 +1242,9 @@ name = "bitcoin-internals" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" +dependencies = [ + "serde", +] [[package]] name = "bitcoin-io" @@ -1262,6 +1265,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" dependencies = [ "bitcoin-internals", + "serde", ] [[package]] @@ -1269,9 +1273,6 @@ name = "bitcoin_hashes" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "006cc91e1a1d99819bc5b8214be3555c1f0611b169f527a1fdc54ed1f2b745b0" -dependencies = [ - "serde", -] [[package]] name = "bitcoin_hashes" @@ -1291,16 +1292,17 @@ checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" dependencies = [ "bitcoin-io", "hex-conservative", + "serde", ] [[package]] name = "bitcoincore-rpc" -version = "0.15.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0e67dbf7a9971e7f4276f6089e9e814ce0f624a03216b7d92d00351ae7fb3e" +checksum = "aedd23ae0fd321affb4bbbc36126c6f49a32818dc6b979395d24da8c9d4e80ee" dependencies = [ "bitcoincore-rpc-json", - "jsonrpc 0.12.1", + "jsonrpc 0.18.0", "log", "serde", "serde_json", @@ -1308,11 +1310,11 @@ dependencies = [ [[package]] name = "bitcoincore-rpc-json" -version = "0.15.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2ae16202721ba8c3409045681fac790a5ddc791f05731a2df22c0c6bffc0f1" +checksum = "d8909583c5fab98508e80ef73e5592a651c954993dc6b7739963257d19f0e71a" dependencies = [ - "bitcoin 0.28.2", + "bitcoin 0.32.5", "serde", "serde_json", ] @@ -2609,7 +2611,7 @@ dependencies = [ "cfg-if 1.0.0", "cpufeatures", "hex", - "proptest", + "proptest 1.6.0", "serde", ] @@ -5586,7 +5588,7 @@ dependencies = [ "ic-protobuf", "ic-test-utilities-compare-dirs", "phantom_newtype", - "proptest", + "proptest 1.6.0", "proptest-derive", "prost 0.13.4", "serde", @@ -5609,7 +5611,7 @@ name = "ic-bitcoin-canister-mock" version = "0.9.0" dependencies = [ "bech32 0.9.1", - "bitcoin 0.28.2", + "bitcoin 0.32.5", "candid", "candid_parser", "hex", @@ -5879,7 +5881,7 @@ dependencies = [ name = "ic-btc-adapter" version = "0.9.0" dependencies = [ - "bitcoin 0.28.2", + "bitcoin 0.32.5", "bitcoincore-rpc", "bitcoind", "clap 4.5.26", @@ -5903,6 +5905,7 @@ dependencies = [ "ic-metrics", "ic-test-utilities-logger", "parking_lot 0.12.3", + "primitive-types", "prometheus", "prost 0.13.4", "rand 0.8.5", @@ -5945,7 +5948,7 @@ dependencies = [ name = "ic-btc-adapter-test-utils" version = "0.9.0" dependencies = [ - "bitcoin 0.28.2", + "bitcoin 0.32.5", "flate2", "hex", "rand 0.8.5", @@ -5977,7 +5980,7 @@ dependencies = [ "ic-types", "ic-universal-canister", "pocket-ic", - "proptest", + "proptest 1.6.0", "scraper", "serde", "serde_json", @@ -6014,7 +6017,7 @@ dependencies = [ "ic-types", "mockall", "prometheus", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "slog", "thiserror 2.0.11", @@ -6056,8 +6059,10 @@ dependencies = [ name = "ic-btc-validation" version = "0.9.0" dependencies = [ - "bitcoin 0.28.2", + "bitcoin 0.32.5", "csv", + "hex", + "proptest 0.9.6", ] [[package]] @@ -6260,7 +6265,7 @@ dependencies = [ "leb128", "maplit", "phantom_newtype", - "proptest", + "proptest 1.6.0", "serde", "serde_bytes", "serde_cbor", @@ -6280,7 +6285,7 @@ dependencies = [ "ic-crypto-tree-hash-test-utils", "itertools 0.12.1", "leb128", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rand_chacha 0.3.1", "scoped_threadpool", @@ -6620,7 +6625,7 @@ dependencies = [ "minicbor-derive", "mockall", "num-traits", - "proptest", + "proptest 1.6.0", "ripemd", "scopeguard", "serde", @@ -6673,7 +6678,7 @@ dependencies = [ "num-bigint 0.4.6", "num-traits", "phantom_newtype", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rlp", "scopeguard", @@ -6731,7 +6736,7 @@ dependencies = [ "ic-sys", "ic-types", "json5", - "proptest", + "proptest 1.6.0", "proptest-derive", "serde", "tempfile", @@ -6796,7 +6801,7 @@ dependencies = [ "num-traits", "phantom_newtype", "prometheus", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", @@ -7006,7 +7011,7 @@ dependencies = [ "maplit", "mockall", "parking_lot 0.12.3", - "proptest", + "proptest 1.6.0", "proptest-derive", "prost 0.13.4", "rand 0.8.5", @@ -7186,7 +7191,7 @@ dependencies = [ "ic-protobuf", "ic-types", "num-bigint 0.4.6", - "proptest", + "proptest 1.6.0", "proptest-derive", "rand 0.8.5", "rand_chacha 0.3.1", @@ -7345,7 +7350,7 @@ dependencies = [ "mockall", "num_cpus", "parking_lot 0.12.3", - "proptest", + "proptest 1.6.0", "proptest-derive", "prost 0.13.4", "rand 0.8.5", @@ -7389,7 +7394,7 @@ dependencies = [ "ic-protobuf", "ic-types", "paste", - "proptest", + "proptest 1.6.0", "strum", ] @@ -7451,7 +7456,7 @@ dependencies = [ "ic-crypto-test-utils-reproducible-rng", "ic-protobuf", "ic-types", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rand_chacha 0.3.1", "serde", @@ -7504,7 +7509,7 @@ dependencies = [ "ic-types", "lazy_static", "parking_lot 0.12.3", - "proptest", + "proptest 1.6.0", "proptest-derive", "rand 0.8.5", "rand_chacha 0.3.1", @@ -8037,7 +8042,7 @@ dependencies = [ "ic-crypto-tree-hash-test-utils", "ic-protobuf", "maplit", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "serde", @@ -8053,7 +8058,7 @@ dependencies = [ "assert_matches", "ic-crypto-test-utils-reproducible-rng", "ic-crypto-tree-hash", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "thiserror 2.0.11", ] @@ -8290,7 +8295,7 @@ dependencies = [ "num-traits", "pretty_assertions", "prometheus", - "proptest", + "proptest 1.6.0", "rayon", "rustc-demangle", "serde", @@ -8327,7 +8332,7 @@ dependencies = [ "ic-sha3 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "minicbor", "minicbor-derive", - "proptest", + "proptest 1.6.0", "serde", "serde_json", ] @@ -8396,7 +8401,7 @@ dependencies = [ "num-traits", "phantom_newtype", "prometheus", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "regex", "scoped_threadpool", @@ -8555,7 +8560,7 @@ dependencies = [ "mockall", "pretty_assertions", "prometheus", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "reqwest 0.12.12", @@ -8755,7 +8760,7 @@ dependencies = [ "ic-types", "mockall", "prometheus", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rand_chacha 0.3.1", "slog", @@ -8880,7 +8885,7 @@ dependencies = [ "num-traits", "once_cell", "pocket-ic", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "reqwest 0.12.12", "rolling-file", @@ -8968,7 +8973,7 @@ dependencies = [ "leb128", "num-bigint 0.4.6", "num-traits", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "serde", "serde_bytes", @@ -9033,7 +9038,7 @@ dependencies = [ "ic-types", "icrc-ledger-types", "num-traits", - "proptest", + "proptest 1.6.0", "scopeguard", "serde", "serde_bytes", @@ -9078,7 +9083,7 @@ dependencies = [ "minicbor", "num-bigint 0.4.6", "num-traits", - "proptest", + "proptest 1.6.0", "serde", "serde_bytes", ] @@ -9098,7 +9103,7 @@ dependencies = [ "ic-types", "icrc-ledger-types", "num-traits", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rand_chacha 0.3.1", "rosetta-core", @@ -9120,7 +9125,7 @@ dependencies = [ "minicbor", "num-bigint 0.4.6", "num-traits", - "proptest", + "proptest 1.6.0", "serde", ] @@ -9134,7 +9139,7 @@ dependencies = [ "ic-stable-structures", "minicbor", "num-traits", - "proptest", + "proptest 1.6.0", "serde", ] @@ -9184,7 +9189,7 @@ dependencies = [ "ic-validator", "pprof", "prometheus", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "slog", "tokio", @@ -9207,7 +9212,7 @@ dependencies = [ "ic-types", "ic-wasm-types", "phantom_newtype", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "serde", "strum", @@ -9310,7 +9315,7 @@ dependencies = [ "ic-types", "icp-ledger", "on_wire", - "proptest", + "proptest 1.6.0", "reqwest 0.12.12", "rusqlite", "serde", @@ -9358,7 +9363,7 @@ dependencies = [ "ic-stable-structures", "minicbor", "num-traits", - "proptest", + "proptest 1.6.0", "serde", "serde_bytes", ] @@ -9405,7 +9410,7 @@ dependencies = [ "mockall", "num-traits", "paste", - "proptest", + "proptest 1.6.0", "scopeguard", "scraper", "serde", @@ -9434,7 +9439,7 @@ dependencies = [ "ic-universal-canister", "icrc-ledger-types", "paste", - "proptest", + "proptest 1.6.0", ] [[package]] @@ -9472,7 +9477,7 @@ dependencies = [ "icrc1-test-env", "icrc1-test-suite", "num-traits", - "proptest", + "proptest 1.6.0", ] [[package]] @@ -9668,7 +9673,7 @@ dependencies = [ "mockall", "pretty_assertions", "prometheus", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rand_chacha 0.3.1", "random-traffic-test", @@ -9821,7 +9826,7 @@ dependencies = [ "mockall", "num-traits", "priority-queue", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rust_decimal", "serde", @@ -10155,7 +10160,7 @@ dependencies = [ "assert_matches", "ic-nervous-system-common", "lazy_static", - "proptest", + "proptest 1.6.0", "rust_decimal", "rust_decimal_macros", "serde", @@ -10295,7 +10300,7 @@ dependencies = [ "on_wire", "pretty_assertions", "prometheus-parse", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", @@ -11582,7 +11587,7 @@ dependencies = [ "nix 0.24.3", "phantom_newtype", "prometheus", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", @@ -11684,7 +11689,7 @@ dependencies = [ "on_wire", "pocket-ic", "prometheus", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", @@ -11908,7 +11913,7 @@ dependencies = [ "maplit", "num-traits", "pretty_assertions", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "prost-build 0.13.4", "rand 0.8.5", @@ -12094,7 +12099,7 @@ dependencies = [ "on_wire", "pretty-bytes", "pretty_assertions", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rust_decimal", @@ -12189,7 +12194,7 @@ dependencies = [ "lazy_static", "maplit", "pretty_assertions", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rust_decimal", "rust_decimal_macros", @@ -12386,7 +12391,7 @@ dependencies = [ "itertools 0.12.1", "libc", "prometheus", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "scoped_threadpool", "slog", @@ -12452,7 +12457,7 @@ dependencies = [ "ic-universal-canister", "ic-xnet-payload-builder", "maplit", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rcgen", "serde", @@ -12518,7 +12523,7 @@ dependencies = [ "nix 0.24.3", "parking_lot 0.12.3", "prometheus", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", @@ -12789,7 +12794,7 @@ dependencies = [ "once_cell", "pem 1.1.1", "phantom_newtype", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", @@ -12913,7 +12918,7 @@ dependencies = [ "nix 0.24.3", "parking_lot 0.12.3", "rand 0.8.5", - "rusty-fork", + "rusty-fork 0.3.0", "serde", "serde_cbor", "slog", @@ -13093,7 +13098,7 @@ dependencies = [ "ic-types", "ic-wasm-types", "mockall", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "rand_chacha 0.3.1", "strum", @@ -13291,12 +13296,12 @@ dependencies = [ "once_cell", "phantom_newtype", "pretty_assertions", - "proptest", + "proptest 1.6.0", "proptest-derive", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", - "rusty-fork", + "rusty-fork 0.3.0", "serde", "serde_bytes", "serde_cbor", @@ -13314,7 +13319,7 @@ version = "0.9.0" dependencies = [ "ic-protobuf", "ic-types", - "proptest", + "proptest 1.6.0", "strum", ] @@ -13375,7 +13380,7 @@ version = "0.9.0" dependencies = [ "ic-types", "lru", - "proptest", + "proptest 1.6.0", ] [[package]] @@ -13686,7 +13691,7 @@ dependencies = [ "mockall", "nix 0.24.3", "prometheus", - "proptest", + "proptest 1.6.0", "rand 0.8.5", "reqwest 0.12.12", "slog", @@ -14008,7 +14013,7 @@ dependencies = [ "maplit", "on_wire", "pocket-ic", - "proptest", + "proptest 1.6.0", "prost 0.13.4", "rand 0.8.5", "rand_chacha 0.3.1", @@ -14054,7 +14059,7 @@ dependencies = [ "minicbor", "num-bigint 0.4.6", "num-traits", - "proptest", + "proptest 1.6.0", ] [[package]] @@ -14106,7 +14111,7 @@ dependencies = [ "minicbor", "num-bigint 0.4.6", "num-traits", - "proptest", + "proptest 1.6.0", "serde", "serde_bytes", "sha2 0.10.8", @@ -14684,8 +14689,9 @@ dependencies = [ [[package]] name = "jsonrpc" -version = "0.12.1" -source = "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" dependencies = [ "base64 0.13.1", "serde", @@ -14694,11 +14700,12 @@ dependencies = [ [[package]] name = "jsonrpc" -version = "0.13.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd8d6b3f301ba426b30feca834a2a18d48d5b54e5065496b5c1b05537bee3639" +checksum = "3662a38d341d77efecb73caf01420cfa5aa63c0253fd7bc05289ef9f6616e1bf" dependencies = [ "base64 0.13.1", + "minreq", "serde", "serde_json", ] @@ -14988,7 +14995,7 @@ dependencies = [ "minicbor", "num-traits", "on_wire", - "proptest", + "proptest 1.6.0", "serde", "serde_bytes", "serde_cbor", @@ -15574,7 +15581,7 @@ dependencies = [ "lazy_static", "libc", "nix 0.24.3", - "proptest", + "proptest 1.6.0", "slog", "tempfile", ] @@ -15688,6 +15695,17 @@ dependencies = [ "adler2", ] +[[package]] +name = "minreq" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36a8e50e917e18a37d500d27d40b7bc7d127e71c0c94fb2d83f43b4afd308390" +dependencies = [ + "log", + "serde", + "serde_json", +] + [[package]] name = "mio" version = "0.8.11" @@ -17236,7 +17254,7 @@ dependencies = [ "axum-server", "backoff", "base64 0.13.1", - "bitcoin 0.28.2", + "bitcoin 0.32.5", "bitcoincore-rpc", "bytes", "candid", @@ -17650,6 +17668,26 @@ dependencies = [ "regex", ] +[[package]] +name = "proptest" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c477819b845fe023d33583ebf10c9f62518c8d79a0960ba5c36d6ac8a55a5b" +dependencies = [ + "bit-set 0.5.3", + "bitflags 1.3.2", + "byteorder", + "lazy_static", + "num-traits", + "quick-error", + "rand 0.6.5", + "rand_chacha 0.1.1", + "rand_xorshift 0.1.1", + "regex-syntax 0.6.29", + "rusty-fork 0.2.2", + "tempfile", +] + [[package]] name = "proptest" version = "1.6.0" @@ -17665,7 +17703,7 @@ dependencies = [ "rand_chacha 0.3.1", "rand_xorshift 0.3.0", "regex-syntax 0.8.5", - "rusty-fork", + "rusty-fork 0.3.0", "tempfile", "unarray", ] @@ -18802,7 +18840,7 @@ dependencies = [ "icp-ledger", "icrc-ledger-types", "num-bigint 0.4.6", - "proptest", + "proptest 1.6.0", "serde", "serde_bytes", "serde_json", @@ -19235,6 +19273,18 @@ version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +[[package]] +name = "rusty-fork" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dd93264e10c577503e926bd1430193eeb5d21b059148910082245309b424fae" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "rusty-fork" version = "0.3.0" @@ -19409,7 +19459,6 @@ checksum = "295642060261c80709ac034f52fca8e5a9fa2c7d341ded5cdb164b7c33768b2a" dependencies = [ "rand 0.6.5", "secp256k1-sys 0.5.2", - "serde", ] [[package]] @@ -19431,7 +19480,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "bitcoin_hashes 0.14.0", + "rand 0.8.5", "secp256k1-sys 0.10.1", + "serde", ] [[package]] @@ -21573,7 +21624,7 @@ dependencies = [ "ic-crypto-tree-hash", "leb128", "maplit", - "proptest", + "proptest 1.6.0", "proptest-derive", "serde", ] @@ -23198,3 +23249,8 @@ dependencies = [ "cc", "pkg-config", ] + +[[patch.unused]] +name = "jsonrpc" +version = "0.12.1" +source = "git+https://github.com/apoelstra/rust-jsonrpc?rev=e42044d#e42044d8e0896317488dfbd65eb5563d76e937fe" diff --git a/Cargo.toml b/Cargo.toml index 2a2cc45c379..d9b2baf1431 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -509,7 +509,8 @@ axum = "0.7.9" backoff = "0.4" base64 = { version = "0.13.1" } bincode = "1.3.3" -bitcoin = { version = "0.28.2", features = ["default", "use-serde", "rand"] } +bitcoin = { version = "0.32.4", features = ["default", "rand", "serde"] } +bitcoincore-rpc = "0.19.0" # build-info and build-info-build MUST be kept in sync! build-info = { git = "https://github.com/dfinity-lab/build-info", rev = "701a696844fba5c87df162fbbc1ccef96f27c9d7" } build-info-build = { git = "https://github.com/dfinity-lab/build-info", rev = "701a696844fba5c87df162fbbc1ccef96f27c9d7", default-features = false } diff --git a/bazel/external_crates.bzl b/bazel/external_crates.bzl index f25afadc154..6d34ca53ca2 100644 --- a/bazel/external_crates.bzl +++ b/bazel/external_crates.bzl @@ -266,12 +266,17 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable "bit-vec": crate.spec( version = "^0.6.3", ), - "bitcoin-0-32": crate.spec( - package = "bitcoin", - version = "^0.32.2", + "bitcoin": crate.spec( + version = "^0.32.4", + features = [ + "std", + "rand", + "serde", + ], default_features = False, ), - "bitcoin": crate.spec( + "bitcoin-0-28": crate.spec( + package = "bitcoin", version = "^0.28.2", features = [ "default", @@ -280,7 +285,7 @@ def external_crates_repository(name, cargo_lockfile, lockfile, sanitizers_enable ], ), "bitcoincore-rpc": crate.spec( - version = "^0.15.0", + version = "^0.19.0", ), "bitcoind": crate.spec( version = "^0.32.0", diff --git a/packages/pocket-ic/BUILD.bazel b/packages/pocket-ic/BUILD.bazel index c300ced383d..3cbe06bfe13 100644 --- a/packages/pocket-ic/BUILD.bazel +++ b/packages/pocket-ic/BUILD.bazel @@ -33,7 +33,8 @@ MACRO_DEPENDENCIES = [ TEST_DEPENDENCIES = [ # Keep sorted. "//rs/types/error_types", - "@crate_index//:bitcoin", + #TODO: try upgrading this to the latest bitcion crate + "@crate_index//:bitcoin_0_28", "@crate_index//:candid_parser", "@crate_index//:ed25519-dalek", "@crate_index//:flate2", diff --git a/packages/pocket-ic/Cargo.toml b/packages/pocket-ic/Cargo.toml index fbf1a1555bf..2f607c8ed66 100644 --- a/packages/pocket-ic/Cargo.toml +++ b/packages/pocket-ic/Cargo.toml @@ -46,7 +46,8 @@ tracing-subscriber = { workspace = true } wslpath = "0.0.2" [dev-dependencies] -bitcoin = { workspace = true } +#TODO: try upgrading this to the latest bitcion crate +bitcoin = { version = "0.28.2" } candid_parser = { workspace = true } ed25519-dalek = { workspace = true } flate2 = { workspace = true } diff --git a/rs/bitcoin/adapter/Cargo.toml b/rs/bitcoin/adapter/Cargo.toml index 38c50a38463..41e657a1a14 100644 --- a/rs/bitcoin/adapter/Cargo.toml +++ b/rs/bitcoin/adapter/Cargo.toml @@ -22,6 +22,7 @@ ic-config = { path = "../../config" } ic-logger = { path = "../../monitoring/logger" } ic-metrics = { path = "../../monitoring/metrics" } parking_lot = { workspace = true } +primitive-types = "0.12" prometheus = { workspace = true } prost = { workspace = true } rand = { workspace = true } @@ -36,7 +37,7 @@ tonic = { workspace = true } tower = { workspace = true, optional = true } [dev-dependencies] -bitcoincore-rpc = "0.15.0" +bitcoincore-rpc = { workspace = true } bitcoind = "0.32.0" criterion = { workspace = true } ic-btc-adapter-client = { path = "../client" } diff --git a/rs/bitcoin/adapter/benches/e2e.rs b/rs/bitcoin/adapter/benches/e2e.rs index 6702e2657b7..1248a1bbbb5 100644 --- a/rs/bitcoin/adapter/benches/e2e.rs +++ b/rs/bitcoin/adapter/benches/e2e.rs @@ -1,4 +1,6 @@ -use bitcoin::{blockdata::constants::genesis_block, BlockHash, BlockHeader, Network}; +use bitcoin::{ + block::Header as BlockHeader, blockdata::constants::genesis_block, BlockHash, Network, +}; use criterion::{criterion_group, criterion_main, Criterion}; use ic_btc_adapter::config::Config; use ic_btc_adapter::config::IncomingSource; diff --git a/rs/bitcoin/adapter/src/addressbook.rs b/rs/bitcoin/adapter/src/addressbook.rs index eb67a39402f..370c109647f 100644 --- a/rs/bitcoin/adapter/src/addressbook.rs +++ b/rs/bitcoin/adapter/src/addressbook.rs @@ -1,5 +1,6 @@ use crate::config::Config; -use bitcoin::network::{constants::ServiceFlags, Address}; +use bitcoin::p2p::Address; +use bitcoin::p2p::ServiceFlags; use ic_logger::{info, ReplicaLogger}; use rand::{ prelude::{IteratorRandom, SliceRandom, StdRng}, diff --git a/rs/bitcoin/adapter/src/blockchainmanager.rs b/rs/bitcoin/adapter/src/blockchainmanager.rs index ccc3ffc2063..56e7a0eca2e 100644 --- a/rs/bitcoin/adapter/src/blockchainmanager.rs +++ b/rs/bitcoin/adapter/src/blockchainmanager.rs @@ -5,11 +5,13 @@ use crate::{ Channel, Command, ProcessBitcoinNetworkMessageError, }; use bitcoin::{ - network::{ + block::Header as BlockHeader, + hashes::Hash as _, + p2p::{ message::{NetworkMessage, MAX_INV_SIZE}, message_blockdata::{GetHeadersMessage, Inventory}, }, - Block, BlockHash, BlockHeader, + Block, BlockHash, }; use hashlink::{LinkedHashMap, LinkedHashSet}; use ic_btc_validation::ValidateHeaderError; @@ -389,7 +391,7 @@ impl BlockchainManager { if headers.len() < MAX_HEADERS_SIZE { None } else { - Some((vec![last.header.block_hash()], BlockHash::default())) + Some((vec![last.header.block_hash()], BlockHash::all_zeros())) } } else { None @@ -472,7 +474,7 @@ impl BlockchainManager { tip: initial_hash, }, ); - let locators = (locator_hashes, BlockHash::default()); + let locators = (locator_hashes, BlockHash::all_zeros()); self.send_getheaders(channel, addr, locators); } @@ -687,7 +689,7 @@ impl BlockchainManager { if !self.getheaders_requests.contains_key(&addr) && self.catchup_headers.contains(&addr) { let locators = self.blockchain.lock().unwrap().locator_hashes(); - self.send_getheaders(channel, &addr, (locators, BlockHash::default())); + self.send_getheaders(channel, &addr, (locators, BlockHash::all_zeros())); self.catchup_headers.remove(&addr); } } @@ -777,9 +779,7 @@ pub mod test { use bitcoin::blockdata::constants::genesis_block; use bitcoin::consensus::deserialize; use bitcoin::Network; - use bitcoin::{ - network::message::NetworkMessage, network::message_blockdata::Inventory, BlockHash, - }; + use bitcoin::{p2p::message::NetworkMessage, BlockHash}; use hex::FromHex; use ic_btc_adapter_test_utils::{ generate_headers, generate_large_block_blockchain, BLOCK_1_ENCODED, BLOCK_2_ENCODED, @@ -815,7 +815,7 @@ pub mod test { assert_eq!(channel.command_count(), 1); - let locators = (vec![genesis_hash], BlockHash::default()); + let locators = (vec![genesis_hash], BlockHash::all_zeros()); blockchain_manager.send_getheaders(&mut channel, &addr, locators.clone()); assert!(blockchain_manager.getheaders_requests.contains_key(&addr)); let request = blockchain_manager.getheaders_requests.get(&addr).unwrap(); @@ -824,7 +824,7 @@ pub mod test { let command = channel.pop_front().expect("command not found"); assert!(matches!(command.address, Some(address) if address == addr)); assert!( - matches!(&command.message, NetworkMessage::GetHeaders(GetHeadersMessage { version: _, locator_hashes: _, stop_hash }) if *stop_hash == BlockHash::default()) + matches!(&command.message, NetworkMessage::GetHeaders(GetHeadersMessage { version: _, locator_hashes: _, stop_hash }) if *stop_hash == BlockHash::all_zeros()) ); assert!( matches!(&command.message, NetworkMessage::GetHeaders(GetHeadersMessage { version, locator_hashes: _, stop_hash: _ }) if *version == MINIMUM_VERSION_NUMBER) @@ -894,7 +894,7 @@ pub mod test { _ => GetHeadersMessage { version: 0, locator_hashes: vec![], - stop_hash: BlockHash::default(), + stop_hash: BlockHash::all_zeros(), }, }; assert_eq!( @@ -904,7 +904,7 @@ pub mod test { ); assert_eq!( get_headers_message.stop_hash, - BlockHash::default(), + BlockHash::all_zeros(), "Didn't send the right stop hash for initial syncing" ); @@ -932,7 +932,7 @@ pub mod test { _ => GetHeadersMessage { version: 0, locator_hashes: vec![], - stop_hash: BlockHash::default(), + stop_hash: BlockHash::all_zeros(), }, }; assert_eq!( @@ -941,7 +941,7 @@ pub mod test { ); assert_eq!( get_headers_message.stop_hash, - BlockHash::default(), + BlockHash::all_zeros(), "Didn't send the right stop hash for initial syncing" ); } diff --git a/rs/bitcoin/adapter/src/blockchainstate.rs b/rs/bitcoin/adapter/src/blockchainstate.rs index 1bda79b46ad..b0711f5e3b1 100644 --- a/rs/bitcoin/adapter/src/blockchainstate.rs +++ b/rs/bitcoin/adapter/src/blockchainstate.rs @@ -1,14 +1,16 @@ //! The module is responsible for keeping track of the blockchain state. //! use crate::{common::BlockHeight, config::Config, metrics::BlockchainStateMetrics}; -use bitcoin::{blockdata::constants::genesis_block, Block, BlockHash, BlockHeader, Network}; +use bitcoin::{ + block::Header as BlockHeader, blockdata::constants::genesis_block, Block, BlockHash, Network, +}; + use ic_btc_validation::{validate_header, HeaderStore, ValidateHeaderError}; use ic_metrics::MetricsRegistry; use std::collections::HashMap; use thiserror::Error; -/// This field contains the datatype used to store "work" of a Bitcoin blockchain -pub type Work = bitcoin::util::uint::Uint256; +use bitcoin::Work; /// Contains the necessary information about a tip. #[derive(Clone, Debug)] @@ -328,7 +330,9 @@ impl BlockchainState { /// Returns the current size of the block cache. pub fn get_block_cache_size(&self) -> usize { - self.block_cache.values().fold(0, |sum, b| b.size() + sum) + self.block_cache + .values() + .fold(0, |sum, b| b.total_size() + sum) } } @@ -338,13 +342,13 @@ impl HeaderStore for BlockchainState { .map(|cached| (cached.header, cached.height)) } - fn get_height(&self) -> BlockHeight { - self.get_active_chain_tip().height - } - fn get_initial_hash(&self) -> BlockHash { self.genesis().block_hash() } + + fn get_height(&self) -> BlockHeight { + self.get_active_chain_tip().height + } } #[cfg(test)] @@ -538,7 +542,7 @@ mod test { let initial_header = state.genesis(); let mut chain = generate_headers(initial_header.block_hash(), initial_header.time, 16, &[]); let last_header = chain.get_mut(10).unwrap(); - last_header.prev_blockhash = BlockHash::default(); + last_header.prev_blockhash = BlockHash::from_raw_hash(bitcoin::hashes::Hash::all_zeros()); let chain_hashes: Vec = chain.iter().map(|header| header.block_hash()).collect(); let last_hash = chain_hashes[10]; @@ -575,7 +579,8 @@ mod test { assert!(matches!(result, Ok(()))); // Make a block 2's merkle root invalid and try to add the block to the cache. - block_2.header.merkle_root = TxMerkleNode::default(); + block_2.header.merkle_root = + TxMerkleNode::from_raw_hash(bitcoin::hashes::Hash::all_zeros()); // Block 2's hash will now be changed because of the merkle root change. let block_2_hash = block_2.block_hash(); let result = state.add_block(block_2); @@ -632,7 +637,7 @@ mod test { state.add_block(test_state.block_1.clone()).unwrap(); state.add_block(test_state.block_2.clone()).unwrap(); - let expected_cache_size = test_state.block_1.size() + test_state.block_2.size(); + let expected_cache_size = test_state.block_1.total_size() + test_state.block_2.total_size(); let block_cache_size = state.get_block_cache_size(); assert_eq!(expected_cache_size, block_cache_size); @@ -685,7 +690,7 @@ mod test { /// Test header store `get_header` function. #[test] - fn test_headerstore_get_header() { + fn test_headerstore_get_cached_header() { let config = ConfigBuilder::new().with_network(Network::Regtest).build(); let mut state = BlockchainState::new(&config, &MetricsRegistry::default()); @@ -700,9 +705,10 @@ mod test { if h == 0 { assert_eq!(state.get_initial_hash(), state.genesis().block_hash(),); } else { + let header_node = state.get_cached_header(&header.block_hash()).unwrap(); assert_eq!( - state.get_header(&header.block_hash()).unwrap(), - (chain[h], (h + 1) as u32), + (header_node.header, header_node.height), + (chain[h], (h + 1) as u32) ); } } diff --git a/rs/bitcoin/adapter/src/config.rs b/rs/bitcoin/adapter/src/config.rs index 9c69afd12f4..3082e41e734 100644 --- a/rs/bitcoin/adapter/src/config.rs +++ b/rs/bitcoin/adapter/src/config.rs @@ -64,6 +64,7 @@ pub(crate) fn address_limits(network: Network) -> (usize, usize) { Network::Testnet => (100, 1000), Network::Signet => (1, 1), Network::Regtest => (1, 1), + other => unreachable!("Unsupported network: {:?}", other), } } diff --git a/rs/bitcoin/adapter/src/connection.rs b/rs/bitcoin/adapter/src/connection.rs index d5cc54493b9..3fabee72f98 100644 --- a/rs/bitcoin/adapter/src/connection.rs +++ b/rs/bitcoin/adapter/src/connection.rs @@ -1,5 +1,5 @@ use crate::addressbook::AddressEntry; -use bitcoin::network::message::NetworkMessage; +use bitcoin::p2p::message::NetworkMessage; use std::time::{Duration, SystemTime}; use thiserror::Error; use tokio::{sync::mpsc::UnboundedSender, task::JoinHandle}; diff --git a/rs/bitcoin/adapter/src/connectionmanager.rs b/rs/bitcoin/adapter/src/connectionmanager.rs index 91b5d605ba7..eeb9f8eaad6 100644 --- a/rs/bitcoin/adapter/src/connectionmanager.rs +++ b/rs/bitcoin/adapter/src/connectionmanager.rs @@ -4,11 +4,12 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; -use bitcoin::network::{ - constants::ServiceFlags, +use bitcoin::p2p::ServiceFlags; + +use bitcoin::p2p::{ message::{CommandString, NetworkMessage}, message_network::VersionMessage, - Address, + Address, Magic, }; use ic_logger::{error, info, trace, warn, ReplicaLogger}; use rand::prelude::*; @@ -81,7 +82,7 @@ pub struct ConnectionManager { logger: ReplicaLogger, /// This field is used to provide the magic value to the raw network message. /// The magic number is used to identity the type of Bitcoin network being accessed. - magic: u32, + magic: Magic, /// This field contains the number of connections the connection manager can manage at one time. max_connections: usize, /// This field contains the number of connections the connection manager must have in order to send messages. @@ -693,7 +694,8 @@ fn connection_limits(address_book: &AddressBook) -> (usize, usize) { mod test { use super::*; use crate::config::test::ConfigBuilder; - use bitcoin::{network::constants::ServiceFlags, Network}; + use bitcoin::p2p::ServiceFlags; + use bitcoin::Network; use ic_logger::replica_logger::no_op_logger; use ic_metrics::MetricsRegistry; use std::str::FromStr; diff --git a/rs/bitcoin/adapter/src/get_successors_handler.rs b/rs/bitcoin/adapter/src/get_successors_handler.rs index a9c1a137f11..d3ddc79e9ea 100644 --- a/rs/bitcoin/adapter/src/get_successors_handler.rs +++ b/rs/bitcoin/adapter/src/get_successors_handler.rs @@ -3,7 +3,7 @@ use std::{ sync::{Arc, Mutex}, }; -use bitcoin::{Block, BlockHash, BlockHeader, Network}; +use bitcoin::{block::Header as BlockHeader, Block, BlockHash, Network}; use ic_metrics::MetricsRegistry; use tokio::sync::mpsc::Sender; use tonic::Status; @@ -168,7 +168,7 @@ fn get_successor_blocks( // Retrieve the block from the cache. match state.get_block(block_hash) { Some(block) => { - let block_size = block.size(); + let block_size = block.total_size(); if response_block_size == 0 || (response_block_size + block_size <= MAX_BLOCKS_BYTES && successor_blocks.len() < MAX_BLOCKS_LENGTH @@ -238,6 +238,7 @@ fn are_multiple_blocks_allowed(network: Network, anchor_height: BlockHeight) -> match network { Network::Bitcoin => anchor_height <= MAINNET_MAX_MULTI_BLOCK_ANCHOR_HEIGHT, Network::Testnet | Network::Signet | Network::Regtest => true, + other => unreachable!("Unsupported network: {:?}", other), } } diff --git a/rs/bitcoin/adapter/src/lib.rs b/rs/bitcoin/adapter/src/lib.rs index 61329ee5136..4d6a91a635d 100644 --- a/rs/bitcoin/adapter/src/lib.rs +++ b/rs/bitcoin/adapter/src/lib.rs @@ -4,7 +4,8 @@ //! and publish transactions. Moreover, it interacts with the Bitcoin system //! component to provide blocks and collect outgoing transactions. -use bitcoin::{network::message::NetworkMessage, BlockHash, BlockHeader}; +use bitcoin::p2p::message::NetworkMessage; +use bitcoin::{block::Header as BlockHeader, BlockHash}; use ic_logger::ReplicaLogger; use ic_metrics::MetricsRegistry; use std::{ diff --git a/rs/bitcoin/adapter/src/router.rs b/rs/bitcoin/adapter/src/router.rs index a4f10ad02da..a74d1b61fa8 100644 --- a/rs/bitcoin/adapter/src/router.rs +++ b/rs/bitcoin/adapter/src/router.rs @@ -7,7 +7,7 @@ use crate::{ Channel, ProcessBitcoinNetworkMessage, ProcessBitcoinNetworkMessageError, ProcessEvent, TransactionManagerRequest, }; -use bitcoin::network::message::NetworkMessage; +use bitcoin::p2p::message::NetworkMessage; use ic_logger::ReplicaLogger; use ic_metrics::MetricsRegistry; use std::net::SocketAddr; diff --git a/rs/bitcoin/adapter/src/stream.rs b/rs/bitcoin/adapter/src/stream.rs index 7aab1e945ca..46252773590 100644 --- a/rs/bitcoin/adapter/src/stream.rs +++ b/rs/bitcoin/adapter/src/stream.rs @@ -1,7 +1,9 @@ +use bitcoin::io as bitcoin_io; use bitcoin::{ consensus::serialize, - network::message::RawNetworkMessage, - {consensus::encode, network::message::NetworkMessage}, + p2p::message::RawNetworkMessage, + p2p::Magic, + {consensus::encode, p2p::message::NetworkMessage}, }; use futures::TryFutureExt; use http::Uri; @@ -69,7 +71,7 @@ pub struct StreamConfig { pub logger: ReplicaLogger, /// This field is used to provide the magic value to the raw network message. /// The magic number is used to identity the type of Bitcoin network being accessed. - pub magic: u32, + pub magic: Magic, /// This field is used to receive network messages to send out to the connected /// BTC node. pub network_message_receiver: UnboundedReceiver, @@ -116,8 +118,8 @@ pub struct Stream { read_half: OwnedReadHalf, write_half: OwnedWriteHalf, /// This field is used to provide the magic value to the raw network message. - /// The magic number is used to identity the type of Bitcoin network being accessed. - magic: u32, + /// The magic number is used to identify the type of Bitcoin network being accessed. + magic: Magic, /// This field contains the receiver used to intake messages that are to be /// sent to the connected node. network_message_receiver: UnboundedReceiver, @@ -228,7 +230,9 @@ impl Stream { // If the read successfully received bytes, then the bytes are added to the // unparsed buffer to attempt another deserialize call. If no bytes found, // return the unexpected end-of-file error. - Err(encode::Error::Io(ref err)) if err.kind() == io::ErrorKind::UnexpectedEof => { + Err(encode::Error::Io(ref err)) + if err.kind() == bitcoin_io::ErrorKind::UnexpectedEof => + { let count = self .read_half .try_read(&mut self.data) @@ -248,7 +252,7 @@ impl Stream { // and then re-wrap it into a StreamError. Err(err) => { return Err(match err { - encode::Error::Io(err) => StreamError::Io(err), + encode::Error::Io(err) => StreamError::Io(err.into()), err => StreamError::Encode(err), }); } @@ -265,10 +269,7 @@ impl Stream { /// This function is used to write a network message to the connected Bitcoin /// node. async fn write_message(&mut self, network_message: NetworkMessage) -> StreamResult<()> { - let raw_network_message = RawNetworkMessage { - magic: self.magic, - payload: network_message, - }; + let raw_network_message = RawNetworkMessage::new(self.magic, network_message); let bytes = serialize(&raw_network_message); self.write_half .write_all(bytes.as_slice()) @@ -290,7 +291,7 @@ impl Stream { let raw_message = self.read_message()?; let result = self .network_message_sender - .send((self.address, raw_message.payload)) + .send((self.address, raw_message.payload().clone())) .await; if result.is_err() { return Err(StreamError::UnableToReceiveMessages); @@ -411,10 +412,10 @@ pub mod test { // Send message that exceeds size limit. tokio::spawn(async move { let (mut socket, _addr) = listener.accept().await.unwrap(); - let addr = RawNetworkMessage { - magic: network.magic(), - payload: NetworkMessage::Alert(vec![0; MAX_RAW_MESSAGE_SIZE + 10]), - }; + let addr = RawNetworkMessage::new( + network.magic(), + NetworkMessage::Alert(vec![0; MAX_RAW_MESSAGE_SIZE + 10]), + ); let mut buf = Vec::new(); let raw_addr = addr.consensus_encode(&mut buf).unwrap(); socket.write_all(&buf[..raw_addr]).await.unwrap(); @@ -492,18 +493,18 @@ pub mod test { ); // Large messgage just below limit. - let payload_large = RawNetworkMessage { - magic: network.magic(), - payload: NetworkMessage::Alert(vec![0; MAX_RAW_MESSAGE_SIZE - 30]), - }; + let payload_large = RawNetworkMessage::new( + network.magic(), + NetworkMessage::Alert(vec![0; MAX_RAW_MESSAGE_SIZE - 30]), + ); let mut buf_large = Vec::new(); let _ = payload_large.consensus_encode(&mut buf_large).unwrap(); // Message that crosses the boundary limit. - let payload_small = RawNetworkMessage { - magic: network.magic(), - payload: NetworkMessage::Alert(vec![0; 31 + STREAM_BUFFER_SIZE]), - }; + let payload_small = RawNetworkMessage::new( + network.magic(), + NetworkMessage::Alert(vec![0; 31 + STREAM_BUFFER_SIZE]), + ); let mut buf_small = Vec::new(); let _ = payload_small.consensus_encode(&mut buf_small).unwrap(); @@ -515,11 +516,11 @@ pub mod test { assert_eq!( net_rx.recv().await.unwrap(), - (address, payload_large.payload) + (address, payload_large.payload().clone()) ); assert_eq!( net_rx.recv().await.unwrap(), - (address, payload_small.payload) + (address, payload_small.payload().clone()) ); } } diff --git a/rs/bitcoin/adapter/src/stress_test.rs b/rs/bitcoin/adapter/src/stress_test.rs index 2ea6e3767d4..57949cf22cd 100644 --- a/rs/bitcoin/adapter/src/stress_test.rs +++ b/rs/bitcoin/adapter/src/stress_test.rs @@ -57,8 +57,11 @@ async fn main() { loop { let mut request = tonic::Request::new(BtcServiceGetSuccessorsRequest { - processed_block_hashes: processed_block_hashes.iter().map(|h| h.to_vec()).collect(), - anchor: current_anchor.to_vec(), + processed_block_hashes: processed_block_hashes + .iter() + .map(|h| h[..].to_vec()) + .collect(), + anchor: current_anchor[..].to_vec(), }); request.set_timeout(request_timeout_ms); @@ -79,7 +82,11 @@ async fn main() { let block_hashes = inner .blocks .iter() - .map(|b| Block::consensus_decode(b.as_slice()).unwrap().block_hash()) + .map(|b| { + Block::consensus_decode(&mut b.as_slice()) + .unwrap() + .block_hash() + }) .collect::>(); current_anchor = *block_hashes.last().expect("failed to get last block hash"); diff --git a/rs/bitcoin/adapter/src/transaction_store.rs b/rs/bitcoin/adapter/src/transaction_store.rs index e25d1274c04..29e2e743fa4 100644 --- a/rs/bitcoin/adapter/src/transaction_store.rs +++ b/rs/bitcoin/adapter/src/transaction_store.rs @@ -4,8 +4,8 @@ use std::{time::Duration, time::SystemTime}; use bitcoin::consensus::deserialize; use bitcoin::{ - blockdata::transaction::Transaction, hash_types::Txid, network::message::NetworkMessage, - network::message_blockdata::Inventory, + blockdata::transaction::Transaction, hash_types::Txid, p2p::message::NetworkMessage, + p2p::message_blockdata::Inventory, }; use hashlink::LinkedHashMap; use ic_logger::{debug, info, trace, ReplicaLogger}; @@ -86,7 +86,7 @@ impl TransactionStore { .txn_ops .with_label_values(&["insert", "enqueued"]) .inc(); - let txid = transaction.txid(); + let txid = transaction.compute_txid(); trace!(self.logger, "Received {} from the system component", txid); // If hashmap has `TX_CACHE_SIZE` values we remove the oldest transaction in the cache. if self.transactions.len() == TX_CACHE_SIZE { @@ -203,7 +203,10 @@ mod test { use super::*; use crate::common::test_common::TestChannel; use bitcoin::{ - blockdata::constants::genesis_block, consensus::serialize, Network, Transaction, + absolute::{LockTime, LOCK_TIME_THRESHOLD}, + blockdata::constants::genesis_block, + consensus::serialize, + Network, Transaction, }; use ic_logger::replica_logger::no_op_logger; use std::str::FromStr; @@ -245,7 +248,7 @@ mod test { let info = manager .transactions - .get_mut(&transaction.txid()) + .get_mut(&transaction.compute_txid()) .expect("transaction should be map"); info.ttl = SystemTime::now() - Duration::from_secs(TX_CACHE_TIMEOUT_PERIOD_SECS); manager.advertise_txids(&mut channel); @@ -264,12 +267,12 @@ mod test { let mut manager = make_transaction_manager(); let transaction = get_transaction(); let raw_tx = serialize(&transaction); - let txid = transaction.txid(); + let txid = transaction.compute_txid(); manager.enqueue_transaction(&raw_tx); assert_eq!(manager.transactions.len(), 1); let info = manager .transactions - .get(&transaction.txid()) + .get(&transaction.compute_txid()) .expect("transaction should be map"); assert!(info.advertised.is_empty()); // Initial broadcast @@ -304,7 +307,7 @@ mod test { // Send one transaction. This transaction should be removed first if we are at capacity. let mut first_tx = get_transaction(); - first_tx.lock_time = u32::MAX; + first_tx.lock_time = LockTime::from_height(LOCK_TIME_THRESHOLD - 1).unwrap(); let raw_tx = serialize(&first_tx); manager.enqueue_transaction(&raw_tx); @@ -312,12 +315,12 @@ mod test { // First regtest genesis transaction. let mut transaction = get_transaction(); // Alter transaction such that we get a different `txid` - transaction.lock_time = i.try_into().unwrap(); + transaction.lock_time = LockTime::from_height(i.try_into().unwrap()).unwrap(); let raw_tx = serialize(&transaction); manager.enqueue_transaction(&raw_tx); } assert_eq!(manager.transactions.len(), TX_CACHE_SIZE); - assert!(manager.transactions.get(&first_tx.txid()).is_none()); + assert!(manager.transactions.get(&first_tx.compute_txid()).is_none()); } /// This function tests that we don't readvertise transactions that were already advertised. @@ -333,7 +336,7 @@ mod test { let mut manager = make_transaction_manager(); let mut transaction = get_transaction(); - transaction.lock_time = 0; + transaction.lock_time = LockTime::ZERO; let raw_tx = serialize(&transaction); manager.enqueue_transaction(&raw_tx); manager.advertise_txids(&mut channel); @@ -344,7 +347,7 @@ mod test { .process_bitcoin_network_message( &mut channel, address, - &NetworkMessage::GetData(vec![Inventory::Transaction(transaction.txid())]), + &NetworkMessage::GetData(vec![Inventory::Transaction(transaction.compute_txid())]), ) .unwrap(); // Send transaction @@ -357,7 +360,7 @@ mod test { assert_eq!( manager .transactions - .get(&transaction.txid()) + .get(&transaction.compute_txid()) .unwrap() .advertised .len(), @@ -366,7 +369,7 @@ mod test { assert_eq!( manager .transactions - .get(&transaction.txid()) + .get(&transaction.compute_txid()) .unwrap() .advertised .get(&address), @@ -388,7 +391,7 @@ mod test { let mut manager = make_transaction_manager(); let mut transaction = get_transaction(); - transaction.lock_time = 0; + transaction.lock_time = LockTime::ZERO; let raw_tx = serialize(&transaction); manager.enqueue_transaction(&raw_tx); manager.advertise_txids(&mut channel); @@ -402,7 +405,7 @@ mod test { .process_bitcoin_network_message( &mut channel, address1, - &NetworkMessage::GetData(vec![Inventory::Transaction(transaction.txid())]), + &NetworkMessage::GetData(vec![Inventory::Transaction(transaction.compute_txid())]), ) .unwrap(); // Send transaction to peer 1 @@ -429,7 +432,7 @@ mod test { // 1. let mut transaction = get_transaction(); - transaction.lock_time = 0; + transaction.lock_time = LockTime::ZERO; let raw_tx = serialize(&transaction); manager.enqueue_transaction(&raw_tx); manager.advertise_txids(&mut channel); @@ -441,7 +444,7 @@ mod test { .process_bitcoin_network_message( &mut channel, address1, - &NetworkMessage::GetData(vec![Inventory::Transaction(transaction.txid())]), + &NetworkMessage::GetData(vec![Inventory::Transaction(transaction.compute_txid())]), ) .unwrap(); channel.pop_front().unwrap(); @@ -461,7 +464,9 @@ mod test { channel.pop_front().unwrap(), Command { address: Some(address2), - message: NetworkMessage::Inv(vec![Inventory::Transaction(transaction.txid())]) + message: NetworkMessage::Inv(vec![Inventory::Transaction( + transaction.compute_txid() + )]) } ); } @@ -479,7 +484,7 @@ mod test { let mut manager = make_transaction_manager(); let transaction = get_transaction(); let raw_tx = serialize(&transaction); - let txid = transaction.txid(); + let txid = transaction.compute_txid(); manager.enqueue_transaction(&raw_tx); assert_eq!(manager.transactions.len(), 1); manager @@ -491,7 +496,7 @@ mod test { .ok(); assert_eq!(channel.command_count(), 1); let command = channel.pop_front().unwrap(); - assert!(matches!(command.message, NetworkMessage::Tx(t) if t.txid() == txid)); + assert!(matches!(command.message, NetworkMessage::Tx(t) if t.compute_txid() == txid)); } /// This function tests the `TransactionStore::process_bitcoin_network_message(...)` method. @@ -510,8 +515,8 @@ mod test { // First regtest genesis transaction. let mut transaction = get_transaction(); // Alter transaction such that we get a different `txid` - transaction.lock_time = i.try_into().unwrap(); - let txid = transaction.txid(); + transaction.lock_time = LockTime::from_height(i.try_into().unwrap()).unwrap(); + let txid = transaction.compute_txid(); inventory.push(Inventory::Transaction(txid)); } manager @@ -536,7 +541,7 @@ mod test { let mut manager = make_transaction_manager(); let transaction = get_transaction(); let raw_tx = serialize(&transaction); - let txid = transaction.txid(); + let txid = transaction.compute_txid(); manager.enqueue_transaction(&raw_tx); manager.advertise_txids(&mut channel); manager @@ -561,12 +566,12 @@ mod test { ); let command = channel.pop_front().unwrap(); - assert!(matches!(command.message, NetworkMessage::Tx(t) if t.txid() == txid)); + assert!(matches!(command.message, NetworkMessage::Tx(t) if t.compute_txid() == txid)); manager.enqueue_transaction(&raw_tx); let info = manager .transactions - .get_mut(&transaction.txid()) + .get_mut(&transaction.compute_txid()) .expect("transaction should be in the map"); info.ttl = SystemTime::now() - Duration::from_secs(TX_CACHE_TIMEOUT_PERIOD_SECS); manager.advertise_txids(&mut channel); diff --git a/rs/bitcoin/adapter/test_utils/src/bitcoind.rs b/rs/bitcoin/adapter/test_utils/src/bitcoind.rs index da9c0c83365..b3ef7a9b94c 100644 --- a/rs/bitcoin/adapter/test_utils/src/bitcoind.rs +++ b/rs/bitcoin/adapter/test_utils/src/bitcoind.rs @@ -5,16 +5,21 @@ use std::{ sync::Arc, }; +use bitcoin::p2p::{Magic, ServiceFlags}; + use bitcoin::{ + block::Header as BlockHeader, consensus::{deserialize_partial, encode, serialize}, - network::{ - constants::ServiceFlags, + p2p::{ message::{NetworkMessage, RawNetworkMessage}, message_blockdata::{GetHeadersMessage, Inventory}, message_network::VersionMessage, }, - Block, BlockHash, BlockHeader, + Block, BlockHash, }; + +use bitcoin::io as bitcoin_io; + use tokio::{ io::{AsyncReadExt, AsyncWriteExt}, net::{TcpListener, TcpStream}, @@ -24,10 +29,10 @@ const MINIMUM_PROTOCOL_VERSION: u32 = 70001; async fn write_network_message( socket: &mut TcpStream, - magic: u32, + magic: Magic, payload: NetworkMessage, ) -> io::Result<()> { - let res = RawNetworkMessage { magic, payload }; + let res = RawNetworkMessage::new(magic, payload); let serialized = serialize(&res); socket.write_all(&serialized).await?; socket.flush().await?; @@ -36,8 +41,8 @@ async fn write_network_message( async fn handle_getdata( socket: &mut TcpStream, - msg: Vec, - magic: u32, + msg: &[Inventory], + magic: Magic, blocks: Arc>, ) -> io::Result<()> { for inv in msg.iter() { @@ -57,11 +62,15 @@ async fn handle_getdata( Ok(()) } -async fn handle_ping(socket: &mut TcpStream, val: u64, magic: u32) -> io::Result<()> { +async fn handle_ping(socket: &mut TcpStream, val: u64, magic: Magic) -> io::Result<()> { write_network_message(socket, magic, NetworkMessage::Pong(val)).await } -async fn handle_version(socket: &mut TcpStream, v: VersionMessage, magic: u32) -> io::Result<()> { +async fn handle_version( + socket: &mut TcpStream, + v: &VersionMessage, + magic: Magic, +) -> io::Result<()> { if v.version < MINIMUM_PROTOCOL_VERSION { let err = io::Error::new(ErrorKind::Other, "Protocol version too low"); return Err(err); @@ -73,14 +82,14 @@ async fn handle_version(socket: &mut TcpStream, v: VersionMessage, magic: u32) - Ok(()) } -async fn handle_getaddr(socket: &mut TcpStream, magic: u32) -> io::Result<()> { +async fn handle_getaddr(socket: &mut TcpStream, magic: Magic) -> io::Result<()> { write_network_message(socket, magic, NetworkMessage::Addr(vec![])).await } async fn handle_getheaders( socket: &mut TcpStream, - msg: GetHeadersMessage, - magic: u32, + msg: &GetHeadersMessage, + magic: Magic, cached_headers: Arc>, children: Arc>>, ) -> io::Result<()> { @@ -89,18 +98,18 @@ async fn handle_getheaders( let locator = { let mut found = None; - for locator in msg.locator_hashes { - if cached_headers.contains_key(&locator) { - found = Some(locator); + for locator in &msg.locator_hashes { + if cached_headers.contains_key(locator) { + found = Some(*locator); break; } } - found.unwrap_or( + found.unwrap_or_else(|| { // If no locators are found, use the genesis hash. "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" .parse() - .unwrap(), - ) + .unwrap() + }) }; let mut queue = VecDeque::new(); @@ -183,22 +192,22 @@ impl FakeBitcoind { match deserialize_partial::(&unparsed) { Ok((raw, cnt)) => { let handler_result = - match raw.payload { + match raw.payload() { NetworkMessage::Version(v) => { - handle_version(&mut socket, v, raw.magic).await + handle_version(&mut socket, v, *raw.magic()).await } NetworkMessage::Verack => Ok(()), NetworkMessage::GetAddr => { - handle_getaddr(&mut socket, raw.magic).await + handle_getaddr(&mut socket, *raw.magic()).await } NetworkMessage::GetHeaders(msg) => { - handle_getheaders(&mut socket, msg, raw.magic, cached_headers.clone(), children.clone()).await + handle_getheaders(&mut socket, msg, *raw.magic(), cached_headers.clone(), children.clone()).await } NetworkMessage::GetData(msg) => { - handle_getdata(&mut socket, msg, raw.magic, blocks.clone()).await + handle_getdata(&mut socket, msg, *raw.magic(), blocks.clone()).await } NetworkMessage::Ping(val) => { - handle_ping(&mut socket, val, raw.magic).await + handle_ping(&mut socket, *val, *raw.magic()).await } smth => panic!("Unexpected NetworkMessage: {:?}", smth), }; @@ -208,7 +217,7 @@ impl FakeBitcoind { unparsed.drain(..cnt); } Err(encode::Error::Io(ref err)) // Received incomplete message - if err.kind() == std::io::ErrorKind::UnexpectedEof => + if err.kind() == bitcoin_io::ErrorKind::UnexpectedEof => { break } diff --git a/rs/bitcoin/adapter/test_utils/src/lib.rs b/rs/bitcoin/adapter/test_utils/src/lib.rs index 17c4c81ed9f..e8a52da88c6 100644 --- a/rs/bitcoin/adapter/test_utils/src/lib.rs +++ b/rs/bitcoin/adapter/test_utils/src/lib.rs @@ -1,8 +1,10 @@ use std::collections::HashSet; use bitcoin::{ - consensus::deserialize, util::uint::Uint256, Block, BlockHash, BlockHeader, Transaction, - TxMerkleNode, + block::{Header as BlockHeader, Version}, + consensus::deserialize, + hashes::Hash, + Block, BlockHash, Target, Transaction, TxMerkleNode, }; use hex::FromHex; use rand::{prelude::StdRng, Rng, SeedableRng}; @@ -21,12 +23,7 @@ pub const BLOCK_2_ENCODED: &str = "010000004860eb18bf1b1620e37e9490fc8a427514416 /// an overflow occurs if bits is set to 0. /// /// https://github.com/bitcoin/bitcoin/blame/master/src/chainparams.cpp#L402 -const TARGET: Uint256 = Uint256([ - 0xffffffffffffffff, - 0xffffffffffffffff, - 0xffffffffffffffff, - 0x7fffffffffffffff, -]); +const TARGET: Target = Target::MAX_ATTAINABLE_REGTEST; fn decode_block(hex_str: &str) -> Block { let encoded_block_1 = Vec::from_hex(hex_str).expect("failed to covert hex to vec"); @@ -49,11 +46,11 @@ pub fn headers_to_hashes(headers: &[BlockHeader]) -> Vec { fn large_block(prev_blockhash: &BlockHash, prev_time: u32, tx: Transaction) -> Block { let mut block = Block { header: BlockHeader { - version: 1, + version: Version::ONE, prev_blockhash: *prev_blockhash, - merkle_root: TxMerkleNode::default(), + merkle_root: TxMerkleNode::all_zeros(), time: prev_time + gen_time_delta(), - bits: BlockHeader::compact_target_from_u256(&TARGET), + bits: TARGET.to_compact_lossy(), nonce: 0, }, txdata: vec![], @@ -64,7 +61,9 @@ fn large_block(prev_blockhash: &BlockHash, prev_time: u32, tx: Transaction) -> B block.txdata.push(tx.clone()); } - block.header.merkle_root = block.compute_merkle_root().unwrap_or_default(); + block.header.merkle_root = block + .compute_merkle_root() + .unwrap_or(TxMerkleNode::all_zeros()); solve_proof_of_work(&mut block.header); block } @@ -124,11 +123,11 @@ pub fn generate_headers( /// This helper generates a single header with a given previous blockhash. pub fn generate_header(prev_blockhash: BlockHash, prev_time: u32, nonce: u32) -> BlockHeader { let mut header = BlockHeader { - version: 1, + version: Version::ONE, prev_blockhash, - merkle_root: TxMerkleNode::default(), + merkle_root: TxMerkleNode::all_zeros(), time: prev_time + gen_time_delta(), - bits: BlockHeader::compact_target_from_u256(&TARGET), + bits: TARGET.to_compact_lossy(), nonce, }; @@ -145,7 +144,7 @@ fn gen_time_delta() -> u32 { /// This method is used to solve a header's proof of work puzzle. fn solve_proof_of_work(header: &mut BlockHeader) { let target = header.target(); - while header.validate_pow(&target).is_err() { + while header.validate_pow(target).is_err() { header.nonce += 1; } } diff --git a/rs/bitcoin/adapter/tests/adapter_test.rs b/rs/bitcoin/adapter/tests/adapter_test.rs index 0192a8d99e3..3fa103e20dc 100644 --- a/rs/bitcoin/adapter/tests/adapter_test.rs +++ b/rs/bitcoin/adapter/tests/adapter_test.rs @@ -192,7 +192,7 @@ fn start_adapter_and_client( .unwrap(); if let AdapterState::Active = adapter_state { // We send this request to make sure the adapter is not idle. - let _ = make_get_successors_request(&res.0, anchor.to_vec(), vec![]); + let _ = make_get_successors_request(&res.0, anchor[..].to_vec(), vec![]); } res @@ -379,7 +379,9 @@ fn sync_blocks_at_once( } fn get_blackhole_address() -> Address { - Address::from_str("mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn").unwrap() + Address::from_str("mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn") + .unwrap() + .assume_checked() } fn create_alice_and_bob_wallets(bitcoind: &BitcoinD) -> (Client, Client, Address, Address) { @@ -401,8 +403,14 @@ fn create_alice_and_bob_wallets(bitcoind: &BitcoinD) -> (Client, Client, Address .create_wallet("bob", None, None, None, None) .unwrap(); - let alice_address = alice_client.get_new_address(None, None).unwrap(); - let bob_address = bob_client.get_new_address(None, None).unwrap(); + let alice_address = alice_client + .get_new_address(None, None) + .unwrap() + .assume_checked(); + let bob_address = bob_client + .get_new_address(None, None) + .unwrap() + .assume_checked(); (alice_client, bob_client, alice_address, bob_address) } @@ -411,7 +419,7 @@ fn fund_with_btc(to_fund_client: &Client, to_fund_address: &Address) { let initial_amount = to_fund_client .get_received_by_address(to_fund_address, Some(0)) .unwrap() - .as_btc(); + .to_btc(); to_fund_client .generate_to_address(1, to_fund_address) @@ -526,7 +534,7 @@ fn test_receives_blocks() { assert_eq!(0, client.get_blockchain_info().unwrap().blocks); - let address = client.get_new_address(None, None).unwrap(); + let address = client.get_new_address(None, None).unwrap().assume_checked(); client.generate_to_address(150, &address).unwrap(); @@ -709,7 +717,7 @@ fn test_receives_new_3rd_party_txs() { let blocks = sync_until_end_block(&adapter_client, &alice_client, 101, &mut vec![], 15); assert_eq!(blocks.len(), 1); - assert!(blocks[0].txdata.iter().any(|tx| tx.txid() == txid)); + assert!(blocks[0].txdata.iter().any(|tx| tx.compute_txid() == txid)); } /// Ensures the client (replica) can send a transaction (1 BTC from Alice to Bob) using the gRPC service. @@ -821,13 +829,19 @@ fn test_receives_blocks_from_forks() { wait_for_connection(&client1, 2); wait_for_connection(&client2, 2); - let address1 = client1.get_new_address(None, None).unwrap(); + let address1 = client1 + .get_new_address(None, None) + .unwrap() + .assume_checked(); client1.generate_to_address(25, &address1).unwrap(); wait_for_blocks(&client1, 25); wait_for_blocks(&client2, 25); - let address2 = client2.get_new_address(None, None).unwrap(); + let address2 = client2 + .get_new_address(None, None) + .unwrap() + .assume_checked(); client2.generate_to_address(25, &address2).unwrap(); wait_for_blocks(&client1, 50); @@ -889,7 +903,10 @@ fn test_bfs_order() { wait_for_connection(&client1, 2); wait_for_connection(&client2, 2); - let address1 = client1.get_new_address(None, None).unwrap(); + let address1 = client1 + .get_new_address(None, None) + .unwrap() + .assume_checked(); let shared_blocks = client1.generate_to_address(5, &address1).unwrap(); wait_for_blocks(&client1, 5); @@ -905,7 +922,10 @@ fn test_bfs_order() { let fork1 = client1.generate_to_address(15, &address1).unwrap(); - let address2 = client2.get_new_address(None, None).unwrap(); + let address2 = client2 + .get_new_address(None, None) + .unwrap() + .assume_checked(); let fork2 = client2.generate_to_address(15, &address2).unwrap(); wait_for_blocks(&client1, 20); diff --git a/rs/bitcoin/checker/BUILD.bazel b/rs/bitcoin/checker/BUILD.bazel index 3bc774f10df..e881302c0d4 100644 --- a/rs/bitcoin/checker/BUILD.bazel +++ b/rs/bitcoin/checker/BUILD.bazel @@ -17,7 +17,7 @@ rust_library( crate_name = "ic_btc_checker", deps = [ # Keep sorted. - "@crate_index//:bitcoin_0_32", + "@crate_index//:bitcoin", "@crate_index//:candid", "@crate_index//:serde", ], @@ -62,7 +62,7 @@ rust_canister( "//rs/rust_canisters/http_types", "@crate_index//:askama", "@crate_index//:base64", - "@crate_index//:bitcoin_0_32", + "@crate_index//:bitcoin", "@crate_index//:candid", "@crate_index//:candid_parser", "@crate_index//:ciborium", diff --git a/rs/bitcoin/checker/Cargo.toml b/rs/bitcoin/checker/Cargo.toml index 757e9ef16bc..59d73720b1c 100644 --- a/rs/bitcoin/checker/Cargo.toml +++ b/rs/bitcoin/checker/Cargo.toml @@ -13,7 +13,7 @@ path = "src/main.rs" [dependencies] askama = { workspace = true } base64 = { workspace = true } -bitcoin = { version = "0.32.2", default-features = false } +bitcoin = { workspace = true } candid = { workspace = true } ciborium = { workspace = true } futures = { workspace = true } diff --git a/rs/bitcoin/ckbtc/minter/BUILD.bazel b/rs/bitcoin/ckbtc/minter/BUILD.bazel index bc7dd02b463..8e942337897 100644 --- a/rs/bitcoin/ckbtc/minter/BUILD.bazel +++ b/rs/bitcoin/ckbtc/minter/BUILD.bazel @@ -109,7 +109,7 @@ rust_test( crate = ":ckbtc_minter_lib", deps = [ # Keep sorted. - "@crate_index//:bitcoin", + "@crate_index//:bitcoin_0_28", "@crate_index//:maplit", "@crate_index//:mockall", "@crate_index//:proptest", @@ -141,7 +141,7 @@ rust_test( deps = [ # Keep sorted. ":ckbtc_minter_lib", - "@crate_index//:bitcoin", + "@crate_index//:bitcoin_0_28", "@crate_index//:candid", "@crate_index//:flate2", "@crate_index//:ic-agent", @@ -185,7 +185,7 @@ rust_ic_test( "//rs/types/base_types", "//rs/types/types", "@crate_index//:assert_matches", - "@crate_index//:bitcoin", + "@crate_index//:bitcoin_0_28", "@crate_index//:candid", "@crate_index//:ic-btc-interface", "@crate_index//:minicbor", diff --git a/rs/bitcoin/ckbtc/minter/Cargo.toml b/rs/bitcoin/ckbtc/minter/Cargo.toml index 8f867f2f11c..c15f8898b5f 100644 --- a/rs/bitcoin/ckbtc/minter/Cargo.toml +++ b/rs/bitcoin/ckbtc/minter/Cargo.toml @@ -48,7 +48,7 @@ serde_json = { workspace = true } [dev-dependencies] assert_matches = { workspace = true } -bitcoin = { workspace = true } +bitcoin = { version = "0.28.2" } candid_parser = { workspace = true } canister-test = { path = "../../../rust_canisters/canister_test" } flate2 = { workspace = true } diff --git a/rs/bitcoin/mock/tests/tests.rs b/rs/bitcoin/mock/tests/tests.rs index a2b5b4ef574..0d0b71cd890 100644 --- a/rs/bitcoin/mock/tests/tests.rs +++ b/rs/bitcoin/mock/tests/tests.rs @@ -152,7 +152,7 @@ fn test_install_bitcoin_mock_canister() { .expect("failed to decode get_mempool response"); assert_eq!(mempool.len(), 1); - let tx = deserialize::(&mempool[0]).expect("failed to parse transaction"); + let tx: Transaction = deserialize(&mempool[0]).expect("failed to parse transaction"); assert_eq!(tx.input.len(), 1); assert_eq!(tx.output.len(), 2); diff --git a/rs/bitcoin/validation/Cargo.toml b/rs/bitcoin/validation/Cargo.toml index 9198b12fbbe..752eea92d36 100644 --- a/rs/bitcoin/validation/Cargo.toml +++ b/rs/bitcoin/validation/Cargo.toml @@ -10,6 +10,8 @@ documentation.workspace = true [dependencies] bitcoin = { workspace = true } +hex = { workspace = true } [dev-dependencies] csv = "1.1" +proptest = "0.9.4" diff --git a/rs/bitcoin/validation/src/constants.rs b/rs/bitcoin/validation/src/constants.rs index 432e752b4d7..5a632b27808 100644 --- a/rs/bitcoin/validation/src/constants.rs +++ b/rs/bitcoin/validation/src/constants.rs @@ -1,6 +1,6 @@ -use std::collections::HashMap; +use std::{collections::HashMap, str::FromStr}; -use bitcoin::{hashes::hex::FromHex, util::uint::Uint256, BlockHash, Network}; +use bitcoin::{BlockHash, CompactTarget, Network, Target}; use crate::BlockHeight; @@ -57,45 +57,14 @@ const TESTNET: &[(BlockHeight, &str)] = &[ (546, "000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70") ]; -/// Bitcoin mainnet maximum target value -const BITCOIN_MAX_TARGET: Uint256 = Uint256([ - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x00000000ffff0000, -]); - -/// Bitcoin testnet maximum target value -const TESTNET_MAX_TARGET: Uint256 = Uint256([ - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x00000000ffff0000, -]); - -/// Bitcoin regtest maximum target value -const REGTEST_MAX_TARGET: Uint256 = Uint256([ - 0x0000000000000000, - 0x0000000000000000, - 0x0000000000000000, - 0x7fffff0000000000, -]); - -/// Bitcoin signet maximum target value -const SIGNET_MAX_TARGET: Uint256 = Uint256([ - 0x0000000000000000u64, - 0x0000000000000000u64, - 0x0000000000000000u64, - 0x00000377ae000000u64, -]); - /// Returns the maximum difficulty target depending on the network -pub fn max_target(network: &Network) -> Uint256 { +pub fn max_target(network: &Network) -> Target { match network { - Network::Bitcoin => BITCOIN_MAX_TARGET, - Network::Testnet => TESTNET_MAX_TARGET, - Network::Regtest => REGTEST_MAX_TARGET, - Network::Signet => SIGNET_MAX_TARGET, + Network::Bitcoin => Target::MAX_ATTAINABLE_MAINNET, + Network::Testnet => Target::MAX_ATTAINABLE_TESTNET, + Network::Regtest => Target::MAX_ATTAINABLE_REGTEST, + Network::Signet => Target::MAX_ATTAINABLE_SIGNET, + &other => unreachable!("Unsupported network: {:?}", other), } } @@ -105,17 +74,19 @@ pub fn no_pow_retargeting(network: &Network) -> bool { match network { Network::Bitcoin | Network::Testnet | Network::Signet => false, Network::Regtest => true, + &other => unreachable!("Unsupported network: {:?}", other), } } /// Returns the PoW limit bits of the bitcoin network -pub fn pow_limit_bits(network: &Network) -> u32 { - match network { +pub fn pow_limit_bits(network: &Network) -> CompactTarget { + CompactTarget::from_consensus(match network { Network::Bitcoin => 0x1d00ffff, Network::Testnet => 0x1d00ffff, Network::Regtest => 0x207fffff, Network::Signet => 0x1e0377ae, - } + &other => unreachable!("Unsupported network: {:?}", other), + }) } /// Checkpoints used to validate blocks at certain heights. @@ -123,14 +94,17 @@ pub fn checkpoints(network: &Network) -> HashMap { let points = match network { Network::Bitcoin => BITCOIN, Network::Testnet => TESTNET, + Network::Testnet4 => &[], Network::Signet => &[], Network::Regtest => &[], + _ => &[], }; points .iter() .cloned() .map(|(height, hash)| { - let hash = BlockHash::from_hex(hash).expect("Programmer error: invalid hash"); + //TODO: handle this unwrap without crashing + let hash = BlockHash::from_str(hash).expect("Programmer error: invalid hash"); (height, hash) }) .collect() @@ -140,8 +114,10 @@ pub fn latest_checkpoint_height(network: &Network, current_height: BlockHeight) let points = match network { Network::Bitcoin => BITCOIN, Network::Testnet => TESTNET, + Network::Testnet4 => &[], Network::Signet => &[], Network::Regtest => &[], + _ => &[], }; points @@ -151,29 +127,8 @@ pub fn latest_checkpoint_height(network: &Network, current_height: BlockHeight) .map_or(0, |(height, _)| *height) } -pub fn last_checkpoint(network: &Network) -> Option { - let points = match network { - Network::Bitcoin => BITCOIN, - Network::Testnet => TESTNET, - Network::Signet => &[], - Network::Regtest => &[], - }; - - points.last().map(|(height, _)| *height) -} - #[cfg(test)] pub mod test { - - use super::*; - - /// Mainnet 00000000bcb3c8ff4e3e243ad47832d75bb81e922efdc05be63f2696c5dfad09 - pub const MAINNET_HEADER_11109: &str = "0100000027e37046713f768e57bd9c613f70657048320cab3e016c6ad437dadd00000000a12e0863a26054892799db694b8ccd9f44ad062b4d6ef09d2be12e994d50649b9ca2e649ffff001d2823bacb"; - /// Mainnet 00000000deaa3a36d8531844fd1cb11faff6a1171d5228d42131d1b302c56271 - pub const MAINNET_HEADER_11110: &str = "0100000009addfc596263fe65bc0fd2e921eb85bd73278d43a243e4effc8b3bc0000000006413a83ca2d3fbf6b1ac332976043152e0093f17e29fef68c3eb736d379d7365aa3e649ffff001da44e7f02"; - /// Mainnet 0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d - pub const MAINNET_HEADER_11111: &str = "010000007162c502b3d13121d428521d17a1f6af1fb11cfd441853d8363aaade000000007adf7b53a9dc840a210766054aa8a1b2076fd30dadcc3f757c23318a8c8be55213a4e649ffff001d05d9428b"; - /// Mainnet 000000000000000000063108ecc1f03f7fd1481eb20f97307d532a612bc97f04 pub const MAINNET_HEADER_586656: &str ="00008020cff0e07ab39db0f31d4ded81ba2339173155b9c57839110000000000000000007a2d75dce5981ec421a54df706d3d407f66dc9170f1e0d6e48ed1e8a1cad7724e9ed365d083a1f17bc43b10a"; /// Mainnet 0000000000000000000d37dfef7fe1c7bd22c893dbe4a94272c8cf556e40be99 @@ -187,22 +142,4 @@ pub mod test { pub const TESTNET_HEADER_2132555: &str = "004000200e1ff99438666c67c649def743fb82117537c2017bcc6ad617000000000000007fa40cf82bf224909e3174281a57af2eb3a4a2a961d33f50ec0772c1221c9e61ddfdc061ffff001a64526636"; /// Testnet 00000000383cd7fff4692410ccd9bd6201790043bb41b93bacb21e9b85620767 pub const TESTNET_HEADER_2132556: &str = "00000020974f55e77dff100bc252a01aa7b00d16736c6e04a091b03be200000000000000c44f2d69fc200c4a2211885000b6b67512f42c1bec550f3754e103b6c4046e05a202c161ffff001d09ec1bc4"; - - #[test] - fn test_latest_checkpoint_height() { - let height = latest_checkpoint_height(&Network::Bitcoin, 1_000_000); - assert_eq!(height, 704_256); - - let height = latest_checkpoint_height(&Network::Bitcoin, 40_000); - assert_eq!(height, 33_333); - - let height = latest_checkpoint_height(&Network::Testnet, 1_000_000); - assert_eq!(height, 546); - } - - #[test] - fn test_last_checkpoint() { - assert_eq!(last_checkpoint(&Network::Bitcoin), Some(704_256)); - assert_eq!(last_checkpoint(&Network::Regtest), None); - } } diff --git a/rs/bitcoin/validation/src/header.rs b/rs/bitcoin/validation/src/header.rs index b17d0ba47d7..ef7769ebaf4 100644 --- a/rs/bitcoin/validation/src/header.rs +++ b/rs/bitcoin/validation/src/header.rs @@ -1,21 +1,29 @@ -use bitcoin::{util::uint::Uint256, BlockHash, BlockHeader, Network}; +use bitcoin::{ + block::Header as BlockHeader, block::ValidationError, BlockHash, CompactTarget, Network, Target, +}; use crate::{ constants::{ - checkpoints, last_checkpoint, latest_checkpoint_height, max_target, no_pow_retargeting, - pow_limit_bits, BLOCKS_IN_ONE_YEAR, DIFFICULTY_ADJUSTMENT_INTERVAL, TEN_MINUTES, + checkpoints, latest_checkpoint_height, max_target, no_pow_retargeting, pow_limit_bits, + BLOCKS_IN_ONE_YEAR, DIFFICULTY_ADJUSTMENT_INTERVAL, TEN_MINUTES, }, BlockHeight, }; /// An error thrown when trying to validate a header. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum ValidateHeaderError { /// Used when the timestamp in the header is lower than /// the median of timestamps of past 11 headers. HeaderIsOld, /// Used when the header doesn't match with a checkpoint. DoesNotMatchCheckpoint, + /// Used when the timestamp in the header is more than 2 hours + /// from the current time. + HeaderIsTooFarInFuture { + block_time: u64, + max_allowed_time: u64, + }, /// Used when the PoW in the header is invalid as per the target mentioned /// in the header. InvalidPoWForHeaderTarget, @@ -33,12 +41,13 @@ pub enum ValidateHeaderError { } pub trait HeaderStore { - /// Retrieves the header from the store. + /// Returns the header with the given block hash. fn get_header(&self, hash: &BlockHash) -> Option<(BlockHeader, BlockHeight)>; - /// Retrieves the current height of the block chain. - fn get_height(&self) -> BlockHeight; - /// Retrieves the initial hash the store starts from. + + /// Returns the initial hash the store starts from. fn get_initial_hash(&self) -> BlockHash; + + fn get_height(&self) -> BlockHeight; } /// Validates a header. If a failure occurs, a @@ -73,15 +82,16 @@ pub fn validate_header( return Err(ValidateHeaderError::TargetDifficultyAboveMax); } - if header.validate_pow(&header_target).is_err() { + if header.validate_pow(header_target).is_err() { return Err(ValidateHeaderError::InvalidPoWForHeaderTarget); } - let target = get_next_target(network, store, &prev_header, prev_height, header); - if let Err(err) = header.validate_pow(&target) { + let compact_target = + get_next_compact_target(network, store, &prev_header, prev_height, header.time); + if let Err(err) = header.validate_pow(Target::from_compact(compact_target)) { match err { - bitcoin::Error::BlockBadProofOfWork => println!("bad proof of work"), - bitcoin::Error::BlockBadTarget => println!("bad target"), + ValidationError::BadProofOfWork => println!("bad proof of work"), + ValidationError::BadTarget => println!("bad target"), _ => {} }; return Err(ValidateHeaderError::InvalidPoWForComputedTarget); @@ -90,16 +100,6 @@ pub fn validate_header( Ok(()) } -/// Checks if block height is higher than the last checkpoint height. -/// By beeing beyond the last checkpoint we are sure that we store the correct chain up to the height -/// of the last checkpoint. -pub fn is_beyond_last_checkpoint(network: &Network, height: BlockHeight) -> bool { - match last_checkpoint(network) { - Some(last) => last <= height, - None => true, - } -} - /// This validates the header against the network's checkpoints. /// 1. If the next header is at a checkpoint height, the checkpoint is compared to the next header's block hash. /// 2. If the header is not the same height, the function then compares the height to the latest checkpoint. @@ -154,19 +154,15 @@ fn is_timestamp_valid(store: &impl HeaderStore, header: &BlockHeader) -> bool { header.time > median } -/// Gets the next target by doing the following: -/// * If the network allows blocks to have the max target (testnet & regtest), -/// the next difficulty is searched for unless the header's timestamp is -/// greater than 20 minutes from the previous header's timestamp. -/// * If the network does not allow blocks with the max target, the next -/// difficulty is computed and then cast into the next target. -fn get_next_target( +// Returns the next required target at the given timestamp. +// The target is the number that a block hash must be below for it to be accepted. +fn get_next_compact_target( network: &Network, store: &impl HeaderStore, prev_header: &BlockHeader, prev_height: BlockHeight, - header: &BlockHeader, -) -> Uint256 { + timestamp: u32, +) -> CompactTarget { match network { Network::Testnet | Network::Regtest => { if (prev_height + 1) % DIFFICULTY_ADJUSTMENT_INTERVAL != 0 { @@ -175,32 +171,23 @@ fn get_next_target( // "If no block has been found in 20 minutes, the difficulty automatically // resets back to the minimum for a single block, after which it // returns to its previous value." - if header.time > prev_header.time + TEN_MINUTES * 2 { + if timestamp > prev_header.time + TEN_MINUTES * 2 { //If no block has been found in 20 minutes, then use the maximum difficulty // target - max_target(network) + max_target(network).to_compact_lossy() } else { //If the block has been found within 20 minutes, then use the previous // difficulty target that is not equal to the maximum difficulty target - BlockHeader::u256_from_compact_target(find_next_difficulty_in_chain( - network, - store, - prev_header, - prev_height, - )) + find_next_difficulty_in_chain(network, store, prev_header, prev_height) } } else { - BlockHeader::u256_from_compact_target(compute_next_difficulty( - network, - store, - prev_header, - prev_height, - )) + compute_next_difficulty(network, store, prev_header, prev_height) } } - Network::Bitcoin | Network::Signet => BlockHeader::u256_from_compact_target( - compute_next_difficulty(network, store, prev_header, prev_height), - ), + Network::Bitcoin | Network::Signet => { + compute_next_difficulty(network, store, prev_header, prev_height) + } + &other => unreachable!("Unsupported network: {:?}", other), } } @@ -216,36 +203,44 @@ fn find_next_difficulty_in_chain( store: &impl HeaderStore, prev_header: &BlockHeader, prev_height: BlockHeight, -) -> u32 { +) -> CompactTarget { // This is the maximum difficulty target for the network let pow_limit_bits = pow_limit_bits(network); match network { Network::Testnet | Network::Regtest => { let mut current_header = *prev_header; let mut current_height = prev_height; - let mut current_hash = prev_header.block_hash(); + let mut current_hash = current_header.block_hash(); let initial_header_hash = store.get_initial_hash(); // Keep traversing the blockchain backwards from the recent block to initial // header hash. - while current_hash != initial_header_hash { + loop { + // Check if non-limit PoW found or it's time to adjust difficulty. if current_header.bits != pow_limit_bits || current_height % DIFFICULTY_ADJUSTMENT_INTERVAL == 0 { return current_header.bits; } - // Traverse to the previous header - let header_info = store - .get_header(¤t_header.prev_blockhash) + // Stop if we reach the initial header. + if current_hash == initial_header_hash { + break; + } + + // Traverse to the previous header. + let prev_blockhash = current_header.prev_blockhash; + (current_header, _) = store + .get_header(&prev_blockhash) .expect("previous header should be in the header store"); - current_header = header_info.0; - current_height = header_info.1; - current_hash = current_header.prev_blockhash; + // Update the current height and hash. + current_height -= 1; + current_hash = prev_blockhash; } pow_limit_bits } Network::Bitcoin | Network::Signet => pow_limit_bits, + &other => unreachable!("Unsupported network: {:?}", other), } } @@ -256,13 +251,14 @@ fn compute_next_difficulty( store: &impl HeaderStore, prev_header: &BlockHeader, prev_height: BlockHeight, -) -> u32 { +) -> CompactTarget { // Difficulty is adjusted only once in every interval of 2 weeks (2016 blocks) // If an interval boundary is not reached, then previous difficulty target is // returned Regtest network doesn't adjust PoW difficult levels. For // regtest, simply return the previous difficulty target - if (prev_height + 1) % DIFFICULTY_ADJUSTMENT_INTERVAL != 0 || no_pow_retargeting(network) { + let height = prev_height + 1; + if height % DIFFICULTY_ADJUSTMENT_INTERVAL != 0 || no_pow_retargeting(network) { return prev_header.bits; } @@ -283,32 +279,10 @@ fn compute_next_difficulty( // actual_interval will deviate slightly from 2 weeks. Our goal is to // readjust the difficulty target so that the expected time taken for the next // 2016 blocks is again 2 weeks. - let actual_interval = (prev_header.time as i64) - (last_adjustment_time as i64); - - // The target_adjustment_interval_time is 2 weeks of time expressed in seconds - let target_adjustment_interval_time: i64 = - (DIFFICULTY_ADJUSTMENT_INTERVAL * TEN_MINUTES) as i64; - - // Adjusting the actual_interval to [0.5 week, 8 week] range in case the - // actual_interval deviates too much from the expected 2 weeks. - let adjusted_interval = actual_interval.clamp( - target_adjustment_interval_time / 4, - target_adjustment_interval_time * 4, - ) as u32; - - // Computing new difficulty target. - // new difficulty target = old difficult target * (adjusted_interval / - // 2_weeks); - let mut target = prev_header.target(); - target = target.mul_u32(adjusted_interval); - target = target / Uint256::from_u64(target_adjustment_interval_time as u64).unwrap(); - - // Adjusting the newly computed difficulty target so that it doesn't exceed the - // max_difficulty_target limit - target = Uint256::min(target, max_target(network)); - - // Converting the target (Uint256) into a 32 bit representation used by Bitcoin - BlockHeader::compact_target_from_u256(&target) + let actual_interval = + std::cmp::max((prev_header.time as i64) - (last_adjustment_time as i64), 0) as u64; + + CompactTarget::from_next_work_required(prev_header.bits, actual_interval, *network) } #[cfg(test)] @@ -316,13 +290,14 @@ mod test { use std::{collections::HashMap, path::PathBuf, str::FromStr}; - use bitcoin::{consensus::deserialize, hashes::hex::FromHex, TxMerkleNode}; + use bitcoin::{ + block::Version, consensus::deserialize, hashes::hex::FromHex, hashes::Hash, TxMerkleNode, + }; use csv::Reader; use super::*; use crate::constants::test::{ - MAINNET_HEADER_11109, MAINNET_HEADER_11110, MAINNET_HEADER_11111, MAINNET_HEADER_586656, - MAINNET_HEADER_705600, MAINNET_HEADER_705601, MAINNET_HEADER_705602, + MAINNET_HEADER_586656, MAINNET_HEADER_705600, MAINNET_HEADER_705601, MAINNET_HEADER_705602, TESTNET_HEADER_2132555, TESTNET_HEADER_2132556, }; @@ -335,12 +310,14 @@ mod test { struct SimpleHeaderStore { headers: HashMap, height: BlockHeight, + tip_hash: BlockHash, initial_hash: BlockHash, } impl SimpleHeaderStore { fn new(initial_header: BlockHeader, height: BlockHeight) -> Self { let initial_hash = initial_header.block_hash(); + let tip_hash = initial_header.block_hash(); let mut headers = HashMap::new(); headers.insert( initial_hash, @@ -353,6 +330,7 @@ mod test { Self { headers, height, + tip_hash, initial_hash, } } @@ -369,6 +347,7 @@ mod test { self.height = stored_header.height; self.headers.insert(header.block_hash(), stored_header); + self.tip_hash = header.block_hash(); } } @@ -379,13 +358,13 @@ mod test { .map(|stored| (stored.header, stored.height)) } - fn get_height(&self) -> BlockHeight { - self.height - } - fn get_initial_hash(&self) -> BlockHash { self.initial_hash } + + fn get_height(&self) -> BlockHeight { + self.height + } } fn deserialize_header(encoded_bytes: &str) -> BlockHeader { @@ -395,8 +374,6 @@ mod test { /// This function reads `num_headers` headers from `tests/data/headers.csv` /// and returns them. - /// This function reads `num_headers` headers from `blockchain_headers.csv` - /// and returns them. fn get_bitcoin_headers() -> Vec { let rdr = Reader::from_path( PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap()) @@ -408,11 +385,15 @@ mod test { for result in rdr.records() { let record = result.unwrap(); let header = BlockHeader { - version: i32::from_str_radix(record.get(0).unwrap(), 16).unwrap(), + version: Version::from_consensus( + i32::from_str_radix(record.get(0).unwrap(), 16).unwrap(), + ), prev_blockhash: BlockHash::from_str(record.get(1).unwrap()).unwrap(), merkle_root: TxMerkleNode::from_str(record.get(2).unwrap()).unwrap(), time: u32::from_str_radix(record.get(3).unwrap(), 16).unwrap(), - bits: u32::from_str_radix(record.get(4).unwrap(), 16).unwrap(), + bits: CompactTarget::from_consensus( + u32::from_str_radix(record.get(4).unwrap(), 16).unwrap(), + ), nonce: u32::from_str_radix(record.get(5).unwrap(), 16).unwrap(), }; headers.push(header); @@ -420,17 +401,6 @@ mod test { headers } - fn genesis_header(bits: u32) -> BlockHeader { - BlockHeader { - version: 1, - prev_blockhash: Default::default(), - merkle_root: Default::default(), - time: 1296688602, - bits, - nonce: 0, - } - } - #[test] fn test_simple_mainnet() { let header_705600 = deserialize_header(MAINNET_HEADER_705600); @@ -466,39 +436,6 @@ mod test { } } - #[test] - fn test_is_timestamp_valid() { - let header_705600 = deserialize_header(MAINNET_HEADER_705600); - let header_705601 = deserialize_header(MAINNET_HEADER_705601); - let header_705602 = deserialize_header(MAINNET_HEADER_705602); - let mut store = SimpleHeaderStore::new(header_705600, 705_600); - store.add(header_705601); - store.add(header_705602); - - let mut header = BlockHeader { - version: 0x20800004, - prev_blockhash: BlockHash::from_hex( - "00000000000000000001eea12c0de75000c2546da22f7bf42d805c1d2769b6ef", - ) - .unwrap(), - merkle_root: TxMerkleNode::from_hex( - "c120ff2ae1363593a0b92e0d281ec341a0cc989b4ee836dc3405c9f4215242a6", - ) - .unwrap(), - time: 1634590600, - bits: 0x170e0408, - nonce: 0xb48e8b0a, - }; - assert!(is_timestamp_valid(&store, &header)); - - // Monday, October 18, 2021 20:26:40 - header.time = 1634588800; - assert!(!is_timestamp_valid(&store, &header)); - - let result = validate_header(&Network::Bitcoin, &store, &header); - assert!(matches!(result, Err(ValidateHeaderError::HeaderIsOld))); - } - #[test] fn test_is_header_valid_missing_prev_header() { let header_705600 = deserialize_header(MAINNET_HEADER_705600); @@ -511,82 +448,6 @@ mod test { )); } - #[test] - fn test_is_header_valid_checkpoint_valid_at_height() { - let network = Network::Bitcoin; - let header_11110 = deserialize_header(MAINNET_HEADER_11110); - let mut header_11111 = deserialize_header(MAINNET_HEADER_11111); - let store = SimpleHeaderStore::new(header_11110, 11110); - let (_, prev_height) = store.get_header(&header_11111.prev_blockhash).unwrap(); - - assert!(is_checkpoint_valid( - &network, - prev_height, - &header_11111, - store.get_height() - )); - - // Change time to slightly modify the block hash to make it invalid for the - // checkpoint. - header_11111.time -= 1; - - let result = validate_header(&network, &store, &header_11111); - assert!(matches!( - result, - Err(ValidateHeaderError::DoesNotMatchCheckpoint) - )); - } - - #[test] - fn test_is_header_valid_checkpoint_valid_detect_fork_around_11111() { - let network = Network::Bitcoin; - let header_11109 = deserialize_header(MAINNET_HEADER_11109); - let header_11110 = deserialize_header(MAINNET_HEADER_11110); - let header_11111 = deserialize_header(MAINNET_HEADER_11111); - // Make a header for height 11110 that would cause a fork. - let mut bad_header_11110 = header_11110; - bad_header_11110.time -= 1; - - let mut store = SimpleHeaderStore::new(header_11109, 11109); - store.add(header_11110); - - let (_, prev_height) = store.get_header(&header_11111.prev_blockhash).unwrap(); - - assert!(is_checkpoint_valid( - &network, - prev_height, - &header_11111, - store.get_height() - )); - - store.add(header_11111); - - // This should return false as bad_header_11110 is a fork. - let (_, prev_height) = store.get_header(&header_11111.prev_blockhash).unwrap(); - assert!(!is_checkpoint_valid( - &network, - prev_height, - &bad_header_11110, - store.get_height() - )); - } - - #[test] - fn test_is_header_valid_checkpoint_valid_detect_fork_around_705600() { - let network = Network::Bitcoin; - let header_705600 = deserialize_header(MAINNET_HEADER_705600); - let header_705601 = deserialize_header(MAINNET_HEADER_705601); - let store = SimpleHeaderStore::new(header_705600, 705_600); - let (_, prev_height) = store.get_header(&header_705601.prev_blockhash).unwrap(); - - assert!(is_checkpoint_valid( - &network, - prev_height, - &header_705601, - store.get_height() - )); - } - #[test] fn test_is_header_valid_invalid_header_target() { let header_705600 = deserialize_header(MAINNET_HEADER_705600); @@ -602,10 +463,16 @@ mod test { #[test] fn test_is_header_valid_invalid_computed_target() { - let header_705600 = deserialize_header(MAINNET_HEADER_705600); - let header = deserialize_header(MAINNET_HEADER_705601); - let store = SimpleHeaderStore::new(header_705600, 705_600); - let result = validate_header(&Network::Regtest, &store, &header); + let pow_bitcoin = pow_limit_bits(&Network::Bitcoin); + let pow_regtest = pow_limit_bits(&Network::Regtest); + let h0 = genesis_header(pow_bitcoin); + let h1 = next_block_header(h0, pow_regtest); + let h2 = next_block_header(h1, pow_regtest); + let h3 = next_block_header(h2, pow_regtest); + let mut store = SimpleHeaderStore::new(h0, 0); + store.add(h1); + store.add(h2); + let result = validate_header(&Network::Regtest, &store, &h3); assert!(matches!( result, Err(ValidateHeaderError::InvalidPoWForComputedTarget) @@ -625,42 +492,70 @@ mod test { )); } - #[test] - fn test_is_header_within_one_year_of_tip_next_height_is_above_the_minimum() { - assert!( - is_header_within_one_year_of_tip(700_000, 650_000), - "next height is above the one year minimum" - ); - assert!( - is_header_within_one_year_of_tip(700_000, 750_000), - "next height is within the one year range" - ); - assert!( - !is_header_within_one_year_of_tip(700_000, 800_000), - "next height is below the one year minimum" - ); + fn genesis_header(bits: CompactTarget) -> BlockHeader { + BlockHeader { + version: Version::ONE, + prev_blockhash: Hash::all_zeros(), + merkle_root: Hash::all_zeros(), + time: 1296688602, + bits, + nonce: 0, + } } - #[test] - #[should_panic(expected = "next height causes an overflow")] - fn test_is_header_within_one_year_of_tip_should_panic_as_next_height_is_too_high() { - is_header_within_one_year_of_tip(BlockHeight::MAX, 0); + fn next_block_header(prev: BlockHeader, bits: CompactTarget) -> BlockHeader { + BlockHeader { + prev_blockhash: prev.block_hash(), + time: prev.time + TEN_MINUTES, + bits, + ..prev + } + } + + /// Creates a chain of headers with the given length and + /// proof of work for the first header. + fn create_chain( + network: &Network, + initial_pow: CompactTarget, + chain_length: u32, + ) -> (SimpleHeaderStore, BlockHeader) { + let pow_limit = pow_limit_bits(network); + let h0 = genesis_header(initial_pow); + let mut store = SimpleHeaderStore::new(h0, 0); + let mut last_header = h0; + + for _ in 1..chain_length { + let new_header = next_block_header(last_header, pow_limit); + store.add(new_header); + last_header = new_header; + } + + (store, last_header) } #[test] - fn test_is_header_within_one_year_of_tip_chain_height_is_less_than_one_year() { - assert!( - is_header_within_one_year_of_tip(1, 0), - "chain height is less than one year" - ); - assert!( - is_header_within_one_year_of_tip(1, BLOCKS_IN_ONE_YEAR + 2), - "chain height difference is exactly one year" - ); - assert!( - !is_header_within_one_year_of_tip(1, BLOCKS_IN_ONE_YEAR + 3), - "chain height difference is one year + 1 block" - ); + fn test_next_target_regtest() { + // This test checks the chain of headers of different lengths + // with non-limit PoW in the first block header and PoW limit + // in all the other headers. + // Expect difficulty to be equal to the non-limit PoW. + + // Arrange. + let network = Network::Regtest; + let expected_pow = CompactTarget::from_consensus(7); // Some non-limit PoW, the actual value is not important. + for chain_length in 1..10 { + let (store, last_header) = create_chain(&network, expected_pow, chain_length); + // Act. + let compact_target = get_next_compact_target( + &network, + &store, + &last_header, + chain_length - 1, + last_header.time + TEN_MINUTES, + ); + // Assert. + assert_eq!(compact_target, expected_pow); + } } #[test] @@ -668,7 +563,7 @@ mod test { // Arrange: Set up the test network and parameters let network = Network::Testnet; let chain_length = DIFFICULTY_ADJUSTMENT_INTERVAL - 1; // To trigger the difficulty adjustment. - let genesis_difficulty = 486604799; + let genesis_difficulty = CompactTarget::from_consensus(486604799); // Create the genesis header and initialize the header store let genesis_header = genesis_header(genesis_difficulty); @@ -688,6 +583,6 @@ mod test { let difficulty = compute_next_difficulty(&network, &store, &last_header, chain_length); // Assert. - assert_eq!(difficulty, 473956288); + assert_eq!(difficulty, CompactTarget::from_consensus(473956288)); } } diff --git a/rs/bitcoin/validation/src/lib.rs b/rs/bitcoin/validation/src/lib.rs index 99843cea939..dbfaee7bfec 100644 --- a/rs/bitcoin/validation/src/lib.rs +++ b/rs/bitcoin/validation/src/lib.rs @@ -1,8 +1,7 @@ mod constants; mod header; -pub use crate::header::{ - is_beyond_last_checkpoint, validate_header, HeaderStore, ValidateHeaderError, -}; +pub use crate::constants::max_target; +pub use crate::header::{validate_header, HeaderStore, ValidateHeaderError}; type BlockHeight = u32; diff --git a/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/BUILD.bazel b/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/BUILD.bazel index f95f0370a6c..27e05aead38 100644 --- a/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/BUILD.bazel +++ b/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/BUILD.bazel @@ -14,7 +14,8 @@ rust_library( "//rs/crypto/sha2", "//rs/types/types", "@crate_index//:assert_matches", - "@crate_index//:bitcoin", + #TODO(BTC-CRATE-UPGRADE): Migrate this to bitcoin. + "@crate_index//:bitcoin_0_28", "@crate_index//:ed25519-dalek", "@crate_index//:hex", "@crate_index//:k256", diff --git a/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/Cargo.toml b/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/Cargo.toml index c5abd4850cc..8d3138963b6 100644 --- a/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/Cargo.toml +++ b/rs/crypto/internal/crypto_lib/threshold_sig/canister_threshold_sig/test_utils/Cargo.toml @@ -9,6 +9,7 @@ documentation.workspace = true [dependencies] assert_matches = { workspace = true } ed25519-dalek = { workspace = true } +#TODO: try migrating this to the latest bitcoin crate. bitcoin = { version = "0.28.2" } hex = "0.4" secp256k1 = { version = "0.22", features = ["global-context", "rand-std"] } diff --git a/rs/crypto/secp256k1/BUILD.bazel b/rs/crypto/secp256k1/BUILD.bazel index c646f7b7969..9f7d69d1c9c 100644 --- a/rs/crypto/secp256k1/BUILD.bazel +++ b/rs/crypto/secp256k1/BUILD.bazel @@ -21,7 +21,7 @@ MACRO_DEPENDENCIES = [] DEV_DEPENDENCIES = [ # Keep sorted. "@crate_index//:bip32", - "@crate_index//:bitcoin", + "@crate_index//:bitcoin_0_28", "@crate_index//:hex", "@crate_index//:hex-literal", "@crate_index//:wycheproof", diff --git a/rs/fuzzers/bitcoin/fuzz_targets/deserialize_bitcoin_raw_network_message.rs b/rs/fuzzers/bitcoin/fuzz_targets/deserialize_bitcoin_raw_network_message.rs index a7b0e1d2499..d86fe821233 100644 --- a/rs/fuzzers/bitcoin/fuzz_targets/deserialize_bitcoin_raw_network_message.rs +++ b/rs/fuzzers/bitcoin/fuzz_targets/deserialize_bitcoin_raw_network_message.rs @@ -1,6 +1,6 @@ #![no_main] use bitcoin::consensus::encode::deserialize; -use bitcoin::network::message::RawNetworkMessage; +use bitcoin::p2p::message::RawNetworkMessage; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { diff --git a/rs/pocket_ic_server/Cargo.toml b/rs/pocket_ic_server/Cargo.toml index 2fe09384489..8ed2df90b47 100644 --- a/rs/pocket_ic_server/Cargo.toml +++ b/rs/pocket_ic_server/Cargo.toml @@ -12,7 +12,7 @@ axum-extra = { version = "^0.9", features = ["typed-header"] } axum-server = { version = "0.6.0", features = ["tls-rustls"] } backoff = { workspace = true } base64 = { workspace = true } -bitcoin = { version = "0.28.1", features = ["default", "use-serde", "rand"] } +bitcoin = { workspace = true } bytes = { workspace = true } candid = { workspace = true } clap = { workspace = true } @@ -84,7 +84,7 @@ tracing-subscriber = { workspace = true } wat = { workspace = true } [dev-dependencies] -bitcoincore-rpc = "0.15.0" +bitcoincore-rpc = { workspace = true } ic-btc-interface = { workspace = true } ic-config = { path = "../config" } ic-registry-transport = { path = "../registry/transport" } diff --git a/rs/pocket_ic_server/tests/bitcoin_integration_tests.rs b/rs/pocket_ic_server/tests/bitcoin_integration_tests.rs index 3a36651f1d6..7b29841928c 100644 --- a/rs/pocket_ic_server/tests/bitcoin_integration_tests.rs +++ b/rs/pocket_ic_server/tests/bitcoin_integration_tests.rs @@ -143,7 +143,12 @@ rpcauth=ic-btc-integration:cdf2741387f3a12438f69092f0fdad8e$62081498c98bee09a0dc // retry generating blocks until the bitcoind is up and running let start = std::time::Instant::now(); loop { - match btc_rpc.generate_to_address(n, &Address::from_str(&bitcoin_address).unwrap()) { + match btc_rpc.generate_to_address( + n, + &Address::from_str(&bitcoin_address) + .unwrap() + .assume_checked(), + ) { Ok(_) => break, Err(bitcoincore_rpc::Error::JsonRpc(err)) => { if start.elapsed() > std::time::Duration::from_secs(30) { @@ -186,7 +191,12 @@ rpcauth=ic-btc-integration:cdf2741387f3a12438f69092f0fdad8e$62081498c98bee09a0dc break; } else { btc_rpc - .generate_to_address(1, &Address::from_str(&bitcoin_address).unwrap()) + .generate_to_address( + 1, + &Address::from_str(&bitcoin_address) + .unwrap() + .assume_checked(), + ) .unwrap(); n += 1; } diff --git a/rs/tests/ckbtc/Cargo.toml b/rs/tests/ckbtc/Cargo.toml index d7156f4b708..e23131167b0 100644 --- a/rs/tests/ckbtc/Cargo.toml +++ b/rs/tests/ckbtc/Cargo.toml @@ -9,7 +9,7 @@ documentation.workspace = true [dependencies] anyhow = { workspace = true } assert_matches = { workspace = true } -bitcoincore-rpc = "0.15.0" +bitcoincore-rpc = { workspace = true } candid = { workspace = true } canister-test = { path = "../../rust_canisters/canister_test" } dfn_candid = { path = "../../rust_canisters/dfn_candid" } diff --git a/rs/tests/ckbtc/ckbtc_minter_batching.rs b/rs/tests/ckbtc/ckbtc_minter_batching.rs index a8f23e13fd3..9f439bf2358 100644 --- a/rs/tests/ckbtc/ckbtc_minter_batching.rs +++ b/rs/tests/ckbtc/ckbtc_minter_batching.rs @@ -61,7 +61,10 @@ pub fn test_batching(env: TestEnv) { let btc_rpc = get_btc_client(&env); ensure_wallet(&btc_rpc, &logger); - let default_btc_address = btc_rpc.get_new_address(None, None).unwrap(); + let default_btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); // Creating the 101 first block to reach the min confirmations to spend a coinbase utxo. debug!( &logger, @@ -163,7 +166,10 @@ pub fn test_batching(env: TestEnv) { "Transfer to the minter account occurred at block {}", transfer_result ); - let destination_btc_address = btc_rpc.get_new_address(None, None).unwrap(); + let destination_btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); info!(&logger, "Call retrieve_btc"); @@ -239,7 +245,7 @@ pub fn test_batching(env: TestEnv) { // Let's wait for the transaction to appear on the mempool let mempool_txids = wait_for_mempool_change(&btc_rpc, &logger).await; let txid = mempool_txids[0]; - let btc_txid = Txid::from_hash(Hash::from_slice(&txid).unwrap()); + let btc_txid = Txid::from_raw_hash(Hash::from_slice(&txid[..]).unwrap()); // Check if we have the txid in the bitcoind mempool assert!( mempool_txids.contains(&btc_txid), @@ -262,7 +268,7 @@ pub fn test_batching(env: TestEnv) { // Hence, we expect the fee to be 3650 // By checking the fee we know that we have the right amount of inputs and outputs const EXPECTED_FEE: u64 = 3650; - assert_eq!(get_tx_infos.fees.base.as_sat(), EXPECTED_FEE); + assert_eq!(get_tx_infos.fees.base.to_sat(), EXPECTED_FEE); // Check that we can modify the fee assert!(get_tx_infos.bip125_replaceable); @@ -278,7 +284,7 @@ pub fn test_batching(env: TestEnv) { let finalized_txid = wait_for_finalization_no_new_blocks(&minter_agent, block_indexes[0]).await; // We don't need to check which input has been used as there is only one input in the possession of the minter - let txid_array: [u8; 32] = txid.as_hash().to_vec().try_into().unwrap(); + let txid_array: [u8; 32] = txid[..].to_vec().try_into().unwrap(); assert_eq!(ic_btc_interface::Txid::from(txid_array), finalized_txid); // We can now check that the destination_btc_address received some utxos @@ -293,7 +299,7 @@ pub fn test_batching(env: TestEnv) { .expect("failed to get tx infos"); let destination_balance = unspent_result .iter() - .map(|entry| entry.amount.as_sat()) + .map(|entry| entry.amount.to_sat()) .sum::(); // We have 1 input and 21 outputs (20 requests and the minter's address) diff --git a/rs/tests/ckbtc/ckbtc_minter_checker.rs b/rs/tests/ckbtc/ckbtc_minter_checker.rs index 1dc74182214..c3c8a096953 100644 --- a/rs/tests/ckbtc/ckbtc_minter_checker.rs +++ b/rs/tests/ckbtc/ckbtc_minter_checker.rs @@ -49,7 +49,10 @@ pub fn test_btc_checker(env: TestEnv) { // Create wallet if required. ensure_wallet(&btc_rpc, &logger); - let default_btc_address = btc_rpc.get_new_address(None, None).unwrap(); + let default_btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); // Creating the 101 first block to reach the min confirmations to spend a coinbase utxo. debug!( &logger, diff --git a/rs/tests/ckbtc/ckbtc_minter_deposit_and_withdrawal.rs b/rs/tests/ckbtc/ckbtc_minter_deposit_and_withdrawal.rs index 64b0f6a77ee..f103058d6e9 100644 --- a/rs/tests/ckbtc/ckbtc_minter_deposit_and_withdrawal.rs +++ b/rs/tests/ckbtc/ckbtc_minter_deposit_and_withdrawal.rs @@ -41,7 +41,10 @@ pub fn test_deposit_and_withdrawal(env: TestEnv) { let btc_rpc = get_btc_client(&env); ensure_wallet(&btc_rpc, &logger); - let default_btc_address = btc_rpc.get_new_address(None, None).unwrap(); + let default_btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); // Creating the 101 first block to reach the min confirmations to spend a coinbase utxo. debug!( &logger, @@ -128,7 +131,10 @@ pub fn test_deposit_and_withdrawal(env: TestEnv) { "Transfer to the minter account occurred at block {}", transfer_result ); - let destination_btc_address = btc_rpc.get_new_address(None, None).unwrap(); + let destination_btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); info!(&logger, "Call retrieve_btc"); @@ -165,7 +171,7 @@ pub fn test_deposit_and_withdrawal(env: TestEnv) { // We wait for the heartbeat to send the transaction to the mempool info!(&logger, "Waiting for tx to appear in mempool"); let mempool_txids = wait_for_mempool_change(&btc_rpc, &logger).await; - let btc_txid = Txid::from_hash(Hash::from_slice(&txid_bytes).unwrap()); + let btc_txid = Txid::from_raw_hash(Hash::from_slice(&txid_bytes).unwrap()); // Check if we have the txid in the bitcoind mempool assert!( mempool_txids.contains(&btc_txid), @@ -187,7 +193,7 @@ pub fn test_deposit_and_withdrawal(env: TestEnv) { // - a fee of 5 satoshis/vbytes // Hence a total fee of 705 satoshis const EXPECTED_FEE: u64 = 705; - assert_eq!(get_tx_infos.fees.base.as_sat(), EXPECTED_FEE); + assert_eq!(get_tx_infos.fees.base.to_sat(), EXPECTED_FEE); // Check that we can modify the fee assert!(get_tx_infos.bip125_replaceable); diff --git a/rs/tests/ckbtc/ckbtc_minter_retrieve_btc.rs b/rs/tests/ckbtc/ckbtc_minter_retrieve_btc.rs index 58f32badf37..5879cd9ec75 100644 --- a/rs/tests/ckbtc/ckbtc_minter_retrieve_btc.rs +++ b/rs/tests/ckbtc/ckbtc_minter_retrieve_btc.rs @@ -45,11 +45,15 @@ pub fn test_retrieve_btc(env: TestEnv) { let btc_rpc = get_btc_client(&env); ensure_wallet(&btc_rpc, &logger); - let default_btc_address = btc_rpc.get_new_address(None, None).unwrap(); + let default_btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); // Creating the 10 first block to reach the min confirmations of the minter canister. debug!( &logger, - "Generating 10 blocks to default address: {}", &default_btc_address + "Generating 10 blocks to default address: {}", + &default_btc_address.to_string() ); btc_rpc .generate_to_address(10, &default_btc_address) diff --git a/rs/tests/ckbtc/ckbtc_minter_update_balance.rs b/rs/tests/ckbtc/ckbtc_minter_update_balance.rs index e0419c7b2cf..d00fbf11f01 100644 --- a/rs/tests/ckbtc/ckbtc_minter_update_balance.rs +++ b/rs/tests/ckbtc/ckbtc_minter_update_balance.rs @@ -55,7 +55,10 @@ pub fn test_update_balance(env: TestEnv) { // Create wallet if required. ensure_wallet(&btc_rpc, &logger); - let default_btc_address = btc_rpc.get_new_address(None, None).unwrap(); + let default_btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); // Creating the 10 first block to reach the min confirmations of the minter canister. debug!( &logger, diff --git a/rs/tests/ckbtc/src/utils.rs b/rs/tests/ckbtc/src/utils.rs index 9d5c1ed9f69..abcb645bc29 100644 --- a/rs/tests/ckbtc/src/utils.rs +++ b/rs/tests/ckbtc/src/utils.rs @@ -382,7 +382,7 @@ pub async fn get_btc_address( debug!(logger, "Btc address for subaccount is: {}", address); // Checking only proper format of address since ECDSA signature is non-deterministic. assert_eq!(ADDRESS_LENGTH, address.len()); - address.parse().unwrap() + address.parse::>().unwrap().assume_checked() } pub async fn send_to_btc_address(btc_rpc: &Client, logger: &Logger, dst: &Address, amount: u64) { diff --git a/rs/tests/execution/Cargo.toml b/rs/tests/execution/Cargo.toml index a50cb647351..5c3ede82769 100644 --- a/rs/tests/execution/Cargo.toml +++ b/rs/tests/execution/Cargo.toml @@ -8,7 +8,7 @@ documentation.workspace = true [dependencies] anyhow = { workspace = true } -bitcoincore-rpc = "0.15.0" +bitcoincore-rpc = { workspace = true } candid = { workspace = true } futures = { workspace = true } ic-agent = { workspace = true } diff --git a/rs/tests/execution/btc_get_balance_test.rs b/rs/tests/execution/btc_get_balance_test.rs index 6200c1be7c9..859d0a81d16 100644 --- a/rs/tests/execution/btc_get_balance_test.rs +++ b/rs/tests/execution/btc_get_balance_test.rs @@ -149,8 +149,15 @@ pub fn get_balance(env: TestEnv) { .unwrap(); // Generate an address. - let btc_address = btc_rpc.get_new_address(None, None).unwrap(); - info!(&logger, "Created temporary btc address: {}", btc_address); + let btc_address = btc_rpc + .get_new_address(None, None) + .unwrap() + .assume_checked(); + info!( + &logger, + "Created temporary btc address: {}", + btc_address.to_string() + ); // Mint some blocks for the address we generated. let block = btc_rpc.generate_to_address(101, &btc_address).unwrap();