diff --git a/src/engine.cairo b/src/engine.cairo deleted file mode 100644 index 556fc702..00000000 --- a/src/engine.cairo +++ /dev/null @@ -1,181 +0,0 @@ -use core::result::Result; -use core::option::OptionTrait; -use core::traits::Into; -use core::byte_array::ByteArray; - -// Constants -const BLOCK_HEADER_SIZE: u32 = 80; -const MAX_BITS: u32 = 0x1d00FFFF; -const MAX_TARGET: u256 = 0x00000000FFFF0000000000000000000000000000000000000000000000000000; -const EXPECTED_EPOCH_TIMESPAN: u32 = 60 * 60 * 24 * 14; // 2 weeks in seconds -const BLOCKS_PER_EPOCH: u32 = 2016; - -#[derive(Drop, Clone)] -struct BlockHeader { - version: u32, - prev_block_hash: ByteArray, - merkle_root_hash: ByteArray, - time: u32, - bits: u32, - nonce: u32 -} - -#[derive(Drop, Clone)] -pub struct ChainState { - pub block_height: u32, - pub total_work: u256, - pub best_block_hash: ByteArray, - pub current_target: u32, - pub epoch_start_time: u32, - pub prev_timestamps: Array -} - -#[derive(Drop)] -struct BlockHeaderValidationContext { - block_header: BlockHeader, - block_hash: ByteArray, - target: u256, - prev_chain_state: ChainState, - block_height: u32 -} - -#[generate_trait] -pub impl BlockHeaderImpl of BlockHeaderTrait { - fn new( - version: u32, - prev_block_hash: ByteArray, - merkle_root_hash: ByteArray, - time: u32, - bits: u32, - nonce: u32 - ) -> BlockHeader { - BlockHeader { version, prev_block_hash, merkle_root_hash, time, bits, nonce } - } -} - -#[generate_trait] -pub impl ChainStateImpl of ChainStateTrait { - fn new( - block_height: u32, - total_work: u256, - best_block_hash: ByteArray, - current_target: u32, - epoch_start_time: u32, - prev_timestamps: Array - ) -> ChainState { - ChainState { - block_height, - total_work, - best_block_hash, - current_target, - epoch_start_time, - prev_timestamps - } - } -} - -#[generate_trait] -pub impl BlockHeaderValidationContextImpl of BlockHeaderValidationContextTrait { - fn new( - block_header: BlockHeader, - block_hash: ByteArray, - target: u256, - prev_chain_state: ChainState, - block_height: u32 - ) -> BlockHeaderValidationContext { - BlockHeaderValidationContext { - block_header, block_hash, target, prev_chain_state, block_height - } - } -} - -// The main engine for block header validation -#[derive(Drop)] -struct BlockHeaderEngine { - context: BlockHeaderValidationContext -} - -#[generate_trait] -pub impl BlockHeaderEngineImpl of BlockHeaderEngineTrait { - fn new(context: BlockHeaderValidationContext) -> BlockHeaderEngine { - BlockHeaderEngine { context } - } - - fn validate_and_apply_block_header(ref self: BlockHeaderEngine) -> Result { - self.validate_prev_block_hash()?; - self.validate_proof_of_work()?; - self.validate_target()?; - self.validate_timestamp()?; - - let next_state = self.apply_block_header(); - Result::Ok(next_state) - } - - fn validate_prev_block_hash(ref self: BlockHeaderEngine) -> Result<(), felt252> { - if self - .context - .block_header - .prev_block_hash != self - .context - .prev_chain_state - .best_block_hash { - return Result::Err('Invalid prev_block_hash'); - } - Result::Ok(()) - } - - fn validate_proof_of_work(ref self: BlockHeaderEngine) -> Result<(), felt252> { - Result::Ok(()) - } - - fn validate_target(ref self: BlockHeaderEngine) -> Result<(), felt252> { - Result::Ok(()) - } - - fn validate_timestamp(ref self: BlockHeaderEngine) -> Result<(), felt252> { - Result::Ok(()) - } - - fn apply_block_header(ref self: BlockHeaderEngine) -> ChainState { - ChainState { - block_height: 0, - total_work: 0, - best_block_hash: "", - current_target: 0, - epoch_start_time: 0, - prev_timestamps: ArrayTrait::new() - } - } - - fn next_prev_timestamps(ref self: BlockHeaderEngine) -> Array { - let mut timestamps = ArrayTrait::new(); - - timestamps - } - - fn compute_total_work(ref self: BlockHeaderEngine) -> u256 { - let work_in_block = compute_work_from_target(self.context.target); - self.context.prev_chain_state.total_work + work_in_block - } - - fn adjust_difficulty(ref self: BlockHeaderEngine) -> (u32, u32) { - (0, 0) - } -} - -// Helper functions -fn bits_to_target(bits: u32) -> u256 { - 0 -} - -fn target_to_bits(target: u256) -> u32 { - 0 -} - -fn compute_work_from_target(target: u256) -> u256 { - 0 -} - -fn compute_timestamps_median(timestamps: Span) -> u32 { - 0 -} diff --git a/src/lib.cairo b/src/lib.cairo index 3138255b..8abc785f 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,3 +1,3 @@ -pub mod engine; -pub mod state; +mod state; +mod validation; mod main; diff --git a/src/main.cairo b/src/main.cairo index 7ad9b6cb..dc1a66e6 100644 --- a/src/main.cairo +++ b/src/main.cairo @@ -1,36 +1,3 @@ -use raito::engine::BlockHeaderEngineTrait; -use raito::engine::BlockHeaderEngineImpl; -use raito::engine::BlockHeaderValidationContextTrait; -use raito::engine::BlockHeaderValidationContextImpl; -use raito::engine::BlockHeaderTrait; -use raito::engine::BlockHeaderImpl; -use raito::engine::ChainStateTrait; -use raito::engine::ChainStateImpl; -use raito::engine::ChainState; - fn main() { println!("Running Raito Bitcoin ZK client"); - let block_header = BlockHeaderImpl::new(0, "", "", 0, 0, 0); - - // The Times 03/Jan/2009 Chancellor on brink of second bailout for banks - let GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"; - - let chain_state = ChainState { - block_height: 0, - total_work: 0, - best_block_hash: GENESIS, - current_target: 0, - epoch_start_time: 0, - prev_timestamps: ArrayTrait::new() - }; - - let mut context = BlockHeaderValidationContextImpl::new(block_header, "", 0, chain_state, 0); - let mut engine = BlockHeaderEngineImpl::new(context); - - let res = engine.validate_and_apply_block_header(); - if res.is_ok() { - println!("Execution successful"); - } else { - println!("Execution failed"); - } } diff --git a/src/state.cairo b/src/state.cairo index f207f391..b1a75261 100644 --- a/src/state.cairo +++ b/src/state.cairo @@ -1,57 +1,86 @@ -// https://developer.bitcoin.org/reference/block_chain.html#block-headers -#[derive(Drop, Clone)] +/// Represents the state of the blockchain. +#[derive(Drop, Copy)] +pub struct ChainState { + /// Height of the current block. + pub block_height: u32, // not u256? + /// Total work done. + pub total_work: u256, + /// Best block. + pub best_block_hash: u256, + /// Current block. + pub current_target: u32, + /// Start of the current epoch. + pub epoch_start_time: u32, + /// Previous timestamps. + pub prev_timestamps: Span, + // TODO: utreexo_roots? +} + +/// Represents a block in the blockchain. +/// +#[derive(Drop, Copy)] +pub struct Block { + /// block header + pub header: Header, + // TODO: how to handle coinbase transactions? + + /// Transactions + pub txs: Span, +} + +/// Block header +/// https://developer.bitcoin.org/reference/block_chain.html#block-headers +#[derive(Drop, Copy)] struct Header { + /// The version of the block. pub version: u32, + /// The hash of the previous block in the blockchain. pub prev_block_hash: u256, + /// The Merkle root hash of the transactions in the block. pub merkle_root_hash: u256, + /// The timestamp of the block. pub time: u32, + /// The difficulty target for mining the block. pub bits: u32, - pub nonce: u32 -} - -// https://developer.bitcoin.org/reference/transactions.html#txin-a-transaction-input-non-coinbase -#[derive(Drop, Clone)] -pub struct TxIn { - txid: u256, - index: u32, - script: ByteArray, - sequence: u32, + /// The nonce used in mining the block. + pub nonce: u32, } -// https://developer.bitcoin.org/reference/transactions.html#txout-a-transaction-output -#[derive(Drop, Clone)] -pub struct TxOut { - value: i64, // TODO: why signed? - pk_script: ByteArray -} - -// https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format -#[derive(Drop, Clone)] +/// Transaction +/// https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format +#[derive(Drop, Copy)] pub struct Transaction { + /// The version of the transaction. pub version: i32, + /// The inputs of the transaction. pub inputs: Span, + /// The outputs of the transaction. pub outputs: Span, + /// The lock time of the transaction. pub lock_time: u32, } -#[derive(Drop, Clone)] -pub struct Block { - pub header: Header, - // TODO: how to handle coinbase transactions? - pub txs: Span +/// Output of a transaction. +/// https://developer.bitcoin.org/reference/transactions.html#txout-a-transaction-output +#[derive(Drop, Copy)] +pub struct TxOut { + /// The value of the output. + value: i64, + /// The public key script of the output. + pk_script: @ByteArray, } -#[derive(Drop, Clone)] -pub struct ChainState { - pub block_height: u32, // not u256? - pub total_work: u256, - pub best_block_hash: u256, - pub current_target: u32, - pub epoch_start_time: u32, - pub prev_timestamps: Span, -// TODO: utreexo_roots? +/// Input of a transaction. +/// https://developer.bitcoin.org/reference/transactions.html#txin-a-transaction-input-non-coinbase +#[derive(Drop, Copy)] +pub struct TxIn { + /// The transaction ID of the input. + txid: u256, + /// The index of the input. + index: u32, + /// The script of the input. + script: @ByteArray, + /// The sequence of the input. + sequence: u32, } -trait BlockValidator { - fn validate_and_apply(self: ChainState, block: Block) -> Result; -}