-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
6608b0f
commit 090ff51
Showing
2 changed files
with
196 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,181 @@ | ||
// The engine is the main component that coordinates the verification of the Bitcoin consensus rules in Cairo. | ||
#[derive(Destruct)] | ||
pub struct Engine {} | ||
use core::result::Result; | ||
use core::option::OptionTrait; | ||
use core::traits::Into; | ||
use core::byte_array::ByteArray; | ||
|
||
pub trait EngineTrait { | ||
fn new() -> Engine; | ||
fn check_consensus_rules(ref self: Engine) -> Result<ByteArray, felt252>; | ||
// 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<u32> | ||
} | ||
|
||
pub impl EngineTraitImpl of EngineTrait { | ||
fn new() -> Engine { | ||
Engine {} | ||
#[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<u32> | ||
) -> ChainState { | ||
ChainState { | ||
block_height, | ||
total_work, | ||
best_block_hash, | ||
current_target, | ||
epoch_start_time, | ||
prev_timestamps | ||
} | ||
} | ||
} | ||
|
||
fn check_consensus_rules(ref self: Engine) -> Result<ByteArray, felt252> { | ||
return Result::Ok(""); | ||
#[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<ChainState, felt252> { | ||
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<u32> { | ||
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>) -> u32 { | ||
0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters