Comments (4)
I think this is just due to the fact that this test uses identical values for all the transaction ids (which is not a valid scenario) and a [1u8; 32]
hashed with another [1u8; 32]
will result in the same hash as every other pair of leaves; I wrote my own test case which uses randomized transaction ids and checks the root hashes for all the subsequent merkle trees they would create and didn't encounter this issue:
#[test]
fn test_changing_tx_roots() {
let mut rng = thread_rng();
// The number of transactions for which to check subsequent merkle tree root values.
const NUM_TXS: usize = 200;
// Create a vector with transaction ids consisting of random values.
let transaction_ids = {
let mut vec = Vec::with_capacity(NUM_TXS);
for _ in 0..NUM_TXS {
let mut id = [0u8; 32];
let random = Standard.sample_iter(&mut rng).take(32).collect::<Vec<_>>();
id.copy_from_slice(&random);
vec.push(id);
}
vec
};
// Collect the transactions into a collection of their growing sequences, i.e.
// [[tx0], [tx0, tx1], [tx0, tx1, tx2], ..., [tx0, ..., NUM_TXS]].
let growing_tx_ids = transaction_ids.into_iter().scan(Vec::with_capacity(NUM_TXS), |acc, tx_id| {
acc.push(tx_id);
Some(acc.clone())
}).collect::<Vec<_>>();
// Calculate the root hashes for the sequences of transactions.
let subsequent_root_hashes = growing_tx_ids.into_iter().map(|tx_ids| {
let (root, pedersen_root, _subroots) = txids_to_roots(&tx_ids);
(root, pedersen_root)
}).collect::<Vec<_>>();
// Ensure that the subsequent roots differ for every new transaction.
let mut hashes_differ = true;
for window in subsequent_root_hashes.windows(2) {
match window {
[(root1, pedersen_root1), (root2, pedersen_root2)] => {
if root1 == root2 || pedersen_root1 == pedersen_root2 {
hashes_differ = false;
break;
}
}
_ => unreachable!(),
}
}
assert!(hashes_differ);
}
from snarkvm.
I think this is just due to the fact that this test uses identical values for all the transaction ids (which is not a valid scenario) and a
[1u8; 32]
hashed with another[1u8; 32]
will result in the same hash as every other pair of leaves; I wrote my own test case which uses randomized transaction ids and checks the root hashes for all the subsequent merkle trees they would create and didn't encounter this issue:#[test] fn test_changing_tx_roots() { let mut rng = thread_rng(); // The number of transactions for which to check subsequent merkle tree root values. const NUM_TXS: usize = 200; // Create a vector with transaction ids consisting of random values. let transaction_ids = { let mut vec = Vec::with_capacity(NUM_TXS); for _ in 0..NUM_TXS { let mut id = [0u8; 32]; let random = Standard.sample_iter(&mut rng).take(32).collect::<Vec<_>>(); id.copy_from_slice(&random); vec.push(id); } vec }; // Collect the transactions into a collection of their growing sequences, i.e. // [[tx0], [tx0, tx1], [tx0, tx1, tx2], ..., [tx0, ..., NUM_TXS]]. let growing_tx_ids = transaction_ids.into_iter().scan(Vec::with_capacity(NUM_TXS), |acc, tx_id| { acc.push(tx_id); Some(acc.clone()) }).collect::<Vec<_>>(); // Calculate the root hashes for the sequences of transactions. let subsequent_root_hashes = growing_tx_ids.into_iter().map(|tx_ids| { let (root, pedersen_root, _subroots) = txids_to_roots(&tx_ids); (root, pedersen_root) }).collect::<Vec<_>>(); // Ensure that the subsequent roots differ for every new transaction. let mut hashes_differ = true; for window in subsequent_root_hashes.windows(2) { match window { [(root1, pedersen_root1), (root2, pedersen_root2)] => { if root1 == root2 || pedersen_root1 == pedersen_root2 { hashes_differ = false; break; } } _ => unreachable!(), } } assert!(hashes_differ); }
Does the PoSW have the above process? Why is the number of subroots 1 instead of 5, when the number of transactions is 9, and so on?
from snarkvm.
@mengsuenyan as someone who has only tweaked the related code I'm not sure if this particular behavior is expected, so I'll leave the answer to the others assigned.
@howardwu if you agree that we should be testing random unique transaction ids instead of fixed dummy values (which I've seen in more places, and duplicated as well), I can publish this test as a PR and look for other places that could use an adjustment like this.
from snarkvm.
The expected behaviour of the POSW process should be to compute the subtree roots from the transactions, as @mengsuenyan mentions above in the table. These should then be fed into the circuit, which should only verify the MaskedPedersen hashes up to a fixed depth, which we constrained to always be 2. Therefore, even though the number of txids can be much larger, the circuit should always verify 3 MaskedPedersen circuits (i.e. a tree of depth 2).
from snarkvm.
Related Issues (20)
- [Feature] Adding DB usage metrics to SnarkVM
- [Feature] Add self.address to the Aleo instructions
- [Feature] Better UI for Users HOT 1
- Price in time-intensive finalize scopes HOT 5
- [Bug]rustc version
- [Bug]rusc version
- Optimizations to struct deserialization HOT 1
- [Feature] HOT 1
- [Bug] Aleo variable index array access HOT 1
- [Optimization] Inefficient fetching of `credits.aleo` PKs HOT 1
- Multiple crates missing `repository` field HOT 1
- [Bug] Truncated `ARCHOR_HEIGHT` leads to less `coinbase_reward` than expected HOT 3
- [Bug] No constant `BLOCK_TIME` with Bullshark HOT 4
- bug: incorrect timestamp in explorer HOT 1
- No need to create a credits with microcredits =0 HOT 1
- [Bug]Malicious validators can prevent legitimate transactions from being executed. HOT 6
- [Bug] Credits.aleo HOT 6
- When you are going build with rust on Linux HOT 5
- [Bug] The delegator may fail to execute unbond_public
- Flaky Tests on CI HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from snarkvm.