Access List State Test Support for evmtool (#1945)

Update reference test hash for access list tests.

Signed-off-by: Ratan Rai Sur <ratan.r.sur@gmail.com>
pull/1965/head
Ratan (Rai) Sur 4 years ago committed by GitHub
parent 2e87576245
commit f25d458345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/JsonCallParameter.java
  2. 3
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionCompleteResult.java
  3. 3
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/TransactionPendingResult.java
  4. 40
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/AccessListEntry.java
  5. 51
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/Transaction.java
  6. 7
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/encoding/TransactionEncoder.java
  7. 55
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/AccessListEntryDeserializer.java
  8. 54
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/AccessListEntrySerializer.java
  9. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/GasDeserializer.java
  10. 2
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/json/HexStringDeserializer.java
  11. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/BerlinGasCalculator.java
  12. 8
      ethereum/evmtool/src/test/java/org/hyperledger/besu/evmtool/StateTestSubCommandTest.java
  13. 90
      ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/access-list.json
  14. 2
      ethereum/referencetests/build.gradle
  15. 3
      ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/GeneralStateTestCaseSpec.java
  16. 45
      ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/StateTestAccessListDeserializer.java
  17. 22
      ethereum/referencetests/src/main/java/org/hyperledger/besu/ethereum/referencetests/StateTestVersionedTransaction.java
  18. 2
      ethereum/referencetests/src/test/resources

@ -19,8 +19,8 @@ import static java.lang.Boolean.FALSE;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.core.deserializer.GasDeserializer;
import org.hyperledger.besu.ethereum.core.deserializer.HexStringDeserializer;
import org.hyperledger.besu.ethereum.core.json.GasDeserializer;
import org.hyperledger.besu.ethereum.core.json.HexStringDeserializer;
import org.hyperledger.besu.ethereum.transaction.CallParameter;
import java.util.Optional;

@ -78,8 +78,7 @@ public class TransactionCompleteResult implements TransactionResult {
public TransactionCompleteResult(final TransactionWithMetadata tx) {
final Transaction transaction = tx.getTransaction();
final TransactionType transactionType = transaction.getType();
this.accessList =
transactionType.equals(TransactionType.ACCESS_LIST) ? transaction.getAccessList() : null;
this.accessList = transaction.getAccessList().orElse(null);
this.blockHash = tx.getBlockHash().get().toString();
this.blockNumber = Quantity.create(tx.getBlockNumber().get());
this.chainId = transaction.getChainId().map(Quantity::create).orElse(null);

@ -68,8 +68,7 @@ public class TransactionPendingResult implements TransactionResult {
public TransactionPendingResult(final Transaction transaction) {
final TransactionType transactionType = transaction.getType();
this.accessList =
transactionType.equals(TransactionType.ACCESS_LIST) ? transaction.getAccessList() : null;
this.accessList = transaction.getAccessList().orElse(null);
this.chainId = transaction.getChainId().map(Quantity::create).orElse(null);
this.from = transaction.getSender().toString();
this.gas = Quantity.create(transaction.getGasLimit());

@ -14,16 +14,17 @@
*/
package org.hyperledger.besu.ethereum.core;
import java.io.IOException;
import org.hyperledger.besu.ethereum.core.json.AccessListEntryDeserializer;
import org.hyperledger.besu.ethereum.core.json.AccessListEntrySerializer;
import java.util.List;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.apache.tuweni.bytes.Bytes32;
@JsonSerialize(using = AccessListEntry.Serializer.class)
@JsonSerialize(using = AccessListEntrySerializer.class)
@JsonDeserialize(using = AccessListEntryDeserializer.class)
public class AccessListEntry {
private final Address address;
private final List<Bytes32> storageKeys;
@ -41,33 +42,4 @@ public class AccessListEntry {
public List<Bytes32> getStorageKeys() {
return storageKeys;
}
public static class Serializer extends StdSerializer<AccessListEntry> {
Serializer() {
this(null);
}
protected Serializer(final Class<AccessListEntry> t) {
super(t);
}
@Override
public void serialize(
final AccessListEntry accessListEntry,
final JsonGenerator gen,
final SerializerProvider provider)
throws IOException {
gen.writeStartObject();
gen.writeFieldName("address");
gen.writeString(accessListEntry.getAddress().toHexString());
gen.writeFieldName("storageKeys");
final List<Bytes32> storageKeys = accessListEntry.getStorageKeys();
gen.writeArray(
storageKeys.stream().map(Bytes32::toHexString).toArray(String[]::new),
0,
storageKeys.size());
gen.writeEndObject();
}
}
}

@ -15,7 +15,6 @@
package org.hyperledger.besu.ethereum.core;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Collections.emptyList;
import static org.hyperledger.besu.crypto.Hash.keccak256;
import org.hyperledger.besu.crypto.KeyPair;
@ -77,7 +76,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
private final Bytes payload;
private final List<AccessListEntry> accessList;
private final Optional<List<AccessListEntry>> maybeAccessList;
private final Optional<BigInteger> chainId;
@ -119,7 +118,8 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
* @param value the value being transferred to the recipient
* @param signature the signature
* @param payload the payload
* @param accessList the list of addresses/storage slots this transaction intends to preload
* @param maybeAccessList the optional list of addresses/storage slots this transaction intends to
* preload
* @param sender the transaction sender
* @param chainId the chain id to apply the transaction to
* @param v the v value. This is only passed in directly for GoQuorum private transactions
@ -141,7 +141,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
final Wei value,
final SECPSignature signature,
final Bytes payload,
final List<AccessListEntry> accessList,
final Optional<List<AccessListEntry>> maybeAccessList,
final Address sender,
final Optional<BigInteger> chainId,
final Optional<BigInteger> v) {
@ -149,6 +149,14 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
throw new IllegalStateException(
String.format("chainId '%s' and v '%s' cannot both be provided", chainId.get(), v.get()));
}
if (Objects.equals(transactionType, TransactionType.ACCESS_LIST)) {
checkState(
maybeAccessList.isPresent(), "Must specify access list for access list transaction");
} else {
checkState(
maybeAccessList.isEmpty(),
"Must not specify access list for non-access list transaction");
}
this.transactionType = transactionType;
this.nonce = nonce;
this.gasPrice = gasPrice;
@ -159,7 +167,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
this.value = value;
this.signature = signature;
this.payload = payload;
this.accessList = accessList;
this.maybeAccessList = maybeAccessList;
this.sender = sender;
this.chainId = chainId;
this.v = v;
@ -189,7 +197,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
value,
signature,
payload,
emptyList(),
Optional.empty(),
sender,
chainId,
v);
@ -380,8 +388,8 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
return getTo().isPresent() ? Optional.of(payload) : Optional.empty();
}
public List<AccessListEntry> getAccessList() {
return accessList;
public Optional<List<AccessListEntry>> getAccessList() {
return maybeAccessList;
}
/**
@ -441,7 +449,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
to,
value,
payload,
accessList,
maybeAccessList,
chainId);
}
return hashNoSignature;
@ -564,7 +572,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
final Optional<Address> to,
final Wei value,
final Bytes payload,
final List<AccessListEntry> accessList,
final Optional<List<AccessListEntry>> accessList,
final Optional<BigInteger> chainId) {
final Bytes preimage;
switch (transactionType) {
@ -578,7 +586,18 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
break;
case ACCESS_LIST:
preimage =
accessListPreimage(nonce, gasPrice, gasLimit, to, value, payload, accessList, chainId);
accessListPreimage(
nonce,
gasPrice,
gasLimit,
to,
value,
payload,
accessList.orElseThrow(
() ->
new IllegalStateException(
"Developer error: the transaction should be guaranteed to have an access list here")),
chainId);
break;
default:
throw new IllegalStateException(
@ -705,9 +724,9 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
sb.append("sig=").append(getSignature()).append(", ");
if (chainId.isPresent()) sb.append("chainId=").append(getChainId().get()).append(", ");
if (v.isPresent()) sb.append("v=").append(v.get()).append(", ");
sb.append("payload=").append(getPayload()).append(", ");
sb.append("payload=").append(getPayload());
if (transactionType.equals(TransactionType.ACCESS_LIST)) {
sb.append("accessList=").append(accessList);
sb.append(", ").append("accessList=").append(maybeAccessList);
}
return sb.append("}").toString();
}
@ -741,7 +760,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
protected Bytes payload;
protected List<AccessListEntry> accessList = emptyList();
protected Optional<List<AccessListEntry>> accessList = Optional.empty();
protected Address sender;
@ -805,7 +824,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
}
public Builder accessList(final List<AccessListEntry> accessList) {
this.accessList = accessList;
this.accessList = Optional.ofNullable(accessList);
return this;
}
@ -820,7 +839,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction
}
public Builder guessType() {
if (!accessList.isEmpty()) {
if (accessList.isPresent()) {
transactionType = TransactionType.ACCESS_LIST;
} else if (gasPremium != null || feeCap != null) {
transactionType = TransactionType.EIP1559;

@ -97,7 +97,12 @@ public class TransactionEncoder {
transaction.getTo(),
transaction.getValue(),
transaction.getPayload(),
transaction.getAccessList(),
transaction
.getAccessList()
.orElseThrow(
() ->
new IllegalStateException(
"Developer error: access list should be guaranteed to be present")),
rlpOutput);
rlpOutput.writeIntScalar(transaction.getSignature().getRecId());
writeSignature(transaction, rlpOutput);

@ -0,0 +1,55 @@
/*
* Copyright ConsenSys AG.
*
* 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.core.json;
import static com.google.common.base.Preconditions.checkState;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
import org.hyperledger.besu.ethereum.core.Address;
import java.io.IOException;
import java.util.ArrayList;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import org.apache.tuweni.bytes.Bytes32;
public class AccessListEntryDeserializer extends StdDeserializer<AccessListEntry> {
private AccessListEntryDeserializer() {
this(null);
}
protected AccessListEntryDeserializer(final Class<?> vc) {
super(vc);
}
@Override
public AccessListEntry deserialize(final JsonParser p, final DeserializationContext ctxt)
throws IOException {
checkState(p.nextFieldName().equals("address"));
final Address address = Address.fromHexString(p.nextTextValue());
checkState(p.nextFieldName().equals("storageKeys"));
checkState(p.nextToken().equals(JsonToken.START_ARRAY));
final ArrayList<Bytes32> storageKeys = new ArrayList<>();
while (!p.nextToken().equals(JsonToken.END_ARRAY)) {
storageKeys.add(Bytes32.fromHexString(p.getText()));
}
p.nextToken(); // consume end of object
return new AccessListEntry(address, storageKeys);
}
}

@ -0,0 +1,54 @@
/*
* Copyright ConsenSys AG.
*
* 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.core.json;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
import java.io.IOException;
import java.util.List;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.apache.tuweni.bytes.Bytes32;
public class AccessListEntrySerializer extends StdSerializer<AccessListEntry> {
AccessListEntrySerializer() {
this(null);
}
protected AccessListEntrySerializer(final Class<AccessListEntry> t) {
super(t);
}
@Override
public void serialize(
final AccessListEntry accessListEntry,
final JsonGenerator gen,
final SerializerProvider provider)
throws IOException {
gen.writeStartObject();
gen.writeFieldName("address");
gen.writeString(accessListEntry.getAddress().toHexString());
gen.writeFieldName("storageKeys");
final List<Bytes32> storageKeys = accessListEntry.getStorageKeys();
gen.writeArray(
storageKeys.stream().map(Bytes32::toHexString).toArray(String[]::new),
0,
storageKeys.size());
gen.writeEndObject();
}
}

@ -12,7 +12,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.core.deserializer;
package org.hyperledger.besu.ethereum.core.json;
import org.hyperledger.besu.ethereum.core.Gas;

@ -12,7 +12,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.ethereum.core.deserializer;
package org.hyperledger.besu.ethereum.core.json;
import java.io.IOException;

@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.mainnet;
import static java.util.Collections.emptyList;
import static org.hyperledger.besu.ethereum.core.Address.BLAKE2B_F_COMPRESSION;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
@ -75,7 +76,7 @@ public class BerlinGasCalculator extends IstanbulGasCalculator {
public GasAndAccessedState transactionIntrinsicGasCostAndAccessedState(
final Transaction transaction) {
// As per https://eips.ethereum.org/EIPS/eip-2930
final List<AccessListEntry> accessList = transaction.getAccessList();
final List<AccessListEntry> accessList = transaction.getAccessList().orElse(emptyList());
long accessedStorageCount = 0;
final Set<Address> accessedAddresses = new HashSet<>();

@ -41,4 +41,12 @@ public class StateTestSubCommandTest {
cmd.parseArgs(StateTestSubCommandTest.class.getResource("valid-state-test.json").getPath());
stateTestSubCommand.run();
}
@Test
public void shouldWorkWithValidAccessListStateTest() {
final StateTestSubCommand stateTestSubCommand = new StateTestSubCommand(new EvmToolCommand());
final CommandLine cmd = new CommandLine(stateTestSubCommand);
cmd.parseArgs(StateTestSubCommandTest.class.getResource("access-list.json").getPath());
stateTestSubCommand.run();
}
}

@ -0,0 +1,90 @@
{
"accessList" : {
"_info" : {
"comment" : "Access list in tr example",
"filling-rpc-server" : "evm version 1.10.0-unstable-e09dc4eb-20210211",
"filling-tool-version" : "retesteth-0.1.0-accesslist+commit.37e87c45.Linux.g++",
"lllcversion" : "Version: 0.5.14-develop.2020.6.22+commit.9189ad7a.Linux.g++",
"source" : "src/GeneralStateTestsFiller/stExample/accessListFiller.json",
"sourceHash" : "0b91ae030423fd2d178aea8c362196b24e059c2525c64f5aca273e3e277c22ed",
"labels" : {
"0" : ":label somelabel",
"1" : ":label somelabel2"
}
},
"env" : {
"currentCoinbase" : "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "0x020000",
"currentGasLimit" : "0xff112233445566",
"currentNumber" : "0x01",
"currentTimestamp" : "0x03e8",
"previousHash" : "0x5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"post" : {
"Berlin" : [
{
"indexes" : {
"data" : 0,
"gas" : 0,
"value" : 0
},
"hash" : "0x6ef2bfc9fbc7f1ad04aefc6ca5d64ec882f81c60a14f5171f181a169a6db1a6b",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
},
{
"indexes" : {
"data" : 1,
"gas" : 0,
"value" : 0
},
"hash" : "0x0bdf3644f34b9678b88307ffe487c8215daa8689580eacf2e93ba809843f6898",
"logs" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
]
},
"pre" : {
"0x095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x600160010160005500",
"nonce" : "0x00",
"storage" : {
}
},
"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x0de0b6b3a7640000",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
}
},
"transaction" : {
"data" : [
"0x1122",
"0x3344"
],
"accessLists" : [
[
{
"address" : "0x0000000000000000000000000000000000001337",
"storageKeys" : [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002"
]
}
],
null
],
"gasLimit" : [
"0x061a80"
],
"gasPrice" : "0x01",
"nonce" : "0x00",
"secretKey" : "0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "0x095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : [
"0x0186a0"
]
}
}
}

@ -41,7 +41,7 @@ task ('validateReferenceTestSubmodule') {
description = "Checks that the reference tests submodule is not accidentally changed"
doLast {
def result = new ByteArrayOutputStream()
def expectedHash = '1508126ea04cd61495b60db2f036ac823de274b1'
def expectedHash = '31d663076b6678df18983d6da912d7cad4ad3416'
def submodulePath = java.nio.file.Path.of("${rootProject.projectDir}", "ethereum/referencetests/src/test/resources").toAbsolutePath()
try {
exec {

@ -128,7 +128,8 @@ public class GeneralStateTestCaseSpec {
public PostSection(
@JsonProperty("hash") final String hash,
@JsonProperty("logs") final String logs,
@JsonProperty("indexes") final Indexes indexes) {
@JsonProperty("indexes") final Indexes indexes,
@JsonProperty("txbytes") final String txbytes) {
this.rootHash = Hash.fromHexString(hash);
this.logsHash = Hash.fromHexString(logs);
this.indexes = indexes;

@ -0,0 +1,45 @@
/*
* Copyright ConsenSys AG.
*
* 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.referencetests;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
public class StateTestAccessListDeserializer extends JsonDeserializer<List<List<AccessListEntry>>> {
@Override
public List<List<AccessListEntry>> deserialize(
final JsonParser p, final DeserializationContext ctxt) throws IOException {
final ObjectMapper objectMapper = new ObjectMapper();
final List<List<AccessListEntry>> accessLists = new ArrayList<>();
while (!p.nextToken().equals(JsonToken.END_ARRAY)) {
accessLists.add(
p.currentToken().equals(JsonToken.VALUE_NULL)
? null
: Arrays.asList(objectMapper.readValue(p, AccessListEntry[].class)));
}
return accessLists;
}
}

@ -18,19 +18,23 @@ package org.hyperledger.besu.ethereum.referencetests;
import org.hyperledger.besu.crypto.KeyPair;
import org.hyperledger.besu.crypto.SignatureAlgorithm;
import org.hyperledger.besu.crypto.SignatureAlgorithmFactory;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Wei;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import javax.annotation.Nullable;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
@ -64,6 +68,7 @@ public class StateTestVersionedTransaction {
private final List<Gas> gasLimits;
private final List<Wei> values;
private final List<Bytes> payloads;
private final Optional<List<List<AccessListEntry>>> maybeAccessLists;
/**
* Constructor for populating a mock transaction with json data.
@ -75,6 +80,7 @@ public class StateTestVersionedTransaction {
* @param value Amount of ether transferred in the mock transaction.
* @param secretKey Secret Key of the mock transaction.
* @param data Call data of the mock transaction.
* @param maybeAccessLists List of access lists of the mock transaction. Can be null.
*/
@JsonCreator
public StateTestVersionedTransaction(
@ -84,7 +90,9 @@ public class StateTestVersionedTransaction {
@JsonProperty("to") final String to,
@JsonProperty("value") final String[] value,
@JsonProperty("secretKey") final String secretKey,
@JsonProperty("data") final String[] data) {
@JsonProperty("data") final String[] data,
@JsonDeserialize(using = StateTestAccessListDeserializer.class) @JsonProperty("accessLists")
final List<List<AccessListEntry>> maybeAccessLists) {
this.nonce = Long.decode(nonce);
this.gasPrice = Wei.fromHexString(gasPrice);
@ -98,6 +106,7 @@ public class StateTestVersionedTransaction {
this.gasLimits = parseArray(gasLimit, Gas::fromHexString);
this.values = parseArray(value, Wei::fromHexString);
this.payloads = parseArray(data, Bytes::fromHexString);
this.maybeAccessLists = Optional.ofNullable(maybeAccessLists);
}
private static <T> List<T> parseArray(final String[] array, final Function<String, T> parseFct) {
@ -109,14 +118,17 @@ public class StateTestVersionedTransaction {
}
public Transaction get(final GeneralStateTestCaseSpec.Indexes indexes) {
return Transaction.builder()
final Transaction.Builder transactionBuilder =
Transaction.builder()
.nonce(nonce)
.gasPrice(gasPrice)
.gasLimit(gasLimits.get(indexes.gas).asUInt256().toLong())
.to(to)
.value(values.get(indexes.value))
.payload(payloads.get(indexes.data))
.guessType()
.signAndBuild(keys);
.payload(payloads.get(indexes.data));
maybeAccessLists.ifPresent(
accessLists ->
transactionBuilder.accessList(accessLists.get(indexes.data)).chainId(BigInteger.ONE));
return transactionBuilder.guessType().signAndBuild(keys);
}
}

@ -1 +1 @@
Subproject commit 1508126ea04cd61495b60db2f036ac823de274b1
Subproject commit 31d663076b6678df18983d6da912d7cad4ad3416
Loading…
Cancel
Save