From 0dfa7213fd974929beef99bf9a13893bf8b11dea Mon Sep 17 00:00:00 2001 From: Sander Bosma Date: Fri, 18 Aug 2023 12:46:20 +0200 Subject: [PATCH] feat(wip): embedded relayer --- Cargo.lock | 347 ++++++++++++++++++++++++-- crates/bitcoin/src/parser.rs | 2 +- crates/btc-relay/src/lib.rs | 2 +- parachain/Cargo.toml | 7 +- parachain/runtime/kintsugi/src/lib.rs | 2 +- parachain/src/cli.rs | 4 + parachain/src/command.rs | 5 + parachain/src/service.rs | 325 +++++++++++++++++++++++- 8 files changed, 660 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44f1949205..bb638c19c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -553,6 +553,20 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backoff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fe17f59a06fe8b87a6fc8bf53bb70b3aba76d7685f432487a68cd5552853625" +dependencies = [ + "futures-core", + "getrandom 0.2.10", + "instant", + "pin-project", + "rand 0.8.5", + "tokio", +] + [[package]] name = "backtrace" version = "0.3.67" @@ -610,6 +624,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + [[package]] name = "beef" version = "0.5.2" @@ -672,11 +692,52 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +[[package]] +name = "bitcoin" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e99ff7289b20a7385f66a0feda78af2fc119d28fb56aea8886a9cd0a4abdd75" +dependencies = [ + "bech32", + "bitcoin-private", + "bitcoin_hashes 0.12.0", + "hex_lit", + "secp256k1 0.27.0", + "serde", +] + +[[package]] +name = "bitcoin" +version = "1.1.0" +dependencies = [ + "async-trait", + "backoff", + "bitcoincore-rpc", + "cfg-if", + "clap", + "futures", + "hex", + "hyper", + "log", + "num 0.2.1", + "num-derive", + "num-traits", + "regex", + "reqwest", + "serde", + "serde_json", + "sha2 0.8.2", + "sp-core", + "thiserror", + "tokio", + "url", +] + [[package]] name = "bitcoin" version = "1.2.0" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.7.6", "frame-support", "hex", "impl-serde 0.3.2", @@ -690,12 +751,50 @@ dependencies = [ "spin 0.7.1", ] +[[package]] +name = "bitcoin-private" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" + [[package]] name = "bitcoin_hashes" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b375d62f341cef9cd9e77793ec8f1db3fc9ce2e4d57e982c8fe697a2c16af3b6" +[[package]] +name = "bitcoin_hashes" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501" +dependencies = [ + "bitcoin-private", + "serde", +] + +[[package]] +name = "bitcoincore-rpc" +version = "0.17.0" +dependencies = [ + "bitcoin-private", + "bitcoincore-rpc-json", + "jsonrpc", + "log", + "serde", + "serde_json", +] + +[[package]] +name = "bitcoincore-rpc-json" +version = "0.17.0" +dependencies = [ + "bitcoin 0.30.1", + "bitcoin-private", + "serde", + "serde_json", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -861,7 +960,7 @@ checksum = "bd769563b4ea2953e2825c9e6b7470a5f55f67e0be00030bf3e390a2a6071f64" name = "btc-relay" version = "1.2.0" dependencies = [ - "bitcoin", + "bitcoin 1.2.0", "frame-benchmarking", "frame-support", "frame-system", @@ -2354,7 +2453,7 @@ dependencies = [ "asn1-rs 0.3.1", "displaydoc", "nom", - "num-bigint", + "num-bigint 0.4.3", "num-traits", "rusticata-macros", ] @@ -2368,7 +2467,7 @@ dependencies = [ "asn1-rs 0.5.2", "displaydoc", "nom", - "num-bigint", + "num-bigint 0.4.3", "num-traits", "rusticata-macros", ] @@ -2819,6 +2918,15 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encoding_rs" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +dependencies = [ + "cfg-if", +] + [[package]] name = "enum-as-inner" version = "0.5.1" @@ -4401,6 +4509,12 @@ dependencies = [ "proc-macro-hack", ] +[[package]] +name = "hex_lit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" + [[package]] name = "hkdf" version = "0.12.3" @@ -4547,6 +4661,19 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -4751,7 +4878,8 @@ name = "interbtc-parachain" version = "1.2.0" dependencies = [ "async-trait", - "bitcoin", + "bitcoin 1.1.0", + "bitcoin 1.2.0", "btc-relay-rpc-runtime-api", "clap", "cumulus-client-cli", @@ -4784,6 +4912,7 @@ dependencies = [ "frame-support", "frame-system", "futures", + "hex", "hex-literal 0.2.2", "interbtc-primitives", "interbtc-rpc", @@ -4795,6 +4924,7 @@ dependencies = [ "loans-rpc-runtime-api", "log", "oracle-rpc-runtime-api", + "pallet-balances", "pallet-evm", "pallet-transaction-payment", "pallet-transaction-payment-rpc", @@ -4844,6 +4974,7 @@ dependencies = [ "substrate-build-script-utils", "substrate-frame-rpc-system", "substrate-prometheus-endpoint", + "tokio", "try-runtime-cli", "vault-registry-rpc-runtime-api", ] @@ -4852,7 +4983,7 @@ dependencies = [ name = "interbtc-primitives" version = "1.2.0" dependencies = [ - "bitcoin", + "bitcoin 1.2.0", "bstringify", "parity-scale-codec", "primitive-types", @@ -4930,7 +5061,7 @@ name = "interlay-runtime-parachain" version = "1.2.0" dependencies = [ "annuity", - "bitcoin", + "bitcoin 1.2.0", "btc-relay", "btc-relay-rpc-runtime-api", "clients-info", @@ -5072,7 +5203,7 @@ dependencies = [ "socket2 0.5.3", "widestring", "windows-sys 0.48.0", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -5097,7 +5228,7 @@ dependencies = [ name = "issue" version = "1.2.0" dependencies = [ - "bitcoin", + "bitcoin 1.2.0", "btc-relay", "currency", "fee", @@ -5182,6 +5313,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpc" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8128f36b47411cd3f044be8c1f5cc0c9e24d1d1bfdc45f0a57897b32513053f2" +dependencies = [ + "base64 0.13.1", + "serde", + "serde_json", +] + [[package]] name = "jsonrpsee" version = "0.16.2" @@ -5353,7 +5495,7 @@ name = "kintsugi-runtime-parachain" version = "1.2.0" dependencies = [ "annuity", - "bitcoin", + "bitcoin 1.2.0", "btc-relay", "btc-relay-rpc-runtime-api", "clients-info", @@ -6543,6 +6685,12 @@ dependencies = [ "thrift", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -6803,8 +6951,8 @@ dependencies = [ "approx", "matrixmultiply", "nalgebra-macros", - "num-complex", - "num-rational", + "num-complex 0.4.3", + "num-rational 0.4.1", "num-traits", "simba", "typenum", @@ -6985,17 +7133,42 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex 0.2.4", + "num-integer", + "num-iter", + "num-rational 0.2.4", + "num-traits", +] + [[package]] name = "num" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ - "num-bigint", - "num-complex", + "num-bigint 0.4.3", + "num-complex 0.4.3", "num-integer", "num-iter", - "num-rational", + "num-rational 0.4.1", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg 1.1.0", + "num-integer", "num-traits", ] @@ -7010,6 +7183,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg 1.1.0", + "num-traits", +] + [[package]] name = "num-complex" version = "0.4.3" @@ -7019,6 +7202,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "num-format" version = "0.4.4" @@ -7050,6 +7244,18 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg 1.1.0", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.1" @@ -7057,7 +7263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ "autocfg 1.1.0", - "num-bigint", + "num-bigint 0.4.3", "num-integer", "num-traits", ] @@ -7937,7 +8143,7 @@ version = "2.0.0-dev" source = "git+https://github.com/paritytech/frontier?branch=polkadot-v0.9.42#1a718546085be20ce381b70e1f9e4c8b4d4b1f03" dependencies = [ "fp-evm", - "num", + "num 0.4.1", ] [[package]] @@ -8644,7 +8850,7 @@ name = "parachain-tests" version = "1.2.0" dependencies = [ "annuity", - "bitcoin", + "bitcoin 1.2.0", "btc-relay", "btc-relay-rpc-runtime-api", "clients-info", @@ -10896,7 +11102,7 @@ dependencies = [ name = "redeem" version = "1.2.0" dependencies = [ - "bitcoin", + "bitcoin 1.2.0", "btc-relay", "currency", "fee", @@ -11069,7 +11275,7 @@ dependencies = [ name = "replace" version = "1.2.0" dependencies = [ - "bitcoin", + "bitcoin 1.2.0", "btc-relay", "currency", "fee", @@ -11119,6 +11325,43 @@ dependencies = [ "sp-std", ] +[[package]] +name = "reqwest" +version = "0.11.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +dependencies = [ + "base64 0.21.2", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite 0.2.9", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.10.1", +] + [[package]] name = "resolv-conf" version = "0.7.0" @@ -11888,8 +12131,8 @@ dependencies = [ "fork-tree", "futures", "log", - "num-bigint", - "num-rational", + "num-bigint 0.4.3", + "num-rational 0.4.1", "num-traits", "parity-scale-codec", "parking_lot 0.12.1", @@ -13016,6 +13259,18 @@ dependencies = [ "secp256k1-sys 0.6.1", ] +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "bitcoin_hashes 0.12.0", + "rand 0.8.5", + "secp256k1-sys 0.8.1", + "serde", +] + [[package]] name = "secp256k1-sys" version = "0.4.0" @@ -13033,6 +13288,15 @@ dependencies = [ "cc", ] +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + [[package]] name = "secrecy" version = "0.8.0" @@ -13147,6 +13411,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "sha-1" version = "0.9.8" @@ -13268,7 +13544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" dependencies = [ "approx", - "num-complex", + "num-complex 0.4.3", "num-traits", "paste", "wide", @@ -14852,6 +15128,16 @@ dependencies = [ "syn 2.0.22", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.23.4" @@ -15094,7 +15380,7 @@ dependencies = [ "impl-trait-for-tuples", "interbtc-primitives", "log", - "num-bigint", + "num-bigint 0.4.3", "num-traits", "parity-scale-codec", "scale-info", @@ -15430,7 +15716,7 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" name = "vault-registry" version = "1.2.0" dependencies = [ - "bitcoin", + "bitcoin 1.2.0", "currency", "fee", "fixed-hash 0.7.0", @@ -15762,7 +16048,7 @@ dependencies = [ "downcast-rs", "libm 0.2.7", "memory_units", - "num-rational", + "num-rational 0.4.1", "num-traits", "region", ] @@ -16597,6 +16883,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/crates/bitcoin/src/parser.rs b/crates/bitcoin/src/parser.rs index f57345eda2..44f1ed604f 100644 --- a/crates/bitcoin/src/parser.rs +++ b/crates/bitcoin/src/parser.rs @@ -413,7 +413,7 @@ pub(crate) mod tests { #[test] fn test_parse_block_header() { - let hex_header = sample_block_header(); + let hex_header = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f2002000000"; let parsed_header = BlockHeader::from_hex(&hex_header).unwrap(); assert_eq!(parsed_header.version, 4); assert_eq!(parsed_header.timestamp, 1415239972); diff --git a/crates/btc-relay/src/lib.rs b/crates/btc-relay/src/lib.rs index 9844414331..031ebed1ab 100644 --- a/crates/btc-relay/src/lib.rs +++ b/crates/btc-relay/src/lib.rs @@ -352,7 +352,7 @@ pub mod pallet { /// BTC height when the relay was initialized #[pallet::storage] - pub(super) type StartBlockHeight = StorageValue<_, u32, ValueQuery>; + pub type StartBlockHeight = StorageValue<_, u32, ValueQuery>; /// Increment-only counter used to track new BlockChain entries #[pallet::storage] diff --git a/parachain/Cargo.toml b/parachain/Cargo.toml index 29e46babfc..89e8262d28 100644 --- a/parachain/Cargo.toml +++ b/parachain/Cargo.toml @@ -25,13 +25,15 @@ futures = "0.3.15" jsonrpsee = { version = "0.16.2", features = ["server", "macros"] } serde_json = "1.0.68" regex = "1.5.6" +bitcoin_client = { path = "../../polkabtc-clients/bitcoin/", package = "bitcoin", features=["cli"]} +hex = "0.4.2" # Parachain dependencies interlay-runtime = { package = "interlay-runtime-parachain", path = "./runtime/interlay" } kintsugi-runtime = { package = "kintsugi-runtime-parachain", path = "./runtime/kintsugi" } runtime-common = { package = "runtime-common", path = "./runtime/common" } interbtc-rpc = { path = "../rpc" } -bitcoin = { path = "../crates/bitcoin" } +bitcoin = { path = "../crates/bitcoin", features = ["parser"] } loans = { path = "../crates/loans" } primitives = { package = "interbtc-primitives", path = "../primitives" } @@ -124,6 +126,9 @@ fp-evm = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0 fp-rpc = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42" } pallet-evm = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v0.9.42" } +tokio = "1.22.0" +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } + [features] default = [] diff --git a/parachain/runtime/kintsugi/src/lib.rs b/parachain/runtime/kintsugi/src/lib.rs index e283de4d0c..1abf192a88 100644 --- a/parachain/runtime/kintsugi/src/lib.rs +++ b/parachain/runtime/kintsugi/src/lib.rs @@ -75,7 +75,7 @@ pub use sp_runtime::BuildStorage; pub use sp_runtime::{FixedU128, Perbill, Permill}; // interBTC exports -pub use btc_relay::{bitcoin, Call as BtcRelayCall, TARGET_SPACING}; +pub use btc_relay::{self, bitcoin, Call as BtcRelayCall, TARGET_SPACING}; pub use constants::{currency::*, time::*}; pub use oracle_rpc_runtime_api::BalanceWrapper; pub use orml_asset_registry::AssetMetadata; diff --git a/parachain/src/cli.rs b/parachain/src/cli.rs index f6aaad6011..ce9fdb7c8f 100644 --- a/parachain/src/cli.rs +++ b/parachain/src/cli.rs @@ -90,6 +90,10 @@ pub struct Cli { #[clap(flatten)] pub eth: EthConfiguration, + /// Connection settings for Bitcoin Core for relay purposes. + #[clap(flatten)] + pub bitcoin: bitcoin_client::cli::BitcoinOpts, + /// Relaychain arguments #[clap(raw = true)] pub relaychain_args: Vec, diff --git a/parachain/src/command.rs b/parachain/src/command.rs index e3aa51ec4e..9006e66084 100644 --- a/parachain/src/command.rs +++ b/parachain/src/command.rs @@ -470,6 +470,10 @@ pub fn run() -> Result<()> { runner .run_node_until_exit(|config| async move { + log::info!("Im here"); + // let bitcoin_rpc = cli.bitcoin.new_client(None).await.unwrap(); + // plan: use pool. + // bitcoin_rpc. if cli.instant_seal { start_instant(cli, config).await } else { @@ -484,6 +488,7 @@ pub fn run() -> Result<()> { async fn start_instant(cli: Cli, config: Configuration) -> sc_service::error::Result { with_runtime_or_err!(config.chain_spec, { { + log::info!("starting instant.."); crate::service::start_instant::(config, cli.eth) .await .map(|r| r.0) diff --git a/parachain/src/service.rs b/parachain/src/service.rs index 1b02e504f9..f5d0051f70 100644 --- a/parachain/src/service.rs +++ b/parachain/src/service.rs @@ -1,3 +1,5 @@ +use async_trait::async_trait; +use bitcoin_client::relay::{Error as RelayError, Issuing}; use cumulus_client_cli::CollatorOptions; use cumulus_client_consensus_aura::{AuraConsensus, BuildAuraConsensusParams, SlotProportion}; use cumulus_client_consensus_common::{ParachainBlockImport as TParachainBlockImport, ParachainConsensus}; @@ -11,7 +13,8 @@ use cumulus_relay_chain_inprocess_interface::build_inprocess_relay_chain; use cumulus_relay_chain_interface::{RelayChainInterface, RelayChainResult}; use cumulus_relay_chain_minimal_node::build_minimal_relay_chain_node; use futures::StreamExt; -use polkadot_service::CollatorPair; +use polkadot_primitives::BlockId; +use polkadot_service::{Client, CollatorPair}; use primitives::*; use sc_client_api::{HeaderBackend, StateBackendFor}; use sc_consensus::{ImportQueue, LongestChain}; @@ -20,16 +23,85 @@ use sc_network::NetworkBlock; use sc_network_sync::SyncingService; use sc_service::{Configuration, PartialComponents, RpcHandlers, TFullBackend, TFullClient, TaskManager}; use sc_telemetry::{Telemetry, TelemetryHandle, TelemetryWorker, TelemetryWorkerHandle}; -use sp_api::ConstructRuntimeApi; +use sc_transaction_pool::{ChainApi, Pool}; +use sp_api::{ConstructRuntimeApi, Encode, StateBackend}; use sp_consensus_aura::{ sr25519::{AuthorityId as AuraId, AuthorityPair as AuraPair}, SlotDuration, }; -use sp_core::H256; +use sp_core::{Pair, H256}; use sp_keystore::KeystorePtr; -use sp_runtime::traits::{BlakeTwo256, Block as BlockT}; +use sp_runtime::{ + traits::{BlakeTwo256, Block as BlockT}, + OpaqueExtrinsic, +}; use std::{sync::Arc, time::Duration}; use substrate_prometheus_endpoint::Registry; +use tokio::sync::Mutex; + +fn create_extrinsic( + client: Arc>>, + nonce: u32, + call: kintsugi_runtime::RuntimeCall, +) -> OpaqueExtrinsic +where + Executor: sc_executor::NativeExecutionDispatch + 'static, +{ + use sc_client_api::BlockBackend; + use sp_keyring::Sr25519Keyring; + use sp_runtime::SaturatedConversion; + + let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"); + let best_hash = client.chain_info().best_hash; + let best_block = client.chain_info().best_number; + + let period = kintsugi_runtime::BlockHashCount::get() + .checked_next_power_of_two() + .map(|c| c / 2) + .unwrap_or(2) as u64; + + let extra: kintsugi_runtime::SignedExtra = ( + frame_system::CheckSpecVersion::::new(), + frame_system::CheckTxVersion::::new(), + frame_system::CheckGenesis::::new(), + frame_system::CheckEra::::from(sp_runtime::generic::Era::mortal( + period, + best_block.saturated_into(), + )), + frame_system::CheckNonce::::from(nonce), + frame_system::CheckWeight::::new(), + // frame_system::CheckNonZeroSender::::new(), + pallet_transaction_payment::ChargeTransactionPayment::::from(0), + ); + + /// The payload being signed + type SignedPayload = + sp_runtime::generic::SignedPayload; + + let raw_payload = SignedPayload::from_raw( + call.clone(), + extra.clone(), + ( + kintsugi_runtime::VERSION.spec_version, + kintsugi_runtime::VERSION.transaction_version, + genesis_hash, + best_hash, + (), + (), + (), + ), + ); + let sender = Sr25519Keyring::Alice.pair(); + let signature = raw_payload.using_encoded(|e| sender.sign(e)); + + kintsugi_runtime::UncheckedExtrinsic::new_signed( + call.clone(), + sp_runtime::AccountId32::from(sender.public()).into(), + kintsugi_runtime::Signature::Sr25519(signature.clone()), + extra.clone(), + ) + .into() +} // Frontier imports use crate::eth::{ @@ -686,6 +758,188 @@ where .await } +struct DirectIssuer +where + PoolApi: ChainApi + 'static, + Executor: sc_executor::NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection>, + RuntimeApi::RuntimeApi: sp_consensus_aura::AuraApi, +{ + pool: Arc>, + client: Arc>, + nonce: Arc>, + // pool: Arc< + // Pool< + // FullChainApi< + // Client< + // Backend, OpaqueExtrinsic>>, + // LocalCallExecutor< + // Block, OpaqueExtrinsic>, + // Backend, OpaqueExtrinsic>>, + // NativeElseWasmExecutor, + // >, + // Block, OpaqueExtrinsic>, + // RuntimeApi, + // >, + // Block, OpaqueExtrinsic>, + // >, + // >, + // >, +} + +impl DirectIssuer +where + PoolApi: ChainApi + 'static, + Executor: sc_executor::NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection>, + RuntimeApi::RuntimeApi: sp_consensus_aura::AuraApi, +{ + async fn new(pool: Arc>, client: Arc>) -> Self { + // system.account(alice) + let address = hex::decode("26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d").unwrap(); + let info = client.chain_info(); + + let state = client.state_at(info.best_hash).unwrap().storage(&address).unwrap(); + let nonce = match state { + None => { + log::info!("No nonce set"); + 0 + } + Some(state) => { + let account_info: frame_system::AccountInfo> = + codec::Decode::decode(&mut &state[..]).unwrap(); + log::info!("Nonce: {}", account_info.nonce); + account_info.nonce + } + }; + + Self { + pool, + client, + nonce: Arc::new(Mutex::new(nonce)), + } + } + + async fn get_nonce(&self) -> u32 { + let mut nonce_lock = self.nonce.lock().await; + let ret = *nonce_lock; + *nonce_lock += 1; + ret + } + async fn call(&self, call: kintsugi_runtime::RuntimeCall) { + let info = self.client.chain_info(); + + let nonce = self.get_nonce().await; + + let tx = create_extrinsic(self.client.clone(), nonce, call); + + // todo: wait until inclusion: use submit_and_watch + self.pool + .submit_one( + &BlockId::Hash(info.best_hash), + sp_runtime::transaction_validity::TransactionSource::Local, + tx, + ) + .await + .unwrap(); + } +} + +#[async_trait] +impl Issuing for DirectIssuer +where + PoolApi: ChainApi + 'static, + Executor: sc_executor::NativeExecutionDispatch + 'static, + RuntimeApi: ConstructRuntimeApi> + Send + Sync + 'static, + RuntimeApi::RuntimeApi: RuntimeApiCollection>, + RuntimeApi::RuntimeApi: sp_consensus_aura::AuraApi, +{ + async fn is_initialized(&self) -> Result { + // let tx = create_extrinsic(self.client.clone(), 123); + let info = self.client.chain_info(); + + // kintsugi_runtime::BTCRelay::StartBlockHeight::key(); + // let q = kintsugi_runtime::|metadata(); + + // StartBlockHeight + let address = hex::decode("8df2c0f8b3fb547e6fbe821d8f53ce4234ca9a8dc00a85a82b3efc9543f686f4").unwrap(); + let state = self.client.state_at(info.best_hash).unwrap().storage(&address).unwrap(); + match state { + None => { + log::info!("Reading returned None - assuming uninitialized even though we exepected a 0 value"); + Ok(false) + } + Some(state) => { + println!("Startblockheight: 0x{}", hex::encode(&state)); + Ok(true) + } + } + } + + async fn initialize(&self, header: Vec, height: u32) -> Result<(), RelayError> { + let block_header = bitcoin::parser::parse_block_header(&header).unwrap(); + + let call = kintsugi_runtime::RuntimeCall::BTCRelay(kintsugi_runtime::btc_relay::Call::initialize { + block_header, + block_height: height, + }); + + self.call(call).await; + + Ok(()) + } + + async fn submit_block_header(&self, header: Vec) -> Result<(), RelayError> { + let block_header = bitcoin::parser::parse_block_header(&header).unwrap(); + + let call = kintsugi_runtime::RuntimeCall::BTCRelay(kintsugi_runtime::btc_relay::Call::store_block_header { + block_header, + fork_bound: 10, + }); + + self.call(call).await; + + Ok(()) + } + + async fn submit_block_header_batch(&self, headers: Vec>) -> Result<(), RelayError> { + for header in headers { + self.submit_block_header(header).await.unwrap(); + } + Ok(()) + } + + async fn get_best_height(&self) -> Result { + // let tx = create_extrinsic(self.client.clone(), 123); + let info = self.client.chain_info(); + + // bestBlockHeight + let address = hex::decode("8df2c0f8b3fb547e6fbe821d8f53ce427e6a2038e919bb8eb04f4f120aa0b65b").unwrap(); + let state = self.client.state_at(info.best_hash).unwrap().storage(&address).unwrap(); + match state { + None => { + log::info!("bestBlockHeight read failure"); + Ok(0) // fixme + } + Some(bytes) => { + let best_height: u32 = codec::Decode::decode(&mut &bytes[..]).unwrap(); + log::info!("get_best_height: {}", best_height); + Ok(best_height) + } + } + } + + async fn get_block_hash(&self, height: u32) -> Result, RelayError> { + todo!() + } + + async fn is_block_stored(&self, hash_le: Vec) -> Result { + todo!() + } +} + pub async fn start_instant( mut config: Configuration, eth_config: EthConfiguration, @@ -697,6 +951,8 @@ where Executor: sc_executor::NativeExecutionDispatch + 'static, CT: fp_rpc::ConvertTransaction<::Extrinsic> + Clone + Default + Send + Sync + 'static, { + log::info!("In instant.."); + let sc_service::PartialComponents { client, backend, @@ -839,6 +1095,67 @@ where } }; + // use substrate:: + // type ExtrinsicFor = <::Block as sp_runtime::traits::Block>::Extrinsic; + // let f = || -> ExtrinsicFor { todo!() }; + + // OpaqueExtrinsic:: + let moved_pool = transaction_pool.clone(); + let moved_client = client.clone(); + // let key = [0u8, 1, 2, 3]; + // // client. + // backend.storage(&key); + // backend. + // client.state_at(todo!()).unwrap(). + // assert_eq!(state.storage(&[1, 3, 5]).unwrap(), Some(vec![2, 4, 6])); + log::info!("starting relay..."); + + task_manager.spawn_handle().spawn("btc-relay", None, async move { + log::info!("In relay, sleeping..."); + tokio::time::sleep(Duration::from_secs(5)).await; + log::info!("Waking up..."); + + + let pool = moved_pool.pool(); + let q = DirectIssuer::new(pool.clone(),moved_client.clone()).await; + + q.is_initialized().await; + + let raw_header = hex::decode("0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f9f233ca7b08179b3345f74e70d48d60e426dea4df41e504a6bef4f502a6cd0354f27de64ffff7f2000000000").unwrap(); + let raw_header_vec = raw_header.to_vec(); + q.initialize(raw_header_vec, 1).await.unwrap(); + + let raw_header = hex::decode("00000020323827761e799d7223cb2ec31806cdafa92d52872110f4ee970769fd41ee4a7f1646edebfb500e7892b716d705f8a389b47559ab6bc89f150812636a237ccae55027de64ffff7f2003000000").unwrap(); + let raw_header_vec = raw_header.to_vec(); + q.submit_block_header(raw_header_vec).await.unwrap(); + q.get_best_height().await; + + let raw_header = hex::decode("00000020900a6894ffe887477e6cc536ac6804a4bf8def4998caa978e32c9f9dd554137252eac09613ddd8133e3a6af07c072802b8bccb572f39e46df99fd2bd9b9e78525027de64ffff7f2000000000").unwrap(); + let raw_header_vec = raw_header.to_vec(); + q.submit_block_header(raw_header_vec).await.unwrap(); + q.get_best_height().await; + + loop { + log::info!("Hello"); + q.get_best_height().await; + + q.is_initialized().await.unwrap(); + + tokio::time::sleep(Duration::from_secs(1)).await; +// let tx = create_extrinsic(moved_client.clone(), 123); +// let info = moved_client.chain_info(); +// +// let state = moved_client.state_at(info.best_hash).unwrap().storage(&[1, 3, 5]); +// +// pool.submit_one( +// &BlockId::Hash(info.best_hash), +// sp_runtime::transaction_validity::TransactionSource::Local, +// tx, +// ) +// .await; + } + }); + let rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { rpc_builder: Box::new(rpc_builder), client: client.clone(),