mirror of https://github.com/hyperledger/besu
TrieLog shipping prep (#5317)
* trielog save event, observer, test * add zero read slots to Accumulator storageToUpdate, omit zero read slots from trielog generation * add account zero reads, mark self-destructed accounts, code and storage as cleared Signed-off-by: garyschulte <garyschulte@gmail.com>pull/5374/head
parent
de4aa7b8f5
commit
9eec16eed4
@ -0,0 +1,35 @@ |
||||
/* |
||||
* Copyright contributors to Hyperledger Besu. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
* |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.bonsai.trielog; |
||||
|
||||
public class TrieLogAddedEvent { |
||||
|
||||
private final TrieLogLayer layer; |
||||
|
||||
public TrieLogAddedEvent(final TrieLogLayer layer) { |
||||
this.layer = layer; |
||||
} |
||||
|
||||
public TrieLogLayer getLayer() { |
||||
return layer; |
||||
} |
||||
|
||||
@FunctionalInterface |
||||
interface TrieLogAddedObserver { |
||||
|
||||
void onTrieLogAdded(TrieLogAddedEvent event); |
||||
} |
||||
} |
@ -0,0 +1,122 @@ |
||||
/* |
||||
* Copyright contributors to Hyperledger Besu. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
* |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.bonsai.trielog; |
||||
|
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.datatypes.Hash; |
||||
import org.hyperledger.besu.datatypes.Wei; |
||||
import org.hyperledger.besu.ethereum.worldstate.StateTrieAccountValue; |
||||
|
||||
import java.util.Optional; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.apache.tuweni.units.bigints.UInt256; |
||||
import org.assertj.core.api.Assertions; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
public class TrieLogLayerTests { |
||||
private TrieLogLayer trieLogLayer; |
||||
private TrieLogLayer otherTrieLogLayer; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
trieLogLayer = new TrieLogLayer(); |
||||
otherTrieLogLayer = new TrieLogLayer(); |
||||
} |
||||
|
||||
@Test |
||||
public void testAddAccountChange() { |
||||
Address address = Address.fromHexString("0x00"); |
||||
StateTrieAccountValue oldValue = new StateTrieAccountValue(0, Wei.ZERO, Hash.EMPTY, Hash.EMPTY); |
||||
StateTrieAccountValue newValue = |
||||
new StateTrieAccountValue(1, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY); |
||||
|
||||
Address otherAddress = Address.fromHexString("0x000000"); |
||||
StateTrieAccountValue otherOldValue = |
||||
new StateTrieAccountValue(0, Wei.ZERO, Hash.EMPTY, Hash.EMPTY); |
||||
StateTrieAccountValue otherNewValue = |
||||
new StateTrieAccountValue(1, Wei.fromEth(1), Hash.EMPTY, Hash.EMPTY); |
||||
|
||||
trieLogLayer.addAccountChange(address, oldValue, newValue); |
||||
otherTrieLogLayer.addAccountChange(otherAddress, otherOldValue, otherNewValue); |
||||
|
||||
Assertions.assertThat(trieLogLayer).isEqualTo(otherTrieLogLayer); |
||||
|
||||
Optional<StateTrieAccountValue> priorAccount = trieLogLayer.getPriorAccount(address); |
||||
Assertions.assertThat(priorAccount).isPresent(); |
||||
Assertions.assertThat(priorAccount.get()).isEqualTo(oldValue); |
||||
|
||||
Optional<StateTrieAccountValue> updatedAccount = trieLogLayer.getAccount(address); |
||||
Assertions.assertThat(updatedAccount).isPresent(); |
||||
Assertions.assertThat(updatedAccount.get()).isEqualTo(newValue); |
||||
} |
||||
|
||||
@Test |
||||
public void testAddCodeChange() { |
||||
Address address = Address.fromHexString("0xdeadbeef"); |
||||
Bytes oldValue = Bytes.fromHexString("0x00"); |
||||
Bytes newValue = Bytes.fromHexString("0x01030307"); |
||||
Hash blockHash = Hash.fromHexStringLenient("0xfeedbeef02dead"); |
||||
|
||||
Address otherAddress = Address.fromHexString("0x0000deadbeef"); |
||||
Bytes otherOldValue = Bytes.fromHexString("0x00"); |
||||
Bytes otherNewValue = Bytes.fromHexString("0x01030307"); |
||||
Hash otherBlockHash = Hash.fromHexStringLenient("0x00feedbeef02dead"); |
||||
|
||||
trieLogLayer.addCodeChange(address, oldValue, newValue, blockHash); |
||||
otherTrieLogLayer.addCodeChange(otherAddress, otherOldValue, otherNewValue, otherBlockHash); |
||||
|
||||
Assertions.assertThat(trieLogLayer).isEqualTo(otherTrieLogLayer); |
||||
|
||||
Optional<Bytes> priorCode = trieLogLayer.getPriorCode(address); |
||||
Assertions.assertThat(priorCode).isPresent(); |
||||
Assertions.assertThat(priorCode.get()).isEqualTo(oldValue); |
||||
|
||||
Optional<Bytes> updatedCode = trieLogLayer.getCode(address); |
||||
Assertions.assertThat(updatedCode).isPresent(); |
||||
Assertions.assertThat(updatedCode.get()).isEqualTo(newValue); |
||||
} |
||||
|
||||
@Test |
||||
public void testAddStorageChange() { |
||||
Address address = Address.fromHexString("0x0"); |
||||
UInt256 oldValue = UInt256.ZERO; |
||||
UInt256 newValue = UInt256.ONE; |
||||
UInt256 slot = UInt256.ONE; |
||||
|
||||
Address otherAddress = Address.fromHexString("0x0"); |
||||
UInt256 otherOldValue = UInt256.ZERO; |
||||
UInt256 otherNewValue = UInt256.ONE; |
||||
UInt256 otherSlot = UInt256.ONE; |
||||
|
||||
trieLogLayer.addStorageChange(address, Hash.hash(slot), oldValue, newValue); |
||||
otherTrieLogLayer.addStorageChange( |
||||
otherAddress, Hash.hash(otherSlot), otherOldValue, otherNewValue); |
||||
|
||||
Assertions.assertThat(trieLogLayer).isEqualTo(otherTrieLogLayer); |
||||
|
||||
Optional<UInt256> priorStorageValue = |
||||
trieLogLayer.getPriorStorageBySlotHash(address, Hash.hash(slot)); |
||||
Assertions.assertThat(priorStorageValue).isPresent(); |
||||
Assertions.assertThat(priorStorageValue.get()).isEqualTo(oldValue); |
||||
|
||||
Optional<UInt256> updatedStorageValue = |
||||
trieLogLayer.getStorageBySlotHash(address, Hash.hash(slot)); |
||||
Assertions.assertThat(updatedStorageValue).isPresent(); |
||||
Assertions.assertThat(updatedStorageValue.get()).isEqualTo(newValue); |
||||
} |
||||
} |
@ -0,0 +1,77 @@ |
||||
/* |
||||
* Copyright contributors to Hyperledger Besu. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
* |
||||
* SPDX-License-Identifier: Apache-2.0 |
||||
* |
||||
*/ |
||||
package org.hyperledger.besu.ethereum.bonsai.trielog; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.mockito.Mockito.spy; |
||||
|
||||
import org.hyperledger.besu.datatypes.Hash; |
||||
import org.hyperledger.besu.ethereum.bonsai.BonsaiWorldStateProvider; |
||||
import org.hyperledger.besu.ethereum.bonsai.cache.CachedWorldStorageManager; |
||||
import org.hyperledger.besu.ethereum.bonsai.storage.BonsaiWorldStateKeyValueStorage; |
||||
import org.hyperledger.besu.ethereum.bonsai.worldview.BonsaiWorldState; |
||||
import org.hyperledger.besu.ethereum.bonsai.worldview.BonsaiWorldStateUpdateAccumulator; |
||||
import org.hyperledger.besu.ethereum.chain.Blockchain; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeader; |
||||
import org.hyperledger.besu.ethereum.core.BlockHeaderTestFixture; |
||||
import org.hyperledger.besu.metrics.noop.NoOpMetricsSystem; |
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.mockito.Answers; |
||||
import org.mockito.Mock; |
||||
import org.mockito.junit.MockitoJUnitRunner; |
||||
|
||||
@RunWith(MockitoJUnitRunner.class) |
||||
public class TrieLogManagerTests { |
||||
|
||||
BlockHeader blockHeader = new BlockHeaderTestFixture().buildHeader(); |
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS) |
||||
BonsaiWorldState bonsaiWorldState; |
||||
|
||||
@Mock BonsaiWorldStateKeyValueStorage bonsaiWorldStateKeyValueStorage; |
||||
@Mock BonsaiWorldState worldState; |
||||
@Mock BonsaiWorldStateProvider archive; |
||||
@Mock Blockchain blockchain; |
||||
BonsaiWorldStateUpdateAccumulator bonsaiUpdater = |
||||
spy(new BonsaiWorldStateUpdateAccumulator(worldState, (__, ___) -> {}, (__, ___) -> {})); |
||||
|
||||
TrieLogManager trieLogManager; |
||||
|
||||
@Before |
||||
public void setup() { |
||||
trieLogManager = |
||||
new CachedWorldStorageManager( |
||||
archive, blockchain, bonsaiWorldStateKeyValueStorage, new NoOpMetricsSystem(), 512); |
||||
} |
||||
|
||||
@Test |
||||
public void testSaveTrieLogEvent() { |
||||
AtomicBoolean eventFired = new AtomicBoolean(false); |
||||
trieLogManager.subscribe( |
||||
layer -> { |
||||
assertThat(layer).isNotNull(); |
||||
eventFired.set(true); |
||||
}); |
||||
trieLogManager.saveTrieLog(bonsaiUpdater, Hash.ZERO, blockHeader, bonsaiWorldState); |
||||
|
||||
assertThat(eventFired.get()).isTrue(); |
||||
} |
||||
} |
Loading…
Reference in new issue