Update to bitcoin 0.30

Also performs a general update with a variety of upgraded Substrate depends.
This commit is contained in:
Luke Parker
2023-04-09 02:31:10 -04:00
parent 96525330c2
commit f6206b60ec
17 changed files with 387 additions and 284 deletions

View File

@@ -16,8 +16,8 @@ rand_core = "0.6"
sha2 = "0.10"
secp256k1 = { version = "0.24", features = ["global-context"] }
bitcoin = { version = "0.29", features = ["serde"] }
secp256k1 = { version = "0.27", features = ["global-context"] }
bitcoin = { version = "0.30", features = ["serde"] }
k256 = { version = "0.13", features = ["arithmetic"] }
transcript = { package = "flexible-transcript", path = "../../crypto/transcript", version = "0.3", features = ["recommended"] }

View File

@@ -23,7 +23,7 @@ use frost::{
algorithm::{Hram as HramTrait, Algorithm, Schnorr as FrostSchnorr},
};
use bitcoin::XOnlyPublicKey;
use bitcoin::key::XOnlyPublicKey;
/// Get the x coordinate of a non-infinity, even point. Panics on invalid input.
pub fn x(key: &ProjectivePoint) -> [u8; 32] {

View File

@@ -6,10 +6,7 @@ use serde::{Deserialize, de::DeserializeOwned};
use serde_json::json;
use bitcoin::{
hashes::{
Hash,
hex::{FromHex, ToHex},
},
hashes::{Hash, hex::FromHex},
consensus::encode,
Txid, Transaction, BlockHash, Block,
};
@@ -88,8 +85,11 @@ impl Rpc {
/// Get the hash of a block by the block's number.
pub async fn get_block_hash(&self, number: usize) -> Result<[u8; 32], RpcError> {
let mut hash =
self.rpc_call::<BlockHash>("getblockhash", json!([number])).await?.as_hash().into_inner();
let mut hash = *self
.rpc_call::<BlockHash>("getblockhash", json!([number]))
.await?
.as_raw_hash()
.as_byte_array();
// bitcoin stores the inner bytes in reverse order.
hash.reverse();
Ok(hash)
@@ -101,16 +101,16 @@ impl Rpc {
struct Number {
height: usize,
}
Ok(self.rpc_call::<Number>("getblockheader", json!([hash.to_hex()])).await?.height)
Ok(self.rpc_call::<Number>("getblockheader", json!([hex::encode(hash)])).await?.height)
}
/// Get a block by its hash.
pub async fn get_block(&self, hash: &[u8; 32]) -> Result<Block, RpcError> {
let hex = self.rpc_call::<String>("getblock", json!([hash.to_hex(), 0])).await?;
let hex = self.rpc_call::<String>("getblock", json!([hex::encode(hash), 0])).await?;
let bytes: Vec<u8> = FromHex::from_hex(&hex).map_err(|_| RpcError::InvalidResponse)?;
let block: Block = encode::deserialize(&bytes).map_err(|_| RpcError::InvalidResponse)?;
let mut block_hash = block.block_hash().as_hash().into_inner();
let mut block_hash = *block.block_hash().as_raw_hash().as_byte_array();
block_hash.reverse();
if hash != &block_hash {
Err(RpcError::InvalidResponse)?;
@@ -130,11 +130,11 @@ impl Rpc {
/// Get a transaction by its hash.
pub async fn get_transaction(&self, hash: &[u8; 32]) -> Result<Transaction, RpcError> {
let hex = self.rpc_call::<String>("getrawtransaction", json!([hash.to_hex()])).await?;
let hex = self.rpc_call::<String>("getrawtransaction", json!([hex::encode(hash)])).await?;
let bytes: Vec<u8> = FromHex::from_hex(&hex).map_err(|_| RpcError::InvalidResponse)?;
let tx: Transaction = encode::deserialize(&bytes).map_err(|_| RpcError::InvalidResponse)?;
let mut tx_hash = tx.txid().as_hash().into_inner();
let mut tx_hash = *tx.txid().as_raw_hash().as_byte_array();
tx_hash.reverse();
if hash != &tx_hash {
Err(RpcError::InvalidResponse)?;

View File

@@ -14,8 +14,8 @@ use frost::{
use bitcoin::{
consensus::encode::{Decodable, serialize},
schnorr::TweakedPublicKey,
OutPoint, Script, TxOut, Transaction, Block, Network, Address,
key::TweakedPublicKey,
OutPoint, ScriptBuf, TxOut, Transaction, Block, Network, Address,
};
use crate::crypto::{x_only, make_even};
@@ -95,7 +95,7 @@ impl ReceivedOutput {
#[derive(Clone, Debug)]
pub struct Scanner {
key: ProjectivePoint,
scripts: HashMap<Script, Scalar>,
scripts: HashMap<ScriptBuf, Scalar>,
}
impl Scanner {

View File

@@ -13,9 +13,10 @@ use k256::{elliptic_curve::sec1::ToEncodedPoint, Scalar};
use frost::{curve::Secp256k1, Participant, ThresholdKeys, FrostError, sign::*};
use bitcoin::{
hashes::Hash,
util::sighash::{SchnorrSighashType, SighashCache, Prevouts},
OutPoint, Script, Sequence, Witness, TxIn, TxOut, PackedLockTime, Transaction, Network, Address,
sighash::{TapSighashType, SighashCache, Prevouts},
absolute::LockTime,
script::{PushBytesBuf, ScriptBuf},
OutPoint, Sequence, Witness, TxIn, TxOut, Transaction, Network, Address,
};
use crate::{
@@ -61,18 +62,18 @@ impl SignableTransaction {
// Expand this a full transaction in order to use the bitcoin library's weight function
let mut tx = Transaction {
version: 2,
lock_time: PackedLockTime::ZERO,
lock_time: LockTime::ZERO,
input: vec![
TxIn {
// This is a fixed size
// See https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format
previous_output: OutPoint::default(),
// This is empty for a Taproot spend
script_sig: Script::new(),
script_sig: ScriptBuf::new(),
// This is fixed size, yet we do use Sequence::MAX
sequence: Sequence::MAX,
// Our witnesses contains a single 64-byte signature
witness: Witness::from_vec(vec![vec![0; 64]])
witness: Witness::from_slice(&[vec![0; 64]])
};
inputs
],
@@ -137,7 +138,7 @@ impl SignableTransaction {
.iter()
.map(|input| TxIn {
previous_output: input.outpoint,
script_sig: Script::new(),
script_sig: ScriptBuf::new(),
sequence: Sequence::MAX,
witness: Witness::new(),
})
@@ -151,7 +152,13 @@ impl SignableTransaction {
// Add the OP_RETURN output
if let Some(data) = data {
tx_outs.push(TxOut { value: 0, script_pubkey: Script::new_op_return(&data) })
tx_outs.push(TxOut {
value: 0,
script_pubkey: ScriptBuf::new_op_return(
&PushBytesBuf::try_from(data)
.expect("data didn't fit into PushBytes depsite being checked"),
),
})
}
let mut weight = Self::calculate_weight(tx_ins.len(), payments, None);
@@ -182,12 +189,7 @@ impl SignableTransaction {
}
Ok(SignableTransaction {
tx: Transaction {
version: 2,
lock_time: PackedLockTime::ZERO,
input: tx_ins,
output: tx_outs,
},
tx: Transaction { version: 2, lock_time: LockTime::ZERO, input: tx_ins, output: tx_outs },
offsets,
prevouts: inputs.drain(..).map(|input| input.output).collect(),
needed_fee,
@@ -208,7 +210,7 @@ impl SignableTransaction {
// Transcript the inputs and outputs
let tx = &self.tx;
for input in &tx.input {
transcript.append_message(b"input_hash", input.previous_output.txid.as_hash().into_inner());
transcript.append_message(b"input_hash", input.previous_output.txid);
transcript.append_message(b"input_output_index", input.previous_output.vout.to_le_bytes());
}
for payment in &tx.output {
@@ -335,9 +337,10 @@ impl SignMachine<Transaction> for TransactionSignMachine {
.map(|(i, sig)| {
let (sig, share) = sig.sign(
commitments[i].clone(),
&cache
.taproot_key_spend_signature_hash(i, &prevouts, SchnorrSighashType::Default)
.unwrap(),
cache
.taproot_key_spend_signature_hash(i, &prevouts, TapSighashType::Default)
.unwrap()
.as_ref(),
)?;
shares.push(share);
Ok(sig)
@@ -369,7 +372,7 @@ impl SignatureMachine<Transaction> for TransactionSignatureMachine {
shares.iter_mut().map(|(l, shares)| (*l, shares.remove(0))).collect::<HashMap<_, _>>(),
)?;
let mut witness: Witness = Witness::new();
let mut witness = Witness::new();
witness.push(sig.as_ref());
input.witness = witness;
}

View File

@@ -18,7 +18,7 @@ async_sequential! {
// Test get_block by checking the received block's hash matches the request
let block = rpc.get_block(&hash).await.unwrap();
// Hashes are stored in reverse. It's bs from Satoshi
let mut block_hash = block.block_hash().as_hash().into_inner();
let mut block_hash = *block.block_hash().as_raw_hash().as_byte_array();
block_hash.reverse();
assert_eq!(hash, block_hash);
}

View File

@@ -20,11 +20,9 @@ use frost::{
use bitcoin_serai::{
bitcoin::{
hashes::Hash as HashTrait,
blockdata::{
opcodes::all::OP_RETURN,
script::{Instruction, Instructions},
},
OutPoint, Script, TxOut, Transaction, Network, Address,
blockdata::opcodes::all::OP_RETURN,
script::{PushBytesBuf, Instruction, Instructions, Script},
OutPoint, TxOut, Transaction, Network, Address,
},
wallet::{tweak_keys, address, ReceivedOutput, Scanner, TransactionError, SignableTransaction},
rpc::Rpc,
@@ -54,7 +52,7 @@ async fn send_and_get_output(rpc: &Rpc, scanner: &Scanner, key: ProjectivePoint)
rpc
.rpc_call::<Vec<String>>(
"generatetoaddress",
serde_json::json!([100, Address::p2sh(&Script::new(), Network::Regtest).unwrap()]),
serde_json::json!([100, Address::p2sh(Script::empty(), Network::Regtest).unwrap()]),
)
.await
.unwrap();
@@ -306,7 +304,7 @@ async_sequential! {
// This also tests send_raw_transaction and get_transaction, which the RPC test can't
// effectively test
rpc.send_raw_transaction(&tx).await.unwrap();
let mut hash = tx.txid().as_hash().into_inner();
let mut hash = *tx.txid().as_raw_hash().as_byte_array();
hash.reverse();
assert_eq!(tx, rpc.get_transaction(&hash).await.unwrap());
}
@@ -338,7 +336,10 @@ async_sequential! {
assert!(tx.output[0].script_pubkey.is_op_return());
let check = |mut instructions: Instructions| {
assert_eq!(instructions.next().unwrap().unwrap(), Instruction::Op(OP_RETURN));
assert_eq!(instructions.next().unwrap().unwrap(), Instruction::PushBytes(&data));
assert_eq!(
instructions.next().unwrap().unwrap(),
Instruction::PushBytes(&PushBytesBuf::try_from(data.clone()).unwrap()),
);
assert!(instructions.next().is_none());
};
check(tx.output[0].script_pubkey.instructions());