Skip to content

Commit

Permalink
Fix Access List Encoding in JSON-RPC (hyperledger#1936)
Browse files Browse the repository at this point in the history
Signed-off-by: Ratan Rai Sur <ratan.r.sur@gmail.com>
  • Loading branch information
RatanRSur authored Feb 22, 2021
1 parent 490ca8c commit 0187bed
Show file tree
Hide file tree
Showing 12 changed files with 180 additions and 83 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
## 21.1.0
* Added activation blocks for Berlin Network Upgrade [\#1929](https://github.com/hyperledger/besu/pull/1929)

### Bug Fixes
* Fixed representation of access list for access list transactions in JSON-RPC results.

## 21.1.0-RC2
### Additions and Improvements
* Support for the Berlin Network Upgrade, although the block number must be set manually with `--override-genesis-config=berlinBlock=<blocknumber>`. This is because the block numbers haven't been determined yet. The next release will include the number in the genesis file so it will support Berlin with no intervention. [\#1898](https://github.com/hyperledger/besu/pull/1898)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;

import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.core.AccessList;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.encoding.TransactionEncoder;
import org.hyperledger.besu.plugin.data.TransactionType;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Expand Down Expand Up @@ -49,7 +51,7 @@
public class TransactionCompleteResult implements TransactionResult {

@JsonInclude(JsonInclude.Include.NON_NULL)
private final AccessList accessList;
private final List<AccessListEntry> accessList;

private final String blockHash;
private final String blockNumber;
Expand Down Expand Up @@ -102,7 +104,7 @@ public TransactionCompleteResult(final TransactionWithMetadata tx) {
}

@JsonGetter(value = "accessList")
public AccessList getAccessList() {
public List<AccessListEntry> getAccessList() {
return accessList;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results;

import org.hyperledger.besu.ethereum.core.AccessList;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput;
import org.hyperledger.besu.plugin.data.TransactionType;

import java.util.List;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Expand All @@ -43,7 +45,7 @@
public class TransactionPendingResult implements TransactionResult {

@JsonInclude(JsonInclude.Include.NON_NULL)
private final AccessList accessList;
private final List<AccessListEntry> accessList;

private final String chainId;
private final String from;
Expand Down Expand Up @@ -91,7 +93,7 @@ public TransactionPendingResult(final Transaction transaction) {
}

@JsonGetter(value = "accessList")
public AccessList getAccessList() {
public List<AccessListEntry> getAccessList() {
return accessList;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.api.jsonrpc.internal.results;

import static org.assertj.core.api.Assertions.assertThat;

import org.hyperledger.besu.ethereum.api.query.TransactionWithMetadata;
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.plugin.data.TransactionType;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;

public class TransactionCompleteResultTest {
@Test
public void accessListTransactionFields() throws JsonProcessingException {
final BlockDataGenerator gen = new BlockDataGenerator();
final Transaction transaction = gen.transaction(TransactionType.ACCESS_LIST);
final TransactionCompleteResult transactionCompleteResult =
new TransactionCompleteResult(
new TransactionWithMetadata(
transaction,
136,
Hash.fromHexString(
"0xfc84c3946cb419cbd8c2c68d5e79a3b2a03a8faff4d9e2be493f5a07eb5da95e"),
0));

final ObjectMapper objectMapper = new ObjectMapper();
final String jsonString =
objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(transactionCompleteResult);

assertThat(jsonString)
.startsWith(
"{\n"
+ " \"accessList\" : [ {\n"
+ " \"address\" : \"0x47902028e61cfdc243d9d16008aabc9fb77cc723\",\n"
+ " \"storageKeys\" : [ ]\n"
+ " }, {\n"
+ " \"address\" : \"0xa56017e14f1ce8b1698341734a6823ce02043e01\",\n"
+ " \"storageKeys\" : [ \"0x6b544901214a2ddab82fec85c0b9fe0549c475be5b887bb4b8995b24fb5c6846\", \"0xf88b527b4f9d4c1391f1678b23ba4f9c9cd7bc93eb5776f4f036753448642946\" ]\n"
+ " } ],");
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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;

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.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import org.apache.tuweni.bytes.Bytes32;

@JsonSerialize(using = AccessListEntry.Serializer.class)
public class AccessListEntry {
private final Address address;
private final List<Bytes32> storageKeys;

public AccessListEntry(final Address address, final List<Bytes32> storageKeys) {

this.address = address;
this.storageKeys = storageKeys;
}

public Address getAddress() {
return address;
}

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();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
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.SECP256K1;
Expand All @@ -28,6 +29,7 @@
import org.hyperledger.besu.plugin.data.TransactionType;

import java.math.BigInteger;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

Expand Down Expand Up @@ -72,7 +74,7 @@ public class Transaction implements org.hyperledger.besu.plugin.data.Transaction

private final Bytes payload;

private final AccessList accessList;
private final List<AccessListEntry> accessList;

private final Optional<BigInteger> chainId;

Expand Down Expand Up @@ -134,7 +136,7 @@ public Transaction(
final Wei value,
final SECP256K1.Signature signature,
final Bytes payload,
final AccessList accessList,
final List<AccessListEntry> accessList,
final Address sender,
final Optional<BigInteger> chainId,
final Optional<BigInteger> v) {
Expand Down Expand Up @@ -182,7 +184,7 @@ public Transaction(
value,
signature,
payload,
AccessList.EMPTY,
emptyList(),
sender,
chainId,
v);
Expand Down Expand Up @@ -373,7 +375,7 @@ public Optional<Bytes> getData() {
return getTo().isPresent() ? Optional.of(payload) : Optional.empty();
}

public AccessList getAccessList() {
public List<AccessListEntry> getAccessList() {
return accessList;
}

Expand Down Expand Up @@ -555,7 +557,7 @@ private static Bytes32 computeSenderRecoveryHash(
final Optional<Address> to,
final Wei value,
final Bytes payload,
final AccessList accessList,
final List<AccessListEntry> accessList,
final Optional<BigInteger> chainId) {
final Bytes preimage;
switch (transactionType) {
Expand Down Expand Up @@ -641,7 +643,7 @@ private static Bytes accessListPreimage(
final Optional<Address> to,
final Wei value,
final Bytes payload,
final AccessList accessList,
final List<AccessListEntry> accessList,
final Optional<BigInteger> chainId) {
final Bytes encode =
RLP.encode(
Expand Down Expand Up @@ -732,7 +734,7 @@ public static class Builder {

protected Bytes payload;

protected AccessList accessList = AccessList.EMPTY;
protected List<AccessListEntry> accessList = emptyList();

protected Address sender;

Expand Down Expand Up @@ -795,7 +797,7 @@ public Builder payload(final Bytes payload) {
return this;
}

public Builder accessList(final AccessList accessList) {
public Builder accessList(final List<AccessListEntry> accessList) {
this.accessList = accessList;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

import org.hyperledger.besu.config.GoQuorumOptions;
import org.hyperledger.besu.crypto.SECP256K1;
import org.hyperledger.besu.ethereum.core.AccessList;
import org.hyperledger.besu.ethereum.core.AccessListEntry;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Wei;
Expand All @@ -34,14 +34,10 @@
import org.hyperledger.besu.plugin.data.TransactionType;

import java.math.BigInteger;
import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import com.google.common.collect.ImmutableMap;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;

public class TransactionDecoder {

Expand Down Expand Up @@ -138,17 +134,16 @@ private static Transaction decodeAccessList(final RLPInput rlpInput) {
.value(Wei.of(rlpInput.readUInt256Scalar()))
.payload(rlpInput.readBytes())
.accessList(
new AccessList(
rlpInput.readList(
accessListEntryRLPInput -> {
accessListEntryRLPInput.enterList();
final Map.Entry<Address, List<Bytes32>> accessListEntry =
new AbstractMap.SimpleEntry<>(
Address.wrap(accessListEntryRLPInput.readBytes()),
accessListEntryRLPInput.readList(RLPInput::readBytes32));
accessListEntryRLPInput.leaveList();
return accessListEntry;
})));
rlpInput.readList(
accessListEntryRLPInput -> {
accessListEntryRLPInput.enterList();
final AccessListEntry accessListEntry =
new AccessListEntry(
Address.wrap(accessListEntryRLPInput.readBytes()),
accessListEntryRLPInput.readList(RLPInput::readBytes32));
accessListEntryRLPInput.leaveList();
return accessListEntry;
}));
final byte recId = (byte) rlpInput.readIntScalar();
final Transaction transaction =
preSignatureTransactionBuilder
Expand Down
Loading

0 comments on commit 0187bed

Please sign in to comment.