mirror of https://github.com/hyperledger/besu
refactor SimpleWorld to use Optional for storing accounts and extra null checks (#7532)
Signed-off-by: Luis Pinto <luis.pinto@consensys.net>pull/7558/head
parent
e1dd400aa5
commit
4c4f2f3362
@ -0,0 +1,331 @@ |
||||
/* |
||||
* 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.evm.fluent; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
import org.hyperledger.besu.datatypes.Address; |
||||
import org.hyperledger.besu.evm.account.Account; |
||||
import org.hyperledger.besu.evm.account.MutableAccount; |
||||
import org.hyperledger.besu.evm.worldstate.WorldUpdater; |
||||
|
||||
import org.apache.tuweni.units.bigints.UInt256; |
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
public class SimpleWorldTest { |
||||
private static final Address ADDRESS1 = Address.fromHexString("0x0"); |
||||
private static final Address ADDRESS2 = Address.fromHexString("0x1"); |
||||
private static final Address ADDRESS3 = Address.fromHexString("0x2"); |
||||
|
||||
private SimpleWorld simpleWorld; |
||||
|
||||
@BeforeEach |
||||
void setUp() { |
||||
simpleWorld = new SimpleWorld(); |
||||
} |
||||
|
||||
@Test |
||||
void get_noAccounts() { |
||||
assertThat(simpleWorld.get(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void get_noAccountsWithParent() { |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
assertThat(childUpdater.get(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void createAccount_cannotCreateIfExists() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
assertThatThrownBy(() -> simpleWorld.createAccount(ADDRESS1)) |
||||
.isInstanceOf(IllegalStateException.class); |
||||
} |
||||
|
||||
@Test |
||||
void get_createdAccountExistsInParent() { |
||||
MutableAccount account = simpleWorld.createAccount(ADDRESS1); |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
assertThat(childUpdater.get(ADDRESS1)).isEqualTo(account); |
||||
} |
||||
|
||||
@Test |
||||
void get_createdAccountExistsInMultiParent() { |
||||
MutableAccount account = simpleWorld.createAccount(ADDRESS1); |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
childUpdater = childUpdater.updater(); |
||||
childUpdater = childUpdater.updater(); |
||||
childUpdater = childUpdater.updater(); |
||||
assertThat(childUpdater.get(ADDRESS1)).isEqualTo(account); |
||||
} |
||||
|
||||
@Test |
||||
void get_createdAccountExists() { |
||||
MutableAccount account = simpleWorld.createAccount(ADDRESS1); |
||||
assertThat(simpleWorld.get(ADDRESS1)).isEqualTo(account); |
||||
} |
||||
|
||||
@Test |
||||
void get_createdAccountDeleted() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.deleteAccount(ADDRESS1); |
||||
assertThat(simpleWorld.get(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void get_revertRemovesAllAccounts() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.revert(); |
||||
assertThat(simpleWorld.get(ADDRESS1)).isNull(); |
||||
assertThat(simpleWorld.get(ADDRESS2)).isNull(); |
||||
assertThat(simpleWorld.get(ADDRESS3)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void get_commitKeepsAllAccounts() { |
||||
MutableAccount acc1 = simpleWorld.createAccount(ADDRESS1); |
||||
MutableAccount acc2 = simpleWorld.createAccount(ADDRESS2); |
||||
MutableAccount acc3 = simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.commit(); |
||||
assertThat(simpleWorld.get(ADDRESS1)).isEqualTo(acc1); |
||||
assertThat(simpleWorld.get(ADDRESS2)).isEqualTo(acc2); |
||||
assertThat(simpleWorld.get(ADDRESS3)).isEqualTo(acc3); |
||||
} |
||||
|
||||
@Test |
||||
void get_createdAccountDeletedInChild() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
childUpdater.deleteAccount(ADDRESS1); |
||||
assertThat(childUpdater.get(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_noAccounts() { |
||||
assertThat(simpleWorld.getAccount(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_noAccountsWithParent() { |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
assertThat(childUpdater.getAccount(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_createdAccountExistsInParent() { |
||||
MutableAccount account = simpleWorld.createAccount(ADDRESS1); |
||||
account.setStorageValue(UInt256.MAX_VALUE, UInt256.ONE); |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
assertThat(childUpdater.getAccount(ADDRESS1).getOriginalStorageValue(UInt256.MAX_VALUE)) |
||||
.isEqualTo(UInt256.ONE); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_createdAccountExistsInMultiParent() { |
||||
MutableAccount account = simpleWorld.createAccount(ADDRESS1); |
||||
account.setStorageValue(UInt256.MAX_VALUE, UInt256.ONE); |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
childUpdater = childUpdater.updater(); |
||||
childUpdater = childUpdater.updater(); |
||||
childUpdater = childUpdater.updater(); |
||||
assertThat(childUpdater.getAccount(ADDRESS1).getOriginalStorageValue(UInt256.MAX_VALUE)) |
||||
.isEqualTo(UInt256.ONE); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_createdAccountExists() { |
||||
MutableAccount account = simpleWorld.createAccount(ADDRESS1); |
||||
assertThat(simpleWorld.getAccount(ADDRESS1)).isEqualTo(account); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_createdAccountDeleted() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.deleteAccount(ADDRESS1); |
||||
assertThat(simpleWorld.getAccount(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_revertRemovesAllAccounts() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.revert(); |
||||
assertThat(simpleWorld.getAccount(ADDRESS1)).isNull(); |
||||
assertThat(simpleWorld.getAccount(ADDRESS2)).isNull(); |
||||
assertThat(simpleWorld.getAccount(ADDRESS3)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_commitKeepsAllAccounts() { |
||||
MutableAccount acc1 = simpleWorld.createAccount(ADDRESS1); |
||||
MutableAccount acc2 = simpleWorld.createAccount(ADDRESS2); |
||||
MutableAccount acc3 = simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.commit(); |
||||
assertThat(simpleWorld.getAccount(ADDRESS1)).isEqualTo(acc1); |
||||
assertThat(simpleWorld.getAccount(ADDRESS2)).isEqualTo(acc2); |
||||
assertThat(simpleWorld.getAccount(ADDRESS3)).isEqualTo(acc3); |
||||
} |
||||
|
||||
@Test |
||||
void getAccount_createdAccountDeletedInChild() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
WorldUpdater childUpdater = simpleWorld.updater(); |
||||
childUpdater.deleteAccount(ADDRESS1); |
||||
assertThat(childUpdater.getAccount(ADDRESS1)).isNull(); |
||||
} |
||||
|
||||
@Test |
||||
void getTouchedAccounts_createdAccounts() { |
||||
Account acc1 = simpleWorld.createAccount(ADDRESS1); |
||||
Account acc2 = simpleWorld.createAccount(ADDRESS2); |
||||
Account acc3 = simpleWorld.createAccount(ADDRESS3); |
||||
assertThat(simpleWorld.getTouchedAccounts().toArray()) |
||||
.containsExactlyInAnyOrder(acc1, acc2, acc3); |
||||
} |
||||
|
||||
@Test |
||||
void getTouchedAccounts_revertedAccounts() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.revert(); |
||||
assertThat(simpleWorld.getTouchedAccounts()).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
void getTouchedAccounts_createdAndDeletedAccounts() { |
||||
Account acc1 = simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
Account acc3 = simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.deleteAccount(ADDRESS2); |
||||
assertThat(simpleWorld.getTouchedAccounts().toArray()).containsExactlyInAnyOrder(acc1, acc3); |
||||
} |
||||
|
||||
@Test |
||||
void getTouchedAccounts_allDeletedAccounts() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.deleteAccount(ADDRESS1); |
||||
simpleWorld.deleteAccount(ADDRESS2); |
||||
simpleWorld.deleteAccount(ADDRESS3); |
||||
assertThat(simpleWorld.getTouchedAccounts()).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
void getTouchedAccounts_createdAndCommittedAccounts() { |
||||
Account acc1 = simpleWorld.createAccount(ADDRESS1); |
||||
Account acc2 = simpleWorld.createAccount(ADDRESS2); |
||||
Account acc3 = simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.commit(); |
||||
assertThat(simpleWorld.getTouchedAccounts().toArray()) |
||||
.containsExactlyInAnyOrder(acc1, acc2, acc3); |
||||
} |
||||
|
||||
@Test |
||||
void getDeletedAccountAddresses_singleDeleted() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.deleteAccount(ADDRESS2); |
||||
assertThat(simpleWorld.getDeletedAccountAddresses().toArray()).containsExactly(ADDRESS2); |
||||
} |
||||
|
||||
@Test |
||||
void getDeletedAccountAddresses_allDeleted() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.deleteAccount(ADDRESS1); |
||||
simpleWorld.deleteAccount(ADDRESS2); |
||||
simpleWorld.deleteAccount(ADDRESS3); |
||||
assertThat(simpleWorld.getDeletedAccountAddresses().toArray()) |
||||
.containsExactlyInAnyOrder(ADDRESS1, ADDRESS2, ADDRESS3); |
||||
} |
||||
|
||||
@Test |
||||
void getDeletedAccountAddresses_allDeletedThenRevert() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.deleteAccount(ADDRESS1); |
||||
simpleWorld.deleteAccount(ADDRESS2); |
||||
simpleWorld.deleteAccount(ADDRESS3); |
||||
simpleWorld.revert(); |
||||
assertThat(simpleWorld.getDeletedAccountAddresses()).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
void getDeletedAccountAddresses_allDeletedThenCommit() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.deleteAccount(ADDRESS1); |
||||
simpleWorld.deleteAccount(ADDRESS2); |
||||
simpleWorld.deleteAccount(ADDRESS3); |
||||
simpleWorld.commit(); |
||||
assertThat(simpleWorld.getDeletedAccountAddresses().toArray()) |
||||
.containsExactlyInAnyOrder(ADDRESS1, ADDRESS2, ADDRESS3); |
||||
} |
||||
|
||||
@Test |
||||
void commit_deletedAccountNoNPEs() { |
||||
simpleWorld.createAccount(ADDRESS1); |
||||
simpleWorld.createAccount(ADDRESS2); |
||||
simpleWorld.createAccount(ADDRESS3); |
||||
simpleWorld.deleteAccount(ADDRESS1); |
||||
simpleWorld.commit(); |
||||
} |
||||
|
||||
@Test |
||||
void commit_onlyCommitsNewAccountsToDirectParent() { |
||||
WorldUpdater simpleWorldLevel1 = simpleWorld.updater(); |
||||
WorldUpdater simpleWorldLevel2 = simpleWorldLevel1.updater(); |
||||
MutableAccount createdAccount = simpleWorldLevel2.createAccount(ADDRESS1); |
||||
simpleWorldLevel2.commit(); |
||||
assertThat(simpleWorldLevel1.getTouchedAccounts().toArray()).containsExactly(createdAccount); |
||||
assertThat(simpleWorld.getTouchedAccounts()).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
void commit_onlyCommitsDeletedAccountsToDirectParent() { |
||||
WorldUpdater simpleWorldLevel1 = simpleWorld.updater(); |
||||
WorldUpdater simpleWorldLevel2 = simpleWorldLevel1.updater(); |
||||
simpleWorldLevel2.createAccount(ADDRESS2); |
||||
simpleWorldLevel2.deleteAccount(ADDRESS2); |
||||
simpleWorldLevel2.commit(); |
||||
assertThat(simpleWorldLevel1.getDeletedAccountAddresses().toArray()).containsExactly(ADDRESS2); |
||||
assertThat(simpleWorld.getDeletedAccountAddresses()).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
void commit_accountsReflectChangesAfterCommit() { |
||||
MutableAccount account = simpleWorld.createAccount(ADDRESS1); |
||||
account.setStorageValue(UInt256.MAX_VALUE, UInt256.ONE); |
||||
WorldUpdater simpleWorldUpdater = simpleWorld.updater(); |
||||
|
||||
account = simpleWorldUpdater.getAccount(ADDRESS1); |
||||
account.setStorageValue(UInt256.MAX_VALUE, UInt256.valueOf(22L)); |
||||
simpleWorldUpdater.commit(); |
||||
|
||||
assertThat(simpleWorldUpdater.get(ADDRESS1).getStorageValue(UInt256.MAX_VALUE)) |
||||
.isEqualTo(simpleWorldUpdater.get(ADDRESS1).getOriginalStorageValue(UInt256.MAX_VALUE)); |
||||
} |
||||
} |
Loading…
Reference in new issue