1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use super::*;
use diem_crypto::hash::{CryptoHash, EventAccumulatorHasher, TransactionAccumulatorHasher};
use diem_types::{
account_address::HashAccountAddress,
ledger_info::LedgerInfoWithSignatures,
proof::accumulator::InMemoryAccumulator,
proptest_types::{AccountInfoUniverse, BlockGen},
};
use executor_types::ProofReader;
use proptest::{collection::vec, prelude::*};
use scratchpad::SparseMerkleTree;
prop_compose! {
fn arb_blocks_to_commit_impl(
num_accounts: usize,
max_user_txns_per_block: usize,
max_blocks: usize,
)(
mut universe in any_with::<AccountInfoUniverse>(num_accounts).no_shrink(),
block_gens in vec(any_with::<BlockGen>(max_user_txns_per_block), 1..=max_blocks),
) -> Vec<(Vec<TransactionToCommit>, LedgerInfoWithSignatures)> {
type EventAccumulator = InMemoryAccumulator<EventAccumulatorHasher>;
type TxnAccumulator = InMemoryAccumulator<TransactionAccumulatorHasher>;
let mut smt = SparseMerkleTree::<AccountStateBlob>::default().freeze();
let mut txn_accumulator = TxnAccumulator::new_empty();
let mut result = Vec::new();
for block_gen in block_gens {
let (mut txns_to_commit, mut ledger_info) = block_gen.materialize(&mut universe);
for txn in txns_to_commit.iter_mut() {
let placeholder_txn_info = txn.transaction_info();
let event_hashes: Vec<_> = txn.events().iter().map(CryptoHash::hash).collect();
let event_root_hash = EventAccumulator::from_leaves(&event_hashes).root_hash();
let state_checkpoint_hash = if txn.account_states().is_empty() {
None
} else {
let updates: Vec<_> = txn.account_states().iter().map(|(addr, blob)| {
( HashAccountAddress::hash(addr), blob )
}).collect();
smt = smt.batch_update(updates, &ProofReader::new_empty()).unwrap();
Some(smt.root_hash())
};
let txn_info = TransactionInfo::new(
txn.transaction().hash(),
state_checkpoint_hash.unwrap(),
event_root_hash,
placeholder_txn_info.gas_used(),
placeholder_txn_info.status().clone(),
);
txn_accumulator = txn_accumulator.append(&[txn_info.hash()]);
txn.set_transaction_info(txn_info);
}
ledger_info.set_executed_state_id(txn_accumulator.root_hash());
let validator_set = universe.get_validator_set(ledger_info.epoch());
let signatures = validator_set
.iter()
.map(|signer| (signer.author(), signer.sign(&ledger_info)))
.collect();
let ledger_info_with_sigs = LedgerInfoWithSignatures::new(ledger_info, signatures);
result.push((txns_to_commit, ledger_info_with_sigs))
}
result
}
}
pub fn arb_blocks_to_commit(
) -> impl Strategy<Value = Vec<(Vec<TransactionToCommit>, LedgerInfoWithSignatures)>> {
arb_blocks_to_commit_impl(
5,
2,
10,
)
}