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

0.2.50 #926

Merged
merged 6 commits into from
Feb 6, 2025
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.2.49
0.2.50
16 changes: 14 additions & 2 deletions saito-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,19 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
tokio = { version = "1.37.0", features = ["sync", "tokio-macros", "test-util", "macros", "tracing"] }
secp256k1 = { version = "0.29.0", features = ["rand", "hashes", "global-context", "serde"] }
tokio = { version = "1.37.0", features = [
"sync",
"tokio-macros",
"test-util",
"macros",
"tracing",
] }
secp256k1 = { version = "0.29.0", features = [
"rand",
"hashes",
"global-context",
"serde",
] }
rand = { version = "0.8.5", features = ["getrandom"] }
pretty_env_logger = "0.5.0"
byteorder = "1.5.0"
Expand Down Expand Up @@ -35,6 +46,7 @@ tokio = { version = "1.37.0", features = ["full"] }
criterion = { version = "0.5.1", features = ["default", "html_reports"] }
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
mockall = "0.13.1"
lazy_static = "1.4.0"

[features]
default = []
Expand Down
4 changes: 2 additions & 2 deletions saito-core/benches/benchmarks/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ fn join() {
assert!(buffer.len() > 0);
}

fn gen_random_bytes(len: u64) {
let buf = generate_random_bytes(len);
async fn gen_random_bytes(len: u64) {
let buf = generate_random_bytes(len).await;
assert_eq!(buf.len(), len as usize);
}

Expand Down
19 changes: 11 additions & 8 deletions saito-core/src/core/consensus/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2178,6 +2178,7 @@ impl Block {
utxoset: &UtxoSet,
configs: &(dyn Configuration + Send + Sync),
storage: &Storage,
validate_against_utxo: bool,
) -> bool {
//
// TODO SYNC : Add the code to check whether this is the genesis block and skip validations
Expand Down Expand Up @@ -2228,7 +2229,7 @@ impl Block {
//
// total_fees
//
if cv.total_fees != self.total_fees {
if validate_against_utxo && cv.total_fees != self.total_fees {
error!(
"total_fees error: {:?} expected : {:?}",
self.total_fees, cv.total_fees
Expand All @@ -2250,7 +2251,7 @@ impl Block {
//
// total_fees_atr
//
if cv.total_fees_atr != self.total_fees_atr {
if validate_against_utxo && cv.total_fees_atr != self.total_fees_atr {
error!(
"total_fees_atr error: {:?} expected : {:?}",
self.total_fees_atr, cv.total_fees_atr
Expand All @@ -2261,7 +2262,7 @@ impl Block {
//
// avg_total_fees
//
if cv.avg_total_fees != self.avg_total_fees {
if validate_against_utxo && cv.avg_total_fees != self.avg_total_fees {
error!(
"avg_total_fees error: {:?} expected : {:?}",
self.avg_total_fees, cv.avg_total_fees
Expand All @@ -2283,7 +2284,7 @@ impl Block {
//
// avg_total_fees_atr
//
if cv.avg_total_fees_atr != self.avg_total_fees_atr {
if validate_against_utxo && cv.avg_total_fees_atr != self.avg_total_fees_atr {
error!(
"avg_total_fees_atr error: {:?} expected : {:?}",
self.avg_total_fees_atr, cv.avg_total_fees_atr
Expand Down Expand Up @@ -2426,7 +2427,9 @@ impl Block {
//
// consensus values -> difficulty (mining/payout unlock difficulty)
//
if cv.avg_nolan_rebroadcast_per_block != self.avg_nolan_rebroadcast_per_block {
if validate_against_utxo
&& cv.avg_nolan_rebroadcast_per_block != self.avg_nolan_rebroadcast_per_block
{
error!(
"ERROR 202392: avg_nolan_rebroadcast_per_block is invalid. expected: {:?} vs actual : {:?}",
cv.avg_nolan_rebroadcast_per_block, self.avg_nolan_rebroadcast_per_block
Expand Down Expand Up @@ -2620,7 +2623,7 @@ impl Block {
// which we counted in the generate_metadata() function, with the
// expected number given the consensus values we calculated earlier.
//
if cv.total_rebroadcast_slips != self.total_rebroadcast_slips {
if validate_against_utxo && cv.total_rebroadcast_slips != self.total_rebroadcast_slips {
error!(
"ERROR 624442: rebroadcast slips total incorrect. expected : {:?} actual : {:?}",
cv.total_rebroadcast_slips, self.total_rebroadcast_slips
Expand All @@ -2635,7 +2638,7 @@ impl Block {
// );
// return false;
//}
if cv.rebroadcast_hash != self.rebroadcast_hash {
if validate_against_utxo && cv.rebroadcast_hash != self.rebroadcast_hash {
error!("ERROR 123422: hash of rebroadcast transactions incorrect. expected : {:?} actual : {:?}",cv.rebroadcast_hash.to_hex(), self.rebroadcast_hash.to_hex());
return false;
}
Expand Down Expand Up @@ -2724,7 +2727,7 @@ impl Block {
self.transactions.len()
);
let transactions_valid = iterate!(self.transactions, 100)
.all(|tx: &Transaction| tx.validate(utxoset, blockchain));
.all(|tx: &Transaction| tx.validate(utxoset, blockchain, validate_against_utxo));

if !transactions_valid {
error!("ERROR 579128: Invalid transactions found, block validation failed");
Expand Down
25 changes: 23 additions & 2 deletions saito-core/src/core/consensus/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ impl Blockchain {
// TODO : what other types should be added back to the mempool
if tx.transaction_type == TransactionType::Normal {
// TODO : is there a way to not validate these again ?
return tx.validate(&self.utxoset, self);
return tx.validate(&self.utxoset, self, true);
}
false
})
Expand Down Expand Up @@ -1222,7 +1222,28 @@ impl Blockchain {
// || block
// .validate(self, &self.utxoset, configs, storage, &wallet)
// .await;
does_block_validate = block.validate(self, &self.utxoset, configs, storage).await;
let has_first_block = self
.blockring
.get_longest_chain_block_hash_at_block_id(1)
.is_some();
let has_genesis_period_of_blocks = self.get_latest_block_id()
> configs.get_consensus_config().unwrap().genesis_period + self.genesis_block_id;
let validate_against_utxo = has_first_block || has_genesis_period_of_blocks;

does_block_validate = block
.validate(self, &self.utxoset, configs, storage, validate_against_utxo)
.await;

if !does_block_validate {
debug!("validate against utxo: {:?}, has_first_block : {:?}, has_genesis_period_of_blocks : {:?}",
validate_against_utxo,has_first_block,has_genesis_period_of_blocks);
debug!("latest_block_id = {:?}", self.get_latest_block_id());
debug!("genesis_block_id = {:?}", self.genesis_block_id);
debug!(
"genesis_period = {:?}",
configs.get_consensus_config().unwrap().genesis_period
);
}
}

let mut wallet_updated = WALLET_NOT_UPDATED;
Expand Down
12 changes: 6 additions & 6 deletions saito-core/src/core/consensus/golden_ticket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,19 +99,19 @@ mod tests {
assert_eq!(GoldenTicket::validate_hashing_difficulty(&hash2, 5), false);
}

#[test]
fn golden_ticket_extremes_test() {
#[tokio::test]
async fn golden_ticket_extremes_test() {
let keys = generate_keys();
let wallet = Wallet::new(keys.1, keys.0);

let random = hash(&generate_random_bytes(32));
let target = hash(&random.to_vec());
let random = hash(&generate_random_bytes(32).await);
let target = hash(random.as_ref());
let public_key = wallet.public_key;

let gt = GoldenTicket::create(target, random, public_key);

assert_eq!(gt.validate(0), true);
assert_eq!(gt.validate(256), false);
assert!(gt.validate(0));
assert!(!gt.validate(256));
}
#[test]
fn gt_against_slr() {
Expand Down
2 changes: 1 addition & 1 deletion saito-core/src/core/consensus/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl Mempool {
public_key = wallet.public_key;
transaction.generate(&public_key, 0, 0);

tx_valid = transaction.validate(&blockchain.utxoset, blockchain);
tx_valid = transaction.validate(&blockchain.utxoset, blockchain, true);
}

// validate
Expand Down
4 changes: 2 additions & 2 deletions saito-core/src/core/consensus/peers/peer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl Peer {
debug!("initiating handshake : {:?}", self.index);

let challenge = HandshakeChallenge {
challenge: generate_random_bytes(32).try_into().unwrap(),
challenge: generate_random_bytes(32).await.try_into().unwrap(),
};
debug!(
"generated challenge : {:?} for peer : {:?}",
Expand Down Expand Up @@ -193,7 +193,7 @@ impl Peer {
let response = HandshakeResponse {
public_key: wallet.public_key,
signature: sign(challenge.challenge.as_slice(), &wallet.private_key),
challenge: generate_random_bytes(32).try_into().unwrap(),
challenge: generate_random_bytes(32).await.try_into().unwrap(),
is_lite,
block_fetch_url,
services: io_handler.get_my_services(),
Expand Down
19 changes: 14 additions & 5 deletions saito-core/src/core/consensus/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,12 @@ impl Transaction {
self.signature = sign(&buffer, private_key);
}

pub fn validate(&self, utxoset: &UtxoSet, blockchain: &Blockchain) -> bool {
pub fn validate(
&self,
utxoset: &UtxoSet,
blockchain: &Blockchain,
validate_against_utxo: bool,
) -> bool {
// Fee Transactions are validated in the block class. There can only
// be one per block, and they are checked by ensuring the transaction hash
// matches our self-generated safety check. We do not need to validate
Expand Down Expand Up @@ -1049,10 +1054,14 @@ impl Transaction {
return false;
}

// trace!("validating transaction against utxo ...");
let inputs_validate = self.validate_against_utxoset(utxoset);
// trace!("validated transaction against utxo !");
inputs_validate
return if validate_against_utxo {
// trace!("validating transaction against utxo ...");
let inputs_validate = self.validate_against_utxoset(utxoset);
// trace!("validated transaction against utxo !");
inputs_validate
} else {
true
};
}

pub fn validate_against_utxoset(&self, utxoset: &UtxoSet) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion saito-core/src/core/mining_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl MiningThread {
info!("node public key = {:?}", self.public_key.to_base58());
}

let random_bytes = hash(&generate_random_bytes(32));
let random_bytes = hash(&generate_random_bytes(32).await);
// The new way of validation will be wasting a GT instance if the validation fails
// old way used a static method instead
let gt = GoldenTicket::create(self.target, random_bytes, self.public_key);
Expand Down
8 changes: 4 additions & 4 deletions saito-core/src/core/msg/block_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ mod tests {
use crate::core::util::crypto::generate_random_bytes;
use crate::core::util::serialize::Serialize;

#[test]
fn test_serialize_with_full_fork_id() {
#[tokio::test]
async fn test_serialize_with_full_fork_id() {
let request = BlockchainRequest {
latest_block_id: 10,
latest_block_hash: generate_random_bytes(32).try_into().unwrap(),
fork_id: generate_random_bytes(32).try_into().unwrap(),
latest_block_hash: generate_random_bytes(32).await.try_into().unwrap(),
fork_id: generate_random_bytes(32).await.try_into().unwrap(),
};
let buffer = request.serialize();
assert_eq!(buffer.len(), 72);
Expand Down
31 changes: 23 additions & 8 deletions saito-core/src/core/util/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use crate::core::defs::{PrintForLog, SaitoHash, SaitoPrivateKey, SaitoPublicKey,
use blake3::Hasher;
use block_modes::BlockMode;
pub use merkle::MerkleTree;
use rand::{thread_rng, Rng};
use rand::{thread_rng, Rng, SeedableRng};
use secp256k1::ecdsa;
pub use secp256k1::{Message, PublicKey, SecretKey, SECP256K1};
use tokio::sync::Mutex;

// type Aes128Cbc = Cbc<Aes128, Pkcs7>;

Expand Down Expand Up @@ -63,24 +64,38 @@ pub fn generate_keypair_from_private_key(slice: &[u8]) -> (SaitoPublicKey, Saito
(public_key.serialize(), secret_bytes)
}

pub fn sign_blob<'a, 'b>(
vbytes: &'a mut Vec<u8>,
private_key: &'b SaitoPrivateKey,
) -> &'a mut Vec<u8> {
pub fn sign_blob<'a>(vbytes: &'a mut Vec<u8>, private_key: &SaitoPrivateKey) -> &'a mut Vec<u8> {
let sig = sign(&hash(vbytes.as_ref()), private_key);
vbytes.extend(&sig);
vbytes
}
#[cfg(test)]
lazy_static::lazy_static! {
pub static ref TEST_RNG: Mutex<rand::rngs::StdRng> = Mutex::new(create_test_rng());
}

fn create_test_rng() -> rand::rngs::StdRng {
rand::rngs::StdRng::from_seed([0; 32])
}

pub fn generate_random_bytes(len: u64) -> Vec<u8> {
pub async fn generate_random_bytes(len: u64) -> Vec<u8> {
if len == 0 {
let x: Vec<u8> = vec![];
return x;
}
// Don't have to be cryptographically secure, since we only need a random hash and only check the signature of that in return
let mut rng = thread_rng();

(0..len).map(|_| rng.gen::<u8>()).collect()
#[cfg(not(test))]
{
let mut rng = thread_rng();
(0..len).map(|_| rng.gen::<u8>()).collect()
}
#[cfg(test)]
{
// let mut rng = TEST_RNG.clone();
let mut rng = TEST_RNG.lock().await;
(0..len).map(|_| rng.gen::<u8>()).collect()
}
}

pub fn hash(data: &[u8]) -> SaitoHash {
Expand Down
5 changes: 3 additions & 2 deletions saito-core/src/core/util/test/node_tester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,10 +607,11 @@ pub mod test {
.for_each(|(key, _)| {
let slip = Slip::parse_slip_from_utxokey(key).unwrap();
info!(
"Utxo : {:?} : {} : {:?}",
"Utxo : {:?} : {} : {:?}, block : {:?}",
slip.public_key.to_base58(),
slip.amount,
slip.slip_type
slip.slip_type,
slip.block_id
);
});

Expand Down
4 changes: 2 additions & 2 deletions saito-core/src/core/util/test/test_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,12 +728,12 @@ pub mod test {

public_key = wallet.public_key;
}
let mut random_bytes = hash(&generate_random_bytes(32));
let mut random_bytes = hash(&generate_random_bytes(32).await);

let mut gt = GoldenTicket::create(block_hash, random_bytes, public_key);

while !gt.validate(block_difficulty) {
random_bytes = hash(&generate_random_bytes(32));
random_bytes = hash(&generate_random_bytes(32).await);
gt = GoldenTicket::create(block_hash, random_bytes, public_key);
}

Expand Down
5 changes: 3 additions & 2 deletions saito-core/src/core/verification_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ impl VerificationThread {
public_key = wallet.public_key;
transaction.generate(&public_key, 0, 0);

if !transaction.validate(&blockchain.utxoset, &blockchain) {
// TODO : should we skip validation against utxo if we don't have the full utxo ?
if !transaction.validate(&blockchain.utxoset, &blockchain, true) {
debug!(
"transaction : {:?} not valid",
transaction.signature.to_hex()
Expand Down Expand Up @@ -82,7 +83,7 @@ impl VerificationThread {
.filter_map(|mut transaction| {
transaction.generate(&public_key, 0, 0);

if !transaction.validate(&blockchain.utxoset, &blockchain) {
if !transaction.validate(&blockchain.utxoset, &blockchain, true) {
debug!(
"transaction : {:?} not valid",
transaction.signature.to_hex()
Expand Down
2 changes: 1 addition & 1 deletion saito-rust/src/network_controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ mod tests {
let mut socket = result.0;

let challenge = HandshakeChallenge {
challenge: generate_random_bytes(32).try_into().unwrap(),
challenge: generate_random_bytes(32).await.try_into().unwrap(),
};
// challenge_for_peer = Some(challenge.challenge);
let message = Message::HandshakeChallenge(challenge);
Expand Down
Loading