Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejka committed Aug 9, 2024
2 parents 4394272 + c07ed7d commit 02d0124
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 36 deletions.
27 changes: 27 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,33 @@
"contributions": [
"code"
]
},
{
"login": "olufemi-olumaiyegun",
"name": "Olufemi Olumaiyegun",
"avatar_url": "https://avatars.githubusercontent.com/u/53274579?v=4",
"profile": "https://www.heyfemi.com/home",
"contributions": [
"code"
]
},
{
"login": "MSghais",
"name": "MSG",
"avatar_url": "https://avatars.githubusercontent.com/u/59928086?v=4",
"profile": "https://github.com/MSghais",
"contributions": [
"code"
]
},
{
"login": "mubarak23",
"name": "Mubarak Muhammad Aminu",
"avatar_url": "https://avatars.githubusercontent.com/u/7858376?v=4",
"profile": "http://mubarak23.github.io/",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 7,
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
<tr>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/harsh-ps-2003"><img src="https://avatars.githubusercontent.com/u/119954739?v=4?s=100" width="100px;" alt="Harsh Pratap Singh"/><br /><sub><b>Harsh Pratap Singh</b></sub></a><br /><a href="https://github.com/keep-starknet-strange/raito/commits?author=harsh-ps-2003" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/Xavek"><img src="https://avatars.githubusercontent.com/u/61218841?v=4?s=100" width="100px;" alt="Xavek"/><br /><sub><b>Xavek</b></sub></a><br /><a href="https://github.com/keep-starknet-strange/raito/commits?author=Xavek" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://www.heyfemi.com/home"><img src="https://avatars.githubusercontent.com/u/53274579?v=4?s=100" width="100px;" alt="Olufemi Olumaiyegun"/><br /><sub><b>Olufemi Olumaiyegun</b></sub></a><br /><a href="https://github.com/keep-starknet-strange/raito/commits?author=olufemi-olumaiyegun" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="https://github.com/MSghais"><img src="https://avatars.githubusercontent.com/u/59928086?v=4?s=100" width="100px;" alt="MSG"/><br /><sub><b>MSG</b></sub></a><br /><a href="https://github.com/keep-starknet-strange/raito/commits?author=MSghais" title="Code">💻</a></td>
<td align="center" valign="top" width="14.28%"><a href="http://mubarak23.github.io/"><img src="https://avatars.githubusercontent.com/u/7858376?v=4?s=100" width="100px;" alt="Mubarak Muhammad Aminu"/><br /><sub><b>Mubarak Muhammad Aminu</b></sub></a><br /><a href="https://github.com/keep-starknet-strange/raito/commits?author=mubarak23" title="Code">💻</a></td>
</tr>
</tbody>
</table>
Expand Down
1 change: 1 addition & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod validation;

mod state;
mod main;
mod merkle_tree;
90 changes: 90 additions & 0 deletions src/merkle_tree.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use super::utils::double_sha256;

pub fn merkle_root(ref txids: Array<u256>) -> u256 {
let len = txids.len();

if len == 1 {
return *txids.at(0);
}

if len % 2 == 1 {
txids.append(*txids.at(len - 1));
} else {
// CVE-2012-2459 bug fix
assert!(
txids.at(len - 1) != txids.at(len - 2), "unexpected node duplication in merkle tree"
);
}

let mut next_txids = ArrayTrait::new();
let mut i = 0;
while i < len {
next_txids.append(double_sha256(*txids.at(i), *txids.at(i + 1)));
i += 2;
};

merkle_root(ref next_txids)
}

#[cfg(test)]
mod tests {
use super::{merkle_root};

#[test]
#[available_gas(100000000)]
fn test_merkle_root_01() {
let mut txids = array![
0xacd9825be8bece7782ec746a80b52f44d6a8af41c63dbab59b03e29558469682_u256,
];

let expected_merkle_root =
0xacd9825be8bece7782ec746a80b52f44d6a8af41c63dbab59b03e29558469682_u256;

assert_eq!(merkle_root(ref txids), expected_merkle_root);
}

#[test]
#[available_gas(100000000)]
fn test_merkle_root_02() {
let mut txids = array![
0x8710b2819a369672a2bce3d5270e7ae0ea59be2f7ce7f9078341b389098953e0_u256,
0x64efde3a3f3531569cdab031bb31cfeb5c2d8cba62ae1ca5b2913b4ef643fd49_u256
];

let expected_merkle_root =
0x20dadaf81170decafec4b025366b75284dbe31dd42c8da5d25ff62fc4bff5d03_u256;

assert_eq!(merkle_root(ref txids), expected_merkle_root);
}

#[test]
#[available_gas(100000000)]
fn test_merkle_root_03() {
let mut txids = array![
0xd47e03351ee65f73321b684832edc4c840a1fe4bbd04bdb66a8328e5c7796e21_u256,
0xbf304002ea77842b32dc91f1efe681a5a7909f4200e658e2ef2beb2a821101b9_u256,
0x397bdf0bf5a8798f5b10bd95c70bb4a3f42ca14a9a837a4a54cd7de525dc0225_u256,
0xd6ce148117a1cd094cdd5303ae0896cae1b29ad010b6cb0f3d43fa99b5e2c2f7_u256,
0x7d5ad03ebf001acb47aafdf4915e86b7368ed3183c1e95f47280d81bb4ef91f8_u256,
0x69cf63b266ebc862bd4d1a01473703c14bdd3a620f93ec323144c7d2c54529a0_u256,
0x155be8f959b0187d7528a1ff11b3450690047aa96dbbb29a1ae3832b237c8179_u256,
0x727d5fbed290d645ced8776c9031d7c3438454b5faf1f5dc0200dbe84f8e6035_u256,
0xc6056c6021081150a86c092f6785955f757024f41472ad4b0cfd9dd39db8b4a2_u256,
0x83f26f37bb715ec325f25544b6d7ae920fcc073c146c8dd12fbbde31a7ae1d2f_u256,
0xd39bc02ef2b2c5afdb7807b0162b573648d9264d5e9872dbf26a7d480de301cd_u256,
0x3dc087cb9e9d66c4d3e2cf29d23949e7b914db4c3f2114d34f34e97a2a44a169_u256,
0x497d1b0bf7b0c502043fe7201a9696c466f514de3190097ef3b7d0664fc3d0bf_u256,
0xa43dbef675b637c554987e8a1b98be3faf8850f88fa1bdf59b124c2356135a33_u256,
0x4f9cf2c386b34b01d48a01ea31b5c795d1e869b42de78410b3ea1adf658f62a2_u256,
0x46ef4071d3ddfd9443361ef2f4b2d5da7c57eaf59785564782d0d9b95280cb9b_u256,
0xa48c60d6b27fd5c662d7dcd248b528474fd2598d26d51525deea3d225d7260e0_u256,
0x5bb6e10378329bf6e78ce3e0f3abae1fb1c4bc40e1ce1b0e1a5f5db8a7fb1897_u256
];

let expected_merkle_root =
0xe1455aa624aa92fa8b52766199033d66e4d100b39029e69906ae594397d977af_u256;

assert_eq!(merkle_root(ref txids), expected_merkle_root);
}
}

133 changes: 116 additions & 17 deletions src/utils.cairo
Original file line number Diff line number Diff line change
@@ -1,36 +1,135 @@
use core::traits::Into;
use core::traits::TryInto;
use core::sha256::{compute_sha256_byte_array, compute_sha256_u32_array};
use core::num::traits::{Zero, One, BitSize};
use core::starknet::secp256_trait::Secp256PointTrait;

// Bitwise shift left for u256
pub fn shl(value: u256, shift: u32) -> u256 {
value * fast_pow(2.into(), shift.into())
pub fn shl<
T,
U,
+Zero<T>,
+Zero<U>,
+One<T>,
+One<U>,
+Add<T>,
+Add<U>,
+Sub<U>,
+Mul<T>,
+Div<U>,
+Rem<U>,
+Copy<T>,
+Copy<U>,
+Drop<T>,
+Drop<U>,
+PartialOrd<U>,
+PartialEq<U>,
+BitSize<T>,
+Into<usize, U>
>(
self: T, shift: U,
) -> T {
if shift > BitSize::<T>::bits().into() - One::one() {
return Zero::zero();
}
let two = One::one() + One::one();
self * fast_pow(two, shift)
}

// Bitwise shift right for u256
pub fn shr(value: u256, shift: u32) -> u256 {
value / fast_pow(2.into(), shift.into())
pub fn shr<
T,
U,
+Zero<T>,
+Zero<U>,
+One<T>,
+One<U>,
+Add<T>,
+Add<U>,
+Sub<U>,
+Div<T>,
+Mul<T>,
+Div<U>,
+Rem<U>,
+Copy<T>,
+Copy<U>,
+Drop<T>,
+Drop<U>,
+PartialOrd<U>,
+PartialEq<U>,
+BitSize<T>,
+Into<usize, U>
>(
self: T, shift: U
) -> T {
if shift > BitSize::<T>::bits().try_into().unwrap() - One::one() {
return Zero::zero();
}

let two = One::one() + One::one();
self / fast_pow(two, shift)
}


// Fast exponentiation using the square-and-multiply algorithm
// Reference:
// https://github.com/keep-starknet-strange/alexandria/blob/bcdca70afdf59c9976148e95cebad5cf63d75a7f/packages/math/src/fast_power.cairo#L12
pub fn fast_pow(base: u256, exp: u32) -> u256 {
if exp == 0 {
return 1_u256;
pub fn fast_pow<
T,
U,
+Zero<T>,
+Zero<U>,
+One<T>,
+One<U>,
+Add<U>,
+Mul<T>,
+Rem<U>,
+Div<U>,
+Copy<T>,
+Copy<U>,
+Drop<T>,
+Drop<U>,
+PartialEq<U>,
>(
base: T, exp: U
) -> T {
if exp == Zero::zero() {
return One::one();
}

let mut res: u256 = 1_u256;
let mut base: u256 = base;
let mut exp: u32 = exp;
let mut res: T = One::one();
let mut base: T = base;
let mut exp: U = exp;

let two: U = One::one() + One::one();

loop {
if exp % 2 == 1 {
if exp % two == One::one() {
res = res * base;
}
exp = exp / 2;
if exp == 0 {
exp = exp / two;
if exp == Zero::zero() {
break res;
}
base = base * base;
}
}

const TWO_POW_32: u128 = 0x100000000;
const TWO_POW_64: u128 = 0x10000000000000000;
const TWO_POW_96: u128 = 0x1000000000000000000000000;

pub fn double_sha256(a: u256, b: u256) -> u256 {
let mut ba = Default::default();

ba.append_word(a.high.into(), 16);
ba.append_word(a.low.into(), 16);
ba.append_word(b.high.into(), 16);
ba.append_word(b.low.into(), 16);

let mut input1 = Default::default();
input1.append_span(compute_sha256_byte_array(@ba).span());

let [x0, x1, x2, x3, x4, x5, x6, x7] = compute_sha256_u32_array(input1, 0, 0);

u256 {
high: x0.into() * TWO_POW_96 + x1.into() * TWO_POW_64 + x2.into() * TWO_POW_32 + x3.into(),
low: x4.into() * TWO_POW_96 + x5.into() * TWO_POW_64 + x6.into() * TWO_POW_32 + x7.into(),
}
}
32 changes: 13 additions & 19 deletions src/validation.cairo
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use super::state::{Block, ChainState, Transaction, UtreexoState};
use super::merkle_tree::merkle_root;
use super::utils::{shl, shr};
use super::state::{Block, ChainState, Transaction, UtreexoState};

const MAX_TARGET: u256 = 0x00000000FFFF0000000000000000000000000000000000000000000000000000;
pub const REWARD_INITIAL: u256 = 50; // 50 BTC in satoshis => 5000000000 SATS
pub const POW_SATS_AMOUNT: u256 = 8; // Pow to convert in SATS

#[generate_trait]
impl BlockValidatorImpl of BlockValidator {
Expand Down Expand Up @@ -95,11 +94,6 @@ fn adjust_difficulty(self: @ChainState, block: @Block) -> (u256, u32) {
(*self.current_target, *self.epoch_start_time)
}

fn validate_merkle_root(self: @ChainState, block: @Block) -> Result<(), ByteArray> {
// TODO: implement
Result::Ok(())
}

// Helper functions
pub fn bits_to_target(bits: u32) -> Result<u256, ByteArray> {
// Extract exponent and mantissa
Expand Down Expand Up @@ -174,7 +168,7 @@ pub fn target_to_bits(target: u256) -> Result<u32, ByteArray> {
let size_u256: u256 = size.into();

// Combine size and mantissa
let result: u32 = (shl(size_u256, 24) + mantissa.into()).try_into().unwrap();
let result: u32 = (shl(size_u256, 24_u32) + mantissa.into()).try_into().unwrap();

Result::Ok(result)
}
Expand All @@ -196,12 +190,7 @@ fn fee_and_merkle_root(block: @Block) -> Result<(u256, u256), ByteArray> {
total_fee += tx.fee();
};

Result::Ok((total_fee, merkle_root(txids)))
}

fn merkle_root(txids: Array<u256>) -> u256 {
// TODO: implement
0
Result::Ok((total_fee, merkle_root(ref txids)))
}

fn validate_coinbase(block: @Block, total_fees: u256) -> Result<(), ByteArray> {
Expand All @@ -211,16 +200,17 @@ fn validate_coinbase(block: @Block, total_fees: u256) -> Result<(), ByteArray> {

// Return BTC reward in SATS
fn compute_block_reward(block_height: u32) -> u64 {
shr(5000000000, block_height / 210_000).try_into().unwrap()
shr(5000000000_u64, (block_height / 210000_u32))
}


#[cfg(test)]
mod tests {
use raito::state::{Header, Transaction, TxIn, TxOut};
use super::{
validate_timestamp, validate_proof_of_work, compute_block_reward, compute_total_work,
compute_work_from_target, shr, shl, REWARD_INITIAL, POW_SATS_AMOUNT
compute_work_from_target, shr, shl, Block, ChainState, UtreexoState,
};
use super::{Block, ChainState, UtreexoState};
use super::super::state::{Header, Transaction, TxIn, TxOut};


#[test]
Expand Down Expand Up @@ -261,27 +251,31 @@ mod tests {
let work = compute_work_from_target(target);
assert(expected_work == work, 'Failed to compute target');
}

#[test]
fn test_compute_work_from_target2() {
let expected_work = 0x26d946e509ac00026d;
let target: u256 = 0x00000000000000000696f4000000000000000000000000000000000000000000;
let work = compute_work_from_target(target);
assert(expected_work == work, 'Failed to compute target');
}

#[test]
fn test_compute_work_from_target3() {
let expected_work = 0xe10005c64415f04ef3e387b97db388404db9fdfaab2b1918f6783471d;
let target: u256 = 0x12345600;
let work = compute_work_from_target(target);
assert(expected_work == work, 'Failed to compute target');
}

#[test]
fn test_compute_work_from_target4() {
let expected_work = 0x1c040c95a099201bcaf85db4e7f2e21e18707c8d55a887643b95afb2f;
let target: u256 = 0x92340000;
let work = compute_work_from_target(target);
assert(expected_work == work, 'Failed to compute target');
}

#[test]
fn test_compute_work_from_target5() {
let expected_work = 0x21809b468faa88dbe34f;
Expand Down

0 comments on commit 02d0124

Please sign in to comment.