diff --git a/package-lock.json b/package-lock.json index 78537478..757e3e0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cardano-serialization-lib", - "version": "12.1.0", + "version": "12.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cardano-serialization-lib", - "version": "12.1.0", + "version": "12.1.1", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/package.json b/package.json index d4c541f4..74066223 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-serialization-lib", - "version": "12.1.0", + "version": "12.1.1", "description": "(De)serialization functions for the Cardano blockchain along with related utility functions", "scripts": { "rust:build-nodejs": "(rimraf ./rust/pkg && cd rust; wasm-pack build --target=nodejs; cd ..; npm run js:ts-json-gen; cd rust; wasm-pack pack) && npm run js:flowgen", diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 04327701..7512c48c 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cardano-serialization-lib" -version = "12.1.0" +version = "12.1.1" edition = "2018" authors = ["EMURGO"] license = "MIT" diff --git a/rust/json-gen/Cargo.lock b/rust/json-gen/Cargo.lock index db579263..4f948604 100644 --- a/rust/json-gen/Cargo.lock +++ b/rust/json-gen/Cargo.lock @@ -49,7 +49,7 @@ checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "cardano-serialization-lib" -version = "12.1.0" +version = "12.1.1" dependencies = [ "bech32", "cbor_event", diff --git a/rust/src/builders/fakes.rs b/rust/src/builders/fakes.rs index a35f3ddd..bc4b68ff 100644 --- a/rust/src/builders/fakes.rs +++ b/rust/src/builders/fakes.rs @@ -1,4 +1,4 @@ -use crate::{Bip32PrivateKey, Ed25519Signature, PublicKey}; +use crate::{Bip32PrivateKey, BootstrapWitness, ByronAddress, Ed25519Signature, PublicKey, Vkey}; pub(crate) fn fake_private_key() -> Bip32PrivateKey { Bip32PrivateKey::from_bytes(&[ @@ -10,7 +10,7 @@ pub(crate) fn fake_private_key() -> Bip32PrivateKey { 0xfd, 0xa5, 0x78, 0x60, 0xac, 0x87, 0x6b, 0xc4, 0x89, 0x19, 0x2c, 0x1e, 0xf4, 0xce, 0x25, 0x3c, 0x19, 0x7e, 0xe2, 0x19, 0xa4, ]) - .unwrap() + .unwrap() } pub(crate) fn fake_raw_key_sig() -> Ed25519Signature { @@ -20,18 +20,65 @@ pub(crate) fn fake_raw_key_sig() -> Ed25519Signature { 24, 40, 73, 45, 119, 122, 103, 39, 253, 102, 194, 251, 204, 189, 168, 194, 174, 237, 146, 3, 44, 153, 121, 10, ]) - .unwrap() + .unwrap() } pub(crate) fn fake_raw_key_public(x: u64) -> PublicKey { - let mut bytes = [0u8; 64]; + let mut x_bytes = [0u8; 8]; for i in 0..8 { - bytes[i] = ((x >> (i * 8)) & 0xff) as u8; + x_bytes[i] = ((x >> (i * 8)) & 0xff) as u8; } PublicKey::from_bytes(&[ 207, 118, 57, 154, 33, 13, 232, 114, 14, 159, 168, 148, 228, 94, 65, 226, 154, 181, 37, - 227, 11, 196, 2, 128, bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], - bytes[7] + 227, 11, 196, 2, 128, x_bytes[0], x_bytes[1], x_bytes[2], x_bytes[3], x_bytes[4], + x_bytes[5], x_bytes[6], x_bytes[7], ]) - .unwrap() -} \ No newline at end of file + .unwrap() +} + +pub(crate) fn fake_bootstrap_witness(index: u64, addr: &ByronAddress) -> BootstrapWitness { + let mut bytes = [0u8; 32]; + for i in 0..32 { + bytes[i] = i as u8; + } + let vkey = fake_vkey_numbered(index); + let signature = fake_signature(index); + let chain_code = fake_chain_code(); + BootstrapWitness::new(&vkey, &signature, chain_code, addr.attributes()) +} + +fn fake_vkey_numbered(x: u64) -> Vkey { + let mut bytes = [0u8; 8]; + for i in 0..8 { + bytes[i] = ((x >> (i * 8)) & 0xff) as u8; + } + let bytes = [ + 0x82, 0x2c, 0x1e, 0xf4, 0xce, 0x25, 0x3c, 0x19, 0x7e, 0xe2, 0x19, 0xa4, 0x36, 0xf8, 0x99, + 0xd3, 0x9b, 0x17, 0xfd, 0x5d, 0x66, 0xc1, 0x92, 0xc4, bytes[0], bytes[1], bytes[2], + bytes[3], bytes[4], bytes[5], bytes[6], bytes[7], + ]; + Vkey::new(&PublicKey::from_bytes(&bytes).unwrap()) +} + +fn fake_signature(x: u64) -> Ed25519Signature { + let mut x_bytes = [0u8; 8]; + for i in 0..8 { + x_bytes[i] = ((x >> (i * 8)) & 0xff) as u8; + } + let bytes = [ + 0x24, 0xf8, 0x99, 0xd3, 0x9b, 0x17, 0xfd, 0x5d, 0x66, 0xc1, 0x92, 0xc4, 0xb5, 0x0d, 0x34, + 0x3e, 0x42, 0xf7, 0x23, 0x5b, 0x30, 0x4c, 0x8a, 0xe7, 0x61, 0x9f, 0x93, 0xc8, 0x28, 0xdc, + 0x6d, 0xce, 0x45, 0x68, 0xdd, 0x69, 0x17, 0x7c, 0x55, 0x18, 0x28, 0x49, 0x2d, 0x77, 0x7a, + 0xc2, 0xfb, 0xcc, 0xbd, 0xa8, 0xc2, 0xae, 0xed, 0x92, 0x03, 0x2c, x_bytes[0], x_bytes[1], + x_bytes[2], x_bytes[3], x_bytes[4], x_bytes[5], x_bytes[6], x_bytes[7], + ]; + Ed25519Signature::from_bytes(bytes.to_vec()).unwrap() +} + +fn fake_chain_code() -> Vec { + let mut bytes = Vec::with_capacity(32); + for i in 0..32 { + bytes.push(i as u8); + } + bytes +} diff --git a/rust/src/builders/tx_builder.rs b/rust/src/builders/tx_builder.rs index d89e7384..1c2e53d8 100644 --- a/rust/src/builders/tx_builder.rs +++ b/rust/src/builders/tx_builder.rs @@ -3,7 +3,7 @@ use crate::*; use super::*; -use crate::builders::fakes::{fake_private_key, fake_raw_key_public, fake_raw_key_sig}; +use crate::builders::fakes::{fake_bootstrap_witness, fake_raw_key_public, fake_raw_key_sig}; use crate::fees; use crate::utils; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; @@ -34,7 +34,6 @@ pub(crate) fn fake_full_tx( tx_builder: &TransactionBuilder, body: TransactionBody, ) -> Result { - let fake_key_root = fake_private_key(); let fake_sig = fake_raw_key_sig(); // recall: this includes keys for input, certs and withdrawals @@ -55,13 +54,11 @@ pub(crate) fn fake_full_tx( 0 => None, _x => { let mut result = BootstrapWitnesses::new(); + let mut number = 1; for addr in bootstraps { + number += 1; // picking icarus over daedalus for fake witness generation shouldn't matter - result.add(&make_icarus_bootstrap_witness( - &TransactionHash::from([0u8; TransactionHash::BYTE_COUNT]), - &ByronAddress::from_bytes(addr.clone()).unwrap(), - &fake_key_root, - )); + result.add(&fake_bootstrap_witness(number, &ByronAddress::from_bytes(addr)?)); } Some(result) } diff --git a/rust/src/tests/builders/tx_builder.rs b/rust/src/tests/builders/tx_builder.rs index 22c2b8f4..b713f700 100644 --- a/rust/src/tests/builders/tx_builder.rs +++ b/rust/src/tests/builders/tx_builder.rs @@ -1,5 +1,5 @@ use crate::tests::helpers::harden; -use crate::tests::fakes::{fake_byron_address, fake_anchor, fake_change_address, fake_default_tx_builder, fake_linear_fee, fake_reallistic_tx_builder, fake_redeemer, fake_redeemer_zero_cost, fake_rich_tx_builder, fake_tx_builder, fake_tx_builder_with_amount, fake_tx_builder_with_fee, fake_tx_builder_with_fee_and_pure_change, fake_tx_builder_with_fee_and_val_size, fake_tx_builder_with_key_deposit, fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_plutus_script_and_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness, fake_root_key_15, fake_base_address_with_payment_cred}; +use crate::tests::fakes::{fake_byron_address, fake_anchor, fake_change_address, fake_default_tx_builder, fake_linear_fee, fake_reallistic_tx_builder, fake_redeemer, fake_redeemer_zero_cost, fake_rich_tx_builder, fake_tx_builder, fake_tx_builder_with_amount, fake_tx_builder_with_fee, fake_tx_builder_with_fee_and_pure_change, fake_tx_builder_with_fee_and_val_size, fake_tx_builder_with_key_deposit, fake_base_address, fake_bytes_32, fake_data_hash, fake_key_hash, fake_plutus_script_and_hash, fake_policy_id, fake_script_hash, fake_tx_hash, fake_tx_input, fake_tx_input2, fake_value, fake_value2, fake_vkey_witness, fake_root_key_15, fake_base_address_with_payment_cred, fake_bootsrap_witness, fake_bootsrap_witness_with_attrs}; use crate::*; use crate::builders::fakes::fake_private_key; @@ -6435,4 +6435,57 @@ fn ref_inputs_and_reg_inputs_no_intersection_error() { let ref_inputs = tx.body().reference_inputs().unwrap(); assert!(ref_inputs.contains(&tx_in_3)); assert_eq!(ref_inputs.len(), 1); +} + +#[test] +fn multiple_boostrap_witnesses() { + let mut tx_builder = fake_reallistic_tx_builder(); + let change_address = fake_base_address(1); + let input_1 = fake_tx_input(1); + let input_2 = fake_tx_input(2); + let input_3 = fake_tx_input(3); + let input_4 = fake_tx_input(4); + let input_5 = fake_tx_input(5); + + let addr_1 = ByronAddress::from_base58("Ae2tdPwUPEZBF8HDUYPkACXQrnZtmbKrdJfpBdx3NwcVs6TkvHsgTCi8DKJ").unwrap().to_address(); + let addr_2 = ByronAddress::from_base58("Ae2tdPwUPEZAmhukfkcunjRRHJyuYEgM8YiKxMxUtaGvmEEy3fpcCdf8urC").unwrap().to_address(); + let addr_3 = ByronAddress::from_base58("Ae2tdPwUPEZ2rukBdtHHiNpdXJ2BU6PbQUFZP6FsJ4ZdbRDCwdKpCEYPGWS").unwrap().to_address(); + let addr_4 = ByronAddress::from_base58("Ae2tdPwUPEZ6EbrKDUyyv3tNr7tyC3SFumXvuLEZc8UUz9m65Sx8BFnkAm5").unwrap().to_address(); + let addr_5 = ByronAddress::from_base58("Ae2tdPwUPEZ5N7ubvrUXM4YJPLsyeuc6A3bN2kAuFTEK9iYiumrn7REkb9V").unwrap().to_address(); + + let value_1 = Value::new(&Coin::from(4000000u64)); + let value_2 = Value::new(&Coin::from(5000000u64)); + let value_3 = Value::new(&Coin::from(2000000u64)); + let value_4 = Value::new(&Coin::from(1000000u64)); + let value_5 = Value::new(&Coin::from(3000000u64)); + + tx_builder.add_regular_input(&addr_1, &input_1, &value_1).unwrap(); + tx_builder.add_regular_input(&addr_2, &input_2, &value_2).unwrap(); + tx_builder.add_regular_input(&addr_3, &input_3, &value_3).unwrap(); + tx_builder.add_regular_input(&addr_4, &input_4, &value_4).unwrap(); + tx_builder.add_regular_input(&addr_5, &input_5, &value_5).unwrap(); + + tx_builder.add_change_if_needed(&change_address).unwrap(); + + let res = tx_builder.build_tx(); + assert!(res.is_ok()); + + let attributes = vec![127u8]; + let mut bootstrap_witnesses = BootstrapWitnesses::new(); + bootstrap_witnesses.add(&fake_bootsrap_witness_with_attrs(1, attributes.clone())); + bootstrap_witnesses.add(&fake_bootsrap_witness_with_attrs(2, attributes.clone())); + bootstrap_witnesses.add(&fake_bootsrap_witness_with_attrs(3, attributes.clone())); + bootstrap_witnesses.add(&fake_bootsrap_witness_with_attrs(4, attributes.clone())); + bootstrap_witnesses.add(&fake_bootsrap_witness_with_attrs(5, attributes.clone())); + + let mut tx = res.unwrap(); + let mut wit_set = tx.witness_set(); + wit_set.set_bootstraps(&bootstrap_witnesses); + tx = Transaction::new(&tx.body(), &wit_set, tx.auxiliary_data()); + let tx_len = tx.to_bytes().len(); + + let total_tx_fee = tx.body().fee(); + let min_fee = min_fee_for_size(tx_len, &fake_linear_fee(44, 155381)).unwrap(); + + assert!(total_tx_fee >= min_fee); } \ No newline at end of file diff --git a/rust/src/tests/fakes.rs b/rust/src/tests/fakes.rs index ee4f132a..d86c8f44 100644 --- a/rust/src/tests/fakes.rs +++ b/rust/src/tests/fakes.rs @@ -616,7 +616,7 @@ pub(crate) fn fake_vkey_witness(x: u8) -> Vkeywitness { Vkeywitness::new(&fake_vkey_numbered(x), &fake_signature(x)) } -pub(crate) fn fake_boostrap_witness(x: u8) -> BootstrapWitness { +pub(crate) fn fake_bootsrap_witness(x: u8) -> BootstrapWitness { BootstrapWitness::new( &fake_vkey_numbered(x), &fake_signature(x), @@ -625,6 +625,15 @@ pub(crate) fn fake_boostrap_witness(x: u8) -> BootstrapWitness { ) } +pub(crate) fn fake_bootsrap_witness_with_attrs(x: u8, attributes: Vec) -> BootstrapWitness { + BootstrapWitness::new( + &fake_vkey_numbered(x), + &fake_signature(x), + vec![x; 32], + attributes, + ) +} + pub(crate) fn fake_plutus_script_and_hash(x: u8) -> (PlutusScript, ScriptHash) { let s = PlutusScript::new(fake_bytes_32(x)); (s.clone(), s.hash()) diff --git a/rust/src/tests/general.rs b/rust/src/tests/general.rs index 29eb5a11..781a9661 100644 --- a/rust/src/tests/general.rs +++ b/rust/src/tests/general.rs @@ -1,6 +1,6 @@ use crate::*; use crate::tests::helpers::harden; -use crate::tests::fakes::{fake_plutus_script, fake_boostrap_witness, fake_tx_input, fake_vkey_witness}; +use crate::tests::fakes::{fake_plutus_script, fake_bootsrap_witness, fake_tx_input, fake_vkey_witness}; #[test] fn native_script_hash() { @@ -462,8 +462,8 @@ fn ed25519_key_hashes_dedup() { #[test] fn bootstrap_witnesses_dedup() { let mut bootstrap_witnesses = BootstrapWitnesses::new(); - let bootstrap_witness1 = fake_boostrap_witness(1); - let bootstrap_witness2 = fake_boostrap_witness(2); + let bootstrap_witness1 = fake_bootsrap_witness(1); + let bootstrap_witness2 = fake_bootsrap_witness(2); assert!(bootstrap_witnesses.add(&bootstrap_witness1)); assert!(bootstrap_witnesses.add(&bootstrap_witness2)); diff --git a/rust/src/tests/serialization/general.rs b/rust/src/tests/serialization/general.rs index eeb067bd..fad31dae 100644 --- a/rust/src/tests/serialization/general.rs +++ b/rust/src/tests/serialization/general.rs @@ -1,7 +1,7 @@ use crate::{Address, BigInt, BigNum, Block, BlockHash, CborContainerType, Coin, Credential, DataHash, ExUnits, HeaderBody, HeaderLeaderCertEnum, Int, KESVKey, MIRPot, MIRToStakeCredentials, MoveInstantaneousReward, NativeScript, OperationalCert, PlutusData, PlutusList, PlutusScript, PlutusScripts, ProtocolVersion, Redeemer, RedeemerTag, Redeemers, ScriptHash, ScriptRef, TimelockStart, TransactionBody, TransactionInputs, TransactionOutput, TransactionOutputs, TransactionWitnessSet, VRFCert, VRFVKey, Value, Vkeywitness, Vkeywitnesses, VersionedBlock, BlockEra, to_bytes, BootstrapWitnesses, Credentials, Ed25519KeyHashes}; use crate::protocol_types::ScriptRefEnum; -use crate::tests::fakes::{fake_base_address, fake_boostrap_witness, fake_bytes_32, fake_data_hash, fake_key_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, fake_vkey_witness}; +use crate::tests::fakes::{fake_base_address, fake_bootsrap_witness, fake_bytes_32, fake_data_hash, fake_key_hash, fake_signature, fake_tx_input, fake_tx_output, fake_value, fake_value2, fake_vkey, fake_vkey_witness}; #[test] fn tx_output_deser_lagacy() { @@ -798,9 +798,9 @@ fn ref_script_serialization() { #[test] fn boostrap_witnesses_round_trip() { let mut witnesses = BootstrapWitnesses::new(); - let bootstrap_witness_1 = fake_boostrap_witness(1); - let bootstrap_witness_2 = fake_boostrap_witness(2); - let bootstrap_witness_3 = fake_boostrap_witness(3); + let bootstrap_witness_1 = fake_bootsrap_witness(1); + let bootstrap_witness_2 = fake_bootsrap_witness(2); + let bootstrap_witness_3 = fake_bootsrap_witness(3); witnesses.add(&bootstrap_witness_1); witnesses.add(&bootstrap_witness_2);