Skip to content

Commit

Permalink
Merge pull request #31 from keep-starknet-strange/m-kus@extended-state
Browse files Browse the repository at this point in the history
feat: extend Bitcoin types with extra fields for validation
  • Loading branch information
maciejka authored Aug 6, 2024
2 parents d304cae + 49c707d commit 8856871
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 20 deletions.
85 changes: 67 additions & 18 deletions src/state.cairo
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
//! Bitcoin data type objects extended with validation context.
//!
//! The data is expected to be prepared in advance and passed as program arguments.
//! The extended set of fields allows to recursively validate entities in a stateless manner,
//! and to avoid repetitive computations.

/// Represents the state of the blockchain.
#[derive(Drop, Copy)]
pub struct ChainState {
Expand All @@ -13,23 +19,56 @@ pub struct ChainState {
pub epoch_start_time: u32,
/// Previous timestamps.
pub prev_timestamps: Span<u32>,
// TODO: utreexo_roots?
/// Utreexo state
pub utreexo_state: UtreexoState,
}

/// Accumulator representation of the state aka "Compact State Node"
#[derive(Drop, Copy)]
pub struct UtreexoState {
/// Roots of Merkle tree forest
pub roots: Span<felt252>,
}

/// Utreexo set is used to retrieve TXOs spent by particular inputs
#[derive(Drop, Copy)]
pub struct UtreexoSet {
/// A list of extended transaction outputs spent in a particular block(s).
pub outputs: Span<UtreexoOutput>,
}

/// TXO extended with info about parent transaction and the position within it.
/// The hash of this structure is a leaf node in the Utreexo Merkle tree forest.
#[derive(Drop, Copy)]
pub struct UtreexoOutput {
/// The TXID this output belongs to.
pub txid: u256,
/// The index of this output.
pub vout: u32,
/// Output data
pub output: TxOut,
}

/// Inclusion proof for multiple leaves
#[derive(Drop, Copy)]
pub struct UtreexoBatchProof {
/// Indices of tree leaves, one for each output in the utreexo set
pub targets: Span<u64>,
/// All the nodes required to calculate the root
pub proof: Span<felt252>,
}

/// 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<Transaction>,
}

/// Block header
/// https://developer.bitcoin.org/reference/block_chain.html#block-headers
/// https://learnmeabitcoin.com/technical/block/
#[derive(Drop, Copy)]
pub struct Header {
/// The version of the block.
Expand All @@ -47,40 +86,50 @@ pub struct Header {
}

/// Transaction
/// https://developer.bitcoin.org/reference/transactions.html#raw-transaction-format
/// https://learnmeabitcoin.com/technical/transaction/
#[derive(Drop, Copy)]
pub struct Transaction {
/// The version of the transaction.
pub version: i32,
pub version: u32,
/// Flag which indicates the presence of witness data.
/// It combines `marker` and `flag` fields for now but in the future
/// we might need to separate them if transaction structure changes.
/// Segwit marker and flag do not contribute to TXID (transaction hash),
/// but do contribute to wTXID.
pub is_segwit: bool,
/// The inputs of the transaction.
pub inputs: Span<TxIn>,
/// The outputs of the transaction.
pub outputs: Span<TxOut>,
/// The list of witnesses, one for each input.
/// Each witness is a list of elements that are to be pushed onto stack.
/// Witnesses do not contribute to TXID but do contribute to wTXID.
pub witnesses: Span<Span<ByteArray>>,
/// The lock time of the transaction.
pub lock_time: u32,
}

/// Output of a transaction.
/// https://developer.bitcoin.org/reference/transactions.html#txout-a-transaction-output
/// https://learnmeabitcoin.com/technical/transaction/output/
#[derive(Drop, Copy)]
pub struct TxOut {
/// The value of the output.
/// The value of the output in satoshis.
pub value: i64,
/// The public key script of the output.
/// The spending script (aka locking code) for this output.
pub pk_script: @ByteArray,
}

/// Input of a transaction.
/// https://developer.bitcoin.org/reference/transactions.html#txin-a-transaction-input-non-coinbase
/// https://learnmeabitcoin.com/technical/transaction/input/
///
/// NOTE that `txid` and `vout` fields can be resolved via Utreexo set using the TXO index.
#[derive(Drop, Copy)]
pub struct TxIn {
/// The transaction ID of the input.
pub txid: u256,
/// The index of the input.
pub index: u32,
/// The script of the input.
/// The signature script which satisfies the conditions placed in the txo pubkey script
/// or coinbase script that contains block height (since 227,836) and miner nonce (optional).
pub script: @ByteArray,
/// The sequence of the input.
/// The sequence number of the input.
pub sequence: u32,
/// The index of output in the utreexo set (meta field).
pub txo_index: u64,
}

6 changes: 4 additions & 2 deletions src/validation.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::state::{Block, ChainState};
use super::state::{Block, ChainState, UtreexoState};

#[generate_trait]
impl BlockValidatorImpl of BlockValidator {
Expand Down Expand Up @@ -73,7 +73,7 @@ fn validate_merkle_root(self: @ChainState, block: @Block) -> Result<(), ByteArra
#[cfg(test)]
mod tests {
use super::{validate_target, validate_timestamp};
use super::{Block, ChainState};
use super::{Block, ChainState, UtreexoState};
use super::super::state::{Header, Transaction, TxIn, TxOut};

#[test]
Expand All @@ -85,6 +85,7 @@ mod tests {
current_target: 1,
epoch_start_time: 1,
prev_timestamps: array![1, 2, 3, 4, 5].span(),
utreexo_state: UtreexoState { roots: array![].span() },
};
let mut block = Block {
header: Header {
Expand Down Expand Up @@ -116,6 +117,7 @@ mod tests {
current_target: 1,
epoch_start_time: 1,
prev_timestamps: array![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].span(),
utreexo_state: UtreexoState { roots: array![].span() },
};
let mut block = Block {
header: Header {
Expand Down

0 comments on commit 8856871

Please sign in to comment.