diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 3736e0bc..f8c56286 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -22,7 +22,7 @@ jobs: - rust: nightly env: DUMMY: true - - rust: 1.36.0 + - rust: 1.41.1 env: PIN_VERSIONS: true steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index 12fd0f8b..1c585c6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +# unreleased + +- the feature "serde-feature" is now renamed to just "serde" +- update MSRV to 1.41.1 +- breaking change in serde in how the Nonce is serialized +- `Block`, `BlockHeader`, `PeginData`, `PegoutData` loose the Default impl +- update rust-bitcoin to 0.29.1 +- update secp256k1-zkp to 0.7.0 +- update bitcoin_hases to 0.11.0 # 0.19.2 - 2022-06-16 diff --git a/Cargo.toml b/Cargo.toml index 54973e1f..53255065 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,37 +14,37 @@ default = [ "json-contract" ] integration = [ "elementsd" ] json-contract = [ "serde_json" ] -"serde-feature" = [ - "bitcoin/use-serde", +"serde" = [ + "bitcoin/serde", "secp256k1-zkp/use-serde", - "serde" + "actual-serde" ] "fuzztarget" = [] [dependencies] -bitcoin = "0.28.0" -secp256k1-zkp = { version = "0.6.0", features = [ "global-context", "bitcoin_hashes" ] } +bitcoin = "0.29.1" +secp256k1-zkp = { version = "0.7.0", features = [ "global-context", "bitcoin_hashes" ] } slip21 = "0.2.0" # While this dependency is included in bitcoin, we need this to use the macros. # We should probably try keep this one in sync with the bitcoin version, # to avoid requiring two version of bitcoin_hashes. -bitcoin_hashes = "0.10.0" +bitcoin_hashes = "0.11.0" # Used for ContractHash::from_json_contract. serde_json = { version = "1.0", optional = true } -serde = { version = "1.0", features=["derive"], optional = true } +actual-serde = { package="serde", version = "1.0", features=["derive"], optional = true } # This should be an optional dev-dependency (only needed for integration tests), # but dev-dependency cannot be optional, and without optionality older toolchain try to compile it and fails -elementsd = {version = "0.5.0", features=["0_21_0","bitcoind_22_0"], optional = true } +elementsd = {version = "0.6.0", features=["0_21_0","bitcoind_22_0"], optional = true } [dev-dependencies] -rand = "0.6.5" +rand = "0.8" serde_test = "1.0" serde_json = "1.0" -serde_cbor = "0.8" # older than latest version to support 1.36 +serde_cbor = "0.8" # older than latest version to support 1.41.1 ryu = "<1.0.5" bincode = "1.3" base64 = "0.13.0" diff --git a/README.md b/README.md index b28a1879..f53f3538 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ structures and network messages related to Elements ## Minimum Supported Rust Version (MSRV) -This library should always compile with any combination of features on **Rust 1.36**. +This library should always compile with any combination of features on **Rust 1.41.1**. diff --git a/contrib/test.sh b/contrib/test.sh index 1e187873..d13bc25c 100755 --- a/contrib/test.sh +++ b/contrib/test.sh @@ -1,6 +1,6 @@ #!/bin/sh -ex -FEATURES="serde-feature" +FEATURES="serde" # Use toolchain if explicitly specified if [ -n "$TOOLCHAIN" ] diff --git a/examples/pset_blind_coinjoin.rs b/examples/pset_blind_coinjoin.rs index 52b0c94d..947bfc15 100644 --- a/examples/pset_blind_coinjoin.rs +++ b/examples/pset_blind_coinjoin.rs @@ -72,7 +72,7 @@ fn parse_txout(txout_info: &str) -> (TxOut, Secrets, pset::Input) { bitcoin::Denomination::Bitcoin, ) .unwrap() - .as_sat(), + .to_sat(), asset: AssetId::from_hex(&v["asset"].as_str().unwrap()).unwrap(), }, }; @@ -324,4 +324,4 @@ impl rand::RngCore for CrappyRng { } } -impl rand::CryptoRng for CrappyRng {} \ No newline at end of file +impl rand::CryptoRng for CrappyRng {} diff --git a/examples/raw_blind.rs b/examples/raw_blind.rs index ca758a06..2ed66c51 100644 --- a/examples/raw_blind.rs +++ b/examples/raw_blind.rs @@ -68,7 +68,7 @@ fn parse_txout(txout_info: &str) -> (TxOut, Secrets, pset::Input) { bitcoin::Denomination::Bitcoin, ) .unwrap() - .as_sat(), + .to_sat(), asset: AssetId::from_hex(&v["asset"].as_str().unwrap()).unwrap(), }, }; diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index e3b93f11..028baa32 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -15,7 +15,7 @@ honggfuzz_fuzz = ["honggfuzz"] [dependencies] honggfuzz = { version = "0.5", optional = true, default-features = false } afl = { version = "0.11", optional = true } -elements = { path = "..", features = ["fuzztarget", "serde-feature"] } +elements = { path = "..", features = ["fuzztarget", "serde"] } # Prevent this from interfering with workspaces [workspace] diff --git a/src/blind.rs b/src/blind.rs index 4d20cf15..cff07475 100644 --- a/src/blind.rs +++ b/src/blind.rs @@ -210,7 +210,7 @@ impl RangeProofMessage { } /// Information about Transaction Input Asset -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "actual_serde"))] #[derive(Debug, PartialEq, Eq, Clone, Hash)] pub struct TxOutSecrets { /// Asset @@ -1008,7 +1008,7 @@ mod tests { let spent_utxo_secrets = TxOutSecrets { asset: AssetId::from_hex("b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23").unwrap(), asset_bf: AssetBlindingFactor::from_hex("a5b3d111cdaa5fc111e2723df4caf315864f25fb4610cc737f10d5a55cd4096f").unwrap(), - value: bitcoin::Amount::from_str_in("20999997.97999114", bitcoin::Denomination::Bitcoin).unwrap().as_sat(), + value: bitcoin::Amount::from_str_in("20999997.97999114", bitcoin::Denomination::Bitcoin).unwrap().to_sat(), value_bf: ValueBlindingFactor::from_hex("e36a4de359469f547571d117bc5509fb74fba73c84b0cdd6f4edfa7ff7fa457d").unwrap(), }; diff --git a/src/block.rs b/src/block.rs index d9d5e89c..cdf2efe2 100644 --- a/src/block.rs +++ b/src/block.rs @@ -202,7 +202,7 @@ impl Default for ExtData { } /// Elements block header -#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct BlockHeader { /// Version - should be 0x20000000 except when versionbits signalling pub version: u32, @@ -355,7 +355,7 @@ impl Decodable for BlockHeader { } /// Elements block -#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)] +#[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Block { /// Header of the block pub header: BlockHeader, diff --git a/src/confidential.rs b/src/confidential.rs index e7aff470..13fadd5a 100644 --- a/src/confidential.rs +++ b/src/confidential.rs @@ -957,14 +957,13 @@ impl AddAssign for ValueBlindingFactor { // for scalar arethematic, we need to abuse secret key // operations for this let sk2 = SecretKey::from_slice(self.into_inner().as_ref()).expect("Valid key"); - let mut sk = SecretKey::from_slice(other.into_inner().as_ref()).expect("Valid key"); + let sk = SecretKey::from_slice(other.into_inner().as_ref()).expect("Valid key"); // The only reason that secret key addition can fail // is when the keys add up to zero since we have already checked // keys are in valid secret keys - if sk.add_assign(sk2.as_ref()).is_err() { - *self = Self::zero(); - } else { - *self = ValueBlindingFactor::from_slice(sk.as_ref()).expect("Valid Tweak") + match sk.add_tweak(&sk2.into()) { + Ok(sk_tweaked) => *self = ValueBlindingFactor::from_slice(sk_tweaked.as_ref()).expect("Valid Tweak"), + Err(_) => *self = Self::zero(), } } } @@ -977,8 +976,7 @@ impl Neg for ValueBlindingFactor { if self.0.as_ref() == &[0u8; 32] { self } else { - let mut sk = SecretKey::from_slice(self.into_inner().as_ref()).expect("Valid key"); - sk.negate_assign(); + let sk = SecretKey::from_slice(self.into_inner().as_ref()).expect("Valid key").negate(); ValueBlindingFactor::from_slice(sk.as_ref()).expect("Valid Tweak") } } @@ -1374,13 +1372,17 @@ mod tests { &[ Token::Seq { len: Some(2) }, Token::U8(2), - Token::Bytes( - &[ - 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 - ] - ), + Token::Tuple { len: 33 }, + Token::U8(2), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), + Token::U8(1), + Token::TupleEnd, Token::SeqEnd ] ); diff --git a/src/dynafed.rs b/src/dynafed.rs index 0c8b2fc2..66d666b9 100644 --- a/src/dynafed.rs +++ b/src/dynafed.rs @@ -590,6 +590,8 @@ mod tests { use bitcoin::hashes::hex::ToHex; use bitcoin::hashes::sha256; + use crate::{BlockHash, TxMerkleNode}; + use super::*; #[test] @@ -655,7 +657,11 @@ mod tests { proposed: full_entry, signblock_witness: vec![], }, - ..Default::default() + version: Default::default(), + prev_blockhash: BlockHash::all_zeros(), + merkle_root: TxMerkleNode::all_zeros(), + time: Default::default(), + height: Default::default(), }; assert_eq!( header.calculate_dynafed_params_root().unwrap().to_hex(), diff --git a/src/lib.rs b/src/lib.rs index 876fd9f9..9ccbff53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,7 @@ pub extern crate bitcoin; extern crate bitcoin_hashes as just_imported_for_the_macros; extern crate slip21; pub extern crate secp256k1_zkp; -#[cfg(feature = "serde")] #[macro_use] extern crate serde; +#[cfg(feature = "serde")] #[macro_use] extern crate actual_serde as serde; #[cfg(all(test, feature = "serde"))] extern crate serde_test; #[cfg(test)] extern crate rand; diff --git a/src/pset/map/global.rs b/src/pset/map/global.rs index 17bb5c7d..76d06a44 100644 --- a/src/pset/map/global.rs +++ b/src/pset/map/global.rs @@ -56,7 +56,7 @@ const PSBT_ELEMENTS_GLOBAL_TX_MODIFIABLE: u8 = 0x01; /// Global transaction data #[derive(Debug, Clone, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "actual_serde"))] pub struct TxData { /// Transaction version. Must be 2. pub version: u32, @@ -91,7 +91,7 @@ impl Default for TxData{ /// A key-value map for global data. #[derive(Clone, Debug, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "actual_serde"))] pub struct Global { /// Global transaction data #[cfg_attr(feature = "serde", serde(flatten))] diff --git a/src/pset/map/input.rs b/src/pset/map/input.rs index 84593421..c7801ff0 100644 --- a/src/pset/map/input.rs +++ b/src/pset/map/input.rs @@ -24,6 +24,7 @@ use crate::encode::{self, Decodable}; use crate::confidential; use bitcoin::util::bip32::KeySource; use bitcoin::{self, PublicKey}; +use hashes::Hash; use crate::hashes::{self, hash160, ripemd160, sha256, sha256d}; use crate::pset::map::Map; use crate::pset::raw; @@ -146,8 +147,8 @@ const PSBT_ELEMENTS_IN_ISSUANCE_BLIND_VALUE_PROOF: u8 = 0x0f; const PSBT_ELEMENTS_IN_ISSUANCE_BLIND_INFLATION_KEYS_PROOF: u8 = 0x10; /// A key-value map for an input of the corresponding index in the unsigned /// transaction. -#[derive(Clone, Default, Debug, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[derive(Clone, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "actual_serde"))] pub struct Input { /// The non-witness transaction this input spends from. Should only be /// [std::option::Option::Some] for inputs which spend non-segwit outputs or @@ -260,6 +261,12 @@ pub struct Input { pub unknown: BTreeMap>, } +impl Default for Input { + fn default() -> Self { + Self { non_witness_utxo: Default::default(), witness_utxo: Default::default(), partial_sigs: Default::default(), sighash_type: Default::default(), redeem_script: Default::default(), witness_script: Default::default(), bip32_derivation: Default::default(), final_script_sig: Default::default(), final_script_witness: Default::default(), ripemd160_preimages: Default::default(), sha256_preimages: Default::default(), hash160_preimages: Default::default(), hash256_preimages: Default::default(), previous_txid: Txid::all_zeros(), previous_output_index: Default::default(), sequence: Default::default(), required_time_locktime: Default::default(), required_height_locktime: Default::default(), tap_key_sig: Default::default(), tap_script_sigs: Default::default(), tap_scripts: Default::default(), tap_key_origins: Default::default(), tap_internal_key: Default::default(), tap_merkle_root: Default::default(), issuance_value_amount: Default::default(), issuance_value_comm: Default::default(), issuance_value_rangeproof: Default::default(), issuance_keys_rangeproof: Default::default(), pegin_tx: Default::default(), pegin_txout_proof: Default::default(), pegin_genesis_hash: Default::default(), pegin_claim_script: Default::default(), pegin_value: Default::default(), pegin_witness: Default::default(), issuance_inflation_keys: Default::default(), issuance_inflation_keys_comm: Default::default(), issuance_blinding_nonce: Default::default(), issuance_asset_entropy: Default::default(), in_utxo_rangeproof: Default::default(), in_issuance_blind_value_proof: Default::default(), in_issuance_blind_inflation_keys_proof: Default::default(), proprietary: Default::default(), unknown: Default::default() } + } +} + /// A Signature hash type for the corresponding input. As of taproot upgrade, the signature hash /// type can be either [`SigHashType`] or [`SchnorrSigHashType`] but it is not possible to know /// directly which signature hash type the user is dealing with. Therefore, the user is responsible diff --git a/src/pset/map/output.rs b/src/pset/map/output.rs index 485b7d75..a243734c 100644 --- a/src/pset/map/output.rs +++ b/src/pset/map/output.rs @@ -87,7 +87,7 @@ const PSBT_ELEMENTS_OUT_BLIND_ASSET_PROOF: u8 = 0x10; /// A key-value map for an output of the corresponding index in the unsigned /// transaction. #[derive(Clone, Default, Debug, PartialEq)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "actual_serde"))] pub struct Output { /// The redeem script for this output. pub redeem_script: Option