From 73b79127f2ac7bbb52197a616fc464df1999a7d1 Mon Sep 17 00:00:00 2001 From: benthecarman Date: Tue, 1 Nov 2022 12:14:20 -0500 Subject: [PATCH] Add generate block command --- client/src/client.rs | 7 +++++ integration_test/src/main.rs | 51 ++++++++++++++++++++++++++++++++++++ json/src/lib.rs | 7 +++++ 3 files changed, 65 insertions(+) diff --git a/client/src/client.rs b/client/src/client.rs index d12c4f4b..7fac32e1 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -866,6 +866,13 @@ pub trait RpcApi: Sized { self.call("generate", &[block_num.into(), opt_into_json(maxtries)?]) } + /// Mine a set of ordered transactions to a specified address + /// and return the block hash. + fn generate_block(&self, address: &Address, txs: &[R]) -> Result { + let tx_strs: Vec<_> = txs.iter().map(|t| t.to_owned().raw_hex()).collect(); + self.call("generateblock", &[address.to_string().into(), tx_strs.into()]) + } + /// Mark a block as invalid by `block_hash` fn invalidate_block(&self, block_hash: &bitcoin::BlockHash) -> Result<()> { self.call("invalidateblock", &[into_json(block_hash)?]) diff --git a/integration_test/src/main.rs b/integration_test/src/main.rs index c91cc33d..acd65897 100644 --- a/integration_test/src/main.rs +++ b/integration_test/src/main.rs @@ -140,6 +140,7 @@ fn main() { test_generate(&cl); test_get_balance_generate_to_address(&cl); test_get_balances_generate_to_address(&cl); + test_generate_block(&cl); test_get_best_block_hash(&cl); test_get_block_count(&cl); test_get_block_hash(&cl); @@ -277,6 +278,56 @@ fn test_get_balances_generate_to_address(cl: &Client) { } } +fn test_generate_block(cl: &Client) { + let sk = PrivateKey { + network: Network::Regtest, + inner: secp256k1::SecretKey::new(&mut secp256k1::rand::thread_rng()), + compressed: true, + }; + let addr = Address::p2wpkh(&sk.public_key(&SECP), Network::Regtest).unwrap(); + + let options = json::ListUnspentQueryOptions { + minimum_amount: Some(btc(2)), + ..Default::default() + }; + let unspent = cl.list_unspent(Some(6), None, None, None, Some(options)).unwrap(); + let unspent = unspent.into_iter().nth(0).unwrap(); + + let tx = Transaction { + version: 1, + lock_time: PackedLockTime::ZERO, + input: vec![TxIn { + previous_output: OutPoint { + txid: unspent.txid, + vout: unspent.vout, + }, + sequence: Sequence::MAX, + script_sig: Script::new(), + witness: Witness::new(), + }], + output: vec![TxOut { + value: (unspent.amount - *FEE).to_sat(), + script_pubkey: addr.script_pubkey(), + }], + }; + + let input = json::SignRawTransactionInput { + txid: unspent.txid, + vout: unspent.vout, + script_pub_key: unspent.script_pub_key, + redeem_script: None, + amount: Some(unspent.amount), + }; + let res = cl.sign_raw_transaction_with_wallet(&tx, Some(&[input]), None).unwrap(); + assert!(res.complete); + + let block_hash = cl + .generate_block(&cl.get_new_address(None, None).unwrap(), &[&res.transaction().unwrap()]) + .unwrap(); + let tip = cl.get_best_block_hash().unwrap(); + assert_eq!(block_hash, tip); +} + fn test_get_best_block_hash(cl: &Client) { let _ = cl.get_best_block_hash().unwrap(); } diff --git a/json/src/lib.rs b/json/src/lib.rs index 63f27327..80d1fab7 100644 --- a/json/src/lib.rs +++ b/json/src/lib.rs @@ -988,6 +988,13 @@ pub struct GetAddressInfoResult { pub label: Option, } +/// Models the result of "generateblock" +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct GenerateBlockResult { + /// Hash of the block generated + pub hash: bitcoin::BlockHash, +} + /// Models the result of "getblockchaininfo" #[derive(Clone, Debug, Deserialize, Serialize)] pub struct GetBlockchainInfoResult {