diff --git a/packages/cmds/src/main.cairo b/packages/cmds/src/main.cairo index 8b6c95f8..294ce1cc 100644 --- a/packages/cmds/src/main.cairo +++ b/packages/cmds/src/main.cairo @@ -12,14 +12,14 @@ use shinigami_tests::validate; #[derive(Clone, Drop)] struct InputData { ScriptSig: ByteArray, - ScriptPubKey: ByteArray + ScriptPubKey: ByteArray, } #[derive(Clone, Drop)] struct InputDataWithFlags { ScriptSig: ByteArray, ScriptPubKey: ByteArray, - Flags: ByteArray + Flags: ByteArray, } #[derive(Clone, Drop)] @@ -27,7 +27,7 @@ struct InputDataWithWitness { ScriptSig: ByteArray, ScriptPubKey: ByteArray, Flags: ByteArray, - Witness: ByteArray + Witness: ByteArray, } fn run_with_flags(input: InputDataWithFlags) -> Result<(), felt252> { @@ -35,7 +35,7 @@ fn run_with_flags(input: InputDataWithFlags) -> Result<(), felt252> { "Running Bitcoin Script with ScriptSig: '{}', ScriptPubKey: '{}' and Flags: '{}'", input.ScriptSig, input.ScriptPubKey, - input.Flags + input.Flags, ); let mut compiler = CompilerImpl::new(); let script_pubkey = compiler.compile(input.ScriptPubKey)?; @@ -55,7 +55,7 @@ fn run_with_witness(input: InputDataWithWitness) -> Result<(), felt252> { input.ScriptSig, input.ScriptPubKey, input.Flags, - input.Witness + input.Witness, ); let mut compiler = CompilerImpl::new(); let script_pubkey = compiler.compile(input.ScriptPubKey)?; @@ -64,7 +64,7 @@ fn run_with_witness(input: InputDataWithWitness) -> Result<(), felt252> { let witness = witness::parse_witness_input(input.Witness); let value = 1; // TODO let tx = EngineInternalTransactionImpl::new_signed_witness( - script_sig, script_pubkey.clone(), witness, value + script_sig, script_pubkey.clone(), witness, value, ); let flags = flags::parse_flags(input.Flags); let hash_cache = HashCacheImpl::new(@tx); @@ -77,7 +77,7 @@ fn run(input: InputData) -> Result<(), felt252> { println!( "Running Bitcoin Script with ScriptSig: '{}' and ScriptPubKey: '{}'", input.ScriptSig, - input.ScriptPubKey + input.ScriptPubKey, ); let mut compiler = CompilerImpl::new(); let script_pubkey = compiler.compile(input.ScriptPubKey)?; @@ -95,7 +95,7 @@ fn run(input: InputData) -> Result<(), felt252> { Result::Err(e) => { println!("Execution failed: {}", felt252_to_byte_array(e)); Result::Err(e) - } + }, } } @@ -103,7 +103,7 @@ fn run_with_json(input: InputData) -> Result<(), felt252> { println!( "Running Bitcoin Script with ScriptSig: '{}' and ScriptPubKey: '{}'", input.ScriptSig, - input.ScriptPubKey + input.ScriptPubKey, ); let mut compiler = CompilerImpl::new(); let script_pubkey = compiler.compile(input.ScriptPubKey)?; @@ -121,7 +121,7 @@ fn debug(input: InputData) -> Result { println!( "Running Bitcoin Script with ScriptSig: '{}' and ScriptPubKey: '{}'", input.ScriptSig, - input.ScriptPubKey + input.ScriptPubKey, ); let mut compiler = CompilerImpl::new(); let script_pubkey = compiler.compile(input.ScriptPubKey)?; @@ -154,7 +154,7 @@ fn main(input: InputDataWithFlags) -> u8 { Result::Err(e) => { println!("Execution failed: {}", felt252_to_byte_array(e)); 0 - } + }, } } @@ -168,7 +168,7 @@ fn main_with_witness(input: InputDataWithWitness) -> u8 { Result::Err(e) => { println!("Execution failed: {}", felt252_to_byte_array(e)); 0 - } + }, } } @@ -182,7 +182,7 @@ fn backend_run(input: InputData) -> u8 { Result::Err(e) => { println!("Execution failed: {}", felt252_to_byte_array(e)); 0 - } + }, } } @@ -196,7 +196,7 @@ fn backend_debug(input: InputData) -> u8 { Result::Err(e) => { println!("Execution failed: {}", felt252_to_byte_array(e)); 0 - } + }, } } @@ -235,7 +235,7 @@ fn run_raw_transaction(mut input: ValidateRawInput) -> u8 { amount: *hint.amount, pubkey_script: pubkey_script, block_height: *hint.block_height, - } + }, ); }; @@ -248,6 +248,6 @@ fn run_raw_transaction(mut input: ValidateRawInput) -> u8 { Result::Err(e) => { println!("Execution failed: {}", felt252_to_byte_array(e)); 0 - } + }, } } diff --git a/packages/compiler/src/compiler.cairo b/packages/compiler/src/compiler.cairo index c089c320..1158b8bf 100644 --- a/packages/compiler/src/compiler.cairo +++ b/packages/compiler/src/compiler.cairo @@ -9,7 +9,7 @@ use crate::utils::{is_hex, is_number, is_string}; #[derive(Destruct)] pub struct Compiler { // Dict containing opcode names to their bytecode representation - opcodes: Felt252Dict> + opcodes: Felt252Dict>, } pub trait CompilerTrait { diff --git a/packages/engine/src/cond_stack.cairo b/packages/engine/src/cond_stack.cairo index 603a7328..57e52793 100644 --- a/packages/engine/src/cond_stack.cairo +++ b/packages/engine/src/cond_stack.cairo @@ -9,7 +9,7 @@ pub struct ConditionalStack { #[generate_trait()] pub impl ConditionalStackImpl of ConditionalStackTrait { fn new() -> ConditionalStack { - ConditionalStack { stack: Default::default(), len: 0, } + ConditionalStack { stack: Default::default(), len: 0 } } fn push(ref self: ConditionalStack, value: u8) { @@ -43,7 +43,7 @@ pub impl ConditionalStackImpl of ConditionalStackTrait { 0 => self.stack.insert(cond_idx.into(), 1), 1 => self.stack.insert(cond_idx.into(), 0), 2 => self.stack.insert(cond_idx.into(), 2), - _ => panic!("Invalid condition") + _ => panic!("Invalid condition"), } } } diff --git a/packages/engine/src/engine.cairo b/packages/engine/src/engine.cairo index 1c9ac950..5f05577a 100644 --- a/packages/engine/src/engine.cairo +++ b/packages/engine/src/engine.cairo @@ -5,7 +5,7 @@ use crate::opcodes::opcodes::Opcode; use crate::flags::ScriptFlags; use crate::stack::{ScriptStack, ScriptStackImpl}; use crate::transaction::{ - EngineTransactionInputTrait, EngineTransactionOutputTrait, EngineTransactionTrait + EngineTransactionInputTrait, EngineTransactionOutputTrait, EngineTransactionTrait, }; use crate::hash_cache::{HashCache, HashCacheTrait}; use crate::witness; @@ -76,7 +76,7 @@ pub trait EngineTrait< +EngineTransactionInputTrait, +EngineTransactionOutputTrait, +EngineTransactionTrait, - +HashCacheTrait + +HashCacheTrait, > { // Create a new Engine with the given script fn new( @@ -85,7 +85,7 @@ pub trait EngineTrait< tx_idx: u32, flags: u32, amount: i64, - hash_cache: @HashCache + hash_cache: @HashCache, ) -> Result, felt252>; // Executes a single step of the script, returning true if more steps are needed fn step(ref self: Engine) -> Result; @@ -100,7 +100,7 @@ pub impl EngineImpl< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, >, +Drop, +Drop, @@ -113,7 +113,7 @@ pub impl EngineImpl< tx_idx: u32, flags: u32, amount: i64, - hash_cache: @HashCache + hash_cache: @HashCache, ) -> Result, felt252> { let transaction_inputs = transaction.get_transaction_inputs(); if tx_idx >= transaction_inputs.len() { @@ -230,7 +230,7 @@ pub impl EngineImpl< if witness_program.len() != 0 { let (witness_version, witness_program) = witness::parse_witness_program( - @witness_program + @witness_program, )?; engine.witness_version = witness_version; engine.witness_program = witness_program; @@ -477,7 +477,7 @@ pub impl EngineInternalImpl< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, >, +Drop, +Drop, @@ -650,7 +650,7 @@ pub impl EngineInternalImpl< if witness_len == 1 { TaprootContextImpl::verify_taproot_spend( - @self.witness_program, witness[0], self.transaction, self.tx_idx + ref self, @self.witness_program, witness[0], self.transaction, self.tx_idx, )?; self.taproot_context.must_succeed = true; return Result::Ok(()); diff --git a/packages/engine/src/errors.cairo b/packages/engine/src/errors.cairo index c87aec26..5f1773ea 100644 --- a/packages/engine/src/errors.cairo +++ b/packages/engine/src/errors.cairo @@ -17,12 +17,14 @@ pub mod Error { pub const UNSATISFIED_LOCKTIME: felt252 = 'Unsatisfied locktime'; pub const SCRIPT_STRICT_MULTISIG: felt252 = 'OP_CHECKMULTISIG invalid dummy'; pub const FINALIZED_TX_CLTV: felt252 = 'Finalized tx in OP_CLTV'; + pub const INVALID_TX_VERSION: felt252 = 'Invalid transaction version'; pub const SCRIPT_INVALID: felt252 = 'Invalid script data'; pub const INVALID_COINBASE: felt252 = 'Invalid coinbase transaction'; pub const SIG_NULLFAIL: felt252 = 'Sig non-zero on failed checksig'; pub const MINIMAL_DATA: felt252 = 'Opcode represents non-minimal'; pub const MINIMAL_IF: felt252 = 'If conditional must be 0 or 1'; pub const DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: felt252 = 'Upgradable witness program'; + pub const INVALID_PUBKEY_UNCOMP_SIZE: felt252 = 'Bad pub key uncompressed size'; pub const WITNESS_PROGRAM_INVALID: felt252 = 'Invalid witness program'; pub const WITNESS_PROGRAM_MISMATCH: felt252 = 'Witness program mismatch'; pub const WITNESS_UNEXPECTED: felt252 = 'Unexpected witness data'; @@ -35,16 +37,21 @@ pub mod Error { pub const CODESEPARATOR_NON_SEGWIT: felt252 = 'CODESEPARATOR in non-segwit'; pub const TAPROOT_MULTISIG: felt252 = 'Multisig in taproot script'; pub const TAPROOT_EMPTY_PUBKEY: felt252 = 'Empty pubkey in taproot script'; + pub const TAPROOT_INVALID_PUBKEY_SIZE: felt252 = 'Bad pubkey size in tapscript'; pub const TAPROOT_INVALID_CONTROL_BLOCK: felt252 = 'Invalid control block'; pub const TAPROOT_INVALID_SIG: felt252 = 'Invalid signature in tap script'; pub const TAPROOT_PARITY_MISMATCH: felt252 = 'Parity mismatch in tap script'; pub const TAPROOT_INVALID_MERKLE_PROOF: felt252 = 'Invalid taproot merkle proof'; + pub const SCHNORR_INVALID_SIG_SIZE: felt252 = 'Invalid schnorr sig size'; + pub const SCHNORR_INVALID_SIG_R_FIELD: felt252 = 'Schnorr sig r >= field'; + pub const SCHNORR_INVALID_MSG_SIZE: felt252 = 'Schnorr msg size != 32'; pub const DISCOURAGE_OP_SUCCESS: felt252 = 'OP_SUCCESS is discouraged'; pub const DISCOURAGE_UPGRADABLE_TAPROOT_VERSION: felt252 = 'Upgradable taproot version'; + pub const DISCOURAGE_UPGRADABLE_PUBKEY_TYPE: felt252 = 'Upgradable pubkey type'; pub const TAPROOT_SIGOPS_EXCEEDED: felt252 = 'Taproot sigops exceeded'; - pub const INVALID_P2MS: felt252 = 'Invalid P2MS transaction'; pub const SCRIPT_UNFINISHED: felt252 = 'Script unfinished'; pub const SCRIPT_ERR_SIG_DER: felt252 = 'Signature DER error'; + pub const SECP256K1_INVALID_POINT: felt252 = 'Invalid secp256k1 point'; pub const PUBKEYTYPE: felt252 = 'Unsupported public key type'; pub const SIG_HIGH_S: felt252 = 'Sig not canonical high S value'; pub const SIG_HASHTYPE: felt252 = 'invalid hash type'; diff --git a/packages/engine/src/hash_cache.cairo b/packages/engine/src/hash_cache.cairo index d989e63f..1e21b88b 100644 --- a/packages/engine/src/hash_cache.cairo +++ b/packages/engine/src/hash_cache.cairo @@ -1,5 +1,5 @@ use crate::transaction::{ - EngineTransactionInputTrait, EngineTransactionOutputTrait, EngineTransactionTrait + EngineTransactionInputTrait, EngineTransactionOutputTrait, EngineTransactionTrait, }; use shinigami_utils::bytecode::write_var_int; use shinigami_utils::hash::double_sha256; @@ -8,7 +8,7 @@ use shinigami_utils::hash::double_sha256; pub struct SegwitSigHashMidstate { pub hash_prevouts_v0: u256, pub hash_sequence_v0: u256, - pub hash_outputs_v0: u256 + pub hash_outputs_v0: u256, } pub trait SigHashMidstateTrait< @@ -17,7 +17,7 @@ pub trait SigHashMidstateTrait< T, +EngineTransactionInputTrait, +EngineTransactionOutputTrait, - +EngineTransactionTrait + +EngineTransactionTrait, > { fn new(transaction: @T) -> SegwitSigHashMidstate; } @@ -29,8 +29,8 @@ pub impl SigHashMidstateImpl< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput - > + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, + >, > of SigHashMidstateTrait { fn new(transaction: @T) -> SegwitSigHashMidstate { let mut prevouts_v0_bytes: ByteArray = ""; @@ -55,7 +55,7 @@ pub impl SigHashMidstateImpl< SegwitSigHashMidstate { hash_prevouts_v0: double_sha256(@prevouts_v0_bytes), hash_sequence_v0: double_sha256(@sequence_v0_bytes), - hash_outputs_v0: double_sha256(@outputs_v0_bytes) + hash_outputs_v0: double_sha256(@outputs_v0_bytes), } } } @@ -80,7 +80,7 @@ pub trait HashCacheTrait< T, +EngineTransactionInputTrait, +EngineTransactionOutputTrait, - +EngineTransactionTrait + +EngineTransactionTrait, > { fn new(transaction: @T) -> HashCache; @@ -104,8 +104,8 @@ pub impl HashCacheImpl< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput - > + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, + >, > of HashCacheTrait { fn new(transaction: @T) -> HashCache { HashCache {} diff --git a/packages/engine/src/hash_tag.cairo b/packages/engine/src/hash_tag.cairo index 03187159..e8a8fabf 100644 --- a/packages/engine/src/hash_tag.cairo +++ b/packages/engine/src/hash_tag.cairo @@ -1,5 +1,10 @@ use shinigami_utils::bytecode::hex_to_bytecode; use shinigami_utils::hash::sha256_byte_array; +use core::sha256::compute_sha256_byte_array; + +const TWO_POW_32: u128 = 0x100000000; +const TWO_POW_64: u128 = 0x10000000000000000; +const TWO_POW_96: u128 = 0x1000000000000000000000000; #[derive(Drop)] pub enum HashTag { @@ -23,64 +28,68 @@ pub enum HashTag { // for the witness program. TapTweak, // Unknown tag. - Other: ByteArray + Other: ByteArray, } // TaggedHash implements the tagged hash scheme described in BIP-340. We use // sha-256 to bind a message hash to a specific context using a tag: // sha256(sha256(tag) || sha256(tag) || msg). -pub fn tagged_hash(tag: HashTag, msg: @ByteArray) -> ByteArray { +pub fn tagged_hash(tag: HashTag, msg: @ByteArray) -> u256 { // Check if we have precomputed tag to avoid an extra sha256 let mut sha_tag: ByteArray = ""; match tag { HashTag::Bip0340Challenge => sha_tag .append( @hex_to_bytecode( - @"0x7bb52d7a9fef58323eb1bf7a407db382d2f3f2d81bb1224f49fe518f6d48d37c" - ) + @"0x7bb52d7a9fef58323eb1bf7a407db382d2f3f2d81bb1224f49fe518f6d48d37c", + ), ), HashTag::Bip0340Aux => sha_tag .append( @hex_to_bytecode( - @"0xf1ef4e5ec063cada6d94cafa9d987ea069265839ecc11f972d77a52ed8c1cc90" - ) + @"0xf1ef4e5ec063cada6d94cafa9d987ea069265839ecc11f972d77a52ed8c1cc90", + ), ), HashTag::Bip0340Nonce => sha_tag .append( @hex_to_bytecode( - @"0x07497734a79bcb355b9b8c7d034f121cf434d73ef72dda19870061fb52bfeb2f" - ) + @"0x07497734a79bcb355b9b8c7d034f121cf434d73ef72dda19870061fb52bfeb2f", + ), ), HashTag::TapSighash => sha_tag .append( @hex_to_bytecode( - @"0xf40a48df4b2a70c8b4924bf2654661ed3d95fd66a313eb87237597c628e4a031" - ) + @"0xf40a48df4b2a70c8b4924bf2654661ed3d95fd66a313eb87237597c628e4a031", + ), ), HashTag::TapLeaf => sha_tag .append( @hex_to_bytecode( - @"0xaeea8fdc4208983105734b58081d1e2638d35f1cb54008d4d357ca03be78e9ee" - ) + @"0xaeea8fdc4208983105734b58081d1e2638d35f1cb54008d4d357ca03be78e9ee", + ), ), HashTag::TapBranch => sha_tag .append( @hex_to_bytecode( - @"0x1941a1f2e56eb95fa2a9f194be5c01f7216f33ed82b091463490d05bf516a015" - ) + @"0x1941a1f2e56eb95fa2a9f194be5c01f7216f33ed82b091463490d05bf516a015", + ), ), HashTag::TapTweak => sha_tag .append( @hex_to_bytecode( - @"0xe80fe1639c9ca050e3af1b39c143c63e429cbceb15d940fbb5c5a1f4af57c5e9" - ) + @"0xe80fe1639c9ca050e3af1b39c143c63e429cbceb15d940fbb5c5a1f4af57c5e9", + ), ), - HashTag::Other(bytes) => sha_tag.append(@sha256_byte_array(@bytes)) + HashTag::Other(bytes) => sha_tag.append(@sha256_byte_array(@bytes)), }; // h = sha256(sha256(tag) || sha256(tag) || msg) let mut h: ByteArray = sha_tag.clone(); h.append(@sha_tag); h.append(msg); - return sha256_byte_array(@h); + let [x0, x1, x2, x3, x4, x5, x6, x7] = compute_sha256_byte_array(@h); + u256 { + high: x0.into() * TWO_POW_96 + x1.into() * TWO_POW_64 + x2.into() * TWO_POW_32 + x3.into(), + low: x4.into() * TWO_POW_96 + x5.into() * TWO_POW_64 + x6.into() * TWO_POW_32 + x7.into(), + } } diff --git a/packages/engine/src/lib.cairo b/packages/engine/src/lib.cairo index 595940f3..5ed3a8e1 100644 --- a/packages/engine/src/lib.cairo +++ b/packages/engine/src/lib.cairo @@ -28,10 +28,15 @@ pub mod signature { pub mod sighash; pub mod constants; pub mod utils; - pub use signature::{BaseSigVerifier, BaseSigVerifierTrait}; + pub mod schnorr; + pub use signature::{ + BaseSigVerifier, BaseSigVerifierTrait, BaseSegwitSigVerifierTrait, TaprootSigVerifier, + TaprootSigVerifierTrait, + }; } pub mod transaction; #[cfg(test)] mod tests { mod test_scriptnum; + mod test_schnorr; } diff --git a/packages/engine/src/opcodes/constants.cairo b/packages/engine/src/opcodes/constants.cairo index ca6ff4d3..b122801e 100644 --- a/packages/engine/src/opcodes/constants.cairo +++ b/packages/engine/src/opcodes/constants.cairo @@ -1,6 +1,6 @@ use crate::engine::{Engine, EngineInternalTrait}; use crate::transaction::{ - EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait, }; use crate::stack::ScriptStackTrait; use shinigami_utils::byte_array::byte_array_to_felt252_le; @@ -20,10 +20,10 @@ pub fn opcode_push_data< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - n: usize, ref engine: Engine + n: usize, ref engine: Engine, ) -> Result<(), felt252> { let data = EngineInternalTrait::::pull_data(ref engine, n)?; engine.dstack.push_byte_array(data); @@ -40,10 +40,10 @@ pub fn opcode_push_data_x< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - n: usize, ref engine: Engine + n: usize, ref engine: Engine, ) -> Result<(), felt252> { let data_len_bytes = EngineInternalTrait::::pull_data(ref engine, n)?; let data_len: usize = byte_array_to_felt252_le(@data_len_bytes).try_into().unwrap(); diff --git a/packages/engine/src/opcodes/crypto.cairo b/packages/engine/src/opcodes/crypto.cairo index 02f4956a..fc8d9658 100644 --- a/packages/engine/src/opcodes/crypto.cairo +++ b/packages/engine/src/opcodes/crypto.cairo @@ -1,13 +1,13 @@ use crate::engine::{Engine, EngineInternalImpl}; use crate::transaction::{ - EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait, }; use crate::stack::ScriptStackTrait; use crate::flags::ScriptFlags; use crate::signature::signature; use crate::signature::sighash; use crate::signature::signature::{ - BaseSigVerifierTrait, TaprootSigVerifierTrait, BaseSegwitSigVerifierTrait + BaseSigVerifierTrait, TaprootSigVerifierTrait, BaseSegwitSigVerifierTrait, }; use starknet::secp256_trait::{is_valid_signature}; use shinigami_utils::hash::{sha256_byte_array, double_sha256_bytearray}; @@ -59,10 +59,10 @@ pub fn opcode_checksig< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { let pk_bytes = engine.dstack.pop_byte_array()?; let full_sig_bytes = engine.dstack.pop_byte_array()?; @@ -113,6 +113,7 @@ pub fn opcode_checksig< is_valid = false; } } else if engine.use_taproot { + // Taproot Signature Verification engine.taproot_context.use_ops_budget()?; if pk_bytes.len() == 0 { return Result::Err(Error::TAPROOT_EMPTY_PUBKEY); @@ -120,9 +121,9 @@ pub fn opcode_checksig< // TODO: Errors or false? let mut verifier = TaprootSigVerifierTrait::< - T - >::new_base(@full_sig_bytes, @pk_bytes, ref engine)?; - is_valid = TaprootSigVerifierTrait::::verify(ref verifier); + I, O, T, + >::new_base(ref engine, @full_sig_bytes, @pk_bytes)?; + is_valid = TaprootSigVerifierTrait::::verify(ref verifier); } if !is_valid && @engine.use_taproot == @true { @@ -146,10 +147,10 @@ pub fn opcode_checkmultisig< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { if engine.use_taproot { return Result::Err(Error::TAPROOT_MULTISIG); @@ -176,7 +177,7 @@ pub fn opcode_checkmultisig< while i != num_pub_keys { match engine.dstack.pop_byte_array() { Result::Ok(pk) => pub_keys.append(pk), - Result::Err(e) => err = e + Result::Err(e) => err = e, }; i += 1; }; @@ -199,7 +200,7 @@ pub fn opcode_checkmultisig< while i != num_sigs { match engine.dstack.pop_byte_array() { Result::Ok(s) => sigs.append(s), - Result::Err(e) => err = e + Result::Err(e) => err = e, }; i += 1; }; @@ -260,7 +261,7 @@ pub fn opcode_checkmultisig< let sig_hashes = SigHashMidstateTrait::new(transaction); sig_hash = sighash::calc_witness_signature_hash( - @script, @sig_hashes, hash_type, transaction, tx_idx, amount + @script, @sig_hashes, hash_type, transaction, tx_idx, amount, ); } else { sig_hash = sighash::calc_signature_hash(@script, hash_type, transaction, tx_idx); @@ -308,13 +309,13 @@ pub fn opcode_codeseparator< impl IEngineTransactionInputTrait: EngineTransactionInputTrait, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >, +Drop, +Drop, +Drop, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { engine.last_code_sep = engine.opcode_idx; @@ -339,10 +340,10 @@ pub fn opcode_checksigverify< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { opcode_checksig(ref engine)?; utils::abstract_verify(ref engine)?; @@ -359,10 +360,10 @@ pub fn opcode_checkmultisigverify< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { opcode_checkmultisig(ref engine)?; utils::abstract_verify(ref engine)?; @@ -383,13 +384,13 @@ pub fn opcode_checksigadd< impl IEngineTransactionInputTrait: EngineTransactionInputTrait, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >, +Drop, +Drop, +Drop, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { if !engine.use_taproot { return Result::Err(Error::OPCODE_RESERVED); @@ -413,9 +414,9 @@ pub fn opcode_checksigadd< } let mut verifier = TaprootSigVerifierTrait::< - T - >::new(@sig_bytes, @pk_bytes, engine.taproot_context.annex)?; - if !(TaprootSigVerifierTrait::::verify(ref verifier)) { + I, O, T, + >::new(ref engine, @sig_bytes, @pk_bytes, engine.taproot_context.annex)?; + if !(TaprootSigVerifierTrait::::verify(ref verifier)) { return Result::Err(Error::TAPROOT_INVALID_SIG); } diff --git a/packages/engine/src/opcodes/flow.cairo b/packages/engine/src/opcodes/flow.cairo index efe97979..09f4a96f 100644 --- a/packages/engine/src/opcodes/flow.cairo +++ b/packages/engine/src/opcodes/flow.cairo @@ -1,6 +1,6 @@ use crate::engine::{Engine, EngineInternalTrait}; use crate::transaction::{ - EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait, }; use crate::flags::ScriptFlags; use crate::cond_stack::ConditionalStackTrait; @@ -17,14 +17,14 @@ pub fn opcode_nop< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine, opcode: u8 + ref engine: Engine, opcode: u8, ) -> Result<(), felt252> { if opcode != Opcode::OP_NOP && EngineInternalTrait::< - I, O, T + I, O, T, >::has_flag(ref engine, ScriptFlags::ScriptDiscourageUpgradableNops) { return Result::Err(Error::SCRIPT_DISCOURAGE_UPGRADABLE_NOPS); } @@ -45,10 +45,10 @@ pub fn opcode_if< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { let mut cond = op_cond_false; // TODO: Pop if bool @@ -74,10 +74,10 @@ pub fn opcode_notif< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { let mut cond = op_cond_false; if engine.cond_stack.branch_executing() { diff --git a/packages/engine/src/opcodes/locktime.cairo b/packages/engine/src/opcodes/locktime.cairo index 8921df9e..b4e20143 100644 --- a/packages/engine/src/opcodes/locktime.cairo +++ b/packages/engine/src/opcodes/locktime.cairo @@ -1,6 +1,6 @@ use crate::engine::{Engine, EngineInternalImpl}; use crate::transaction::{ - EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait, }; use crate::errors::Error; use crate::flags::ScriptFlags; @@ -38,10 +38,10 @@ pub fn opcode_checklocktimeverify< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { if !engine.has_flag(ScriptFlags::ScriptVerifyCheckLockTimeVerify) { if engine.has_flag(ScriptFlags::ScriptDiscourageUpgradableNops) { @@ -52,12 +52,12 @@ pub fn opcode_checklocktimeverify< } let tx_locktime: i64 = EngineTransactionTrait::< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >::get_locktime(engine.transaction) .into(); // Get locktime as 5 byte integer because 'tx_locktime' is u32 let stack_locktime: i64 = ScriptNum::try_into_num_n_bytes( - engine.dstack.peek_byte_array(0)?, 5, engine.dstack.verify_minimal_data + engine.dstack.peek_byte_array(0)?, 5, engine.dstack.verify_minimal_data, )?; if stack_locktime < 0 { @@ -67,7 +67,7 @@ pub fn opcode_checklocktimeverify< // Check if tx sequence is not 'SEQUENCE_MAX' else if tx may be considered as finalized and the // behavior of OP_CHECKLOCKTIMEVERIFY can be bypassed let transaction_input = EngineTransactionTrait::< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >::get_transaction_inputs(engine.transaction) .at(engine.tx_idx); let sequence = EngineTransactionInputTrait::::get_sequence(transaction_input); @@ -88,10 +88,10 @@ pub fn opcode_checksequenceverify< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref engine: Engine + ref engine: Engine, ) -> Result<(), felt252> { if !engine.has_flag(ScriptFlags::ScriptVerifyCheckSequenceVerify) { if engine.has_flag(ScriptFlags::ScriptDiscourageUpgradableNops) { @@ -103,7 +103,7 @@ pub fn opcode_checksequenceverify< // Get sequence as 5 byte integer because 'sequence' is u32 let stack_sequence: i64 = ScriptNum::try_into_num_n_bytes( - engine.dstack.peek_byte_array(0)?, 5, engine.dstack.verify_minimal_data + engine.dstack.peek_byte_array(0)?, 5, engine.dstack.verify_minimal_data, )?; if stack_sequence < 0 { @@ -120,14 +120,14 @@ pub fn opcode_checksequenceverify< // Prevent trigger OP_CHECKSEQUENCEVERIFY before tx version 2 let version = EngineTransactionTrait::< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >::get_version(engine.transaction); if version < 2 { return Result::Err(Error::UNSATISFIED_LOCKTIME); } let transaction_input = EngineTransactionTrait::< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >::get_transaction_inputs(engine.transaction) .at(engine.tx_idx); let tx_sequence: u32 = EngineTransactionInputTrait::::get_sequence(transaction_input); @@ -142,6 +142,6 @@ pub fn opcode_checksequenceverify< verify_locktime( (tx_sequence & locktime_mask).into(), SEQUENCE_LOCKTIME_IS_SECOND.into(), - (stack_sequence_u64 & locktime_mask.into()).try_into().unwrap() + (stack_sequence_u64 & locktime_mask.into()).try_into().unwrap(), ) } diff --git a/packages/engine/src/opcodes/opcodes.cairo b/packages/engine/src/opcodes/opcodes.cairo index ba5633e8..03eca8e2 100644 --- a/packages/engine/src/opcodes/opcodes.cairo +++ b/packages/engine/src/opcodes/opcodes.cairo @@ -192,10 +192,10 @@ pub mod Opcode { use crate::engine::Engine; use crate::transaction::{ - EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait, }; use crate::opcodes::{ - constants, flow, stack, splice, bitwise, arithmetic, crypto, locktime, utils + constants, flow, stack, splice, bitwise, arithmetic, crypto, locktime, utils, }; pub fn execute< @@ -208,10 +208,10 @@ pub mod Opcode { +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - opcode: u8, ref engine: Engine + opcode: u8, ref engine: Engine, ) -> Result<(), felt252> { match opcode { 0 => constants::opcode_false(ref engine), @@ -400,12 +400,12 @@ pub mod Opcode { 183 => flow::opcode_nop(ref engine, 183), 184 => flow::opcode_nop(ref engine, 184), 185 => flow::opcode_nop(ref engine, 185), - _ => utils::not_implemented(ref engine) + _ => utils::not_implemented(ref engine), } } pub fn is_opcode_disabled>( - opcode: u8, ref engine: Engine + opcode: u8, ref engine: Engine, ) -> Result<(), felt252> { if opcode == OP_CAT || opcode == OP_SUBSTR @@ -429,7 +429,7 @@ pub mod Opcode { } pub fn is_opcode_always_illegal>( - opcode: u8, ref engine: Engine + opcode: u8, ref engine: Engine, ) -> Result<(), felt252> { if opcode == OP_VERIF { return utils::opcode_reserved("verif", ref engine); diff --git a/packages/engine/src/parser.cairo b/packages/engine/src/parser.cairo index cfe1e12a..2365fd0b 100644 --- a/packages/engine/src/parser.cairo +++ b/packages/engine/src/parser.cairo @@ -66,7 +66,7 @@ pub fn data_len(script: @ByteArray, idx: usize) -> Result { } return Result::Ok( byte_array_to_felt252_le(@data_at(script, idx + 1, push_data_len)?).try_into().unwrap() - + push_data_len + + push_data_len, ); } @@ -85,7 +85,7 @@ pub fn push_data_len(script: @ByteArray, idx: usize) -> Result { } return Result::Ok( - byte_array_to_felt252_le(@data_at(script, idx + 1, len)?).try_into().unwrap() + byte_array_to_felt252_le(@data_at(script, idx + 1, len)?).try_into().unwrap(), ); } diff --git a/packages/engine/src/scriptnum.cairo b/packages/engine/src/scriptnum.cairo index 05b9559f..5f338753 100644 --- a/packages/engine/src/scriptnum.cairo +++ b/packages/engine/src/scriptnum.cairo @@ -106,7 +106,7 @@ pub mod ScriptNum { // Unwrap 'n' byte of sign-magnitude encoded ByteArray. pub fn try_into_num_n_bytes( - input: ByteArray, n: usize, minimal_required: bool + input: ByteArray, n: usize, minimal_required: bool, ) -> Result { let mut result: i64 = 0; let mut i: u32 = 0; diff --git a/packages/engine/src/signature/constants.cairo b/packages/engine/src/signature/constants.cairo index a543cfab..31c0107a 100644 --- a/packages/engine/src/signature/constants.cairo +++ b/packages/engine/src/signature/constants.cairo @@ -41,6 +41,11 @@ pub const HASH_TYPE_LEN: usize = 1; //including the version byte and the public key hash, ensuring correct data formatting and inclusion //in SegWit transactions. pub const WITNESS_V0_PUB_KEY_HASH_LEN: usize = 22; +//SignatureSize is the size of an encoded Schnorr signature. +pub const SCHNORR_SIG_SIZE: usize = 64; +//Secp256 field value. +pub const SECP256_FIELD_VAL: u256 = + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f; pub const MAX_U128: u128 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; pub const MAX_U32: u32 = 0xFFFFFFFF; diff --git a/packages/engine/src/signature/schnorr.cairo b/packages/engine/src/signature/schnorr.cairo new file mode 100644 index 00000000..e24558e2 --- /dev/null +++ b/packages/engine/src/signature/schnorr.cairo @@ -0,0 +1,95 @@ +use crate::errors::Error; +use crate::signature::{constants, signature}; +use starknet::secp256k1::Secp256k1Point; +use starknet::secp256_trait::{Secp256Trait, Signature, Secp256PointTrait}; +use starknet::SyscallResultTrait; +use crate::hash_tag::{HashTag, tagged_hash}; + +const p: u256 = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F; + +pub fn parse_schnorr_pub_key(pk_bytes: @ByteArray) -> Result { + if pk_bytes.len() == 0 { + return Result::Err(Error::TAPROOT_EMPTY_PUBKEY); + } + if pk_bytes.len() != 32 { + return Result::Err(Error::TAPROOT_INVALID_PUBKEY_SIZE); + } + + let mut key_compressed: ByteArray = "\02"; + key_compressed.append(pk_bytes); + return Result::Ok(signature::parse_pub_key(@key_compressed)?); +} + +pub fn parse_schnorr_signature(sig_bytes: @ByteArray) -> Result { + let sig_len = sig_bytes.len(); + if sig_len != constants::SCHNORR_SIG_SIZE { + return Result::Err(Error::SCHNORR_INVALID_SIG_SIZE); + } + + let mut r: u256 = 0; + let mut s: u256 = 0; + for i in 0 + ..sig_bytes + .len() { + if i < 32 { + r *= 256; + r += sig_bytes[i].into(); + } else { + s *= 256; + s += sig_bytes[i].into(); + } + }; + if r >= constants::SECP256_FIELD_VAL { + return Result::Err(Error::SCHNORR_INVALID_SIG_R_FIELD); + } + + return Result::Ok(Signature { r: r, s: s, y_parity: false }); +} + +// verify_schnorr attempt to verify the signature for the provided hash and secp256k1 public key. +// The algorithm for verifying a BIP-340 signature is reproduced here for reference: +// +// 1. Fail if m is not 32 bytes +// 2. P = lift_x(int(pk)). +// 3. r = int(sig[0:32]); fail is r >= p. +// 4. s = int(sig[32:64]); fail if s >= n. +// 5. e = int(tagged_hash("BIP0340/challenge", bytes(r) || bytes(P) || M)) mod n. +// 6. R = s*G - e*P +// 7. Fail if is_infinite(R) +// 8. Fail if not hash_even_y(R) +// 9. Fail is x(R) != r. +// 10. Return success if failure did not occur before reaching this point. +pub fn verify_schnorr(sig: Signature, hash: ByteArray, pubkey: ByteArray) -> Result { + if hash.len() != 32 { + return Result::Err(Error::SCHNORR_INVALID_MSG_SIZE); + } + + let P = parse_schnorr_pub_key(@pubkey)?; + + let n = Secp256Trait::::get_curve_size(); + if sig.r >= p { + return Result::Err(Error::SCHNORR_INVALID_SIG_R_FIELD); + } else if sig.s >= n { + return Result::Err(Error::SCHNORR_INVALID_SIG_SIZE); + } + + let mut msg: ByteArray = Default::default(); + msg.append_word(sig.r.high.into(), 16); + msg.append_word(sig.r.low.into(), 16); + msg.append(@pubkey); + msg.append(@hash); + let e = tagged_hash(HashTag::Bip0340Challenge, @msg); + + let G = Secp256Trait::::get_generator_point(); + + // R = s⋅G - e⋅P + let p1 = G.mul(sig.s).unwrap_syscall(); + let minus_e = Secp256Trait::::get_curve_size() - e; + let p2 = P.mul(minus_e).unwrap_syscall(); + let R = p1.add(p2).unwrap_syscall(); + + let (Rx, Ry) = R.get_coordinates().unwrap_syscall(); + + // Fail if is_infinite(R) || not has_even_y(R) || x(R) ≠ rx. + Result::Ok(!(Rx == 0 && Ry == 0) && Ry % 2 == 0 && Rx == sig.r) +} diff --git a/packages/engine/src/signature/sighash.cairo b/packages/engine/src/signature/sighash.cairo index b23c6df0..da992d4d 100644 --- a/packages/engine/src/signature/sighash.cairo +++ b/packages/engine/src/signature/sighash.cairo @@ -1,10 +1,10 @@ use crate::transaction::{ EngineTransaction, EngineTransactionTrait, EngineInternalTransactionImpl, - EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionInputTrait, EngineTransactionOutputTrait, }; use crate::signature::constants; use crate::signature::utils::{ - remove_opcodeseparator, transaction_procedure, is_witness_pub_key_hash + remove_opcodeseparator, transaction_procedure, is_witness_pub_key_hash, }; use crate::hash_cache::SegwitSigHashMidstate; use shinigami_utils::bytecode::write_var_int; @@ -19,13 +19,13 @@ pub fn calc_signature_hash< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, >, +Drop, +Drop, - +Drop + +Drop, >( - sub_script: @ByteArray, hash_type: u32, transaction: @T, tx_idx: u32 + sub_script: @ByteArray, hash_type: u32, transaction: @T, tx_idx: u32, ) -> u256 { let transaction_outputs_len: usize = transaction.get_transaction_outputs().len(); // `SIG_HASH_SINGLE` only signs corresponding input/output pair. @@ -41,7 +41,7 @@ pub fn calc_signature_hash< let mut signature_script: @ByteArray = remove_opcodeseparator(sub_script); // Create a modified copy of the transaction according to the hash type. let transaction_copy: EngineTransaction = transaction_procedure( - transaction, tx_idx, signature_script.clone(), hash_type + transaction, tx_idx, signature_script.clone(), hash_type, ); let mut sig_hash_bytes: ByteArray = transaction_copy.serialize_no_witness(); @@ -59,18 +59,18 @@ pub fn calc_witness_signature_hash< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, >, +Drop, +Drop, - +Drop + +Drop, >( sub_script: @ByteArray, sig_hashes: @SegwitSigHashMidstate, hash_type: u32, transaction: @T, tx_idx: u32, - amount: i64 + amount: i64, ) -> u256 { // TODO: Bounds check? @@ -175,7 +175,7 @@ pub struct TaprootSighashOptions { // Key version as defined in BIP-341. Actually always 0. key_version: u8, // Position of the last opcode separator. Used for BIP-342 sighash message extension. - code_sep_pos: u32 + code_sep_pos: u32, } #[generate_trait()] @@ -186,7 +186,7 @@ pub impl TaprootSighashOptionsImpl of TaprootSighashOptionsTrait { annex_hash: @"", tap_leaf_hash: @"", key_version: 0, - code_sep_pos: 0 + code_sep_pos: 0, } } @@ -196,19 +196,19 @@ pub impl TaprootSighashOptionsImpl of TaprootSighashOptionsTrait { annex_hash: @sha256_byte_array(annex), tap_leaf_hash: @"", key_version: 0, - code_sep_pos: 0 + code_sep_pos: 0, } } fn new_with_tapscript_version( - code_sep_pos: u32, tap_leaf_hash: @ByteArray + code_sep_pos: u32, tap_leaf_hash: @ByteArray, ) -> TaprootSighashOptions { TaprootSighashOptions { ext_flag: TAPSCRIPT_SIGHASH_EXT_FLAG, annex_hash: @"", tap_leaf_hash: tap_leaf_hash, key_version: 0, - code_sep_pos: code_sep_pos + code_sep_pos: code_sep_pos, } } @@ -228,7 +228,7 @@ pub impl TaprootSighashOptionsImpl of TaprootSighashOptionsTrait { } // Return true if `taproot_sighash` is valid. -fn is_valid_taproot_sighash(hash_type: u32) -> bool { +pub fn is_valid_taproot_sighash(hash_type: u32) -> bool { if hash_type == constants::SIG_HASH_DEFAULT || hash_type == constants::SIG_HASH_ALL || hash_type == constants::SIG_HASH_NONE @@ -242,11 +242,11 @@ fn is_valid_taproot_sighash(hash_type: u32) -> bool { } } -fn calc_taproot_signature_hash() -> u256 { +pub fn calc_taproot_signature_hash() -> u256 { 0 // TODO } -fn calc_tapscript_signature_hash() -> u256 { +pub fn calc_tapscript_signature_hash() -> u256 { 0 // TODO } diff --git a/packages/engine/src/signature/signature.cairo b/packages/engine/src/signature/signature.cairo index d4be7329..60098231 100644 --- a/packages/engine/src/signature/signature.cairo +++ b/packages/engine/src/signature/signature.cairo @@ -1,6 +1,6 @@ use crate::engine::{Engine, EngineInternalImpl}; use crate::transaction::{ - EngineTransactionInputTrait, EngineTransactionOutputTrait, EngineTransactionTrait + EngineTransactionInputTrait, EngineTransactionOutputTrait, EngineTransactionTrait, }; use starknet::SyscallResultTrait; use starknet::secp256_trait::{Secp256Trait, Signature, is_valid_signature}; @@ -8,7 +8,7 @@ use starknet::secp256k1::{Secp256k1Point}; use crate::flags::ScriptFlags; use crate::hash_cache::SigHashMidstateTrait; use shinigami_utils::byte_array::u256_from_byte_array_with_offset; -use crate::signature::{sighash, constants}; +use crate::signature::{sighash, constants, schnorr}; use crate::errors::Error; use shinigami_utils::byte_array::{sub_byte_array}; use crate::parser; @@ -36,10 +36,10 @@ pub trait BaseSigVerifierTrait< T, +EngineTransactionInputTrait, +EngineTransactionOutputTrait, - +EngineTransactionTrait + +EngineTransactionTrait, > { fn new( - ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray + ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray, ) -> Result; fn verify(ref self: BaseSigVerifier, ref vm: Engine) -> bool; } @@ -51,14 +51,14 @@ impl BaseSigVerifierImpl< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, >, +Drop, +Drop, - +Drop + +Drop, > of BaseSigVerifierTrait { fn new( - ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray + ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray, ) -> Result { let (pub_key, sig, hash_type) = parse_base_sig_and_pk(ref vm, pk_bytes, sig_bytes)?; let sub_script = vm.sub_script(); @@ -69,7 +69,7 @@ impl BaseSigVerifierImpl< fn verify(ref self: BaseSigVerifier, ref vm: Engine) -> bool { let sub_script = remove_signature(@self.sub_script, self.sig_bytes); let sig_hash: u256 = sighash::calc_signature_hash::< - I, O, T + I, O, T, >(sub_script, self.hash_type, vm.transaction, vm.tx_idx); is_valid_signature(sig_hash, self.sig.r, self.sig.s, self.pub_key) @@ -82,7 +82,7 @@ pub trait BaseSegwitSigVerifierTrait< T, +EngineTransactionInputTrait, +EngineTransactionOutputTrait, - +EngineTransactionTrait + +EngineTransactionTrait, > { fn verify(ref self: BaseSigVerifier, ref vm: Engine) -> bool; } @@ -94,16 +94,16 @@ impl BaseSegwitSigVerifierImpl< impl IEngineTransactionInput: EngineTransactionInputTrait, impl IEngineTransactionOutput: EngineTransactionOutputTrait, impl IEngineTransaction: EngineTransactionTrait< - T, I, O, IEngineTransactionInput, IEngineTransactionOutput + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, >, +Drop, +Drop, - +Drop + +Drop, > of BaseSegwitSigVerifierTrait { fn verify(ref self: BaseSigVerifier, ref vm: Engine) -> bool { let sig_hashes = SigHashMidstateTrait::new(vm.transaction); let sig_hash: u256 = sighash::calc_witness_signature_hash::< - I, O, T + I, O, T, >(@self.sub_script, @sig_hashes, self.hash_type, vm.transaction, vm.tx_idx, vm.amount); is_valid_signature(sig_hash, self.sig.r, self.sig.s, self.pub_key) @@ -143,10 +143,10 @@ pub fn check_hash_type_encoding< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref vm: Engine, mut hash_type: u32 + ref vm: Engine, mut hash_type: u32, ) -> Result<(), felt252> { if !vm.has_flag(ScriptFlags::ScriptVerifyStrictEncoding) { return Result::Ok(()); @@ -183,10 +183,10 @@ pub fn check_signature_encoding< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref vm: Engine, sig_bytes: @ByteArray + ref vm: Engine, sig_bytes: @ByteArray, ) -> Result<(), felt252> { // https://github.com/btcsuite/btcd/blob/master/txscript/engine.go#L1221 let low_s = vm.has_flag(ScriptFlags::ScriptVerifyLowS); @@ -338,10 +338,10 @@ pub fn check_pub_key_encoding< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref vm: Engine, pk_bytes: @ByteArray + ref vm: Engine, pk_bytes: @ByteArray, ) -> Result<(), felt252> { if vm.has_flag(ScriptFlags::ScriptVerifyWitnessPubKeyType) && vm.is_witness_active(0) @@ -379,10 +379,11 @@ pub fn parse_pub_key(pk_bytes: @ByteArray) -> Result { if pk_bytes[0] == 0x03 { parity = true; } + return Result::Ok( Secp256Trait::::secp256_ec_get_point_from_x_syscall(pub_key, parity) .unwrap_syscall() - .expect('Secp256k1Point: Invalid point.') + .expect(Error::SECP256K1_INVALID_POINT), ); } else { // Extract X coordinate and determine parity from last byte. @@ -395,21 +396,11 @@ pub fn parse_pub_key(pk_bytes: @ByteArray) -> Result { return Result::Ok( Secp256Trait::::secp256_ec_get_point_from_x_syscall(pub_key, parity) .unwrap_syscall() - .expect('Secp256k1Point: Invalid point.') + .expect(Error::INVALID_PUBKEY_LEN), ); } } -pub fn parse_schnorr_pub_key(pk_bytes: @ByteArray) -> Result { - if pk_bytes.len() == 0 || pk_bytes.len() != 32 { - return Result::Err('Invalid schnorr pubkey length'); - } - - let mut key_compressed: ByteArray = "\02"; - key_compressed.append(pk_bytes); - return parse_pub_key(@key_compressed); -} - // Parses a DER-encoded ECDSA signature byte array into a `Signature` struct. // // This function extracts the `r` and `s` values from a DER-encoded ECDSA signature (`sig_bytes`). @@ -488,29 +479,7 @@ pub fn parse_signature(sig_bytes: @ByteArray) -> Result { return Result::Err('invalid sig: bad final length'); } - return Result::Ok(Signature { r: r_sig, s: s_sig, y_parity: false, }); -} - -pub fn schnorr_parse_signature(sig_bytes: @ByteArray) -> Result<(Signature, u32), felt252> { - let sig_bytes_len = sig_bytes.len(); - let mut hash_type: u32 = 0; - if sig_bytes_len == SCHNORR_SIGNATURE_LEN { - hash_type = constants::SIG_HASH_DEFAULT; - } else if sig_bytes_len == SCHNORR_SIGNATURE_LEN + 1 && sig_bytes[64] != 0 { - hash_type = sig_bytes[64].into(); - } else { - return Result::Err('Invalid taproot signature len'); - } - Result::Ok( - ( - Signature { - r: u256_from_byte_array_with_offset(sig_bytes, 0, 32), - s: u256_from_byte_array_with_offset(sig_bytes, 32, 32), - y_parity: false, // Schnorr signatures don't use y_parity - }, - hash_type - ) - ) + return Result::Ok(Signature { r: r_sig, s: s_sig, y_parity: false }); } // Parses the public key and signature byte arrays based on consensus rules. @@ -525,10 +494,10 @@ pub fn parse_base_sig_and_pk< +Drop, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, >( - ref vm: Engine, pk_bytes: @ByteArray, sig_bytes: @ByteArray + ref vm: Engine, pk_bytes: @ByteArray, sig_bytes: @ByteArray, ) -> Result<(Secp256k1Point, Signature, u32), felt252> { let verify_der = vm.has_flag(ScriptFlags::ScriptVerifyDERSignatures); let verify_strict_encoding = vm.has_flag(ScriptFlags::ScriptVerifyStrictEncoding); @@ -589,7 +558,7 @@ pub fn parse_base_sig_and_pk< let pub_key = match parse_pub_key(pk_bytes) { Result::Ok(key) => key, - Result::Err(e) => { return Result::Err(e); } + Result::Err(e) => { return Result::Err(e); }, }; Result::Ok((pub_key, sig, hash_type)) } @@ -624,6 +593,47 @@ pub fn remove_signature(script: @ByteArray, sig_bytes: @ByteArray) -> @ByteArray @processed_script } +// Parses the public key and signature for taproot spend. +// Returning a tuple containing the parsed public key, signature, and hash type. +pub fn parse_taproot_sig_and_pk< + T, + +Drop, + I, + +Drop, + impl IEngineTransactionInputTrait: EngineTransactionInputTrait, + O, + +Drop, + impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, + impl IEngineTransactionTrait: EngineTransactionTrait< + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, + >, +>( + ref vm: Engine, pk_bytes: @ByteArray, sig_bytes: @ByteArray, +) -> Result<(Secp256k1Point, Signature, u32), felt252> { + // Parse schnorr public key + let pk = schnorr::parse_schnorr_pub_key(pk_bytes)?; + + // Check the size of the signature and if the `sighash byte` is set. + let sig_len = sig_bytes.len(); + let (sig, sighash_type) = if sig_len == constants::SCHNORR_SIG_SIZE { + // Parse signature, `sighash_type` has default value + (schnorr::parse_schnorr_signature(sig_bytes)?, constants::SIG_HASH_DEFAULT) + } else if sig_len == constants::SCHNORR_SIG_SIZE + 1 && sig_bytes[64] != 0 { + // Extract `sighash_byte` and parse signature + let sighash_type = sig_bytes[64]; + let mut sig_bytes_truncate: ByteArray = ""; + for i in 0..constants::SCHNORR_SIG_SIZE { + sig_bytes_truncate.append_byte(sig_bytes[i]); + }; + (schnorr::parse_schnorr_signature(@sig_bytes_truncate)?, sighash_type.into()) + } else { + // Error on invalid signature size. + return Result::Err(Error::SCHNORR_INVALID_SIG_SIZE); + }; + + return Result::Ok((pk, sig, sighash_type)); +} + #[derive(Drop)] pub struct TaprootSigVerifier { // public key as a point on the secp256k1 curve, used to verify the signature @@ -640,80 +650,103 @@ pub struct TaprootSigVerifier { annex: @ByteArray, } -pub trait TaprootSigVerifierTrait { - fn empty() -> TaprootSigVerifier; +pub trait TaprootSigVerifierTrait< + I, + O, + T, + +EngineTransactionInputTrait, + +EngineTransactionOutputTrait, + +EngineTransactionTrait, +> { fn new( - sig_bytes: @ByteArray, pk_bytes: @ByteArray, annex: @ByteArray + ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray, annex: @ByteArray, ) -> Result; fn new_base( - sig_bytes: @ByteArray, pk_bytes: @ByteArray, ref engine: Engine + ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray, ) -> Result; fn verify(ref self: TaprootSigVerifier) -> bool; fn verify_base(ref self: TaprootSigVerifier) -> bool; } -pub const SCHNORR_SIGNATURE_LEN: usize = 64; - pub impl TaprootSigVerifierImpl< - T, - +Drop, I, - +Drop, - impl IEngineTransactionInputTrait: EngineTransactionInputTrait, O, + T, + impl IEngineTransactionInput: EngineTransactionInputTrait, + impl IEngineTransactionOutput: EngineTransactionOutputTrait, + impl IEngineTransaction: EngineTransactionTrait< + T, I, O, IEngineTransactionInput, IEngineTransactionOutput, + >, +Drop, - impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, - impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait - > -> of TaprootSigVerifierTrait { - fn empty() -> TaprootSigVerifier { - TaprootSigVerifier { - pub_key: Secp256Trait::::get_generator_point(), - sig: Signature { r: 0, s: 0, y_parity: false }, - sig_bytes: @"", - pk_bytes: @"", - hash_type: 0, - annex: @"" - } - } - + +Drop, + +Drop, +> of TaprootSigVerifierTrait { fn new( - sig_bytes: @ByteArray, pk_bytes: @ByteArray, annex: @ByteArray + ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray, annex: @ByteArray, ) -> Result { - let pub_key = parse_schnorr_pub_key(pk_bytes)?; - let (sig, hash_type) = schnorr_parse_signature(sig_bytes)?; - + let (pub_key, sig, hash_type) = parse_taproot_sig_and_pk(ref vm, pk_bytes, sig_bytes)?; Result::Ok( TaprootSigVerifier { - pub_key, sig, sig_bytes: sig_bytes, pk_bytes: pk_bytes, hash_type, annex, - } + pub_key: pub_key, sig: sig, sig_bytes, pk_bytes, hash_type: hash_type, annex, + }, ) } fn new_base( - sig_bytes: @ByteArray, pk_bytes: @ByteArray, ref engine: Engine + ref vm: Engine, sig_bytes: @ByteArray, pk_bytes: @ByteArray, ) -> Result { - let pk_bytes_len = pk_bytes.len(); - if pk_bytes_len == 0 { - return Result::Err('Taproot empty public key'); - } else if pk_bytes_len == 32 { - return Self::new(sig_bytes, pk_bytes, engine.taproot_context.annex); + let pk_len = pk_bytes.len(); + // Fail immediately if public key length is zero + if pk_len == 0 { + return Result::Err(Error::TAPROOT_EMPTY_PUBKEY); + // If key is 32 byte, parse as normal + } else if pk_len == 32 { + let (pub_key, sig, hash_type) = parse_taproot_sig_and_pk(ref vm, pk_bytes, sig_bytes)?; + return (Result::Ok( + TaprootSigVerifier { + pub_key: pub_key, + sig: sig, + sig_bytes, + pk_bytes, + hash_type: hash_type, + annex: vm.taproot_context.annex, + }, + )); + // Otherwise, this is an unknown public key, assuming sig is valid } else { - if engine.has_flag(ScriptFlags::ScriptVerifyDiscourageUpgradeablePubkeyType) { - return Result::Err('Unknown pub key type'); + // However, return an error if the flags preventinf usage of unknown key type is set + if vm.has_flag(ScriptFlags::ScriptVerifyDiscourageUpgradeablePubkeyType) { + return Result::Err(Error::DISCOURAGE_UPGRADABLE_PUBKEY_TYPE); } - return Result::Ok(Self::empty()); + + let pub_key: u256 = u256_from_byte_array_with_offset(pk_bytes, 0, 32); + let pk = Secp256Trait::< + Secp256k1Point, + >::secp256_ec_get_point_from_x_syscall(pub_key, false) + .unwrap_syscall() + .expect(Error::SECP256K1_INVALID_POINT); + return (Result::Ok( + TaprootSigVerifier { + pub_key: pk, + sig: Signature { r: 0, s: 0, y_parity: false }, + sig_bytes, + pk_bytes, + hash_type: constants::SIG_HASH_DEFAULT, + annex: @"", + }, + )); } } fn verify(ref self: TaprootSigVerifier) -> bool { - // TODO: implement taproot verification - return false; + // let sig_hash = sighash::calc_taproot_signature_hash(); // TODO + // return schnorr::verify_schnorr(); + false } fn verify_base(ref self: TaprootSigVerifier) -> bool { - // TODO: implement taproot verification - return false; + // let sig_hash = sighash::calc_taproot_signature_hash(); // TODO + // return schnorr::verify_schnorr(); + false } } diff --git a/packages/engine/src/signature/utils.cairo b/packages/engine/src/signature/utils.cairo index 62c95685..d1b962f8 100644 --- a/packages/engine/src/signature/utils.cairo +++ b/packages/engine/src/signature/utils.cairo @@ -1,7 +1,7 @@ use crate::signature::constants; use crate::transaction::{ EngineTransaction, EngineOutPoint, EngineTransactionInput, EngineTransactionOutput, - EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait, }; use crate::parser; use crate::opcodes::Opcode; @@ -49,13 +49,13 @@ pub fn transaction_procedure< impl IEngineTransactionInputTrait: EngineTransactionInputTrait, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >, +Drop, +Drop, +Drop, >( - transaction: @T, index: u32, signature_script: ByteArray, hash_type: u32 + transaction: @T, index: u32, signature_script: ByteArray, hash_type: u32, ) -> EngineTransaction { let hash_type_masked = hash_type & constants::SIG_HASH_MASK; let mut transaction_inputs_clone = array![]; @@ -63,11 +63,11 @@ pub fn transaction_procedure< .get_transaction_inputs() { let new_transaction_input = EngineTransactionInput { previous_outpoint: EngineOutPoint { - txid: input.get_prevout_txid(), vout: input.get_prevout_vout() + txid: input.get_prevout_txid(), vout: input.get_prevout_vout(), }, signature_script: input.get_signature_script().clone(), witness: input.get_witness().into(), - sequence: input.get_sequence() + sequence: input.get_sequence(), }; transaction_inputs_clone.append(new_transaction_input); }; @@ -75,7 +75,7 @@ pub fn transaction_procedure< for output in transaction .get_transaction_outputs() { let new_transaction_output = EngineTransactionOutput { - value: output.get_value(), publickey_script: output.get_publickey_script().clone() + value: output.get_value(), publickey_script: output.get_publickey_script().clone(), }; transaction_outputs_clone.append(new_transaction_output); }; @@ -83,15 +83,15 @@ pub fn transaction_procedure< version: transaction.get_version(), transaction_inputs: transaction_inputs_clone, transaction_outputs: transaction_outputs_clone, - locktime: transaction.get_locktime() + locktime: transaction.get_locktime(), }; let mut i: usize = 0; let mut transaction_input: Array = transaction_copy.transaction_inputs; let mut processed_transaction_input: Array = ArrayTrait::< - EngineTransactionInput + EngineTransactionInput, >::new(); let mut processed_transaction_output: Array = ArrayTrait::< - EngineTransactionOutput + EngineTransactionOutput, >::new(); let tx_input_len = transaction_input.len(); @@ -101,7 +101,7 @@ pub fn transaction_procedure< if hash_type_masked == constants::SIG_HASH_SINGLE && i < index { processed_transaction_output - .append(EngineTransactionOutput { value: -1, publickey_script: "", }); + .append(EngineTransactionOutput { value: -1, publickey_script: "" }); } if i == index { @@ -111,8 +111,8 @@ pub fn transaction_procedure< previous_outpoint: temp_transaction_input.previous_outpoint, signature_script: signature_script.clone(), witness: temp_transaction_input.witness.clone(), - sequence: temp_transaction_input.sequence - } + sequence: temp_transaction_input.sequence, + }, ); } else { if hash_type & constants::SIG_HASH_ANYONECANPAY != 0 { @@ -129,8 +129,8 @@ pub fn transaction_procedure< previous_outpoint: temp_transaction_input.previous_outpoint, signature_script: "", witness: temp_transaction_input.witness.clone(), - sequence: temp_sequence - } + sequence: temp_sequence, + }, ); } diff --git a/packages/engine/src/taproot.cairo b/packages/engine/src/taproot.cairo index ea4e9451..df71d0f8 100644 --- a/packages/engine/src/taproot.cairo +++ b/packages/engine/src/taproot.cairo @@ -1,8 +1,9 @@ use crate::errors::Error; use crate::transaction::{ - EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait + EngineTransactionTrait, EngineTransactionInputTrait, EngineTransactionOutputTrait, }; -use crate::signature::signature::parse_schnorr_pub_key; +use crate::engine::Engine; +use crate::signature::schnorr; use crate::signature::signature::{TaprootSigVerifierImpl}; use starknet::secp256k1::{Secp256k1Point}; @@ -12,7 +13,7 @@ pub struct TaprootContext { pub code_sep: u32, pub tapleaf_hash: u256, sig_ops_budget: i32, - pub must_succeed: bool + pub must_succeed: bool, } #[derive(Drop)] @@ -20,7 +21,7 @@ pub struct ControlBlock { internal_pubkey: Secp256k1Point, output_key_y_is_odd: bool, pub leaf_version: u8, - control_block: @ByteArray + control_block: @ByteArray, } pub fn serialize_pub_key(pub_key: Secp256k1Point) -> @ByteArray { @@ -71,13 +72,13 @@ pub impl ControlBlockImpl of ControlBlockTrait { internal_pubkey: Secp256k1Point, output_key_y_is_odd: bool, leaf_version: u8, - control_block: @ByteArray + control_block: @ByteArray, ) -> ControlBlock { ControlBlock { internal_pubkey: internal_pubkey, output_key_y_is_odd: output_key_y_is_odd, leaf_version: leaf_version, - control_block: control_block + control_block: control_block, } } @@ -87,7 +88,7 @@ pub impl ControlBlockImpl of ControlBlockTrait { } fn verify_taproot_leaf( - self: @ControlBlock, witness_program: @ByteArray, script: @ByteArray + self: @ControlBlock, witness_program: @ByteArray, script: @ByteArray, ) -> Result<(), felt252> { let root_hash = self.root_hash(script); let taproot_key = compute_taproot_output_key(self.internal_pubkey, @root_hash); @@ -125,7 +126,7 @@ pub impl TaprootContextImpl of TaprootContextTrait { code_sep: BASE_CODE_SEP, tapleaf_hash: 0, sig_ops_budget: SIG_OPS_DELTA + witness_size, - must_succeed: false + must_succeed: false, } } @@ -135,7 +136,7 @@ pub impl TaprootContextImpl of TaprootContextTrait { code_sep: BASE_CODE_SEP, tapleaf_hash: 0, sig_ops_budget: SIG_OPS_DELTA, - must_succeed: false + must_succeed: false, } } @@ -146,13 +147,13 @@ pub impl TaprootContextImpl of TaprootContextTrait { impl IEngineTransactionInputTrait: EngineTransactionInputTrait, impl IEngineTransactionOutputTrait: EngineTransactionOutputTrait, impl IEngineTransactionTrait: EngineTransactionTrait< - T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait + T, I, O, IEngineTransactionInputTrait, IEngineTransactionOutputTrait, >, +Drop, +Drop, +Drop, >( - witness_program: @ByteArray, raw_sig: @ByteArray, tx: @T, tx_idx: u32 + ref vm: Engine, witness_program: @ByteArray, raw_sig: @ByteArray, tx: @T, tx_idx: u32, ) -> Result<(), felt252> { let witness: Span = tx.get_transaction_inputs()[tx_idx].get_witness(); let mut annex = @""; @@ -160,8 +161,10 @@ pub impl TaprootContextImpl of TaprootContextTrait { annex = witness[witness.len() - 1]; } - let mut verifier = TaprootSigVerifierImpl::::new(raw_sig, witness_program, annex)?; - let is_valid = TaprootSigVerifierImpl::::verify(ref verifier); + let mut verifier = TaprootSigVerifierImpl::< + I, O, T, + >::new(ref vm, raw_sig, witness_program, annex)?; + let is_valid = TaprootSigVerifierImpl::::verify(ref verifier); if !is_valid { return Result::Err(Error::TAPROOT_INVALID_SIG); } @@ -197,14 +200,14 @@ pub fn parse_control_block(control_block: @ByteArray) -> Result, transaction_outputs: Array, - locktime: u32 + locktime: u32, ) -> EngineTransaction; fn new_signed(script_sig: ByteArray, pubkey_script: ByteArray) -> EngineTransaction; fn new_signed_witness( - script_sig: ByteArray, pubkey_script: ByteArray, witness: Array, value: i64 + script_sig: ByteArray, pubkey_script: ByteArray, witness: Array, value: i64, ) -> EngineTransaction; fn btc_decode(raw: ByteArray, encoding: u32) -> EngineTransaction; fn deserialize(raw: ByteArray) -> EngineTransaction; @@ -55,7 +55,7 @@ pub trait EngineInternalTransactionTrait { fn calculate_block_subsidy(block_height: u32) -> i64; fn is_coinbase(self: @EngineTransaction) -> bool; fn validate_coinbase( - self: EngineTransaction, block_height: u32, total_fees: i64 + self: EngineTransaction, block_height: u32, total_fees: i64, ) -> Result<(), felt252>; fn print(self: @EngineTransaction); } @@ -68,7 +68,7 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { version: i32, transaction_inputs: Array, transaction_outputs: Array, - locktime: u32 + locktime: u32, ) -> EngineTransaction { EngineTransaction { version: version, @@ -81,14 +81,14 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { fn new_signed(script_sig: ByteArray, pubkey_script: ByteArray) -> EngineTransaction { let coinbase_tx_inputs = array![ EngineTransactionInput { - previous_outpoint: EngineOutPoint { txid: 0x0, vout: 0xffffffff, }, + previous_outpoint: EngineOutPoint { txid: 0x0, vout: 0xffffffff }, signature_script: "\x00\x00", witness: array![], sequence: 0xffffffff, - } + }, ]; let coinbase_tx_outputs = array![ - EngineTransactionOutput { value: 0, publickey_script: pubkey_script, } + EngineTransactionOutput { value: 0, publickey_script: pubkey_script }, ]; let coinbase_tx = EngineTransaction { version: 1, @@ -102,15 +102,13 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { version: 1, transaction_inputs: array![ EngineTransactionInput { - previous_outpoint: EngineOutPoint { txid: coinbase_txid, vout: 0, }, + previous_outpoint: EngineOutPoint { txid: coinbase_txid, vout: 0 }, signature_script: script_sig, witness: array![], sequence: 0xffffffff, - } - ], - transaction_outputs: array![ - EngineTransactionOutput { value: 0, publickey_script: "", } + }, ], + transaction_outputs: array![EngineTransactionOutput { value: 0, publickey_script: "" }], locktime: 0, }; // let transaction = EngineTransaction { @@ -130,18 +128,18 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { } fn new_signed_witness( - script_sig: ByteArray, pubkey_script: ByteArray, witness: Array, value: i64 + script_sig: ByteArray, pubkey_script: ByteArray, witness: Array, value: i64, ) -> EngineTransaction { let coinbase_tx_inputs = array![ EngineTransactionInput { - previous_outpoint: EngineOutPoint { txid: 0x0, vout: 0xffffffff, }, + previous_outpoint: EngineOutPoint { txid: 0x0, vout: 0xffffffff }, signature_script: "\x00\x00", witness: array![], sequence: 0xffffffff, - } + }, ]; let coinbase_tx_outputs = array![ - EngineTransactionOutput { value: value, publickey_script: pubkey_script, } + EngineTransactionOutput { value: value, publickey_script: pubkey_script }, ]; let coinbase_tx = EngineTransaction { version: 1, @@ -155,14 +153,14 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { version: 1, transaction_inputs: array![ EngineTransactionInput { - previous_outpoint: EngineOutPoint { txid: coinbase_txid, vout: 0, }, + previous_outpoint: EngineOutPoint { txid: coinbase_txid, vout: 0 }, signature_script: script_sig, witness: witness, sequence: 0xffffffff, - } + }, ], transaction_outputs: array![ - EngineTransactionOutput { value: value, publickey_script: "", } + EngineTransactionOutput { value: value, publickey_script: "" }, ], locktime: 0, }; @@ -209,7 +207,7 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { let value: i64 = byte_array_value_at_le(@raw, ref offset, 8).try_into().unwrap(); let script_len = read_var_int(@raw, ref offset).try_into().unwrap(); let script = sub_byte_array(@raw, ref offset, script_len); - let output = EngineTransactionOutput { value: value, publickey_script: script, }; + let output = EngineTransactionOutput { value: value, publickey_script: script }; outputs.append(output); i += 1; }; @@ -347,7 +345,7 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { } fn validate_coinbase( - self: EngineTransaction, block_height: u32, total_fees: i64 + self: EngineTransaction, block_height: u32, total_fees: i64, ) -> Result<(), felt252> { if !self.is_coinbase() { return Result::Err(Error::INVALID_COINBASE); @@ -385,7 +383,7 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { while i != self.transaction_inputs.len() { let input = self.transaction_inputs.at(i); println!( - " Input {}: {} {}", i, input.previous_outpoint.txid, input.previous_outpoint.vout + " Input {}: {} {}", i, input.previous_outpoint.txid, input.previous_outpoint.vout, ); println!(" Txid: {}", input.previous_outpoint.txid); println!(" Vout: {}", input.previous_outpoint.vout); @@ -414,7 +412,7 @@ pub impl EngineInternalTransactionImpl of EngineInternalTransactionTrait { impl TransactionDefault of Default { fn default() -> EngineTransaction { let default_txin = EngineTransactionInput { - previous_outpoint: EngineOutPoint { txid: 0, vout: 0, }, + previous_outpoint: EngineOutPoint { txid: 0, vout: 0 }, signature_script: "", witness: array![], sequence: 0xffffffff, @@ -438,7 +436,7 @@ pub trait EngineTransactionInputTrait { } pub impl EngineTransactionInputTraitInternalImpl of EngineTransactionInputTrait< - EngineTransactionInput + EngineTransactionInput, > { fn get_prevout_txid(self: @EngineTransactionInput) -> u256 { *self.previous_outpoint.txid @@ -467,7 +465,7 @@ pub trait EngineTransactionOutputTrait { } pub impl EngineTransactionOutputTraitInternalImpl of EngineTransactionOutputTrait< - EngineTransactionOutput + EngineTransactionOutput, > { fn get_publickey_script(self: @EngineTransactionOutput) -> @ByteArray { self.publickey_script @@ -479,7 +477,7 @@ pub impl EngineTransactionOutputTraitInternalImpl of EngineTransactionOutputTrai } pub trait EngineTransactionTrait< - T, I, O, +EngineTransactionInputTrait, +EngineTransactionOutputTrait + T, I, O, +EngineTransactionInputTrait, +EngineTransactionOutputTrait, > { fn get_version(self: @T) -> i32; fn get_transaction_inputs(self: @T) -> Span; @@ -492,7 +490,7 @@ pub impl EngineTransactionTraitInternalImpl of EngineTransactionTrait< EngineTransactionInput, EngineTransactionOutput, EngineTransactionInputTraitInternalImpl, - EngineTransactionOutputTraitInternalImpl + EngineTransactionOutputTraitInternalImpl, > { fn get_version(self: @EngineTransaction) -> i32 { *self.version diff --git a/packages/tests/src/tests/opcodes/test_constants.cairo b/packages/tests/src/tests/opcodes/test_constants.cairo index 9757b7cf..adab8e7e 100644 --- a/packages/tests/src/tests/opcodes/test_constants.cairo +++ b/packages/tests/src/tests/opcodes/test_constants.cairo @@ -3,7 +3,7 @@ use shinigami_engine::scriptnum::ScriptNum; use shinigami_utils::hex::int_to_hex; use shinigami_utils::bytecode::hex_to_bytecode; use crate::utils::{ - test_compile_and_run, test_compile_and_run_err, check_expected_dstack, check_dstack_size + test_compile_and_run, test_compile_and_run_err, check_expected_dstack, check_dstack_size, }; fn test_op_n(value: u8) { diff --git a/packages/tests/src/tests/opcodes/test_crypto.cairo b/packages/tests/src/tests/opcodes/test_crypto.cairo index a3560dbe..2c274850 100644 --- a/packages/tests/src/tests/opcodes/test_crypto.cairo +++ b/packages/tests/src/tests/opcodes/test_crypto.cairo @@ -1,7 +1,7 @@ use crate::utils::{ test_compile_and_run, check_expected_dstack, check_dstack_size, test_compile_and_run_with_tx_flags_err, mock_transaction_legacy_p2ms, - test_compile_and_run_with_tx_err, test_compile_and_run_with_tx, mock_transaction_legacy_p2pkh + test_compile_and_run_with_tx_err, test_compile_and_run_with_tx, mock_transaction_legacy_p2pkh, }; use shinigami_engine::errors::Error; use shinigami_engine::scriptnum::ScriptNum; @@ -14,7 +14,7 @@ fn test_opcode_sha256_1() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let hex_data: ByteArray = hex_to_bytecode( - @"0x4BF5122F344554C53BDE2EBB8CD2B7E3D1600AD631C385A5D7CCE23C7785459A" + @"0x4BF5122F344554C53BDE2EBB8CD2B7E3D1600AD631C385A5D7CCE23C7785459A", ); let expected_dstack = array![hex_data]; check_expected_dstack(ref engine, expected_dstack.span()); @@ -26,7 +26,7 @@ fn test_opcode_sha256_2() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let hex_data: ByteArray = hex_to_bytecode( - @"0xDBC1B4C900FFE48D575B5DA5C638040125F65DB0FE3E24494B76EA986457D986" + @"0xDBC1B4C900FFE48D575B5DA5C638040125F65DB0FE3E24494B76EA986457D986", ); let expected_dstack = array![hex_data]; check_expected_dstack(ref engine, expected_dstack.span()); @@ -38,7 +38,7 @@ fn test_opcode_sha256_data_8() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let hex_data: ByteArray = hex_to_bytecode( - @"0x66840DDA154E8A113C31DD0AD32F7F3A366A80E8136979D8F5A101D3D29D6F72" + @"0x66840DDA154E8A113C31DD0AD32F7F3A366A80E8136979D8F5A101D3D29D6F72", ); let expected_dstack = array![hex_data]; check_expected_dstack(ref engine, expected_dstack.span()); @@ -52,7 +52,7 @@ fn test_opcode_sha256_push_data_2() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let hex_data: ByteArray = hex_to_bytecode( - @"0x40AFF2E9D2D8922E47AFD4648E6967497158785FBD1DA870E7110266BF944880" + @"0x40AFF2E9D2D8922E47AFD4648E6967497158785FBD1DA870E7110266BF944880", ); let expected_dstack = array![hex_data]; check_expected_dstack(ref engine, expected_dstack.span()); @@ -64,7 +64,7 @@ fn test_opcode_sha256_14_double_sha256() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let hex_data: ByteArray = hex_to_bytecode( - @"0xD6CDF7C9478A78B29F16C7E6DDCC5612E827BEAF6F4AEF7C1BB6FEF56BBB9A0F" + @"0xD6CDF7C9478A78B29F16C7E6DDCC5612E827BEAF6F4AEF7C1BB6FEF56BBB9A0F", ); let expected_dstack = array![hex_data]; check_expected_dstack(ref engine, expected_dstack.span()); @@ -134,7 +134,7 @@ fn test_op_hash256() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let expected_stack = array![ - hex_to_bytecode(@"0x39C02658ED1416713CF4098382E80D07786EED7004FC3FD89B38C7165FDABC80") + hex_to_bytecode(@"0x39C02658ED1416713CF4098382E80D07786EED7004FC3FD89B38C7165FDABC80"), ]; check_expected_dstack(ref engine, expected_stack.span()); } @@ -145,7 +145,7 @@ fn test_op_hash256_1() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let expected_stack = array![ - hex_to_bytecode(@"0x9C12CFDC04C74584D787AC3D23772132C18524BC7AB28DEC4219B8FC5B425F70") + hex_to_bytecode(@"0x9C12CFDC04C74584D787AC3D23772132C18524BC7AB28DEC4219B8FC5B425F70"), ]; check_expected_dstack(ref engine, expected_stack.span()); } @@ -156,7 +156,7 @@ fn test_op_hash256_2() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let expected_stack = array![ - hex_to_bytecode(@"0x1CC3ADEA40EBFD94433AC004777D68150CCE9DB4C771BC7DE1B297A7B795BBBA") + hex_to_bytecode(@"0x1CC3ADEA40EBFD94433AC004777D68150CCE9DB4C771BC7DE1B297A7B795BBBA"), ]; check_expected_dstack(ref engine, expected_stack.span()); } @@ -167,7 +167,7 @@ fn test_op_hash256_data_8() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let expected_stack = array![ - hex_to_bytecode(@"0x2502FA942289B144EDB4CD31C0313624C030885420A86363CE91589D78F8295A") + hex_to_bytecode(@"0x2502FA942289B144EDB4CD31C0313624C030885420A86363CE91589D78F8295A"), ]; check_expected_dstack(ref engine, expected_stack.span()); } @@ -180,7 +180,7 @@ fn test_op_hash256_push_data_2() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let hex_data: ByteArray = hex_to_bytecode( - @"0x60BD11C69262F84DDFEA5F0D116D40AF862C4DD8C2A92FB90E368B132E8FA89C" + @"0x60BD11C69262F84DDFEA5F0D116D40AF862C4DD8C2A92FB90E368B132E8FA89C", ); let expected_dstack = array![hex_data]; check_expected_dstack(ref engine, expected_dstack.span()); @@ -192,7 +192,7 @@ fn test_op_hash256_14_double_hash256() { let mut engine = test_compile_and_run(program); check_dstack_size(ref engine, 1); let hex_data: ByteArray = hex_to_bytecode( - @"0x26AA6C7A9B46E9C409F09C179F7DEFF54F7AF5571D38DE5E5D9BA3932B91F55B" + @"0x26AA6C7A9B46E9C409F09C179F7DEFF54F7AF5571D38DE5E5D9BA3932B91F55B", ); let expected_dstack = array![hex_data]; check_expected_dstack(ref engine, expected_dstack.span()); @@ -277,7 +277,7 @@ fn test_op_checksig_wrong_signature() { "OP_DUP OP_HASH160 OP_DATA_20 0x4299ff317fcd12ef19047df66d72454691797bfc OP_EQUALVERIFY OP_CHECKSIG"; let mut transaction = mock_transaction_legacy_p2pkh(script_sig); let mut engine = test_compile_and_run_with_tx_err( - script_pubkey, transaction, Error::SCRIPT_FAILED + script_pubkey, transaction, Error::SCRIPT_FAILED, ); check_dstack_size(ref engine, 1); let expected_stack = array![ScriptNum::wrap(0)]; @@ -292,7 +292,7 @@ fn test_op_checksig_invalid_hash_type() { "OP_DUP OP_HASH160 OP_DATA_20 0x4299ff317fcd12ef19047df66d72454691797bfc OP_EQUALVERIFY OP_CHECKSIG"; let mut transaction = mock_transaction_legacy_p2pkh(script_sig); let mut engine = test_compile_and_run_with_tx_err( - script_pubkey, transaction, Error::SCRIPT_FAILED + script_pubkey, transaction, Error::SCRIPT_FAILED, ); check_dstack_size(ref engine, 1); let expected_stack = array![""]; @@ -307,7 +307,7 @@ fn test_op_checksig_empty_signature() { "OP_DUP OP_HASH160 OP_DATA_20 0x4299ff317fcd12ef19047df66d72454691797bfc OP_EQUALVERIFY OP_CHECKSIG"; let mut transaction = mock_transaction_legacy_p2pkh(script_sig); let mut engine = test_compile_and_run_with_tx_err( - script_pubkey, transaction, Error::SCRIPT_FAILED + script_pubkey, transaction, Error::SCRIPT_FAILED, ); check_dstack_size(ref engine, 1); let expected_stack = array![ScriptNum::wrap(0)]; @@ -322,7 +322,7 @@ fn test_op_checksig_too_short_signature() { "OP_DUP OP_HASH160 OP_DATA_20 0x4299ff317fcd12ef19047df66d72454691797bfc OP_EQUALVERIFY OP_CHECKSIG"; let mut transaction = mock_transaction_legacy_p2pkh(script_sig); let mut engine = test_compile_and_run_with_tx_err( - script_pubkey, transaction, Error::SCRIPT_FAILED + script_pubkey, transaction, Error::SCRIPT_FAILED, ); check_dstack_size(ref engine, 1); let expected_stack = array![ScriptNum::wrap(0)]; @@ -408,7 +408,7 @@ fn test_op_checkmultisig_wrong_signature() { "OP_2 OP_DATA_65 0x04D81FD577272BBE73308C93009EEC5DC9FC319FC1EE2E7066E17220A5D47A18314578BE2FAEA34B9F1F8CA078F8621ACD4BC22897B03DAA422B9BF56646B342A2 OP_DATA_65 0x04EC3AFFF0B2B66E8152E9018FE3BE3FC92B30BF886B3487A525997D00FD9DA2D012DCE5D5275854ADC3106572A5D1E12D4211B228429F5A7B2F7BA92EB0475BB1 OP_DATA_65 0x04B49B496684B02855BC32F5DAEFA2E2E406DB4418F3B86BCA5195600951C7D918CDBE5E6D3736EC2ABF2DD7610995C3086976B2C0C7B4E459D10B34A316D5A5E7 OP_3 OP_CHECKMULTISIG"; let mut transaction = mock_transaction_legacy_p2ms(script_sig); let mut engine = test_compile_and_run_with_tx_err( - script_pubkey, transaction, Error::SCRIPT_FAILED + script_pubkey, transaction, Error::SCRIPT_FAILED, ); check_dstack_size(ref engine, 1); let expected_stack = array![ScriptNum::wrap(0)]; @@ -434,7 +434,7 @@ fn test_op_checkmultisig_bad_order() { "OP_2 OP_DATA_65 0x04D81FD577272BBE73308C93009EEC5DC9FC319FC1EE2E7066E17220A5D47A18314578BE2FAEA34B9F1F8CA078F8621ACD4BC22897B03DAA422B9BF56646B342A2 OP_DATA_65 0x04EC3AFFF0B2B66E8152E9018FE3BE3FC92B30BF886B3487A525997D00FD9DA2D012DCE5D5275854ADC3106572A5D1E12D4211B228429F5A7B2F7BA92EB0475BB1 OP_DATA_65 0x04B49B496684B02855BC32F5DAEFA2E2E406DB4418F3B86BCA5195600951C7D918CDBE5E6D3736EC2ABF2DD7610995C3086976B2C0C7B4E459D10B34A316D5A5E7 OP_3 OP_CHECKMULTISIG"; let mut transaction = mock_transaction_legacy_p2ms(script_sig); let mut engine = test_compile_and_run_with_tx_err( - script_pubkey, transaction, Error::SCRIPT_FAILED + script_pubkey, transaction, Error::SCRIPT_FAILED, ); check_dstack_size(ref engine, 1); let expected_stack = array![ScriptNum::wrap(0)]; @@ -464,7 +464,7 @@ fn test_op_checkmultisig_dummy_not_zero() { script_pubkey, transaction, ScriptFlags::ScriptStrictMultiSig.into(), - Error::SCRIPT_STRICT_MULTISIG + Error::SCRIPT_STRICT_MULTISIG, ); check_dstack_size(ref engine, 0); } diff --git a/packages/tests/src/tests/opcodes/test_disabled.cairo b/packages/tests/src/tests/opcodes/test_disabled.cairo index c62adbb0..e9dbd541 100644 --- a/packages/tests/src/tests/opcodes/test_disabled.cairo +++ b/packages/tests/src/tests/opcodes/test_disabled.cairo @@ -29,7 +29,7 @@ fn test_op_code_disabled() { let disabled_opcodes_len = disabled_opcodes.len(); while i != disabled_opcodes_len { let mut engine = utils::test_compile_and_run_err( - disabled_opcodes.at(i).clone(), Error::OPCODE_DISABLED + disabled_opcodes.at(i).clone(), Error::OPCODE_DISABLED, ); utils::check_dstack_size(ref engine, 0); i += 1; @@ -43,7 +43,7 @@ fn test_disabled_opcodes_if_block() { let disabled_opcodes_len = disabled_opcodes.len(); while i != disabled_opcodes_len { let program = format!( - "OP_1 OP_IF {} OP_ELSE OP_DROP OP_ENDIF", disabled_opcodes.at(i).clone() + "OP_1 OP_IF {} OP_ELSE OP_DROP OP_ENDIF", disabled_opcodes.at(i).clone(), ); let mut engine = utils::test_compile_and_run_err(program, Error::OPCODE_DISABLED); utils::check_dstack_size(ref engine, 0); @@ -58,7 +58,7 @@ fn test_disabled_opcodes_else_block() { let disabled_opcodes_len = disabled_opcodes.len(); while i != disabled_opcodes_len { let program = format!( - "OP_0 OP_IF OP_DROP OP_ELSE {} OP_ENDIF", disabled_opcodes.at(i).clone() + "OP_0 OP_IF OP_DROP OP_ELSE {} OP_ENDIF", disabled_opcodes.at(i).clone(), ); let mut engine = utils::test_compile_and_run_err(program, Error::OPCODE_DISABLED); utils::check_dstack_size(ref engine, 0); @@ -74,7 +74,7 @@ fn test_disabled_opcode_in_unexecd_if_block() { let disabled_opcodes_len = disabled_opcodes.len(); while i != disabled_opcodes_len { let program = format!( - "OP_0 OP_IF {} OP_ELSE OP_DROP OP_ENDIF", disabled_opcodes.at(i).clone() + "OP_0 OP_IF {} OP_ELSE OP_DROP OP_ENDIF", disabled_opcodes.at(i).clone(), ); let mut engine = utils::test_compile_and_run_err(program, Error::OPCODE_DISABLED); utils::check_dstack_size(ref engine, 0); diff --git a/packages/tests/src/tests/opcodes/test_locktime.cairo b/packages/tests/src/tests/opcodes/test_locktime.cairo index 91f837cf..5ac643cb 100644 --- a/packages/tests/src/tests/opcodes/test_locktime.cairo +++ b/packages/tests/src/tests/opcodes/test_locktime.cairo @@ -21,7 +21,7 @@ fn test_opcode_checklocktime_unsatisfied_fail() { let flags: u32 = ScriptFlags::ScriptVerifyCheckLockTimeVerify.into(); let mut engine = utils::test_compile_and_run_with_tx_flags_err( - program, tx, flags, Error::UNSATISFIED_LOCKTIME + program, tx, flags, Error::UNSATISFIED_LOCKTIME, ); utils::check_dstack_size(ref engine, 1); } @@ -62,7 +62,7 @@ fn test_opcode_checklocktime_as_op_nop_fail() { // 'ScriptDiscourageUpgradableNops' prevents to have OP_NOP behavior let flags: u32 = ScriptFlags::ScriptDiscourageUpgradableNops.into(); let mut engine = utils::test_compile_and_run_with_tx_flags_err( - program, tx, flags, Error::SCRIPT_DISCOURAGE_UPGRADABLE_NOPS + program, tx, flags, Error::SCRIPT_DISCOURAGE_UPGRADABLE_NOPS, ); utils::check_dstack_size(ref engine, 1); } @@ -77,7 +77,7 @@ fn test_opcode_checklocktime_max_sequence_fail() { let flags: u32 = ScriptFlags::ScriptVerifyCheckLockTimeVerify.into(); let mut engine = utils::test_compile_and_run_with_tx_flags_err( - program, tx, flags, Error::FINALIZED_TX_CLTV + program, tx, flags, Error::FINALIZED_TX_CLTV, ); utils::check_dstack_size(ref engine, 1); } @@ -112,7 +112,7 @@ fn test_opcode_checksequence_fail() { let flags: u32 = ScriptFlags::ScriptVerifyCheckSequenceVerify.into(); let mut engine = utils::test_compile_and_run_with_tx_flags_err( - program, tx, flags, Error::UNSATISFIED_LOCKTIME + program, tx, flags, Error::UNSATISFIED_LOCKTIME, ); utils::check_dstack_size(ref engine, 1); } @@ -142,7 +142,7 @@ fn test_opcode_checksequence_as_op_nop_fail() { // 'ScriptDiscourageUpgradableNops' prevents to have OP_NOP behavior let flags: u32 = ScriptFlags::ScriptDiscourageUpgradableNops.into(); let mut engine = utils::test_compile_and_run_with_tx_flags_err( - program, tx, flags, Error::SCRIPT_DISCOURAGE_UPGRADABLE_NOPS + program, tx, flags, Error::SCRIPT_DISCOURAGE_UPGRADABLE_NOPS, ); utils::check_dstack_size(ref engine, 1); } @@ -156,7 +156,7 @@ fn test_opcode_checksequence_tx_version_fail() { // Running with tx v1 let flags: u32 = ScriptFlags::ScriptVerifyCheckSequenceVerify.into(); let mut engine = utils::test_compile_and_run_with_tx_flags_err( - program, tx, flags, Error::UNSATISFIED_LOCKTIME + program, tx, flags, Error::UNSATISFIED_LOCKTIME, ); utils::check_dstack_size(ref engine, 1); } @@ -180,7 +180,7 @@ fn test_opcode_checksequence_disabled_bit_tx_fail() { // Run with tx v1 let flags: u32 = ScriptFlags::ScriptVerifyCheckSequenceVerify.into(); let mut engine = utils::test_compile_and_run_with_tx_flags_err( - program, tx, flags, Error::UNSATISFIED_LOCKTIME + program, tx, flags, Error::UNSATISFIED_LOCKTIME, ); utils::check_dstack_size(ref engine, 1); } diff --git a/packages/tests/src/tests/opcodes/test_stack.cairo b/packages/tests/src/tests/opcodes/test_stack.cairo index f0a96f78..53ec571c 100644 --- a/packages/tests/src/tests/opcodes/test_stack.cairo +++ b/packages/tests/src/tests/opcodes/test_stack.cairo @@ -119,7 +119,7 @@ fn test_op_swap_mid() { ScriptNum::wrap(3), ScriptNum::wrap(2), ScriptNum::wrap(4), - ScriptNum::wrap(5) + ScriptNum::wrap(5), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } @@ -153,7 +153,7 @@ fn test_op_2dup() { let mut engine = utils::test_compile_and_run(program); utils::check_dstack_size(ref engine, 4); let expected_dstack = array![ - ScriptNum::wrap(1), ScriptNum::wrap(2), ScriptNum::wrap(1), ScriptNum::wrap(2) + ScriptNum::wrap(1), ScriptNum::wrap(2), ScriptNum::wrap(1), ScriptNum::wrap(2), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } @@ -169,7 +169,7 @@ fn test_op_3dup() { ScriptNum::wrap(3), ScriptNum::wrap(1), ScriptNum::wrap(2), - ScriptNum::wrap(3) + ScriptNum::wrap(3), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } @@ -180,7 +180,7 @@ fn test_op_2swap() { let mut engine = utils::test_compile_and_run(program); utils::check_dstack_size(ref engine, 4); let expected_dstack = array![ - ScriptNum::wrap(3), ScriptNum::wrap(4), ScriptNum::wrap(1), ScriptNum::wrap(2) + ScriptNum::wrap(3), ScriptNum::wrap(4), ScriptNum::wrap(1), ScriptNum::wrap(2), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } @@ -196,7 +196,7 @@ fn test_op_2swap_mid() { ScriptNum::wrap(1), ScriptNum::wrap(2), ScriptNum::wrap(5), - ScriptNum::wrap(6) + ScriptNum::wrap(6), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } @@ -231,7 +231,7 @@ fn test_op_pick_2() { let mut engine = utils::test_compile_and_run(program); utils::check_dstack_size(ref engine, 4); let expected_dstack = array![ - ScriptNum::wrap(1), ScriptNum::wrap(2), ScriptNum::wrap(3), ScriptNum::wrap(1) + ScriptNum::wrap(1), ScriptNum::wrap(2), ScriptNum::wrap(3), ScriptNum::wrap(1), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } @@ -272,7 +272,7 @@ fn test_op_2rot() { ScriptNum::wrap(5), ScriptNum::wrap(6), ScriptNum::wrap(1), - ScriptNum::wrap(2) + ScriptNum::wrap(2), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } @@ -357,7 +357,7 @@ fn test_opcode_2over() { ScriptNum::wrap(3), ScriptNum::wrap(4), ScriptNum::wrap(1), - ScriptNum::wrap(2) + ScriptNum::wrap(2), ]; utils::check_expected_dstack(ref engine, expected_dstack.span()); } diff --git a/packages/tests/src/tests/test_coinbase.cairo b/packages/tests/src/tests/test_coinbase.cairo index 4b4523c5..1eb8dc03 100644 --- a/packages/tests/src/tests/test_coinbase.cairo +++ b/packages/tests/src/tests/test_coinbase.cairo @@ -5,19 +5,19 @@ use shinigami_utils::bytecode::hex_to_bytecode; fn test_block_subsidy_calculation() { assert( EngineInternalTransactionTrait::calculate_block_subsidy(0) == 5000000000, - 'Incorrect genesis subsidy' + 'Incorrect genesis subsidy', ); assert( EngineInternalTransactionTrait::calculate_block_subsidy(210000) == 2500000000, - 'Incorrect halving subsidy' + 'Incorrect halving subsidy', ); assert( EngineInternalTransactionTrait::calculate_block_subsidy(420000) == 1250000000, - 'Incorrect 2nd halving subsidy' + 'Incorrect 2nd halving subsidy', ); assert( EngineInternalTransactionTrait::calculate_block_subsidy(13440000) == 0, - 'Should be 0 after 64 halvings' + 'Should be 0 after 64 halvings', ); } @@ -30,7 +30,7 @@ fn test_validate_coinbase_block_0() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(0, 5000000000).is_ok(), - "Genesis block coinbase transaction invalid" + "Genesis block coinbase transaction invalid", ); } @@ -42,7 +42,8 @@ fn test_validate_coinbase_block_1() { let raw_transaction = hex_to_bytecode(@raw_transaction_hex); let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( - transaction.validate_coinbase(1, 5000000000).is_ok(), "Block 1 coinbase transaction invalid" + transaction.validate_coinbase(1, 5000000000).is_ok(), + "Block 1 coinbase transaction invalid", ); } @@ -55,7 +56,7 @@ fn test_validate_coinbase_block_150007() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(150007, 350000).is_ok(), - "Block 150007 coinbase transaction invalid" + "Block 150007 coinbase transaction invalid", ); } @@ -68,7 +69,7 @@ fn test_validate_coinbase_block_227835() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(227835, 6050010).is_ok(), - "Block 227835 coinbase transaction invalid" + "Block 227835 coinbase transaction invalid", ); } @@ -81,7 +82,7 @@ fn test_validate_coinbase_block_227836() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(227836, 6260000).is_ok(), - "Block 227836 coinbase transaction invalid" + "Block 227836 coinbase transaction invalid", ); } @@ -94,7 +95,7 @@ fn test_validate_coinbase_block_400021() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(400021, 1166059).is_ok(), - "Block 400021 coinbase transaction invalid" + "Block 400021 coinbase transaction invalid", ); } @@ -107,7 +108,7 @@ fn test_validate_coinbase_block_481823() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(481823, 311039505).is_ok(), - "Block 481823 coinbase transaction invalid" + "Block 481823 coinbase transaction invalid", ); } @@ -121,7 +122,7 @@ fn test_validate_coinbase_block_481824() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(481824, 212514269).is_ok(), - "Block 481824 coinbase transaction invalid" + "Block 481824 coinbase transaction invalid", ); } @@ -135,7 +136,7 @@ fn test_validate_coinbase_block_538403() { let transaction = EngineInternalTransactionTrait::deserialize(raw_transaction); assert!( transaction.validate_coinbase(538403, 6517).is_ok(), - "Block 538403 coinbase transaction invalid" + "Block 538403 coinbase transaction invalid", ); } // TODO: Test invalid coinbase diff --git a/packages/tests/src/tests/test_p2ms.cairo b/packages/tests/src/tests/test_p2ms.cairo index 1d0f53d6..36dcef96 100644 --- a/packages/tests/src/tests/test_p2ms.cairo +++ b/packages/tests/src/tests/test_p2ms.cairo @@ -10,7 +10,7 @@ fn test_p2ms_1_of_2() { let prevout_pk_script = "0x514104cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4410461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af52ae"; let prev_out = UTXO { - amount: 1000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 164467 + amount: 1000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 164467, }; let raw_transaction_hex = @@ -33,7 +33,7 @@ fn test_p2ms_2_of_3() { let prevout_pk_script = "0x52410496ec45f878b62c46c4be8e336dff7cc58df9b502178cc240eb3d31b1266f69f5767071aa3e017d1b82a0bb28dab5e27d4d8e9725b3e68ed5f8a2d45c730621e34104cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4410461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af53ae"; let prev_out = UTXO { - amount: 1000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 165227 + amount: 1000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 165227, }; let raw_transaction_hex = @@ -53,7 +53,7 @@ fn test_p2ms_3_of_3() { let prevout_pk_script = "0x534104c46d6462f67f990211d3a7077f005e67154f5f785b3edc06af3de62649a15bad35905fa7af9f272f80379a41525ad57a2245c2edc4807e3e49f43eb1c1b119794104cc71eb30d653c0c3163990c47b976f3fb3f37cccdcbedb169a1dfef58bbfbfaff7d8a473e7e2e6d317b87bafe8bde97e3cf8f065dec022b51d11fcdd0d348ac4410461cbdcc5409fb4b4d42b51d33381354d80e550078cb532a34bfa2fcfdeb7d76519aecc62770f5b0e4ef8551946d8a540911abe3e7854a26f39f58b25c15342af53ae"; let prev_out = UTXO { - amount: 50000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 165224 + amount: 50000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 165224, }; let raw_transaction_hex = @@ -75,7 +75,7 @@ fn test_p2ms_1of2_invalid_pubkey() { let prev_out_1of2_invalid = UTXO { amount: 92750000, pubkey_script: hex_to_bytecode(@prevout_pk_script_1of2_invalid), - block_height: 229517 + block_height: 229517, }; let raw_transaction_hex = @@ -95,7 +95,7 @@ fn test_p2ms_2_of_3_random() { let prevout_pk_script = "0x524104d81fd577272bbe73308c93009eec5dc9fc319fc1ee2e7066e17220a5d47a18314578be2faea34b9f1f8ca078f8621acd4bc22897b03daa422b9bf56646b342a24104ec3afff0b2b66e8152e9018fe3be3fc92b30bf886b3487a525997d00fd9da2d012dce5d5275854adc3106572a5d1e12d4211b228429f5a7b2f7ba92eb0475bb14104b49b496684b02855bc32f5daefa2e2e406db4418f3b86bca5195600951c7d918cdbe5e6d3736ec2abf2dd7610995c3086976b2c0c7b4e459d10b34a316d5a5e753ae"; let prev_out = UTXO { - amount: 1690000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 442241 + amount: 1690000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 442241, }; let raw_transaction_hex = @@ -115,7 +115,7 @@ fn test_p2ms_1_of_1() { let prevout_pk_script = "0x51210281feb90c058c3436f8bc361930ae99fcfb530a699cdad141d7244bfcad521a1f51ae"; let prev_out = UTXO { - amount: 20000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 431077 + amount: 20000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 431077, }; let raw_transaction_hex = @@ -135,7 +135,7 @@ fn test_p2ms_20_of_20() { let prevout_pk_script = "0x0114410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455410478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc34550114ae"; let prev_out = UTXO { - amount: 2201000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 284029 + amount: 2201000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 284029, }; let raw_transaction_hex = diff --git a/packages/tests/src/tests/test_p2pk.cairo b/packages/tests/src/tests/test_p2pk.cairo index 9db9ed58..641c298c 100644 --- a/packages/tests/src/tests/test_p2pk.cairo +++ b/packages/tests/src/tests/test_p2pk.cairo @@ -10,7 +10,7 @@ fn test_compressed_pubkey() { let prevout_pk_script = "0x2103203b768951584fe9af6d9d9e6ff26a5f76e453212f19ba163774182ab8057f3eac"; let prev_out = UTXO { - amount: 2700, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 606376 + amount: 2700, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 606376, }; let raw_transaction_hex = "0x0100000001475948774538830c533ad43cd5cd9a241a72569679e5f0474e670f466c81b83d00000000494830450221009c31a8561a3e422211e72242170d63d5d420398629475b48925720b4ba5b064202201b72633207c17b6129b9fee23247f48a11eb656c1ca4c50c828e4fdbf881be6301ffffffff0160090000000000001976a91474d03dbb59f75ff54ee97dadf221d74a48c3b52288ac00000000"; @@ -28,7 +28,7 @@ fn test_block_181_tx_mainnet() { let prevout_pk_script = "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; let prev_out = UTXO { - amount: 4000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170 + amount: 4000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 170, }; let raw_transaction_hex = "0x0100000001169e1e83e930853391bc6f35f605c6754cfead57cf8387639d3b4096c54f18f40100000048473044022027542a94d6646c51240f23a76d33088d3dd8815b25e9ea18cac67d1171a3212e02203baf203c6e7b80ebd3e588628466ea28be572fe1aaa3f30947da4763dd3b3d2b01ffffffff0200ca9a3b00000000434104b5abd412d4341b45056d3e376cd446eca43fa871b51961330deebd84423e740daa520690e1d9e074654c59ff87b408db903649623e86f1ca5412786f61ade2bfac005ed0b20000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; @@ -46,7 +46,7 @@ fn test_block_182_tx_mainnet() { let prevout_pk_script = "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; let prev_out = UTXO { - amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 181 + amount: 3000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 181, }; let raw_transaction_hex = "0x0100000001be141eb442fbc446218b708f40caeb7507affe8acff58ed992eb5ddde43c6fa1010000004847304402201f27e51caeb9a0988a1e50799ff0af94a3902403c3ad4068b063e7b4d1b0a76702206713f69bd344058b0dee55a9798759092d0916dbbc3e592fee43060005ddc17401ffffffff0200e1f5050000000043410401518fa1d1e1e3e162852d68d9be1c0abad5e3d6297ec95f1f91b909dc1afe616d6876f92918451ca387c4387609ae1a895007096195a824baf9c38ea98c09c3ac007ddaac0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000"; @@ -68,13 +68,13 @@ fn test_block_496_tx_mainnet() { let prevout_pk_script_3 = "0x4104bed827d37474beffb37efe533701ac1f7c600957a4487be8b371346f016826ee6f57ba30d88a472a0e4ecd2f07599a795f1f01de78d791b382e65ee1c58b4508ac"; let prev_out = UTXO { - amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 360 + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 360, }; let prev_out2 = UTXO { - amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 187 + amount: 1000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 187, }; let prev_out3 = UTXO { - amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248 + amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_3), block_height: 248, }; let raw_transaction_hex = diff --git a/packages/tests/src/tests/test_p2pkh.cairo b/packages/tests/src/tests/test_p2pkh.cairo index cbbe11b2..6b7fe6b9 100644 --- a/packages/tests/src/tests/test_p2pkh.cairo +++ b/packages/tests/src/tests/test_p2pkh.cairo @@ -15,12 +15,14 @@ fn test_p2pkh_transaction() { let prevout_pk_script_1 = "0x4104c9560dc538db21476083a5c65a34c7cc219960b1e6f27a87571cd91edfd00dac16dca4b4a7c4ab536f85bc263b3035b762c5576dc6772492b8fb54af23abff6dac"; let prevout_1 = UTXO { - amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_1), block_height: 509 + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_1), block_height: 509, }; let prevout_pk_script_2 = "0x41043987a76015929873f06823f4e8d93abaaf7bcf55c6a564bed5b7f6e728e6c4cb4e2c420fe14d976f7e641d8b791c652dfeee9da584305ae544eafa4f7be6f777ac"; let prevout_2 = UTXO { - amount: 50000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), block_height: 357 + amount: 50000000000, + pubkey_script: hex_to_bytecode(@prevout_pk_script_2), + block_height: 357, }; let utxo_hints = array![prevout_1, prevout_2]; @@ -46,19 +48,19 @@ fn test_p2pkh_transaction_spend() { let prev_out0 = UTXO { amount: 5003000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_0), - block_height: 12983 + block_height: 12983, }; let prev_out1 = UTXO { amount: 10000000000, pubkey_script: hex_to_bytecode(@prevout_pkh_script_1), - block_height: 728 + block_height: 728, }; let prev_out2 = UTXO { amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script_2), - block_height: 17233 + block_height: 17233, }; let utxo_hints = array![prev_out0, prev_out1, prev_out2]; @@ -85,7 +87,9 @@ fn test_block_770000_p2pkh_transaction() { let prevout_pk_script = "0x76a9140900bb14c7cb6a52fd8a22fd68a5986eb193c9f588ac"; let prevout = UTXO { - amount: 8734850959, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 769998 + amount: 8734850959, + pubkey_script: hex_to_bytecode(@prevout_pk_script), + block_height: 769998, }; let utxo_hints = array![prevout]; @@ -103,7 +107,9 @@ fn test_block_770002_p2pkh_transaction() { let prevout_pk_script = "0x76a9149ee1cd0c085b88bd7b22e44abe52734e0a61c94288ac"; let prevout = UTXO { - amount: 8729850284, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 769998 + amount: 8729850284, + pubkey_script: hex_to_bytecode(@prevout_pk_script), + block_height: 769998, }; let utxo_hints = array![prevout]; diff --git a/packages/tests/src/tests/test_p2sh.cairo b/packages/tests/src/tests/test_p2sh.cairo index b85093a4..e2f42dd3 100644 --- a/packages/tests/src/tests/test_p2sh.cairo +++ b/packages/tests/src/tests/test_p2sh.cairo @@ -17,7 +17,7 @@ fn test_p2sh_transaction_1() { let prevout_pubkey = "0xa914748284390f9e263a4b766a75d0633c50426eb87587"; let prev_out_1of2_invalid = UTXO { - amount: 10000000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 177625 + amount: 10000000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 177625, }; let flags: u32 = ScriptFlags::ScriptBip16.into(); @@ -36,7 +36,7 @@ fn test_p2sh_transaction_2() { let prevout_pubkey = "0xa914e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a87"; let prev_out_1of2_invalid = UTXO { - amount: 990000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 272295 + amount: 990000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 272295, }; let utxo_hints = array![prev_out_1of2_invalid]; @@ -57,7 +57,7 @@ fn test_p2sh_transaction_3() { let prevout_pubkey = "0xa914748284390f9e263a4b766a75d0633c50426eb87587"; let prev_out = UTXO { - amount: 10000000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 183729 + amount: 10000000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 183729, }; let flags: u32 = ScriptFlags::ScriptBip16.into(); @@ -77,7 +77,7 @@ fn test_p2sh_transaction_4() { let prevout_pubkey = "0xa914b4acb9d78d6a6256964a60484c95de490eaaae7587"; let prev_out = UTXO { - amount: 9980000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 232593 + amount: 9980000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 232593, }; let utxo_hints = array![prev_out]; @@ -98,7 +98,7 @@ fn test_p2sh_transaction_5() { let prevout_pubkey = "0xa914da5a92e670a66538be1c550af352646000b2367d87"; let prev_out = UTXO { - amount: 10000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 384639 + amount: 10000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 384639, }; let utxo_hints = array![prev_out]; @@ -118,7 +118,7 @@ fn test_p2sh_transaction_6() { let prevout_pubkey = "0xa9144266fc6f2c2861d7fe229b279a79803afca7ba3487"; let prev_out = UTXO { - amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 257797 + amount: 100000000, pubkey_script: hex_to_bytecode(@prevout_pubkey), block_height: 257797, }; let flags: u32 = ScriptFlags::ScriptBip16.into(); diff --git a/packages/tests/src/tests/test_p2wpkh.cairo b/packages/tests/src/tests/test_p2wpkh.cairo index 7bebe819..7638e28c 100644 --- a/packages/tests/src/tests/test_p2wpkh.cairo +++ b/packages/tests/src/tests/test_p2wpkh.cairo @@ -14,7 +14,7 @@ fn test_p2wpkh_create_transaction() { let prevout_script = "0x0014841b80d2cc75f5345c482af96294d04fdd66b2b7"; let prevout = UTXO { - amount: 2595489, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 680226 + amount: 2595489, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 680226, }; let utxo_hints = array![prevout]; @@ -34,7 +34,7 @@ fn test_p2wpkh_unlock_transaction() { let prevout_script = "0x0014841b80d2cc75f5345c482af96294d04fdd66b2b7"; let prevout = UTXO { - amount: 1083200, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 681995 + amount: 1083200, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 681995, }; let utxo_hints = array![prevout]; @@ -54,7 +54,7 @@ fn test_p2wpkh_first_transaction() { let prevout_script = "0xa914811ee2fb2d0c96b478992e1c07320b253ef3ee2687"; let prevout = UTXO { - amount: 224000, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 481819 + amount: 224000, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 481819, }; let utxo_hints = array![prevout]; @@ -74,7 +74,7 @@ fn test_p2wpkh_first_witness_spend() { let prevout_script = "0x00148d7a0a3461e3891723e5fdf8129caa0075060cff"; let prevout = UTXO { - amount: 194300, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 481824 + amount: 194300, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 481824, }; let utxo_hints = array![prevout]; let flags: u32 = ScriptFlags::ScriptVerifyWitness.into() | ScriptFlags::ScriptBip16.into(); @@ -93,7 +93,7 @@ fn test_p2wpkh_uncompressed_key_scriptpubkey_validation() { let prevout_script = "0x76a9149acd0fbc308ea273b61bad6322a17c8a7694845d88ac"; let prevout = UTXO { - amount: 100000, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 801368 + amount: 100000, pubkey_script: hex_to_bytecode(@prevout_script), block_height: 801368, }; let utxo_hints = array![prevout]; diff --git a/packages/tests/src/tests/test_p2wsh.cairo b/packages/tests/src/tests/test_p2wsh.cairo index 4d0bfce7..bcda93e7 100644 --- a/packages/tests/src/tests/test_p2wsh.cairo +++ b/packages/tests/src/tests/test_p2wsh.cairo @@ -82,7 +82,7 @@ fn test_custom_hash_puzzle() { let prevout_pk_script = "0x0020ee4fd29ce2f9ca8411778f8e94687d5e75ec3e86cc530ca9ad1787e5208cc996"; let prev_out = UTXO { - amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087 + amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087, }; let raw_transaction_hex = @@ -102,7 +102,7 @@ fn test_custom_hash_puzzle_invalid_unlock_code() { let prevout_pk_script = "0x0020ee4fd29ce2f9ca8411778f8e94687d5e75ec3e86cc530ca9ad1787e5208cc996"; let prev_out = UTXO { - amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087 + amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087, }; // replace unlock code 1234 by 2345 @@ -125,7 +125,7 @@ fn test_custom_hash_puzzle_wrong_hash_script_in_pubkey_script() { let prevout_pk_script = "0x0020fe4fd29ce2f9ca8411778f8e94687d5e75ec3e86cc530ca9ad1787e5208cc996"; let prev_out = UTXO { - amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087 + amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087, }; let raw_transaction_hex = @@ -146,7 +146,7 @@ fn test_custom_hash_puzzle_different_witness_script_from_hash() { let prevout_pk_script = "0x0020ee4fd29ce2f9ca8411778f8e94687d5e75ec3e86cc530ca9ad1787e5208cc996"; let prev_out = UTXO { - amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087 + amount: 30000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 802087, }; // original witness script diff --git a/packages/tests/src/tests/test_transactions.cairo b/packages/tests/src/tests/test_transactions.cairo index f9ce9b04..29e945af 100644 --- a/packages/tests/src/tests/test_transactions.cairo +++ b/packages/tests/src/tests/test_transactions.cairo @@ -26,11 +26,11 @@ fn test_deserialize_transaction() { assert_eq!( input0.previous_outpoint.txid, @u256_from_byte_array_with_offset(@expected_txid, 0, 32), - "Outpoint txid on input 1 is not correct" + "Outpoint txid on input 1 is not correct", ); assert_eq!(input0.previous_outpoint.vout, @0, "Outpoint vout on input 1 is not correct"); assert_eq!( - input0.signature_script, @expected_sig_script, "Script sig on input 1 is not correct" + input0.signature_script, @expected_sig_script, "Script sig on input 1 is not correct", ); assert_eq!(input0.sequence, @0xFFFFFFFF, "Sequence on input 1 is not correct"); @@ -43,11 +43,11 @@ fn test_deserialize_transaction() { assert_eq!( input1.previous_outpoint.txid, @u256_from_byte_array_with_offset(@expected_txid, 0, 32), - "Outpoint txid on input 2 is not correct" + "Outpoint txid on input 2 is not correct", ); assert_eq!(input1.previous_outpoint.vout, @0, "Outpoint vout on input 2 is not correct"); assert_eq!( - input1.signature_script, @expected_sig_script, "Script sig on input 2 is not correct" + input1.signature_script, @expected_sig_script, "Script sig on input 2 is not correct", ); assert_eq!(input1.sequence, @0xFFFFFFFF, "Sequence on input 2 is not correct"); @@ -87,11 +87,11 @@ fn test_deserialize_first_p2pkh_transaction() { assert_eq!( input0.previous_outpoint.txid, @u256_from_byte_array_with_offset(@expected_txid, 0, 32), - "Outpoint txid on input 1 is not correct" + "Outpoint txid on input 1 is not correct", ); assert_eq!(input0.previous_outpoint.vout, @0, "Outpoint vout on input 1 is not correct"); assert_eq!( - input0.signature_script, @expected_sig_script, "Script sig on input 1 is not correct" + input0.signature_script, @expected_sig_script, "Script sig on input 1 is not correct", ); assert_eq!(input0.sequence, @0xFFFFFFFF, "Sequence on input 1 is not correct"); @@ -104,11 +104,11 @@ fn test_deserialize_first_p2pkh_transaction() { assert_eq!( input1.previous_outpoint.txid, @u256_from_byte_array_with_offset(@expected_txid, 0, 32), - "Outpoint txid on input 2 is not correct" + "Outpoint txid on input 2 is not correct", ); assert_eq!(input1.previous_outpoint.vout, @0, "Outpoint vout on input 2 is not correct"); assert_eq!( - input1.signature_script, @expected_sig_script, "Script sig on input 2 is not correct" + input1.signature_script, @expected_sig_script, "Script sig on input 2 is not correct", ); assert_eq!(input1.sequence, @0xFFFFFFFF, "Sequence on input 2 is not correct"); @@ -142,10 +142,10 @@ fn test_deserialize_first_p2sh_transaction() { assert_eq!( input0.previous_outpoint.txid, @u256_from_byte_array_with_offset(@expected_txid, 0, 32), - "Outpoint txid on input 2 is not correct" + "Outpoint txid on input 2 is not correct", ); assert_eq!( - input0.signature_script, @expected_sig_script, "Script sig on input 1 is not correct" + input0.signature_script, @expected_sig_script, "Script sig on input 1 is not correct", ); let output0 = transaction.transaction_outputs[0]; @@ -154,7 +154,7 @@ fn test_deserialize_first_p2sh_transaction() { assert_eq!(output0.value, @1738699, "Output 1 value is not correct"); assert_eq!( - output0.publickey_script, @expected_pk_script_0, "Output 1 pk_script is not correct" + output0.publickey_script, @expected_pk_script_0, "Output 1 pk_script is not correct", ); let output1 = transaction.transaction_outputs[1]; @@ -163,7 +163,7 @@ fn test_deserialize_first_p2sh_transaction() { assert_eq!(output1.value, @10000000, "Output 2 value is not correct"); assert_eq!( - output1.publickey_script, @expected_pk_script_1, "Output 2 pk_script is not correct" + output1.publickey_script, @expected_pk_script_1, "Output 2 pk_script is not correct", ); assert_eq!(transaction.locktime, 0, "Lock time is not correct"); @@ -192,7 +192,7 @@ fn test_deserialize_p2wsh_transaction() { assert_eq!( input0.previous_outpoint.txid, @u256_from_byte_array_with_offset(@expected_txid, 0, 32), - "Outpoint txid on input 1 is not correct" + "Outpoint txid on input 1 is not correct", ); assert_eq!(input0.signature_script.len(), 0, "Script sig on input 1 is not empty"); assert_eq!(input0.witness.len(), 2, "Witness length on input 1 is not correct"); @@ -227,7 +227,7 @@ fn test_deserialize_p2wpkh_transaction() { assert_eq!( input0.previous_outpoint.txid, @u256_from_byte_array_with_offset(@expected_txid, 0, 32), - "Outpoint txid on input 0 is incorrect" + "Outpoint txid on input 0 is incorrect", ); assert_eq!(input0.signature_script.len(), 0, "Signature script on input 0 should be empty"); @@ -278,7 +278,7 @@ fn test_validate_transaction() { let prevout_pk_script = "0x410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"; let prev_out = UTXO { - amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 9 + amount: 5000000000, pubkey_script: hex_to_bytecode(@prevout_pk_script), block_height: 9, }; let utxo_hints = array![prev_out]; diff --git a/packages/tests/src/utils.cairo b/packages/tests/src/utils.cairo index ecc9c8d7..65a5247b 100644 --- a/packages/tests/src/utils.cairo +++ b/packages/tests/src/utils.cairo @@ -2,7 +2,7 @@ use shinigami_compiler::compiler::CompilerImpl; use shinigami_engine::engine::{Engine, EngineImpl, EngineInternalTrait}; use shinigami_engine::hash_cache::HashCacheImpl; use shinigami_engine::transaction::{ - EngineTransaction, EngineTransactionInput, EngineTransactionOutput, EngineOutPoint + EngineTransaction, EngineTransactionInput, EngineTransactionOutput, EngineOutPoint, }; // Runs a basic bitcoin script as the script_pubkey with empty script_sig @@ -19,7 +19,7 @@ pub fn test_compile_and_run(program: ByteArray) -> Engine { // Runs a bitcoin script `program` as script_pubkey with corresponding `transaction` pub fn test_compile_and_run_with_tx( - program: ByteArray, transaction: EngineTransaction + program: ByteArray, transaction: EngineTransaction, ) -> Engine { let mut compiler = CompilerImpl::new(); let mut bytecode = compiler.compile(program).unwrap(); @@ -32,7 +32,7 @@ pub fn test_compile_and_run_with_tx( // Runs a bitcoin script `program` as script_pubkey with corresponding `transaction` and 'flags' pub fn test_compile_and_run_with_tx_flags( - program: ByteArray, transaction: EngineTransaction, flags: u32 + program: ByteArray, transaction: EngineTransaction, flags: u32, ) -> Engine { let mut compiler = CompilerImpl::new(); let mut bytecode = compiler.compile(program).unwrap(); @@ -45,7 +45,7 @@ pub fn test_compile_and_run_with_tx_flags( // Runs a bitcoin script `program` as script_pubkey with empty script_sig expecting an error pub fn test_compile_and_run_err( - program: ByteArray, expected_err: felt252 + program: ByteArray, expected_err: felt252, ) -> Engine { let mut compiler = CompilerImpl::new(); let bytecode = compiler.compile(program).unwrap(); @@ -61,7 +61,7 @@ pub fn test_compile_and_run_err( // Runs a bitcoin script `program` as script_pubkey with corresponding `transaction` expecting an // error pub fn test_compile_and_run_with_tx_err( - program: ByteArray, transaction: EngineTransaction, expected_err: felt252 + program: ByteArray, transaction: EngineTransaction, expected_err: felt252, ) -> Engine { let mut compiler = CompilerImpl::new(); let mut bytecode = compiler.compile(program).unwrap(); @@ -77,7 +77,7 @@ pub fn test_compile_and_run_with_tx_err( // Runs a bitcoin script `program` as script_pubkey with corresponding `transaction` and 'flags' // expecting an error pub fn test_compile_and_run_with_tx_flags_err( - program: ByteArray, transaction: EngineTransaction, flags: u32, expected_err: felt252 + program: ByteArray, transaction: EngineTransaction, flags: u32, expected_err: felt252, ) -> Engine { let mut compiler = CompilerImpl::new(); let mut bytecode = compiler.compile(program).unwrap(); @@ -111,7 +111,7 @@ pub fn check_expected_astack(ref engine: Engine, expected: Sp } pub fn mock_transaction_input_with( - outpoint: EngineOutPoint, script_sig: ByteArray, witness: Array, sequence: u32 + outpoint: EngineOutPoint, script_sig: ByteArray, witness: Array, sequence: u32, ) -> EngineTransactionInput { let mut compiler = CompilerImpl::new(); let script_sig = compiler.compile(script_sig).unwrap(); @@ -119,19 +119,19 @@ pub fn mock_transaction_input_with( previous_outpoint: outpoint, signature_script: script_sig, witness: witness, - sequence: sequence + sequence: sequence, } } pub fn mock_transaction_input(script_sig: ByteArray) -> EngineTransactionInput { let outpoint: EngineOutPoint = EngineOutPoint { - txid: 0xb7994a0db2f373a29227e1d90da883c6ce1cb0dd2d6812e4558041ebbbcfa54b, vout: 0 + txid: 0xb7994a0db2f373a29227e1d90da883c6ce1cb0dd2d6812e4558041ebbbcfa54b, vout: 0, }; mock_transaction_input_with(outpoint, script_sig, ArrayTrait::new(), 0xffffffff) } pub fn mock_transaction_output_with( - value: i64, script_pubkey: ByteArray + value: i64, script_pubkey: ByteArray, ) -> EngineTransactionOutput { EngineTransactionOutput { value: value, publickey_script: script_pubkey } } @@ -148,7 +148,7 @@ pub fn mock_transaction_with( version: i32, tx_inputs: Array, tx_outputs: Array, - locktime: u32 + locktime: u32, ) -> EngineTransaction { EngineTransaction { version: version, @@ -177,7 +177,7 @@ pub fn mock_transaction_legacy_p2pkh(script_sig: ByteArray) -> EngineTransaction // Legacy P2MS pub fn mock_transaction_legacy_p2ms(script_sig: ByteArray) -> EngineTransaction { let outpoint: EngineOutPoint = EngineOutPoint { - txid: 0x10a5fee9786a9d2d72c25525e52dd70cbd9035d5152fac83b62d3aa7e2301d58, vout: 0 + txid: 0x10a5fee9786a9d2d72c25525e52dd70cbd9035d5152fac83b62d3aa7e2301d58, vout: 0, }; let mut inputs = ArrayTrait::::new(); inputs.append(mock_transaction_input_with(outpoint, script_sig, ArrayTrait::new(), 0xffffffff)); @@ -194,16 +194,16 @@ pub fn mock_transaction_legacy_p2ms(script_sig: ByteArray) -> EngineTransaction pub fn mock_witness_transaction() -> EngineTransaction { let outpoint_0: EngineOutPoint = EngineOutPoint { - txid: 0xac4994014aa36b7f53375658ef595b3cb2891e1735fe5b441686f5e53338e76a, vout: 1 + txid: 0xac4994014aa36b7f53375658ef595b3cb2891e1735fe5b441686f5e53338e76a, vout: 1, }; let transaction_input_0: EngineTransactionInput = EngineTransactionInput { previous_outpoint: outpoint_0, signature_script: "", witness: ArrayTrait::::new(), - sequence: 0xffffffff + sequence: 0xffffffff, }; let mut transaction_inputs: Array = ArrayTrait::< - EngineTransactionInput + EngineTransactionInput, >::new(); transaction_inputs.append(transaction_input_0); let script_u256: u256 = 0x76a914ce72abfd0e6d9354a660c18f2825eb392f060fdc88ac; @@ -213,10 +213,10 @@ pub fn mock_witness_transaction() -> EngineTransaction { script_byte.append_word(script_u256.low.into(), 16); let output_0: EngineTransactionOutput = EngineTransactionOutput { - value: 15000, publickey_script: script_byte + value: 15000, publickey_script: script_byte, }; let mut transaction_outputs: Array = ArrayTrait::< - EngineTransactionOutput + EngineTransactionOutput, >::new(); transaction_outputs.append(output_0); @@ -240,7 +240,7 @@ pub fn mock_transaction_legacy_locktime(script_sig: ByteArray, locktime: u32) -> // Mock transaction version 2 with the specified 'sequence' pub fn mock_transaction_legacy_sequence_v2( - script_sig: ByteArray, sequence: u32 + script_sig: ByteArray, sequence: u32, ) -> EngineTransaction { let mut inputs = ArrayTrait::::new(); let outpoint = EngineOutPoint { txid: 0, vout: 0 }; diff --git a/packages/tests/src/validate.cairo b/packages/tests/src/validate.cairo index 05f7827c..db5283ab 100644 --- a/packages/tests/src/validate.cairo +++ b/packages/tests/src/validate.cairo @@ -9,7 +9,7 @@ use crate::utxo::UTXO; // TODO: Remove hints? // utxo_hints: Set of existing utxos that are being spent by this transaction pub fn validate_transaction( - tx: @EngineTransaction, flags: u32, utxo_hints: Array + tx: @EngineTransaction, flags: u32, utxo_hints: Array, ) -> Result<(), felt252> { let input_count = tx.transaction_inputs.len(); if input_count != utxo_hints.len() { @@ -23,7 +23,7 @@ pub fn validate_transaction( let hash_cache = HashCacheImpl::new(tx); // TODO: Error handling let mut engine = EngineImpl::new( - utxo.pubkey_script, tx, i, flags, *utxo.amount, @hash_cache + utxo.pubkey_script, tx, i, flags, *utxo.amount, @hash_cache, ) .unwrap(); let res = engine.execute(); @@ -42,11 +42,11 @@ pub fn validate_transaction( } pub fn validate_transaction_at( - tx: @EngineTransaction, flags: u32, prevout: UTXO, at: u32 + tx: @EngineTransaction, flags: u32, prevout: UTXO, at: u32, ) -> Result<(), felt252> { let hash_cache = HashCacheImpl::new(tx); let mut engine = EngineImpl::new( - @prevout.pubkey_script, tx, at, flags, prevout.amount, @hash_cache + @prevout.pubkey_script, tx, at, flags, prevout.amount, @hash_cache, ) .unwrap(); let res = engine.execute(); @@ -58,7 +58,7 @@ pub fn validate_transaction_at( } pub fn validate_p2ms( - tx: @EngineTransaction, flags: u32, utxo_hints: Array + tx: @EngineTransaction, flags: u32, utxo_hints: Array, ) -> Result<(), felt252> { // Check if the transaction has at least one input if tx.transaction_inputs.len() == 0 { diff --git a/packages/utils/src/bit_shifts.cairo b/packages/utils/src/bit_shifts.cairo index 4d7da56c..9b5d2355 100644 --- a/packages/utils/src/bit_shifts.cairo +++ b/packages/utils/src/bit_shifts.cairo @@ -23,9 +23,9 @@ pub fn shr< +PartialOrd, +PartialEq, +BitSize, - +Into + +Into, >( - self: T, shift: U + self: T, shift: U, ) -> T { if shift > BitSize::::bits().try_into().unwrap() - One::one() { return Zero::zero(); @@ -56,7 +56,7 @@ pub fn shl< +PartialOrd, +PartialEq, +BitSize, - +Into + +Into, >( self: T, shift: U, ) -> T { diff --git a/packages/utils/src/byte_array.cairo b/packages/utils/src/byte_array.cairo index e8c1de9f..a47e44f4 100644 --- a/packages/utils/src/byte_array.cairo +++ b/packages/utils/src/byte_array.cairo @@ -41,7 +41,7 @@ pub fn byte_array_value_at_be(byte_array: @ByteArray, ref offset: usize, len: us } pub fn byte_array_value_at_le( - byte_array: @ByteArray, ref offset: usize, len: usize + byte_array: @ByteArray, ref offset: usize, len: usize, ) -> felt252 { // TODO: Bounds check let byte_shift = 256; let mut value = 0; @@ -133,3 +133,12 @@ pub fn byte_array_to_bool(bytes: @ByteArray) -> bool { }; ret_bool } + +pub impl U256IntoByteArray of Into { + fn into(self: u256) -> ByteArray { + let mut ba = Default::default(); + ba.append_word(self.high.into(), 16); + ba.append_word(self.low.into(), 16); + ba + } +} diff --git a/packages/utils/src/maths.cairo b/packages/utils/src/maths.cairo index 3278ce34..d4f44b08 100644 --- a/packages/utils/src/maths.cairo +++ b/packages/utils/src/maths.cairo @@ -18,7 +18,7 @@ pub fn fast_power< +Drop, +PartialEq, >( - base: T, exp: U + base: T, exp: U, ) -> T { if exp == Zero::zero() { return One::one();