Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor project into a workspace #169

Merged
merged 1 commit into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ Cargo.lock
.python-version
__pycache__

.raito
.client_cache/
28 changes: 3 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Extend light client with partial transaction validation, but without UTXO checks

Tasks:

* [ ] reassess validation check list (analyze Bitcoin core codebase)
* [x] reassess validation check list (analyze Bitcoin core codebase)
* [x] generate & run integration tests e2e instead of Cairo codegen
* [x] transaction ID calculation
* [x] transaction root computation
Expand Down Expand Up @@ -135,40 +135,18 @@ Raito is a reference to Light Yagami (夜神月, Yagami Raito) from the manga/an

## Usage

This will compile all the components:
This will compile all the packages:

```bash
scarb build
```

This will run unit and integration tests:
This will run tests for all the packages:

```bash
scarb test
```

For integration tests ony:

```bash
scarb run integration_tests
```

Run for specific test file(s):

```bash
scarb run integration_tests tests/data/light_481823.json
```

Re-generate integration test data:

```base
scarb run regenerate_tests --force
```

* Without `--force` flag only non-existent files will be created
* Files are located in [tests/data/](https://github.com/keep-starknet-strange/raito/blob/main/tests/data)
* If you want to add a new test case, edit [scripts/data/regenerate_tests.sh](https://github.com/keep-starknet-strange/raito/blob/main/scripts/data/regenerate_tests.sh)

## Build dependencies

Install necessary packages required by Python scripts:
Expand Down
16 changes: 15 additions & 1 deletion Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,19 @@
version = 1

[[package]]
name = "raito"
name = "client"
version = "0.1.0"
dependencies = [
"consensus",
]

[[package]]
name = "consensus"
version = "0.1.0"
dependencies = [
"utils",
]

[[package]]
name = "utils"
version = "0.1.0"
23 changes: 10 additions & 13 deletions Scarb.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
[package]
name = "raito"
version = "0.1.0"
edition = "2024_07"

[scripts]
regenerate_tests= "./scripts/data/regenerate_tests.sh"
integration_tests = "scarb build && ./scripts/data/integration_tests.sh"
client= "scarb build && ./scripts/data/client.sh"
test = "scarb cairo-test && scarb run integration_tests"
lint = "flake8 scripts/ && black --check scripts/"
[workspace]
members = ["packages/*"]

[dependencies]
[workspace.package]
description = "Bitcoin ZK client."
cairo-version = "2.8.2"
version = "0.1.0"
readme = "README.md"
repository = "https://github.com/keep-starknet-strange/raito"
license-file = "LICENSE"

[dev-dependencies]
[workspace.dependencies]
cairo_test = "2.8.0"
45 changes: 45 additions & 0 deletions packages/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Bitcoin client in Cairo

This package is a standalone Cairo program (outside of Starknet context) that implements a Bitcoin client which can work in two modes:
- Light mode: block header validation only
- Full mode: full Bitcoin consensus validation

## Usage

```sh
# You have to be in the "packages/client" directory
scarb run client START_HEIGHT END_HEIGHT BATCH_SIZE MODE STRATEGY
```

Client expects the following arguments:
* `START_HEIGHT` height of the initial chain state
* `END_HEIGHT` height of the final (resulting) chain state
* `BATCH_SIZE` number of blocks applied per single program run
* `MODE` either `light` or `full` (default is light)
* `STRATEGY` either `sequential` or `random` (default is sequential)

## Integration tests

In order to run integration tests:

```sh
scarb test
```

Run a specific test file (or several files):

```sh
# You have to be in the "packages/client" directory
scarb test tests/data/light_481823.json
```

Re-generate integration test data:

```sh
# You have to be in the "packages/client" directory
scarb run regenerate_tests --force
```

If you want to just add a new test case, edit `scripts/data/regenerate_tests.sh` and run without `--force` flag.

You can also add/remove ignored scenarios, check out `scripts/data/regenerate_tests.sh` as well.
16 changes: 16 additions & 0 deletions packages/client/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "client"
version = "0.1.0"
edition = "2024_07"

[dependencies]
consensus = { path = "../consensus" }

[dev-dependencies]
cairo_test.workspace = true

[scripts]
test = "scarb build && ../../scripts/data/integration_tests.sh"
regenerate_tests= "../../scripts/data/regenerate_tests.sh"
client = "scarb build && ../../scripts/data/client.sh"
lint = "flake8 scripts/ && black --check scripts/ && scarb fmt"
4 changes: 4 additions & 0 deletions packages/client/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod main;
// TODO: scarb cairo-run should support "features" argument
// so that we can conditionally compile this module
mod test;
4 changes: 2 additions & 2 deletions src/main.cairo → packages/client/src/main.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::types::block::Block;
use crate::types::chain_state::{ChainState, BlockValidator};
use consensus::types::block::Block;
use consensus::types::chain_state::{ChainState, BlockValidator};

/// Raito program arguments.
#[derive(Serde)]
Expand Down
4 changes: 2 additions & 2 deletions src/test.cairo → packages/client/src/test.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::types::block::Block;
use crate::types::chain_state::{ChainState, BlockValidator};
use consensus::types::block::Block;
use consensus::types::chain_state::{ChainState, BlockValidator};
use core::testing::get_available_gas;

/// Integration testing program arguments.
Expand Down
File renamed without changes.
File renamed without changes.
8 changes: 8 additions & 0 deletions packages/consensus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Bitcoin consensus in Cairo

This package is a Cairo library providing primitives for validating Bitcoin consensus.

It is structured as follows:
* `types` module contains all Bitcoin specific entities (start your codebase tour with this folder) adapted for recursive verification;
* `validation` module contains most of the consensus validation logic;
* `codec` module contains implementation of Bitcoin binary codec for transaction types.
14 changes: 14 additions & 0 deletions packages/consensus/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "consensus"
version = "0.1.0"
edition = "2024_07"

[dependencies]
utils = { path = "../utils" }

[dev-dependencies]
cairo_test.workspace = true

[scripts]
# TODO: cairo lint
lint = "scarb fmt"
6 changes: 3 additions & 3 deletions src/codec.cairo → packages/consensus/src/codec.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Bitcoin binary codec traits, implementations, and helpers.

use super::types::transaction::{Transaction, TxIn, TxOut, OutPoint};
use raito::utils::hash::Digest;
use utils::hash::Digest;

pub trait Encode<T> {
/// Encode using Bitcoin codec and append to the buffer.
Expand Down Expand Up @@ -133,8 +133,8 @@ pub fn encode_compact_size(len: usize, ref dest: ByteArray) {
}
#[cfg(test)]
mod tests {
use raito::types::transaction::{Transaction, TxIn, TxOut, OutPoint};
use raito::utils::hex::{from_hex, hex_to_hash_rev};
use utils::hex::{from_hex, hex_to_hash_rev};
use crate::types::transaction::{Transaction, TxIn, TxOut, OutPoint};
use super::{Encode, TransactionCodec, encode_compact_size};

#[test]
Expand Down
17 changes: 17 additions & 0 deletions packages/consensus/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pub mod validation {
pub mod difficulty;
pub mod coinbase;
pub mod locktime;
pub mod timestamp;
pub mod transaction;
pub mod work;
pub mod block;
}
pub mod codec;
pub mod types {
pub mod utreexo;
pub mod chain_state;
pub mod block;
pub mod transaction;
pub mod utxo_set;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
//!
//! The data is expected to be prepared in advance and passed as program arguments.

use crate::utils::hash::Digest;
use crate::utils::sha256::double_sha256_u32_array;
use crate::utils::numeric::u32_byte_reverse;
use utils::hash::Digest;
use utils::sha256::double_sha256_u32_array;
use utils::numeric::u32_byte_reverse;
use super::transaction::Transaction;

/// Represents a block in the blockchain.
Expand Down Expand Up @@ -79,8 +79,8 @@ pub impl TransactionDataDefault of Default<TransactionData> {
#[cfg(test)]
mod tests {
use super::{Header, BlockHash};
use raito::types::chain_state::ChainState;
use raito::utils::hash::Digest;
use crate::types::chain_state::ChainState;
use utils::hash::Digest;

#[test]
fn test_block_hash() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! Chain state alone is not enough to do full block validation, however
//! it is sufficient to validate block headers.

use crate::utils::hash::Digest;
use utils::hash::Digest;
use crate::validation::{
difficulty::{validate_bits, adjust_difficulty}, coinbase::validate_coinbase,
timestamp::{validate_timestamp, next_prev_timestamps},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Types are extended with extra information required for validation.
//! The data is expected to be prepared in advance and passed as program arguments.

use crate::utils::{hash::Digest, bytearray::{ByteArraySnapHash, ByteArraySnapSerde}};
use utils::{hash::Digest, bytearray::{ByteArraySnapHash, ByteArraySnapSerde}};

/// Represents a transaction.
/// https://learnmeabitcoin.com/technical/transaction/
Expand Down Expand Up @@ -134,7 +134,7 @@ mod tests {
use core::hash::HashStateExTrait;
use core::poseidon::PoseidonTrait;
use super::{OutPoint, TxOut};
use crate::utils::{hash::{DigestTrait}};
use utils::hash::{DigestTrait};

#[test]
pub fn test_outpoint_poseidon_hash() {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Block validation helpers.
use crate::types::transaction::{Transaction};
use crate::codec::{Encode, TransactionCodec};
use crate::utils::{hash::Digest, merkle_tree::merkle_root, sha256::double_sha256_byte_array};
use utils::{hash::Digest, merkle_tree::merkle_root, sha256::double_sha256_byte_array};
use super::transaction::validate_transaction;

const MAX_BLOCK_WEIGHT_LEGACY: usize = 1_000_000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! https://learnmeabitcoin.com/technical/mining/coinbase-transaction/

use crate::types::transaction::{Transaction, TxIn};
use crate::utils::{bit_shifts::shr, hash::Digest};
use utils::{bit_shifts::shr, hash::Digest};

const BIP_34_BLOCK_HEIGHT: u32 = 227_836;
const BIP_141_BLOCK_HEIGHT: u32 = 481_824;
Expand Down Expand Up @@ -108,7 +108,7 @@ fn compute_block_reward(block_height: u32) -> u64 {
#[cfg(test)]
mod tests {
use crate::types::transaction::{TxIn, TxOut, Transaction, OutPoint};
use crate::utils::hex::from_hex;
use utils::hex::from_hex;
use super::{
compute_block_reward, validate_coinbase, validate_coinbase_input,
validate_coinbase_sig_script, validate_coinbase_witness
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! - https://learnmeabitcoin.com/technical/mining/target/
//! - https://learnmeabitcoin.com/technical/block/bits/

use crate::utils::{bit_shifts::{shl, shr}};
use utils::{bit_shifts::{shl, shr}};

/// Maximum difficulty target allowed
const MAX_TARGET: u256 = 0x00000000FFFF0000000000000000000000000000000000000000000000000000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub fn validate_relative_locktime(
#[cfg(test)]
mod tests {
use crate::types::transaction::{TxIn, OutPoint, TxOut};
use crate::utils::hex::{from_hex, hex_to_hash_rev};
use utils::hex::{from_hex, hex_to_hash_rev};
use super::{validate_absolute_locktime, validate_relative_locktime};

// TODO: tests for invalid relative locktime
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fn validate_coinbase_maturity(output_height: u32, block_height: u32) -> Result<(
#[cfg(test)]
mod tests {
use crate::types::transaction::{Transaction, TxIn, TxOut, OutPoint};
use crate::utils::hex::{from_hex, hex_to_hash_rev};
use utils::hex::{from_hex, hex_to_hash_rev};
use super::validate_transaction;

// TODO: tests for coinbase maturity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Proof-of-work validation helpers.

use crate::utils::hash::Digest;
use utils::hash::Digest;

/// Check if the work done (by calculating the block hash) satisfies the difficulty target.
pub fn validate_proof_of_work(target: u256, block_hash: Digest) -> Result<(), ByteArray> {
Expand Down
3 changes: 3 additions & 0 deletions packages/utils/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Common utilities

This package contains common helpers that are not Bitcoin-specific.
11 changes: 11 additions & 0 deletions packages/utils/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "utils"
version = "0.1.0"
edition = "2024_07"

[dev-dependencies]
cairo_test.workspace = true

[scripts]
# TODO: cairo lint
lint = "scarb fmt"
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion src/utils/hash.cairo → packages/utils/src/hash.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub impl DigestHash<S, +HashStateTrait<S>, +Drop<S>> of Hash<Digest, S> {

#[cfg(test)]
mod tests {
use crate::utils::hex::from_hex;
use crate::hex::from_hex;
use super::Digest;

#[test]
Expand Down
Loading
Loading