mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Update to bitcoin 0.30
Also performs a general update with a variety of upgraded Substrate depends.
This commit is contained in:
@@ -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"] }
|
||||
|
||||
@@ -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] {
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user