Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AccessList to 1559 transaction rlp encoding #1992

Merged
merged 3 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
28 changes: 27 additions & 1 deletion crypto/src/main/java/org/web3j/crypto/RawTransaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.web3j.crypto;

import java.math.BigInteger;
import java.util.Collections;
import java.util.List;

import org.web3j.crypto.transaction.type.ITransaction;
Expand Down Expand Up @@ -115,7 +116,32 @@
value,
data,
maxPriorityFeePerGas,
maxFeePerGas));
maxFeePerGas,
Collections.emptyList()));

Check warning on line 120 in crypto/src/main/java/org/web3j/crypto/RawTransaction.java

View check run for this annotation

Codecov / codecov/patch

crypto/src/main/java/org/web3j/crypto/RawTransaction.java#L120

Added line #L120 was not covered by tests
}

public static RawTransaction createTransaction(
long chainId,
BigInteger nonce,
BigInteger gasLimit,
String to,
BigInteger value,
String data,
BigInteger maxPriorityFeePerGas,
BigInteger maxFeePerGas,
List<AccessListObject> accessList) {

return new RawTransaction(
Transaction1559.createTransaction(
chainId,
nonce,
gasLimit,
to,
value,
data,
maxPriorityFeePerGas,
maxFeePerGas,
accessList));
}

public static RawTransaction createTransaction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ private static RawTransaction decodeEIP1559Transaction(final byte[] transaction)

final BigInteger value = ((RlpString) values.getValues().get(6)).asPositiveBigInteger();
final String data = ((RlpString) values.getValues().get(7)).asString();
List<AccessListObject> accessList =
decodeAccessList(((RlpList) values.getValues().get(8)).getValues());

final RawTransaction rawTransaction =
RawTransaction.createTransaction(
Expand All @@ -74,7 +76,8 @@ private static RawTransaction decodeEIP1559Transaction(final byte[] transaction)
value,
data,
maxPriorityFeePerGas,
maxFeePerGas);
maxFeePerGas,
accessList);

if (values.getValues().size() == UNSIGNED_EIP1559TX_RLP_LIST_SIZE) {
return rawTransaction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,24 @@

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.web3j.crypto.AccessListObject;
import org.web3j.crypto.Sign;
import org.web3j.rlp.RlpList;
import org.web3j.rlp.RlpString;
import org.web3j.rlp.RlpType;
import org.web3j.utils.Bytes;
import org.web3j.utils.Numeric;

import static org.web3j.crypto.transaction.type.TransactionType.EIP1559;

/**
* Transaction class used for signing 1559 transactions locally.<br>
* For the specification, refer to p4 of the <a href="http://gavwood.com/paper.pdf">yellow
* paper</a>.
*/
public class Transaction1559 extends LegacyTransaction implements ITransaction {
public class Transaction1559 extends Transaction2930 implements ITransaction {

private long chainId;
private BigInteger maxPriorityFeePerGas;
private BigInteger maxFeePerGas;

Expand All @@ -45,8 +44,22 @@
String data,
BigInteger maxPriorityFeePerGas,
BigInteger maxFeePerGas) {
super(EIP1559, nonce, null, gasLimit, to, value, data);
this.chainId = chainId;
super(chainId, nonce, null, gasLimit, to, value, data, Collections.emptyList());
this.maxPriorityFeePerGas = maxPriorityFeePerGas;
this.maxFeePerGas = maxFeePerGas;
}

Check warning on line 50 in crypto/src/main/java/org/web3j/crypto/transaction/type/Transaction1559.java

View check run for this annotation

Codecov / codecov/patch

crypto/src/main/java/org/web3j/crypto/transaction/type/Transaction1559.java#L47-L50

Added lines #L47 - L50 were not covered by tests
Comment on lines +47 to +50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if it looks simple a test case will be worth here, also will improve the test coverage


public Transaction1559(
long chainId,
BigInteger nonce,
BigInteger gasLimit,
String to,
BigInteger value,
String data,
BigInteger maxPriorityFeePerGas,
BigInteger maxFeePerGas,
List<AccessListObject> accessList) {
super(chainId, nonce, null, gasLimit, to, value, data, accessList);
this.maxPriorityFeePerGas = maxPriorityFeePerGas;
this.maxFeePerGas = maxFeePerGas;
}
Expand Down Expand Up @@ -83,7 +96,7 @@
result.add(RlpString.create(data));

// access list
result.add(new RlpList());
result.add(new RlpList(rlpAccessListRlp()));

if (signatureData != null) {
result.add(RlpString.create(Sign.getRecId(signatureData, getChainId())));
Expand All @@ -103,7 +116,38 @@
BigInteger maxPriorityFeePerGas,
BigInteger maxFeePerGas) {
return new Transaction1559(
chainId, nonce, gasLimit, to, value, "", maxPriorityFeePerGas, maxFeePerGas);
chainId,
nonce,
gasLimit,
to,
value,
"",
maxPriorityFeePerGas,
maxFeePerGas,
Collections.emptyList());
}

public static Transaction1559 createTransaction(
long chainId,
BigInteger nonce,
BigInteger gasLimit,
String to,
BigInteger value,
String data,
BigInteger maxPriorityFeePerGas,
BigInteger maxFeePerGas,
List<AccessListObject> accessList) {

return new Transaction1559(
chainId,
nonce,
gasLimit,
to,
value,
data,
maxPriorityFeePerGas,
maxFeePerGas,
accessList);
}

public static Transaction1559 createTransaction(
Expand All @@ -121,12 +165,13 @@
}

@Override
public BigInteger getGasPrice() {
throw new UnsupportedOperationException("not available for 1559 transaction");
public TransactionType getType() {
return TransactionType.EIP1559;
}

public long getChainId() {
return chainId;
@Override
public BigInteger getGasPrice() {
throw new UnsupportedOperationException("not available for 1559 transaction");

Check warning on line 174 in crypto/src/main/java/org/web3j/crypto/transaction/type/Transaction1559.java

View check run for this annotation

Codecov / codecov/patch

crypto/src/main/java/org/web3j/crypto/transaction/type/Transaction1559.java#L174

Added line #L174 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be nice to have a test case for this

}

public BigInteger getMaxPriorityFeePerGas() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ public List<RlpType> asRlpValues(Sign.SignatureData signatureData) {
result.add(RlpString.create(data));

// access list
result.add(new RlpList(rlpAccessListRlp()));

if (signatureData != null) {
result.add(RlpString.create(Sign.getRecId(signatureData, getChainId())));
result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getR())));
result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getS())));
}

return result;
}

protected List<RlpType> rlpAccessListRlp() {

List<AccessListObject> accessList = getAccessList();
List<RlpType> rlpAccessList = new ArrayList<>();
accessList.forEach(
Expand All @@ -89,15 +102,7 @@ public List<RlpType> asRlpValues(Sign.SignatureData signatureData) {
rlpAccessListObject.add(new RlpList(keyList));
rlpAccessList.add(new RlpList(rlpAccessListObject));
});
result.add(new RlpList(rlpAccessList));

if (signatureData != null) {
result.add(RlpString.create(Sign.getRecId(signatureData, getChainId())));
result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getR())));
result.add(RlpString.create(Bytes.trimLeadingZeroes(signatureData.getS())));
}

return result;
return rlpAccessList;
}

public static Transaction2930 createEtherTransaction(
Expand Down
51 changes: 51 additions & 0 deletions crypto/src/test/java/org/web3j/crypto/TransactionDecoderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,32 @@ public void testDecoding1559() {
assertEquals(transaction1559.getData(), resultTransaction1559.getData());
}

@Test
public void testDecoding1559AccessList() {
final RawTransaction rawTransaction = createEip1559RawTransactionAccessList();
final Transaction1559 transaction1559 = (Transaction1559) rawTransaction.getTransaction();

final byte[] encodedMessage = TransactionEncoder.encode(rawTransaction);
final String hexMessage = Numeric.toHexString(encodedMessage);

final RawTransaction result = TransactionDecoder.decode(hexMessage);
assertTrue(result.getTransaction() instanceof Transaction1559);
final Transaction1559 resultTransaction1559 = (Transaction1559) result.getTransaction();

assertNotNull(result);
assertEquals(transaction1559.getChainId(), resultTransaction1559.getChainId());
assertEquals(transaction1559.getNonce(), resultTransaction1559.getNonce());
assertEquals(transaction1559.getMaxFeePerGas(), resultTransaction1559.getMaxFeePerGas());
assertEquals(
transaction1559.getMaxPriorityFeePerGas(),
resultTransaction1559.getMaxPriorityFeePerGas());
assertEquals(transaction1559.getGasLimit(), resultTransaction1559.getGasLimit());
assertEquals(transaction1559.getTo(), resultTransaction1559.getTo());
assertEquals(transaction1559.getValue(), resultTransaction1559.getValue());
assertEquals(transaction1559.getData(), resultTransaction1559.getData());
assertEquals(transaction1559.getAccessList(), resultTransaction1559.getAccessList());
}

@Test
public void testDecodingSigned1559() throws SignatureException {
final RawTransaction rawTransaction = createEip1559RawTransaction();
Expand Down Expand Up @@ -202,6 +228,31 @@ private static RawTransaction createEip1559RawTransaction() {
BigInteger.valueOf(1100000));
}

private static RawTransaction createEip1559RawTransactionAccessList() {
List<AccessListObject> accessList =
Stream.of(
new AccessListObject(
"0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae",
Stream.of(
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x0000000000000000000000000000000000000000000000000000000000000007")
.collect(toList())),
new AccessListObject(
"0xbb9bc244d798123fde783fcc1c72d3bb8c189413",
Collections.emptyList()))
.collect(toList());
return RawTransaction.createTransaction(
3L,
BigInteger.valueOf(0),
BigInteger.valueOf(30000),
"0x627306090abab3a6e1400e9345bc60c78a8bef57",
BigInteger.valueOf(123),
"0x1000001111100000",
BigInteger.valueOf(5678),
BigInteger.valueOf(1100000),
accessList);
}

@Test
public void testDecoding2930() {
final RawTransaction rawTransaction = createEip2930RawTransaction();
Expand Down
Loading