Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

[PAN-2829] Account versioning #1612

Merged
merged 7 commits into from
Jul 11, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ private static void writeAccountsTo(
genesisAccount -> {
final MutableAccount account = updater.getOrCreate(genesisAccount.address);
account.setBalance(genesisAccount.balance);
account.setCode(genesisAccount.code, genesisAccount.version);
account.setCode(genesisAccount.code);
account.setVersion(genesisAccount.version);
genesisAccount.storage.forEach(account::setStorageValue);
});
updater.commit();
Expand Down Expand Up @@ -219,7 +220,7 @@ private static final class GenesisAccount {
final Wei balance;
final Map<UInt256, UInt256> storage;
final BytesValue code;
final long version;
final int version;

static GenesisAccount fromAllocation(final GenesisAllocation allocation) {
return new GenesisAccount(
Expand All @@ -239,7 +240,7 @@ private GenesisAccount(
this.address = withNiceErrorMessage("address", hexAddress, Address::fromHexString);
this.balance = withNiceErrorMessage("balance", balance, this::parseBalance);
this.code = hexCode != null ? BytesValue.fromHexString(hexCode) : null;
this.version = version != null ? Long.decode(version) : Account.DEFAULT_VERSION;
this.version = version != null ? Integer.decode(version) : Account.DEFAULT_VERSION;
this.storage = parseStorage(storage);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public static class UpdateTrackingAccount<A extends Account> implements MutableA

private long nonce;
private Wei balance;
private long version;
private int version;

@Nullable private BytesValue updatedCode; // Null if the underlying code has not been updated.
@Nullable private Hash updatedCodeHash;
Expand Down Expand Up @@ -282,13 +282,17 @@ public boolean hasCode() {
}

@Override
public void setCode(final BytesValue code, final long version) {
public void setCode(final BytesValue code) {
this.updatedCode = code;
}

@Override
public void setVersion(final int version) {
this.version = version;
}

@Override
public long getVersion() {
public int getVersion() {
return version;
}

Expand Down Expand Up @@ -427,7 +431,8 @@ public void commit() {
existing.setNonce(update.getNonce());
existing.setBalance(update.getBalance());
if (update.codeWasUpdated()) {
existing.setCode(update.getCode(), update.getVersion());
existing.setCode(update.getCode());
existing.setVersion(update.getVersion());
}
if (update.getStorageWasCleared()) {
existing.clearStorage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public interface Account {

long DEFAULT_NONCE = 0L;
Wei DEFAULT_BALANCE = Wei.ZERO;
long DEFAULT_VERSION = 0L;
int DEFAULT_VERSION = 0;

/**
* The Keccak-256 hash of the account address.
Expand Down Expand Up @@ -106,7 +106,7 @@ default boolean hasCode() {
*
* @return the version of the account code. Default is zero.
*/
long getVersion();
int getVersion();

/**
* Retrieves a value in the account storage given its key.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,15 @@ default Wei decrementBalance(final Wei value) {
* Sets the code for the account.
*
* @param code the code to set for the account.
*/
void setCode(BytesValue code);

/**
* Sets the version for the account.
*
* @param version the version of the code being set
*/
void setCode(BytesValue code, long version);
void setVersion(int version);

/**
* Sets a particular key-value pair in the account storage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class MainnetContractCreationProcessor extends AbstractMessageProcessor {

private final int codeSizeLimit;

private final long accountVersion;
private final int accountVersion;

public MainnetContractCreationProcessor(
final GasCalculator gasCalculator,
Expand All @@ -49,7 +49,7 @@ public MainnetContractCreationProcessor(
final int codeSizeLimit,
final long initialContractNonce,
final Collection<Address> forceCommitAddresses,
final long accountVersion) {
final int accountVersion) {
super(evm, forceCommitAddresses);
this.gasCalculator = gasCalculator;
this.requireCodeDepositToSucceed = requireCodeDepositToSucceed;
Expand Down Expand Up @@ -152,7 +152,8 @@ protected void codeSuccess(final MessageFrame frame) {
// Finalize contract creation, setting the contract code.
final MutableAccount contract =
frame.getWorldState().getOrCreate(frame.getContractAddress());
contract.setCode(contractCode, accountVersion);
contract.setCode(contractCode);
contract.setVersion(accountVersion);
LOG.trace(
"Successful creation of contract {} with code of size {} (Gas remaining: {})",
frame.getContractAddress(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,12 @@ public static ProtocolSpecBuilder<Void> constantinopleFixDefinition(
public static ProtocolSpecBuilder<Void> istanbulDefinition(
final Optional<BigInteger> chainId,
final OptionalInt configContractSizeLimit,
final OptionalInt configStackSizeLimit) {
final OptionalInt configStackSizeLimit,
final boolean enableRevertReason) {
final int contractSizeLimit =
configContractSizeLimit.orElse(SPURIOUS_DRAGON_CONTRACT_SIZE_LIMIT);
return constantinopleFixDefinition(chainId, configContractSizeLimit, configStackSizeLimit)
return constantinopleFixDefinition(
chainId, configContractSizeLimit, configStackSizeLimit, enableRevertReason)
.contractCreationProcessorBuilder(
(gasCalculator, evm) ->
new MainnetContractCreationProcessor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private static BytesValue serializeAccount(
final Wei balance,
final Hash storageRoot,
final Hash codeHash,
final long version) {
final int version) {
final StateTrieAccountValue accountValue =
new StateTrieAccountValue(nonce, balance, storageRoot, codeHash, version);
return RLP.encode(accountValue::writeTo);
Expand Down Expand Up @@ -248,7 +248,7 @@ public Hash getCodeHash() {
}

@Override
public long getVersion() {
public int getVersion() {
return accountValue.getVersion();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class StateTrieAccountValue {
private final Wei balance;
private final Hash storageRoot;
private final Hash codeHash;
private final long version;
private final int version;

private StateTrieAccountValue(
final long nonce, final Wei balance, final Hash storageRoot, final Hash codeHash) {
Expand All @@ -37,7 +37,7 @@ public StateTrieAccountValue(
final Wei balance,
final Hash storageRoot,
final Hash codeHash,
final long version) {
final int version) {
this.nonce = nonce;
this.balance = balance;
this.storageRoot = storageRoot;
Expand Down Expand Up @@ -86,7 +86,7 @@ public Hash getCodeHash() {
*
* @return the version of the account code.
*/
public long getVersion() {
public int getVersion() {
return version;
}

Expand All @@ -113,9 +113,9 @@ public static StateTrieAccountValue readFrom(final RLPInput in) {
final Wei balance = in.readUInt256Scalar(Wei::wrap);
final Hash storageRoot = Hash.wrap(in.readBytes32());
final Hash codeHash = Hash.wrap(in.readBytes32());
final long version;
final int version;
if (!in.isEndOfCurrentList()) {
version = in.readLongScalar();
version = in.readIntScalar();
} else {
version = Account.DEFAULT_VERSION;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ private List<Account> createRandomAccounts(
MutableAccount account = updater.getOrCreate(address());
if (random.nextFloat() < percentContractAccounts) {
// Some percentage of accounts are contract accounts
account.setCode(bytesValue(5, 50), Account.DEFAULT_VERSION);
account.setCode(bytesValue(5, 50));
account.setVersion(Account.DEFAULT_VERSION);
if (random.nextFloat() < percentContractAccountsWithNonEmptyStorage) {
// Add some storage for contract accounts
int storageValues = random.nextInt(20) + 10;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ public void createFromJsonNoAllocs() throws Exception {
assertThat(header.getParentHash()).isEqualTo(Hash.ZERO);
}

private void assertContractInvariants(final String sourceFile, final String blockHash, final int version)
throws Exception {
private void assertContractInvariants(
final String sourceFile, final String blockHash, final int version) throws Exception {
final GenesisState genesisState =
GenesisState.fromJson(
Resources.toString(GenesisStateTest.class.getResource(sourceFile), Charsets.UTF_8),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static class AccountMock {
private final long nonce;
private final Wei balance;
private final BytesValue code;
private final long version;
private final int version;
private final Map<UInt256, UInt256> storage;

private static final Map<UInt256, UInt256> parseStorage(final Map<String, String> values) {
Expand All @@ -55,7 +55,7 @@ public AccountMock(
this.code = BytesValue.fromHexString(code);
this.storage = parseStorage(storage);
if (version != null) {
this.version = Long.decode(version);
this.version = Integer.decode(version);
} else {
this.version = 0;
}
Expand All @@ -73,7 +73,7 @@ public BytesValue getCode() {
return code;
}

public long getVersion() {
public int getVersion() {
return version;
}

Expand All @@ -87,7 +87,8 @@ public static void insertAccount(
final MutableAccount account = updater.getOrCreate(address);
account.setNonce(toCopy.getNonce());
account.setBalance(toCopy.getBalance());
account.setCode(toCopy.getCode(), toCopy.getVersion());
account.setCode(toCopy.getCode());
account.setVersion(toCopy.getVersion());
for (final Map.Entry<UInt256, UInt256> entry : toCopy.getStorage().entrySet()) {
account.setStorageValue(entry.getKey(), entry.getValue());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import tech.pegasys.pantheon.ethereum.core.Gas;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.core.MessageFrameTestFixture;
import tech.pegasys.pantheon.ethereum.core.MutableAccount;
import tech.pegasys.pantheon.ethereum.core.Wei;
import tech.pegasys.pantheon.ethereum.core.WorldUpdater;
import tech.pegasys.pantheon.ethereum.mainnet.ConstantinopleGasCalculator;
Expand Down Expand Up @@ -89,15 +90,19 @@ public void shouldReturnEmptyCodeHashWhenPrecompileHasBalance() {
@Test
public void shouldGetHashOfAccountCodeWhenCodeIsPresent() {
final BytesValue code = BytesValue.fromHexString("0xabcdef");
worldStateUpdater.getOrCreate(REQUESTED_ADDRESS).setCode(code, Account.DEFAULT_VERSION);
MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS);
shemnon marked this conversation as resolved.
Show resolved Hide resolved
account.setCode(code);
account.setVersion(Account.DEFAULT_VERSION);
assertThat(executeOperation(REQUESTED_ADDRESS)).isEqualTo(Hash.hash(code));
}

@Test
public void shouldZeroOutLeftMostBitsToGetAddress() {
// If EXTCODEHASH of A is X, then EXTCODEHASH of A + 2**160 is X.
final BytesValue code = BytesValue.fromHexString("0xabcdef");
worldStateUpdater.getOrCreate(REQUESTED_ADDRESS).setCode(code, Account.DEFAULT_VERSION);
MutableAccount account = worldStateUpdater.getOrCreate(REQUESTED_ADDRESS);
shemnon marked this conversation as resolved.
Show resolved Hide resolved
account.setCode(code);
account.setVersion(Account.DEFAULT_VERSION);
final Bytes32 value =
Words.fromAddress(REQUESTED_ADDRESS)
.asUInt256()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import tech.pegasys.pantheon.ethereum.core.Account;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.ethereum.core.MutableAccount;
Expand Down Expand Up @@ -482,8 +481,8 @@ public void replaceAccountCode() {
final WorldUpdater updater = worldState.updater();
final MutableAccount account = updater.createAccount(ADDRESS);
account.setBalance(Wei.of(100000));
account.setCode(BytesValue.of(1, 2, 3), Account.DEFAULT_VERSION);
account.setCode(BytesValue.of(3, 2, 1), Account.DEFAULT_VERSION);
account.setCode(BytesValue.of(1, 2, 3));
shemnon marked this conversation as resolved.
Show resolved Hide resolved
account.setCode(BytesValue.of(3, 2, 1));
updater.commit();
assertEquals(BytesValue.of(3, 2, 1), worldState.get(ADDRESS).getCode());
assertEquals(
Expand Down