Skip to content

Commit

Permalink
fix: Impl changes
Browse files Browse the repository at this point in the history
  • Loading branch information
od-hunter committed Sep 6, 2024
1 parent da923db commit d5d7daa
Show file tree
Hide file tree
Showing 9 changed files with 615 additions and 99 deletions.
6 changes: 6 additions & 0 deletions Scarb.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,16 @@ version = "0.1.0"
edition = "2024_07"

[scripts]
<<<<<<< HEAD
regenerate_tests= "./scripts/data/regenerate_tests.sh"
integration_tests = "scarb build && ./scripts/data/integration_tests.sh"
light_client= "scarb build && ./scripts/data/light_client.sh"
test = "scarb cairo-test && scarb run integration_tests"
=======
get_block= "python3 ./scripts/data/get_block.py"
get_blocks= "./scripts/data/get_blocks.sh"
light_client= "./scripts/data/light_client.sh"
>>>>>>> 8ad0574 (feat: impl validate BIP-34 sig script)

[dependencies]

Expand Down
177 changes: 177 additions & 0 deletions scripts/data/get_block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import requests
import sys
import os
import json
import progressbar


BTC_RPC = os.getenv("BITCOIN_RPC")
USR = os.getenv("USERPWD")


def request_rpc(method, params):
payload = {
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": 0,
}
headers = {'content-type': 'application/json'}
data = requests.post(BTC_RPC, auth=tuple(USR.split(':')), headers=headers, data=json.dumps(payload)).json()
if data['result'] is None:
raise ConnectionError("Error recieving data")
return data['result']


def buid_witness(array):
witness = str(len(array))
for elem in array:
length = len(str(elem)) / 2
witness += f"{length}{elem}"
return witness


def header(block):
return f'''Header {{
version: {block["version"]}_u32,
time: {block["time"]}_u32,
bits: {int(block["bits"], 16)}_u32,
nonce: {block["nonce"]}_u32,
}}'''


def tx_output(tx):
payload = ""
cached = "false"
for txoutput in tx['vout']:
payload += f'''
TxOut {{
value: {int(txoutput["value"] * 100000000)}_u64,
pk_script: @from_hex(\"{txoutput["scriptPubKey"]["hex"]}\"),
cached: {cached},
}},
'''
return payload


def outpoint(prev_output):
# full_tx = request_rpc("gettxout", [tx_in["txid"], tx_in["vout"]])
prev_tx = request_rpc("getrawtransaction", [prev_output['txid'], True])
prev_block = request_rpc("getblock", [prev_tx['blockhash'], 2])
return f'''
OutPoint {{
txid: 0x{prev_tx['txid']}_u256.into(),
vout: {prev_output['vout']}_u32,
data: {tx_output({'vout': [prev_tx['vout'][prev_output['vout']]]})}
block_height: {prev_block['height']}_u32,
block_time: {prev_block['time']}_u32,
is_coinbase: {str(prev_tx['vin'][0].get('coinbase') is not None).lower()}
}}'''


def tx_input_coinbase(tx_in):
witness = ""
if 'txinwitness' in tx_in:
formatted_elements = [f'from_hex("{elem}")' for elem in tx_in["txinwitness"]]
witness = ", ".join(formatted_elements)
# witness = buid_witness(tx_in['txinwitness'])
return f'''
TxIn {{
script: @from_hex(\"{tx_in["coinbase"]}\"),
sequence: {tx_in["sequence"]},
witness: array![{witness}].span(),
previous_output: OutPoint {{
txid: 0_u256.into(),
vout: 0xffffffff_u32,
data: Default::default(),
block_height: Default::default(),
block_time: Default::default(),
is_coinbase: false,
}},
}}'''


def tx_input_regular(tx_in):
witness = ""
if 'txinwitness' in tx_in:
# witness = buid_witness(tx_in['txinwitness'])
formatted_elements = [f'from_hex("{elem}")' for elem in tx_in["txinwitness"]]
witness = ", ".join(formatted_elements)
return f'''
TxIn {{
script: @from_hex(\"{tx_in["scriptSig"]['hex']}\"),
sequence: {tx_in["sequence"]},
witness: array![{witness}].span(),
previous_output: {outpoint(tx_in)},
}},
'''


def tx_input(tx):
payload = ""
for txinput in tx['vin']:
if 'coinbase' in txinput:
payload += tx_input_coinbase(txinput)
else:
payload += tx_input_regular(txinput)
return payload


def check_segwit(tx):
hex = tx["hex"][8:12] # Skip the first 4 bytes (version) and take the next 4 bytes (marker + flag)
if hex == "0001":
return "true"
return "false"


def txs_process(txsraw, ntx):
payload = ''
bar = progressbar.ProgressBar(max_value=ntx)
bar.update(0)
for i, tx in enumerate(txsraw):
payload += f'''
Transaction {{
version: {tx["version"]},
is_segwit: {check_segwit(tx)},
lock_time: {tx["locktime"]},
inputs: array![{tx_input(tx)}].span(),
outputs: array![{tx_output(tx)}].span(),
}},
'''
bar.update(i + 1)
return payload


def main():
try:
if (len(sys.argv) != 2):
raise TypeError("Error: bad arguments")
block_hash = sys.argv[1]

block = request_rpc("getblock", [block_hash, 2])
txsraw = block["tx"]

file_payload = f'''// THIS CODE IS GENERATED BY SCRIPT, DO NOT EDIT IT MANUALLY
use raito::types::transaction::{{Transaction, TxIn, TxOut, OutPoint}};
use raito::types::block::{{Block, Header, TransactionData}};
use raito::utils::hex::from_hex;
// block_hash: {block_hash}
pub fn block_{block["height"]}() -> Block {{
Block {{
header: {header(block)},
data: TransactionData::Transactions(array![{txs_process(txsraw, block["nTx"])}].span()),
}}
}}'''

path = f'tests/blocks/block_{block["height"]}.cairo'
print(block["height"])
file = open(path, "w")
file.write(file_payload)
file.close()
except Exception as error:
print(error)


main()
43 changes: 43 additions & 0 deletions scripts/data/get_blocks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env bash
set -e;
set -o pipefail;

if [ -f .env ]
then
export $(cat .env | xargs)
fi

get_single_block() {
local block_hash=$1
python3 ./scripts/data/get_block.py "$block_hash"
}

main() {
local block_hashes=(
"00000000d1145790a8694403d4063f323d499e655c83426834d4ce2f8dd4a2ee" # Block containing first P2P tx to Hal Finney (170)
"00000000132fbe8314fc571c0be60b31ccd461c9ee85f42bde8c6d160a9dacc0" # Block containing first off ramp tx from Martti Malmi (24835)
"00000000152340ca42227603908689183edc47355204e7aca59383b0aaac1fd8" # Block containing pizza tx (57043)
"000000000000011f9791dcfdfe0e402b79a165a3b781bafcc918b6f2166d577c" # Small Block (150013)
"000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e" # First halving block (210000)
# "000000000000000002cce816c0ab2c5c269cb081896b7dcb34b8422d6b74ffa1" # Second halving block (420000)
# "0000000000000000011865af4122fe3b144e2cbeea86142e8ff2fb4107352d43" # Bitcoin Cash hard fork block (478558)
# "0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893" # Segwit soft fork block (481824)
# "000000000000000000e5438564434edaf41e63829a637521a96235adf4653e1b" # Bitcoin Gold hard fork block (491407)
# "000000000000000000024bead8df69990852c202db0e0097c1a12ea637d7e96d" # Third halving block (630000)
# "0000000000000000000687bca986194dc2c1f949318629b44bb54ec0a94d8244" # Taproot soft fort block (709632)
"00000000000000000002601c74946371bd1bf00ad3154f011c20abad1cabd0ea" # Block with witness (757739)
"000000000000000000032c781dbe11459fba50312acfca3cd96fa2bc4367d5b1" # Block with witnesses, 81txs (757753)
# "0000000000000000000515e202c8ae73c8155fc472422d7593af87aa74f2cf3d" # Biggest block in Bitcoin history - Taproot Wizards (774628)
# "0000000000000000000320283a032748cef8227873ff4872689bf23f1cda83a5" # Fourth halving block (840000)
)

# Loop through the block hashes and call get_block.sh for each
for block_hash in "${block_hashes[@]}"; do
echo "Getting block: $block_hash"
get_single_block "$block_hash"
done

echo "All blocks retrieved successfully."
}

main
54 changes: 54 additions & 0 deletions src/types/transaction.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,58 @@ impl TxOutDefault of Default<TxOut> {
// TODO: implement Hash trait for OutPoint (for creating hash digests to use in utreexo/utxo cache)
// Maybe we need to rename utils::hash::Hash (e.g. to Digest) to avoid confusion

#[cfg(test)]
mod tests {
use crate::utils::hex::{from_hex, hex_to_hash_rev};
use super::{Transaction, TransactionTrait, TxIn, TxOut, OutPoint};

#[test]
fn test_txid() {
let tx: Transaction = Transaction {
version: 1,
is_segwit: false,
inputs: array![
TxIn {
script: @from_hex(
"47304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901"
),
sequence: 0xffffffff,
previous_output: OutPoint {
txid: hex_to_hash_rev(
"0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9"
),
vout: 0x00000000,
data: Default::default(),
block_height: Default::default(),
block_time: Default::default(),
},
witness: array![].span(),
}
]
.span(),
outputs: array![
TxOut {
value: 0x000000003b9aca00,
pk_script: @from_hex(
"4104ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84cac"
),
cached: false,
},
TxOut {
value: 0x00000000ee6b2800,
pk_script: @from_hex(
"410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac"
),
cached: false,
}
]
.span(),
lock_time: 0
};

assert_eq!(
tx.txid(),
hex_to_hash_rev("f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16")
);
}
}
Loading

0 comments on commit d5d7daa

Please sign in to comment.