diff --git a/Cargo.lock b/Cargo.lock index a95cee548..b53a88a61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -191,13 +191,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -367,19 +367,17 @@ dependencies = [ [[package]] name = "bitcoin" version = "1.2.0" -source = "git+https://github.com/interlay/interbtc?rev=2ec5b959a547f28d7bab7799568321c9cff40343#2ec5b959a547f28d7bab7799568321c9cff40343" +source = "git+https://github.com/interlay/interbtc?rev=1b90616692dcce55749616b4c60bdab228279909#1b90616692dcce55749616b4c60bdab228279909" dependencies = [ "bitcoin_hashes 0.7.6", - "frame-support", "hex", "impl-serde 0.3.2", "parity-scale-codec", + "primitive-types", "scale-info", "secp256k1 0.20.1", "serde", "sha2 0.8.2", - "sp-core", - "sp-std 5.0.0", "spin 0.7.1", ] @@ -549,7 +547,7 @@ checksum = "bd769563b4ea2953e2825c9e6b7470a5f55f67e0be00030bf3e390a2a6071f64" [[package]] name = "btc-relay" version = "1.2.0" -source = "git+https://github.com/interlay/interbtc?rev=2ec5b959a547f28d7bab7799568321c9cff40343#2ec5b959a547f28d7bab7799568321c9cff40343" +source = "git+https://github.com/interlay/interbtc?rev=1b90616692dcce55749616b4c60bdab228279909#1b90616692dcce55749616b4c60bdab228279909" dependencies = [ "bitcoin 1.2.0", "frame-benchmarking", @@ -680,9 +678,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.17" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0827b011f6f8ab38590295339817b0d26f344aa4932c3ced71b45b0c54b4a9" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -691,9 +689,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.17" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9441b403be87be858db6a23edb493e7f694761acdc3343d5a0fcaafd304cbc9e" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -710,7 +708,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -957,7 +955,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -979,7 +977,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -1117,9 +1115,9 @@ checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", "digest 0.10.7", @@ -1166,9 +1164,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" @@ -1303,12 +1301,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "faucet" @@ -1507,7 +1502,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -1519,7 +1514,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -1529,7 +1524,7 @@ source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.42#f dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -1641,7 +1636,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -2257,19 +2252,17 @@ dependencies = [ [[package]] name = "interbtc-primitives" version = "1.2.0" -source = "git+https://github.com/interlay/interbtc?rev=2ec5b959a547f28d7bab7799568321c9cff40343#2ec5b959a547f28d7bab7799568321c9cff40343" +source = "git+https://github.com/interlay/interbtc?rev=1b90616692dcce55749616b4c60bdab228279909#1b90616692dcce55749616b4c60bdab228279909" dependencies = [ "bitcoin 1.2.0", "bstringify", "parity-scale-codec", + "primitive-types", "scale-decode", "scale-encode", "scale-info", "serde", - "sp-core", "sp-runtime", - "sp-std 5.0.0", - "xcm", ] [[package]] @@ -2704,9 +2697,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.9" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" +checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" dependencies = [ "cc", "pkg-config", @@ -3209,9 +3202,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", "libm", @@ -3289,7 +3282,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -3336,12 +3329,11 @@ dependencies = [ [[package]] name = "oracle-rpc-runtime-api" version = "1.2.0" -source = "git+https://github.com/interlay/interbtc?rev=2ec5b959a547f28d7bab7799568321c9cff40343#2ec5b959a547f28d7bab7799568321c9cff40343" +source = "git+https://github.com/interlay/interbtc?rev=1b90616692dcce55749616b4c60bdab228279909#1b90616692dcce55749616b4c60bdab228279909" dependencies = [ "frame-support", + "interbtc-primitives", "parity-scale-codec", - "scale-info", - "serde", "sp-api", "sp-std 5.0.0", ] @@ -3504,7 +3496,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -3631,7 +3623,7 @@ checksum = "0e99670bafb56b9a106419397343bdbc8b8742c3cc449fec6345f86173f47cd4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -3713,9 +3705,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -3901,22 +3893,22 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1641819477c319ef452a075ac34a4be92eb9ba09f6841f62d594d50fdcf0bf6b" +checksum = "61ef7e18e8841942ddb1cf845054f8008410030a3997875d9e49b7a363063df1" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bf53dad9b6086826722cdc99140793afd9f62faa14a1ad07eb4f955e7a7216" +checksum = "2dfaf0c85b766276c797f3791f5bc6d5bd116b41d53049af2789666b0c0bc9fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -4489,7 +4481,7 @@ dependencies = [ [[package]] name = "security" version = "1.2.0" -source = "git+https://github.com/interlay/interbtc?rev=2ec5b959a547f28d7bab7799568321c9cff40343#2ec5b959a547f28d7bab7799568321c9cff40343" +source = "git+https://github.com/interlay/interbtc?rev=1b90616692dcce55749616b4c60bdab228279909#1b90616692dcce55749616b4c60bdab228279909" dependencies = [ "frame-benchmarking", "frame-support", @@ -4505,9 +4497,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -4518,9 +4510,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -4540,22 +4532,22 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.173" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91f70896d6720bc714a4a57d22fc91f1db634680e65c8efe13323f1fa38d53f" +checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.173" +version = "1.0.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6250dde8342e0232232be9ca3db7aa40aceb5a3e5dd9bddbc00d99a007cde49" +checksum = "b23f7ade6f110613c0d63858ddb8b94c1041f550eab58a16b371bdf2c9c80ab4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -4629,7 +4621,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -4899,7 +4891,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5010,7 +5002,7 @@ dependencies = [ "proc-macro2", "quote", "sp-core-hashing 5.0.0", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5020,7 +5012,7 @@ source = "git+https://github.com/paritytech//substrate?branch=polkadot-v0.9.42#f dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5169,7 +5161,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5304,7 +5296,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5498,7 +5490,7 @@ dependencies = [ "quote", "scale-info", "subxt-metadata", - "syn 2.0.26", + "syn 2.0.27", "thiserror", "tokio", ] @@ -5512,7 +5504,7 @@ dependencies = [ "darling 0.20.3", "proc-macro-error", "subxt-codegen", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5541,9 +5533,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.26" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -5604,15 +5596,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ - "autocfg", "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -5633,22 +5624,22 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5733,7 +5724,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -5873,7 +5864,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] @@ -6235,7 +6226,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", "wasm-bindgen-shared", ] @@ -6269,7 +6260,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6683,9 +6674,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" +checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" dependencies = [ "memchr", ] @@ -6708,32 +6699,6 @@ dependencies = [ "tap", ] -[[package]] -name = "xcm" -version = "0.9.42" -source = "git+https://github.com/paritytech//polkadot?branch=release-v0.9.42#6f991987c0b4cbbd7d4badc9ef08d83da5fefbfd" -dependencies = [ - "bounded-collections", - "derivative", - "impl-trait-for-tuples", - "log", - "parity-scale-codec", - "scale-info", - "sp-weights", - "xcm-procedural", -] - -[[package]] -name = "xcm-procedural" -version = "0.9.42" -source = "git+https://github.com/paritytech//polkadot?branch=release-v0.9.42#6f991987c0b4cbbd7d4badc9ef08d83da5fefbfd" -dependencies = [ - "Inflector", - "proc-macro2", - "quote", - "syn 2.0.26", -] - [[package]] name = "yap" version = "0.10.0" @@ -6757,5 +6722,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] diff --git a/Cargo.toml b/Cargo.toml index 5966bedbd..4b8ebbe4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,4 @@ sp-tracing = { git = "https://github.com/paritytech//substrate", branch = "polka sp-trie = { git = "https://github.com/paritytech//substrate", branch = "polkadot-v0.9.42" } sp-version = { git = "https://github.com/paritytech//substrate", branch = "polkadot-v0.9.42" } sp-wasm-interface = { git = "https://github.com/paritytech//substrate", branch = "polkadot-v0.9.42" } -sp-weights = { git = "https://github.com/paritytech//substrate", branch = "polkadot-v0.9.42" } - -[patch."https://github.com/paritytech/polkadot"] -xcm = { git = "https://github.com/paritytech//polkadot", branch = "release-v0.9.42" } \ No newline at end of file +sp-weights = { git = "https://github.com/paritytech//substrate", branch = "polkadot-v0.9.42" } \ No newline at end of file diff --git a/bitcoin/src/electrs/error.rs b/bitcoin/src/electrs/error.rs index 39bef49b8..156631b2a 100644 --- a/bitcoin/src/electrs/error.rs +++ b/bitcoin/src/electrs/error.rs @@ -35,6 +35,9 @@ pub enum Error { TryFromIntError(#[from] TryFromIntError), #[error("ParseIntError: {0}")] ParseIntError(#[from] ParseIntError), + + #[error("No txids in block")] + EmptyBlock, } impl Error { diff --git a/bitcoin/src/electrs/mod.rs b/bitcoin/src/electrs/mod.rs index 7973d77b8..536d3defe 100644 --- a/bitcoin/src/electrs/mod.rs +++ b/bitcoin/src/electrs/mod.rs @@ -136,6 +136,14 @@ impl ElectrsClient { Ok(txs) } + pub(crate) async fn get_coinbase_txid(&self, block_hash: &BlockHash) -> Result { + self.get_and_decode::>(&format!("/block/{block_hash}/txids")) + .await? + .first() + .ok_or(Error::EmptyBlock) + .and_then(|raw_txid| Ok(Txid::from_str(raw_txid)?)) + } + pub(crate) async fn get_block(&self, hash: &BlockHash) -> Result { let (header, txdata) = try_join(self.get_block_header(hash), self.get_transactions_in_block(hash)).await?; Ok(Block { header, txdata }) diff --git a/bitcoin/src/error.rs b/bitcoin/src/error.rs index 6835732f7..119cfb8c9 100644 --- a/bitcoin/src/error.rs +++ b/bitcoin/src/error.rs @@ -77,6 +77,8 @@ pub enum Error { FailedToConstructWalletName, #[error("AddressError: {0}")] AddressError(#[from] AddressError), + #[error("Failed to fetch coinbase tx")] + CoinbaseFetchingFailure, } impl Error { diff --git a/bitcoin/src/iter.rs b/bitcoin/src/iter.rs index 6bbd137d7..7f50ca51a 100644 --- a/bitcoin/src/iter.rs +++ b/bitcoin/src/iter.rs @@ -292,7 +292,7 @@ mod tests { Block { txdata: transactions.into_iter().map(dummy_tx).collect(), header: BlockHeader { - version: Version::from_consensus(4), + version: Version::from_consensus(2), bits: CompactTarget::from_consensus(0), nonce: 0, time: 0, diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 536ec32aa..cfc29f405 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -113,14 +113,21 @@ fn get_exponential_backoff() -> ExponentialBackoff { } } +#[derive(PartialEq, Eq, PartialOrd, Clone, Debug)] +pub struct RawTransactionProof { + pub user_tx_proof: Vec, + pub raw_user_tx: Vec, + pub coinbase_tx_proof: Vec, + pub raw_coinbase_tx: Vec, +} + #[derive(PartialEq, Eq, PartialOrd, Clone, Copy, Debug)] pub struct SatPerVbyte(pub u64); #[derive(Debug, Clone)] pub struct TransactionMetadata { pub txid: Txid, - pub proof: Vec, - pub raw_tx: Vec, + pub proof: RawTransactionProof, pub block_height: u32, pub block_hash: BlockHash, pub fee: Option, @@ -885,19 +892,29 @@ impl BitcoinCoreApi for BitcoinCore { .await?; let proof = retry(get_exponential_backoff(), || async { - Ok(self.get_proof(txid, &block_hash).await?) - }) - .await?; - - let raw_tx = retry(get_exponential_backoff(), || async { - Ok(self.get_raw_tx(&txid, &block_hash).await?) + // fetch coinbase info.. + let block = self.get_block(&block_hash).await?; + let coinbase_tx = block.coinbase().ok_or(Error::CoinbaseFetchingFailure)?; + let coinbase_txid = coinbase_tx.txid(); + let coinbase_tx_proof = self.get_proof(coinbase_txid, &block_hash).await?; + let raw_coinbase_tx = self.get_raw_tx(&coinbase_txid, &block_hash).await?; + + // fetch user tx info.. + let raw_user_tx = self.get_raw_tx(&txid, &block_hash).await?; + let user_tx_proof = self.get_proof(txid, &block_hash).await?; + + Ok(RawTransactionProof { + raw_coinbase_tx, + coinbase_tx_proof, + raw_user_tx, + user_tx_proof, + }) }) .await?; Ok(TransactionMetadata { txid, proof, - raw_tx, block_height, block_hash, fee, diff --git a/bitcoin/src/light/mod.rs b/bitcoin/src/light/mod.rs index 9b94ef711..b432a7467 100644 --- a/bitcoin/src/light/mod.rs +++ b/bitcoin/src/light/mod.rs @@ -7,7 +7,7 @@ pub use error::Error; use async_trait::async_trait; use backoff::future::retry; -use futures::future::{join_all, try_join, try_join_all}; +use futures::future::{join_all, try_join, try_join4, try_join_all}; use std::{convert::TryFrom, sync::Arc, time::Duration}; use tokio::{sync::Mutex, time::sleep}; @@ -82,6 +82,10 @@ impl BitcoinLight { let txid = self.electrs.send_transaction(transaction.transaction).await?; Ok(txid) } + + async fn get_coinbase_txid(&self, block_hash: &BlockHash) -> Result { + Ok(self.electrs.get_coinbase_txid(&block_hash).await?) + } } #[async_trait] @@ -236,15 +240,28 @@ impl BitcoinCoreApi for BitcoinLight { }) .await?; - let (proof, raw_tx) = retry(get_exponential_backoff(), || async { - Ok(try_join(self.get_proof(txid, &block_hash), self.get_raw_tx(&txid, &block_hash)).await?) + let proof = retry(get_exponential_backoff(), || async { + let coinbase_txid = self.get_coinbase_txid(&block_hash).await?; + + let (coinbase_tx_proof, raw_coinbase_tx, user_tx_proof, raw_user_tx) = try_join4( + self.get_proof(coinbase_txid, &block_hash), + self.get_raw_tx(&coinbase_txid, &block_hash), + self.get_proof(txid, &block_hash), + self.get_raw_tx(&txid, &block_hash), + ) + .await?; + Ok(RawTransactionProof { + coinbase_tx_proof, + raw_coinbase_tx, + user_tx_proof, + raw_user_tx, + }) }) .await?; Ok(TransactionMetadata { txid, proof, - raw_tx, block_height, block_hash, fee: Some(fee), diff --git a/docker-compose.yml b/docker-compose.yml index 5d4db6d44..d99f652ca 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.8" services: interbtc: - image: "interlayhq/interbtc:1.25.0-rc1" + image: "interlayhq/interbtc:1.25.0-rc4" command: - --rpc-external - --ws-external diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index cdff1a98c..c3d7a1d4d 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -52,22 +52,23 @@ rand = { version = "0.7", optional = true } [dependencies.primitives] git = "https://github.com/interlay/interbtc" -rev = "2ec5b959a547f28d7bab7799568321c9cff40343" +rev = "1b90616692dcce55749616b4c60bdab228279909" package = "interbtc-primitives" [dependencies.module-bitcoin] git = "https://github.com/interlay/interbtc" -rev = "2ec5b959a547f28d7bab7799568321c9cff40343" +rev = "1b90616692dcce55749616b4c60bdab228279909" package = "bitcoin" +features = ["parser"] [dependencies.module-btc-relay] git = "https://github.com/interlay/interbtc" -rev = "2ec5b959a547f28d7bab7799568321c9cff40343" +rev = "1b90616692dcce55749616b4c60bdab228279909" package = "btc-relay" [dependencies.module-oracle-rpc-runtime-api] git = "https://github.com/interlay/interbtc" -rev = "2ec5b959a547f28d7bab7799568321c9cff40343" +rev = "1b90616692dcce55749616b4c60bdab228279909" package = "oracle-rpc-runtime-api" [dev-dependencies] diff --git a/runtime/metadata-parachain-interlay.scale b/runtime/metadata-parachain-interlay.scale index 28dffb7de..2ed1ce0d5 100644 Binary files a/runtime/metadata-parachain-interlay.scale and b/runtime/metadata-parachain-interlay.scale differ diff --git a/runtime/metadata-parachain-kintsugi.scale b/runtime/metadata-parachain-kintsugi.scale index 4582982a2..7ffb1859d 100644 Binary files a/runtime/metadata-parachain-kintsugi.scale and b/runtime/metadata-parachain-kintsugi.scale differ diff --git a/runtime/src/integration/bitcoin_simulator.rs b/runtime/src/integration/bitcoin_simulator.rs index 50d7d2b1e..d36dcad39 100644 --- a/runtime/src/integration/bitcoin_simulator.rs +++ b/runtime/src/integration/bitcoin_simulator.rs @@ -13,8 +13,8 @@ use bitcoin::{ }, secp256k1::{self, constants::SECRET_KEY_SIZE, Secp256k1, SecretKey}, serialize, Address, Amount, BitcoinCoreApi, Block, BlockHash, BlockHeader, Error as BitcoinError, GetBlockResult, - Hash, Network, OutPoint, PartialMerkleTree, PrivateKey, PublicKey, SatPerVbyte, Script, Transaction, - TransactionExt, TransactionMetadata, TxIn, TxMerkleNode, TxOut, Txid, PUBLIC_KEY_SIZE, + Hash, Network, OutPoint, PartialMerkleTree, PrivateKey, PublicKey, RawTransactionProof, SatPerVbyte, Script, + Transaction, TransactionExt, TransactionMetadata, TxIn, TxMerkleNode, TxOut, Txid, PUBLIC_KEY_SIZE, }; use rand::{thread_rng, Rng}; use std::{convert::TryInto, sync::Arc, time::Duration}; @@ -54,7 +54,7 @@ impl MockBitcoinCore { ret.parachain_rpc .initialize_btc_relay(RawBlockHeader(raw_block_header), 0) .await - .unwrap(); + .expect("failed to initialize relay"); // submit blocks in order to prevent the WaitingForRelayerInitialization error in request_issue let headers = futures::future::join_all((0..7u32).map(|_| ret.generate_block_with_transaction(&dummy_tx))) @@ -192,13 +192,28 @@ impl MockBitcoinCore { fn generate_coinbase_transaction(address: &BtcAddress, reward: u64, height: u32) -> Transaction { let address = ScriptBuf::from(address.to_script_pub_key().as_bytes().to_vec()); + // construct height: see https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki + // first byte is number of bytes in the number (will be 0x03 on main net for the next + // 150 or so years with 223-1 blocks), following bytes are little-endian representation + // of the number (including a sign bit) + let mut height_bytes = height.to_le_bytes().to_vec(); + for i in (1..4).rev() { + // remove trailing zeroes, but always keep first byte even if it's zero + if height_bytes[i] == 0 { + height_bytes.remove(i); + } else { + break; + } + } + height_bytes.insert(0, height_bytes.len() as u8); + // note that we set lock_time to height, otherwise we might generate blocks with // identical block hashes Transaction { input: vec![TxIn { previous_output: OutPoint::null(), // coinbase witness: Witness::from_slice::<&[u8]>(&[]), - script_sig: Default::default(), + script_sig: ScriptBuf::from(height_bytes), sequence: Sequence(u32::max_value()), }], output: vec![TxOut { @@ -360,7 +375,16 @@ impl BitcoinCoreApi for MockBitcoinCore { // part two: info about the transactions (we assume the txid is at index 1) let txids = block.txdata.iter().map(|x| x.txid()).collect::>(); - let partial_merkle_tree = PartialMerkleTree::from_txids(&txids, &[false, true]); + assert_eq!(txids.len(), 2); // expect coinbase and user tx + + let partial_merkle_tree = if txids[0] == txid { + PartialMerkleTree::from_txids(&txids, &[true, false]) + } else if txids[1] == txid { + PartialMerkleTree::from_txids(&txids, &[false, true]) + } else { + panic!("txid not in block") + }; + proof.append(&mut serialize(&partial_merkle_tree)); Ok(proof) @@ -441,13 +465,20 @@ impl BitcoinCoreApi for MockBitcoinCore { tokio::time::sleep(Duration::from_secs(1)).await; }; let block_hash = block.block_hash(); - let proof = self.get_proof(txid, &block_hash).await.unwrap(); - let raw_tx = self.get_raw_tx(&txid, &block_hash).await.unwrap(); + let coinbase_txid = block.coinbase().unwrap().txid(); + let coinbase_tx_proof = self.get_proof(coinbase_txid, &block_hash).await.unwrap(); + let raw_coinbase_tx = self.get_raw_tx(&coinbase_txid, &block_hash).await.unwrap(); + let user_tx_proof = self.get_proof(txid, &block_hash).await.unwrap(); + let raw_user_tx = self.get_raw_tx(&txid, &block_hash).await.unwrap(); Ok(TransactionMetadata { block_hash, - proof, - raw_tx, + proof: RawTransactionProof { + user_tx_proof, + raw_user_tx, + coinbase_tx_proof, + raw_coinbase_tx, + }, txid, block_height: block_height as u32, fee: None, diff --git a/runtime/src/integration/mod.rs b/runtime/src/integration/mod.rs index a7041cd3d..121ee9594 100644 --- a/runtime/src/integration/mod.rs +++ b/runtime/src/integration/mod.rs @@ -33,6 +33,7 @@ pub use bitcoin_simulator::MockBitcoinCore; pub async fn default_root_provider(key: AccountKeyring) -> (InterBtcParachain, TempDir) { let tmp = TempDir::new("btc-parachain-").expect("failed to create tempdir"); let root_provider = setup_provider(key).await; + try_join( root_provider.set_bitcoin_confirmations(1), root_provider.set_parachain_confirmations(1), @@ -81,7 +82,7 @@ pub async fn assert_issue( .unwrap(); parachain_rpc - .execute_issue(*issue.issue_id, &metadata.proof, &metadata.raw_tx) + .execute_issue(*issue.issue_id, &metadata.proof) .await .unwrap(); } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index b7836b7b7..d5dd78e0a 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -71,8 +71,6 @@ pub const DISABLE_DIFFICULTY_CHECK: &str = "DisableDifficultyCheck"; ), derive_for_type(path = "interbtc_primitives::VaultCurrencyPair", derive = "Eq, PartialEq"), derive_for_type(path = "interbtc_primitives::VaultId", derive = "Eq, PartialEq"), - derive_for_type(path = "security::types::ErrorCode", derive = "Eq, PartialEq, Ord, PartialOrd"), - derive_for_type(path = "security::types::StatusCode", derive = "Eq, PartialEq"), substitute_type(path = "primitive_types::H256", with = "::subxt::utils::Static"), substitute_type(path = "primitive_types::U256", with = "::subxt::utils::Static"), substitute_type(path = "primitive_types::H160", with = "::subxt::utils::Static"), @@ -106,6 +104,10 @@ pub const DISABLE_DIFFICULTY_CHECK: &str = "DisableDifficultyCheck"; path = "bitcoin::types::Transaction", with = "::subxt::utils::Static<::module_bitcoin::types::Transaction>" ), + substitute_type( + path = "bitcoin::types::FullTransactionProof", + with = "::subxt::utils::Static<::module_bitcoin::types::FullTransactionProof>" + ), ) )] #[cfg_attr( @@ -123,8 +125,6 @@ pub const DISABLE_DIFFICULTY_CHECK: &str = "DisableDifficultyCheck"; ), derive_for_type(path = "interbtc_primitives::VaultCurrencyPair", derive = "Eq, PartialEq"), derive_for_type(path = "interbtc_primitives::VaultId", derive = "Eq, PartialEq"), - derive_for_type(path = "security::types::ErrorCode", derive = "Eq, PartialEq, Ord, PartialOrd"), - derive_for_type(path = "security::types::StatusCode", derive = "Eq, PartialEq"), substitute_type(path = "primitive_types::H256", with = "::subxt::utils::Static"), substitute_type(path = "primitive_types::U256", with = "::subxt::utils::Static"), substitute_type(path = "primitive_types::H160", with = "::subxt::utils::Static"), @@ -158,6 +158,10 @@ pub const DISABLE_DIFFICULTY_CHECK: &str = "DisableDifficultyCheck"; path = "bitcoin::types::Transaction", with = "::subxt::utils::Static<::module_bitcoin::types::Transaction>" ), + substitute_type( + path = "bitcoin::types::FullTransactionProof", + with = "::subxt::utils::Static<::module_bitcoin::types::FullTransactionProof>" + ), ) )] diff --git a/runtime/src/rpc.rs b/runtime/src/rpc.rs index 8fbd3cbce..ac01627f4 100644 --- a/runtime/src/rpc.rs +++ b/runtime/src/rpc.rs @@ -7,16 +7,18 @@ use crate::{ AccountId, AssetRegistry, CurrencyId, Error, InterBtcRuntime, InterBtcSigner, RetryPolicy, RichH256Le, SubxtError, }; use async_trait::async_trait; +use bitcoin::RawTransactionProof; use codec::{Decode, Encode}; use futures::{future::join_all, stream::StreamExt, FutureExt, SinkExt, Stream}; use module_bitcoin::{ - merkle::MerkleProof, + merkle::{MerkleProof, PartialTransactionProof}, parser::{parse_block_header, parse_transaction}, + types::FullTransactionProof, }; use module_oracle_rpc_runtime_api::BalanceWrapper; use primitives::UnsignedFixedPoint; use serde_json::Value; -use std::{future::Future, ops::Range, sync::Arc, time::Duration}; +use std::{convert::TryInto, future::Future, ops::Range, sync::Arc, time::Duration}; use subxt::{ blocks::ExtrinsicEvents, client::OnlineClient, @@ -31,6 +33,7 @@ use tokio::{ sync::RwLock, time::{sleep, timeout}, }; + // timeout before retrying parachain calls (5 minutes) const TRANSACTION_TIMEOUT: Duration = Duration::from_secs(300); @@ -890,9 +893,8 @@ pub trait ReplacePallet { /// /// * `&self` - sender of the transaction: the old vault /// * `replace_id` - the ID of the replacement request - /// * 'merkle_proof' - the merkle root of the block - /// * `raw_tx` - the transaction id in bytes - async fn execute_replace(&self, replace_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), Error>; + /// * `raw_proof` - raw tx and proofs of coinbase and user tx + async fn execute_replace(&self, replace_id: H256, raw_proof: &RawTransactionProof) -> Result<(), Error>; /// Cancel vault replacement /// @@ -966,13 +968,12 @@ impl ReplacePallet for InterBtcParachain { Ok(()) } - async fn execute_replace(&self, replace_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), Error> { - self.with_unique_signer(metadata::tx().replace().execute_replace( - Static(replace_id), - Static(MerkleProof::parse(merkle_proof)?), - Static(parse_transaction(raw_tx)?), - raw_tx.len() as u32, - )) + async fn execute_replace(&self, replace_id: H256, raw_proof: &RawTransactionProof) -> Result<(), Error> { + self.with_unique_signer( + metadata::tx() + .replace() + .execute_replace(Static(replace_id), build_full_tx_proof(raw_proof)?), + ) .await?; Ok(()) } @@ -1168,31 +1169,12 @@ impl OraclePallet for InterBtcParachain { #[async_trait] pub trait SecurityPallet { - async fn get_parachain_status(&self) -> Result; - - async fn get_error_codes(&self) -> Result, Error>; - /// Gets the current active block number of the parachain async fn get_current_active_block_number(&self) -> Result; } #[async_trait] impl SecurityPallet for InterBtcParachain { - /// Get the current security status of the parachain. - /// Should be one of; `Running`, `Error` or `Shutdown`. - async fn get_parachain_status(&self) -> Result { - self.query_finalized_or_error(metadata::storage().security().parachain_status()) - .await - } - - /// Return any `ErrorCode`s set in the security module. - async fn get_error_codes(&self) -> Result, Error> { - Ok(self - .query_finalized_or_error(metadata::storage().security().errors()) - .await? - .0) - } - /// Gets the current active block number of the parachain async fn get_current_active_block_number(&self) -> Result { self.query_finalized_or_default(metadata::storage().security().active_block_count()) @@ -1206,7 +1188,7 @@ pub trait IssuePallet { async fn request_issue(&self, amount: u128, vault_id: &VaultId) -> Result; /// Execute a issue request by providing a Bitcoin transaction inclusion proof - async fn execute_issue(&self, issue_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), Error>; + async fn execute_issue(&self, issue_id: H256, raw_proof: &RawTransactionProof) -> Result<(), Error>; /// Cancel an ongoing issue request async fn cancel_issue(&self, issue_id: H256) -> Result<(), Error>; @@ -1234,13 +1216,12 @@ impl IssuePallet for InterBtcParachain { .ok_or(Error::RequestIssueIDNotFound) } - async fn execute_issue(&self, issue_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), Error> { - self.with_unique_signer(metadata::tx().issue().execute_issue( - Static(issue_id), - Static(MerkleProof::parse(merkle_proof)?), - Static(parse_transaction(raw_tx)?), - raw_tx.len() as u32, - )) + async fn execute_issue(&self, issue_id: H256, raw_proof: &RawTransactionProof) -> Result<(), Error> { + self.with_unique_signer( + metadata::tx() + .issue() + .execute_issue(Static(issue_id), build_full_tx_proof(raw_proof)?), + ) .await?; Ok(()) } @@ -1310,7 +1291,7 @@ pub trait RedeemPallet { async fn request_redeem(&self, amount: u128, btc_address: BtcAddress, vault_id: &VaultId) -> Result; /// Execute a redeem request by providing a Bitcoin transaction inclusion proof - async fn execute_redeem(&self, redeem_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), Error>; + async fn execute_redeem(&self, redeem_id: H256, raw_proof: &RawTransactionProof) -> Result<(), Error>; /// Cancel an ongoing redeem request async fn cancel_redeem(&self, redeem_id: H256, reimburse: bool) -> Result<(), Error>; @@ -1341,13 +1322,12 @@ impl RedeemPallet for InterBtcParachain { Ok(*redeem_event.redeem_id) } - async fn execute_redeem(&self, redeem_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), Error> { - self.with_unique_signer(metadata::tx().redeem().execute_redeem( - Static(redeem_id), - Static(MerkleProof::parse(merkle_proof)?), - Static(parse_transaction(raw_tx)?), - raw_tx.len() as u32, - )) + async fn execute_redeem(&self, redeem_id: H256, raw_proof: &RawTransactionProof) -> Result<(), Error> { + self.with_unique_signer( + metadata::tx() + .redeem() + .execute_redeem(Static(redeem_id), build_full_tx_proof(raw_proof)?), + ) .await?; Ok(()) } @@ -1694,7 +1674,7 @@ impl VaultRegistryPallet for InterBtcParachain { self.with_unique_signer( metadata::tx() .nomination() - .withdraw_collateral(vault_id.clone(), amount, None), + .withdraw_collateral(vault_id.clone(), Some(amount), None), ) .await?; Ok(()) @@ -1957,3 +1937,18 @@ impl SudoPallet for InterBtcParachain { .await } } + +pub fn build_full_tx_proof(raw_proof: &RawTransactionProof) -> Result, Error> { + Ok(Static(FullTransactionProof { + user_tx_proof: PartialTransactionProof { + transaction: parse_transaction(&raw_proof.raw_user_tx[..])?, + tx_encoded_len: raw_proof.raw_user_tx.len().try_into()?, + merkle_proof: MerkleProof::parse(&raw_proof.user_tx_proof[..])?, + }, + coinbase_proof: PartialTransactionProof { + transaction: parse_transaction(&raw_proof.raw_coinbase_tx[..])?, + tx_encoded_len: raw_proof.raw_coinbase_tx.len().try_into()?, + merkle_proof: MerkleProof::parse(&raw_proof.coinbase_tx_proof[..])?, + }, + })) +} diff --git a/runtime/src/tests.rs b/runtime/src/tests.rs index bda0b3c80..28059507c 100644 --- a/runtime/src/tests.rs +++ b/runtime/src/tests.rs @@ -4,8 +4,8 @@ const DEFAULT_TESTING_CURRENCY: CurrencyId = Token(KSM); use super::{ BtcAddress, BtcPublicKey, BtcRelayPallet, CollateralBalancesPallet, CurrencyId, FixedPointNumber, FixedU128, - OraclePallet, RawBlockHeader, ReplacePallet, SecurityPallet, StatusCode, SudoPallet, Token, TryFromSymbol, - VaultRegistryPallet, KBTC, KINT, KSM, + OraclePallet, RawBlockHeader, ReplacePallet, SecurityPallet, SudoPallet, Token, TryFromSymbol, VaultRegistryPallet, + KBTC, KINT, KSM, }; use crate::{ integration::*, utils::account_id::AccountId32, FeedValuesEvent, OracleKey, RuntimeCurrencyInfo, VaultId, H160, @@ -47,14 +47,11 @@ async fn test_getters() { async { assert_eq!(parachain_rpc.get_free_balance(Token(KINT)).await.unwrap(), 1 << 60); }, - async { - assert_eq!(parachain_rpc.get_parachain_status().await.unwrap(), StatusCode::Error); - }, async { assert!(parachain_rpc.get_replace_dust_amount().await.unwrap() > 0); }, async { - assert!(parachain_rpc.get_current_active_block_number().await.unwrap() == 0); + assert!(parachain_rpc.get_current_active_block_number().await.is_ok()); } ); parachain_runner.kill().unwrap(); diff --git a/runtime/src/types.rs b/runtime/src/types.rs index a45028457..abcb9df71 100644 --- a/runtime/src/types.rs +++ b/runtime/src/types.rs @@ -45,10 +45,7 @@ mod metadata_aliases { pub use metadata::runtime_types::interbtc_primitives::oracle::Key as OracleKey; - pub use metadata::runtime_types::{ - security::types::{ErrorCode, StatusCode}, - vault_registry::types::VaultStatus, - }; + pub use metadata::runtime_types::vault_registry::types::VaultStatus; pub type InterBtcVault = metadata::runtime_types::vault_registry::types::Vault; pub type InterBtcVaultStatic = metadata::runtime_types::vault_registry::types::Vault< diff --git a/vault/src/cancellation.rs b/vault/src/cancellation.rs index ab0deafb9..56e2cc143 100644 --- a/vault/src/cancellation.rs +++ b/vault/src/cancellation.rs @@ -315,12 +315,12 @@ impl Cancel mod tests { use super::*; use async_trait::async_trait; + use bitcoin::RawTransactionProof; use futures::channel::mpsc; use jsonrpc_core::serde_json::{Map, Value}; use runtime::{ - subxt::utils::Static, AccountId, AssetMetadata, BtcAddress, BtcPublicKey, CurrencyId, ErrorCode, - InterBtcIssueRequest, InterBtcReplaceRequest, IssueRequestStatus, RequestIssueEvent, StatusCode, Token, - VaultId, DOT, IBTC, INTR, + subxt::utils::Static, AccountId, AssetMetadata, BtcAddress, BtcPublicKey, CurrencyId, InterBtcIssueRequest, + InterBtcReplaceRequest, IssueRequestStatus, RequestIssueEvent, Token, VaultId, DOT, IBTC, INTR, }; macro_rules! assert_err { @@ -339,7 +339,7 @@ mod tests { #[async_trait] pub trait IssuePallet { async fn request_issue(&self, amount: u128, vault_id: &VaultId) -> Result; - async fn execute_issue(&self, issue_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_issue(&self, issue_id: H256, raw_proof: &RawTransactionProof,) -> Result<(), RuntimeError>; async fn cancel_issue(&self, issue_id: H256) -> Result<(), RuntimeError>; async fn get_issue_request(&self, issue_id: H256) -> Result; async fn get_vault_issue_requests(&self, account_id: AccountId) -> Result, RuntimeError>; @@ -353,7 +353,7 @@ mod tests { async fn request_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn withdraw_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn accept_replace(&self, new_vault: &VaultId, old_vault: &VaultId, amount_btc: u128, collateral: u128, btc_address: BtcAddress) -> Result<(), RuntimeError>; - async fn execute_replace(&self, replace_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_replace(&self, replace_id: H256, raw_proof: &RawTransactionProof) -> Result<(), RuntimeError>; async fn cancel_replace(&self, replace_id: H256) -> Result<(), RuntimeError>; async fn get_new_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; async fn get_old_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; @@ -376,8 +376,6 @@ mod tests { #[async_trait] pub trait SecurityPallet { - async fn get_parachain_status(&self) -> Result; - async fn get_error_codes(&self) -> Result, RuntimeError>; async fn get_current_active_block_number(&self) -> Result; } } diff --git a/vault/src/execution.rs b/vault/src/execution.rs index ac2dccc48..2619714f4 100644 --- a/vault/src/execution.rs +++ b/vault/src/execution.rs @@ -404,7 +404,7 @@ impl Request { // Retry until success or timeout, explicitly handle the cases // where the redeem has expired or the rpc has disconnected runtime::notify_retry( - || (execute)(¶chain_rpc, self.hash, &tx_metadata.proof, &tx_metadata.raw_tx), + || (execute)(¶chain_rpc, self.hash, &tx_metadata.proof), |result| async { match result { Ok(ok) => Ok(ok), @@ -665,15 +665,15 @@ mod tests { use async_trait::async_trait; use bitcoin::{ json, Address, Amount, BitcoinCoreApi, Block, BlockHash, BlockHeader, Error as BitcoinError, Hash, Network, - PrivateKey, PublicKey, Transaction, TransactionMetadata, Txid, + PrivateKey, PublicKey, RawTransactionProof, Transaction, TransactionMetadata, Txid, }; use jsonrpc_core::serde_json::{Map, Value}; use runtime::{ sp_core::H160, AccountId, AssetMetadata, BitcoinBlockHeight, BlockNumber, BtcPublicKey, CurrencyId, - Error as RuntimeError, ErrorCode, FeeRateUpdateReceiver, InterBtcRichBlockHeader, InterBtcVault, OracleKey, - RawBlockHeader, StatusCode, Token, DOT, IBTC, + Error as RuntimeError, FeeRateUpdateReceiver, InterBtcRichBlockHeader, InterBtcVault, OracleKey, + RawBlockHeader, Token, DOT, IBTC, }; - use std::{collections::BTreeSet, sync::Arc}; + use std::sync::Arc; macro_rules! assert_ok { ( $x:expr $(,)? ) => { @@ -724,7 +724,7 @@ mod tests { #[async_trait] pub trait RedeemPallet { async fn request_redeem(&self, amount: u128, btc_address: BtcAddress, vault_id: &VaultId) -> Result; - async fn execute_redeem(&self, redeem_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_redeem(&self, redeem_id: H256, raw_proof: &RawTransactionProof) -> Result<(), RuntimeError>; async fn cancel_redeem(&self, redeem_id: H256, reimburse: bool) -> Result<(), RuntimeError>; async fn get_redeem_request(&self, redeem_id: H256) -> Result; async fn get_vault_redeem_requests(&self, account_id: AccountId) -> Result, RuntimeError>; @@ -736,7 +736,7 @@ mod tests { async fn request_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn withdraw_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn accept_replace(&self, new_vault: &VaultId, old_vault: &VaultId, amount_btc: u128, collateral: u128, btc_address: BtcAddress) -> Result<(), RuntimeError>; - async fn execute_replace(&self, replace_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_replace(&self, replace_id: H256, raw_proof: &RawTransactionProof) -> Result<(), RuntimeError>; async fn cancel_replace(&self, replace_id: H256) -> Result<(), RuntimeError>; async fn get_new_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; async fn get_old_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; @@ -762,8 +762,6 @@ mod tests { #[async_trait] pub trait SecurityPallet { - async fn get_parachain_status(&self) -> Result; - async fn get_error_codes(&self) -> Result, RuntimeError>; async fn get_current_active_block_number(&self) -> Result; } @@ -910,7 +908,7 @@ mod tests { parachain_rpc .expect_get_current_active_block_number() .returning(move || Ok(current_parachain_height)); - parachain_rpc.expect_execute_redeem().returning(|_, _, _| Ok(())); + parachain_rpc.expect_execute_redeem().returning(|_, _| Ok(())); parachain_rpc.expect_wait_for_block_in_relay().returning(|_, _| Ok(())); parachain_rpc @@ -928,8 +926,12 @@ mod tests { mock_bitcoin.expect_wait_for_transaction_metadata().returning(|_, _| { Ok(TransactionMetadata { txid: Txid::all_zeros(), - proof: vec![], - raw_tx: vec![], + proof: RawTransactionProof { + coinbase_tx_proof: vec![], + raw_coinbase_tx: vec![], + raw_user_tx: vec![], + user_tx_proof: vec![], + }, block_height: 0, block_hash: BlockHash::all_zeros(), fee: None, @@ -1042,10 +1044,7 @@ mod tests { .expect_get_current_active_block_number() .times(1) .returning(|| Ok(50)); - parachain_rpc - .expect_execute_replace() - .times(1) - .returning(|_, _, _| Ok(())); + parachain_rpc.expect_execute_replace().times(1).returning(|_, _| Ok(())); parachain_rpc .expect_wait_for_block_in_relay() .times(1) @@ -1062,8 +1061,12 @@ mod tests { mock_bitcoin.expect_wait_for_transaction_metadata().returning(|_, _| { Ok(TransactionMetadata { txid: Txid::all_zeros(), - proof: vec![], - raw_tx: vec![], + proof: RawTransactionProof { + coinbase_tx_proof: vec![], + raw_coinbase_tx: vec![], + raw_user_tx: vec![], + user_tx_proof: vec![], + }, block_height: 0, block_hash: BlockHash::all_zeros(), fee: None, diff --git a/vault/src/issue.rs b/vault/src/issue.rs index a621df503..e8b063461 100644 --- a/vault/src/issue.rs +++ b/vault/src/issue.rs @@ -296,12 +296,9 @@ async fn process_transaction_and_execute_issue( return Ok(()); } - // found tx, submit proof - let txid = transaction.txid(); - - // bitcoin core is currently blocking, no need to try_join - let raw_tx = bitcoin_core.get_raw_tx(&txid, &block_hash).await?; - let proof = bitcoin_core.get_proof(txid, &block_hash).await?; + let tx_metadata = bitcoin_core + .wait_for_transaction_metadata(transaction.txid(), num_confirmations) + .await?; tracing::info!( "Executing issue #{:?} on behalf of user {:?} with vault {:?}", @@ -309,7 +306,7 @@ async fn process_transaction_and_execute_issue( issue.requester.pretty_print(), issue.vault.pretty_print() ); - match btc_parachain.execute_issue(issue_id, &proof, &raw_tx).await { + match btc_parachain.execute_issue(issue_id, &tx_metadata.proof).await { Ok(_) => (), Err(err) if err.is_issue_completed() => { tracing::info!("Issue #{} has already been completed", issue_id); diff --git a/vault/src/metrics.rs b/vault/src/metrics.rs index a62186473..a227e103c 100644 --- a/vault/src/metrics.rs +++ b/vault/src/metrics.rs @@ -661,7 +661,7 @@ mod tests { use async_trait::async_trait; use bitcoin::{ json, Address, Amount, BitcoinCoreApi, Block, BlockHash, BlockHeader, Error as BitcoinError, Network, - PrivateKey, PublicKey, SatPerVbyte, Transaction, TransactionMetadata, Txid, + PrivateKey, PublicKey, RawTransactionProof, SatPerVbyte, Transaction, TransactionMetadata, Txid, }; use jsonrpc_core::serde_json::{Map, Value}; use runtime::{ @@ -669,9 +669,8 @@ mod tests { subxt::utils::Static, AccountId, AssetMetadata, AssetRegistry, Balance, BlockNumber, BtcAddress, BtcPublicKey, CurrencyId::{self, ForeignAsset, LendToken}, - Error as RuntimeError, ErrorCode, InterBtcIssueRequest, InterBtcRedeemRequest, InterBtcReplaceRequest, - InterBtcVault, LendingAssets, RequestIssueEvent, StatusCode, Token, VaultId, VaultStatus, DOT, H256, IBTC, - INTR, + Error as RuntimeError, InterBtcIssueRequest, InterBtcRedeemRequest, InterBtcReplaceRequest, InterBtcVault, + LendingAssets, RequestIssueEvent, Token, VaultId, VaultStatus, DOT, H256, IBTC, INTR, }; mockall::mock! { @@ -692,7 +691,7 @@ mod tests { #[async_trait] pub trait IssuePallet { async fn request_issue(&self, amount: u128, vault_id: &VaultId) -> Result; - async fn execute_issue(&self, issue_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_issue(&self, issue_id: H256, raw_proof: &RawTransactionProof) -> Result<(), RuntimeError>; async fn cancel_issue(&self, issue_id: H256) -> Result<(), RuntimeError>; async fn get_issue_request(&self, issue_id: H256) -> Result; async fn get_vault_issue_requests(&self, account_id: AccountId) -> Result, RuntimeError>; @@ -703,7 +702,7 @@ mod tests { #[async_trait] pub trait RedeemPallet { async fn request_redeem(&self, amount: u128, btc_address: BtcAddress, vault_id: &VaultId) -> Result; - async fn execute_redeem(&self, redeem_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_redeem(&self, redeem_id: H256, raw_proof: &RawTransactionProof) -> Result<(), RuntimeError>; async fn cancel_redeem(&self, redeem_id: H256, reimburse: bool) -> Result<(), RuntimeError>; async fn get_redeem_request(&self, redeem_id: H256) -> Result; async fn get_vault_redeem_requests(&self, account_id: AccountId) -> Result, RuntimeError>; @@ -742,7 +741,7 @@ mod tests { async fn request_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn withdraw_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn accept_replace(&self, new_vault: &VaultId, old_vault: &VaultId, amount_btc: u128, collateral: u128, btc_address: BtcAddress) -> Result<(), RuntimeError>; - async fn execute_replace(&self, replace_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_replace(&self, replace_id: H256, raw_proof: &RawTransactionProof) -> Result<(), RuntimeError>; async fn cancel_replace(&self, replace_id: H256) -> Result<(), RuntimeError>; async fn get_new_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; async fn get_old_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; @@ -753,10 +752,6 @@ mod tests { #[async_trait] pub trait SecurityPallet { - async fn get_parachain_status(&self) -> Result; - - async fn get_error_codes(&self) -> Result, RuntimeError>; - /// Gets the current active block number of the parachain async fn get_current_active_block_number(&self) -> Result; } diff --git a/vault/src/replace.rs b/vault/src/replace.rs index b45897b52..b5ee4d0ae 100644 --- a/vault/src/replace.rs +++ b/vault/src/replace.rs @@ -210,7 +210,7 @@ mod tests { use async_trait::async_trait; use bitcoin::{ json, Address, Amount, BitcoinCoreApi, Block, BlockHash, BlockHeader, Error as BitcoinError, Network, - PrivateKey, PublicKey, SatPerVbyte, Transaction, TransactionMetadata, Txid, + PrivateKey, PublicKey, RawTransactionProof, SatPerVbyte, Transaction, TransactionMetadata, Txid, }; use runtime::{ AccountId, Balance, BtcAddress, BtcPublicKey, CurrencyId, Error as RuntimeError, InterBtcReplaceRequest, @@ -329,7 +329,7 @@ mod tests { async fn request_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn withdraw_replace(&self, vault_id: &VaultId, amount: u128) -> Result<(), RuntimeError>; async fn accept_replace(&self, new_vault: &VaultId, old_vault: &VaultId, amount_btc: u128, collateral: u128, btc_address: BtcAddress) -> Result<(), RuntimeError>; - async fn execute_replace(&self, replace_id: H256, merkle_proof: &[u8], raw_tx: &[u8]) -> Result<(), RuntimeError>; + async fn execute_replace(&self, replace_id: H256, raw_proof: &RawTransactionProof) -> Result<(), RuntimeError>; async fn cancel_replace(&self, replace_id: H256) -> Result<(), RuntimeError>; async fn get_new_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; async fn get_old_vault_replace_requests(&self, account_id: AccountId) -> Result, RuntimeError>; diff --git a/vault/tests/vault_integration_tests.rs b/vault/tests/vault_integration_tests.rs index 11aec80d3..103a26596 100644 --- a/vault/tests/vault_integration_tests.rs +++ b/vault/tests/vault_integration_tests.rs @@ -85,7 +85,7 @@ where #[tokio::test(flavor = "multi_thread")] #[serial] async fn test_redeem_succeeds() { - test_with_vault(|client, vault_id, vault_provider| async move { + test_with_vault(|_client, vault_id, vault_provider| async move { let relayer_provider = setup_provider(AccountKeyring::Bob).await; let user_provider = setup_provider(AccountKeyring::Dave).await; @@ -149,7 +149,7 @@ async fn test_redeem_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] async fn test_replace_succeeds() { - test_with_vault(|client, old_vault_id, old_vault_provider| async move { + test_with_vault(|_client, old_vault_id, old_vault_provider| async move { let relayer_provider = setup_provider(AccountKeyring::Bob).await; let new_vault_provider = setup_provider(AccountKeyring::Eve).await; let new_vault_id = VaultId::new( @@ -262,7 +262,7 @@ async fn test_replace_succeeds() { #[tokio::test(flavor = "multi_thread")] #[serial] async fn test_withdraw_replace_succeeds() { - test_with_vault(|client, old_vault_id, old_vault_provider| async move { + test_with_vault(|_client, old_vault_id, old_vault_provider| async move { let relayer_provider = setup_provider(AccountKeyring::Bob).await; let new_vault_provider = setup_provider(AccountKeyring::Eve).await; let new_vault_id = VaultId::new( @@ -595,7 +595,7 @@ async fn test_issue_overpayment_succeeds() { } }), user_provider - .execute_issue(*issue.issue_id, &metadata.proof, &metadata.raw_tx) + .execute_issue(*issue.issue_id, &metadata.proof) .map(Result::unwrap), ) .await; @@ -1033,7 +1033,7 @@ mod test_with_bitcoind { .unwrap(); parachain_rpc - .execute_issue(*issue.issue_id, &metadata.proof, &metadata.raw_tx) + .execute_issue(*issue.issue_id, &metadata.proof) .await .unwrap(); }