|
|
|
@ -64,9 +64,7 @@ public class AccountHealingTrackingTest { |
|
|
|
|
DataStorageConfiguration.DEFAULT_BONSAI_CONFIG); |
|
|
|
|
|
|
|
|
|
private WorldStateStorageCoordinator worldStateStorageCoordinator; |
|
|
|
|
|
|
|
|
|
private WorldStateProofProvider worldStateProofProvider; |
|
|
|
|
|
|
|
|
|
private MerkleTrie<Bytes, Bytes> accountStateTrie; |
|
|
|
|
|
|
|
|
|
@Mock SnapWorldDownloadState snapWorldDownloadState; |
|
|
|
@ -82,9 +80,7 @@ public class AccountHealingTrackingTest { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
void avoidMarkingAccountWhenStorageProofValid() { |
|
|
|
|
|
|
|
|
|
// generate valid proof
|
|
|
|
|
void shouldMarkAccountForHealingWhenStorageProofIsReceived() { |
|
|
|
|
final Hash accountHash = Hash.hash(accounts.get(0)); |
|
|
|
|
final StateTrieAccountValue stateTrieAccountValue = |
|
|
|
|
StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); |
|
|
|
@ -108,7 +104,7 @@ public class AccountHealingTrackingTest { |
|
|
|
|
root -> |
|
|
|
|
RangeStorageEntriesCollector.collectEntries( |
|
|
|
|
collector, visitor, root, Hash.ZERO)); |
|
|
|
|
// generate the proof
|
|
|
|
|
|
|
|
|
|
final List<Bytes> proofs = |
|
|
|
|
worldStateProofProvider.getStorageProofRelatedNodes( |
|
|
|
|
Hash.wrap(storageTrie.getRootHash()), accountHash, Hash.ZERO); |
|
|
|
@ -127,11 +123,53 @@ public class AccountHealingTrackingTest { |
|
|
|
|
snapWorldDownloadState, worldStateProofProvider, slots, new ArrayDeque<>(proofs)); |
|
|
|
|
storageRangeDataRequest.getChildRequests( |
|
|
|
|
snapWorldDownloadState, worldStateStorageCoordinator, null); |
|
|
|
|
|
|
|
|
|
verify(snapWorldDownloadState).addAccountToHealingList(any(Bytes.class)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
void shouldNotMarkAccountForHealingWhenAllStorageIsReceivedWithoutProof() { |
|
|
|
|
final Hash accountHash = Hash.hash(accounts.get(0)); |
|
|
|
|
final StateTrieAccountValue stateTrieAccountValue = |
|
|
|
|
StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); |
|
|
|
|
|
|
|
|
|
final StoredMerklePatriciaTrie<Bytes, Bytes> storageTrie = |
|
|
|
|
new StoredMerklePatriciaTrie<>( |
|
|
|
|
new StoredNodeFactory<>( |
|
|
|
|
(location, hash) -> |
|
|
|
|
worldStateKeyValueStorage.getAccountStorageTrieNode( |
|
|
|
|
accountHash, location, hash), |
|
|
|
|
Function.identity(), |
|
|
|
|
Function.identity()), |
|
|
|
|
stateTrieAccountValue.getStorageRoot()); |
|
|
|
|
|
|
|
|
|
final RangeStorageEntriesCollector collector = |
|
|
|
|
RangeStorageEntriesCollector.createCollector(Hash.ZERO, MAX_RANGE, 10, Integer.MAX_VALUE); |
|
|
|
|
final TrieIterator<Bytes> visitor = RangeStorageEntriesCollector.createVisitor(collector); |
|
|
|
|
final TreeMap<Bytes32, Bytes> slots = |
|
|
|
|
(TreeMap<Bytes32, Bytes>) |
|
|
|
|
storageTrie.entriesFrom( |
|
|
|
|
root -> |
|
|
|
|
RangeStorageEntriesCollector.collectEntries( |
|
|
|
|
collector, visitor, root, Hash.ZERO)); |
|
|
|
|
|
|
|
|
|
final StorageRangeDataRequest storageRangeDataRequest = |
|
|
|
|
SnapDataRequest.createStorageRangeDataRequest( |
|
|
|
|
Hash.wrap(accountStateTrie.getRootHash()), |
|
|
|
|
accountHash, |
|
|
|
|
storageTrie.getRootHash(), |
|
|
|
|
Hash.ZERO, |
|
|
|
|
MAX_RANGE); |
|
|
|
|
storageRangeDataRequest.addResponse( |
|
|
|
|
snapWorldDownloadState, worldStateProofProvider, slots, new ArrayDeque<>()); |
|
|
|
|
storageRangeDataRequest.getChildRequests( |
|
|
|
|
snapWorldDownloadState, worldStateStorageCoordinator, null); |
|
|
|
|
|
|
|
|
|
verify(snapWorldDownloadState, never()).addAccountToHealingList(any(Bytes.class)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
void markAccountOnInvalidStorageProof() { |
|
|
|
|
void shouldMarkAccountForHealingOnInvalidStorageProof() { |
|
|
|
|
final Hash accountHash = Hash.hash(accounts.get(0)); |
|
|
|
|
final StateTrieAccountValue stateTrieAccountValue = |
|
|
|
|
StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); |
|
|
|
@ -157,8 +195,7 @@ public class AccountHealingTrackingTest { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
void markAccountOnPartialStorageRange() { |
|
|
|
|
// generate valid proof
|
|
|
|
|
void shouldMarkAccountForHealingOnInvalidStorageWithoutProof() { |
|
|
|
|
final Hash accountHash = Hash.hash(accounts.get(0)); |
|
|
|
|
final StateTrieAccountValue stateTrieAccountValue = |
|
|
|
|
StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); |
|
|
|
@ -174,11 +211,46 @@ public class AccountHealingTrackingTest { |
|
|
|
|
stateTrieAccountValue.getStorageRoot()); |
|
|
|
|
|
|
|
|
|
final RangeStorageEntriesCollector collector = |
|
|
|
|
RangeStorageEntriesCollector.createCollector( |
|
|
|
|
RangeStorageEntriesCollector.createCollector(Hash.ZERO, MAX_RANGE, 1, Integer.MAX_VALUE); |
|
|
|
|
final TrieIterator<Bytes> visitor = RangeStorageEntriesCollector.createVisitor(collector); |
|
|
|
|
final TreeMap<Bytes32, Bytes> slots = |
|
|
|
|
(TreeMap<Bytes32, Bytes>) |
|
|
|
|
storageTrie.entriesFrom( |
|
|
|
|
root -> |
|
|
|
|
RangeStorageEntriesCollector.collectEntries( |
|
|
|
|
collector, visitor, root, Hash.ZERO)); |
|
|
|
|
|
|
|
|
|
final StorageRangeDataRequest storageRangeDataRequest = |
|
|
|
|
SnapDataRequest.createStorageRangeDataRequest( |
|
|
|
|
Hash.wrap(accountStateTrie.getRootHash()), |
|
|
|
|
accountHash, |
|
|
|
|
storageTrie.getRootHash(), |
|
|
|
|
Hash.ZERO, |
|
|
|
|
MAX_RANGE, |
|
|
|
|
1, |
|
|
|
|
Integer.MAX_VALUE); // limit to 1 in order to have a partial range
|
|
|
|
|
MAX_RANGE); |
|
|
|
|
storageRangeDataRequest.addResponse( |
|
|
|
|
snapWorldDownloadState, worldStateProofProvider, slots, new ArrayDeque<>()); |
|
|
|
|
|
|
|
|
|
verify(snapWorldDownloadState).addAccountToHealingList(any(Bytes.class)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
void shouldMarkAccountForHealingOnPartialStorageRange() { |
|
|
|
|
final Hash accountHash = Hash.hash(accounts.get(0)); |
|
|
|
|
final StateTrieAccountValue stateTrieAccountValue = |
|
|
|
|
StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); |
|
|
|
|
|
|
|
|
|
final StoredMerklePatriciaTrie<Bytes, Bytes> storageTrie = |
|
|
|
|
new StoredMerklePatriciaTrie<>( |
|
|
|
|
new StoredNodeFactory<>( |
|
|
|
|
(location, hash) -> |
|
|
|
|
worldStateKeyValueStorage.getAccountStorageTrieNode( |
|
|
|
|
accountHash, location, hash), |
|
|
|
|
Function.identity(), |
|
|
|
|
Function.identity()), |
|
|
|
|
stateTrieAccountValue.getStorageRoot()); |
|
|
|
|
|
|
|
|
|
final RangeStorageEntriesCollector collector = |
|
|
|
|
RangeStorageEntriesCollector.createCollector(Hash.ZERO, MAX_RANGE, 1, Integer.MAX_VALUE); |
|
|
|
|
final TrieIterator<Bytes> visitor = RangeStorageEntriesCollector.createVisitor(collector); |
|
|
|
|
final TreeMap<Bytes32, Bytes> slots = |
|
|
|
|
(TreeMap<Bytes32, Bytes>) |
|
|
|
@ -186,7 +258,7 @@ public class AccountHealingTrackingTest { |
|
|
|
|
root -> |
|
|
|
|
RangeStorageEntriesCollector.collectEntries( |
|
|
|
|
collector, visitor, root, Hash.ZERO)); |
|
|
|
|
// generate the proof
|
|
|
|
|
|
|
|
|
|
final List<Bytes> proofs = |
|
|
|
|
worldStateProofProvider.getStorageProofRelatedNodes( |
|
|
|
|
Hash.wrap(storageTrie.getRootHash()), accountHash, Hash.ZERO); |
|
|
|
@ -205,14 +277,14 @@ public class AccountHealingTrackingTest { |
|
|
|
|
snapWorldDownloadState, worldStateProofProvider, slots, new ArrayDeque<>(proofs)); |
|
|
|
|
verify(snapWorldDownloadState, never()).addAccountToHealingList(any(Bytes.class)); |
|
|
|
|
|
|
|
|
|
// should mark during the getchild request
|
|
|
|
|
storageRangeDataRequest.getChildRequests( |
|
|
|
|
snapWorldDownloadState, worldStateStorageCoordinator, null); |
|
|
|
|
|
|
|
|
|
verify(snapWorldDownloadState).addAccountToHealingList(any(Bytes.class)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
void avoidMarkingAccountOnValidStorageTrieNodeDetection() { |
|
|
|
|
void shouldNotMarkAccountForHealingOnValidStorageTrieNodeDetection() { |
|
|
|
|
final Hash accountHash = Hash.hash(accounts.get(0)); |
|
|
|
|
final StateTrieAccountValue stateTrieAccountValue = |
|
|
|
|
StateTrieAccountValue.readFrom(RLP.input(accountStateTrie.get(accountHash).orElseThrow())); |
|
|
|
@ -223,6 +295,7 @@ public class AccountHealingTrackingTest { |
|
|
|
|
Hash.wrap(accountStateTrie.getRootHash()), |
|
|
|
|
Bytes.EMPTY); |
|
|
|
|
storageTrieNodeHealingRequest.getExistingData(worldStateStorageCoordinator); |
|
|
|
|
|
|
|
|
|
verify(snapWorldDownloadState, never()).addAccountToHealingList(any(Bytes.class)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|