mirror of https://github.com/hyperledger/besu
Refactor transaction rlp encoding / decoding (#1375)
* Add utility classes to deal with RLP encoding / decoding of transactions. - Added `TransactionRLPDecoder` with `Transaction decode(RLPInput input);` method. - Added `TransactionRLPEncoder` with `void encode(Transaction transaction, RLPOutput output);` method. - Added `TransactionRLPEncoderDecoder` with 2 static methods: - `static void encode(final Transaction transaction, final RLPOutput output)` - `static Transaction decode(final RLPInput input)` - Updated `Transaction` class to use `TransactionRLPEncoderDecoder`. Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>pull/1382/head
parent
fd98049969
commit
31df8660d4
@ -0,0 +1,132 @@ |
||||
/* |
||||
* 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.encoding; |
||||
|
||||
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_PROTECTED_V_BASE; |
||||
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_PROTECTED_V_MIN; |
||||
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_UNPROTECTED_V_BASE; |
||||
import static org.hyperledger.besu.ethereum.core.Transaction.REPLAY_UNPROTECTED_V_BASE_PLUS_1; |
||||
import static org.hyperledger.besu.ethereum.core.Transaction.TWO; |
||||
|
||||
import org.hyperledger.besu.config.experimental.ExperimentalEIPs; |
||||
import org.hyperledger.besu.crypto.SECP256K1; |
||||
import org.hyperledger.besu.ethereum.core.Address; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.core.Wei; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPInput; |
||||
|
||||
import java.math.BigInteger; |
||||
import java.util.Optional; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
|
||||
@FunctionalInterface |
||||
public interface TransactionRLPDecoder { |
||||
|
||||
TransactionRLPDecoder FRONTIER = frontierDecoder(); |
||||
TransactionRLPDecoder EIP1559 = eip1559Decoder(); |
||||
|
||||
static Transaction decodeTransaction(final RLPInput input) { |
||||
return (ExperimentalEIPs.eip1559Enabled ? EIP1559 : FRONTIER).decode(input); |
||||
} |
||||
|
||||
Transaction decode(RLPInput input); |
||||
|
||||
static TransactionRLPDecoder frontierDecoder() { |
||||
return input -> { |
||||
input.enterList(); |
||||
final Transaction.Builder builder = |
||||
Transaction.builder() |
||||
.nonce(input.readLongScalar()) |
||||
.gasPrice(Wei.of(input.readUInt256Scalar())) |
||||
.gasLimit(input.readLongScalar()) |
||||
.to(input.readBytes(v -> v.size() == 0 ? null : Address.wrap(v))) |
||||
.value(Wei.of(input.readUInt256Scalar())) |
||||
.payload(input.readBytes()); |
||||
|
||||
final BigInteger v = input.readBigIntegerScalar(); |
||||
final byte recId; |
||||
Optional<BigInteger> chainId = Optional.empty(); |
||||
if (v.equals(REPLAY_UNPROTECTED_V_BASE) || v.equals(REPLAY_UNPROTECTED_V_BASE_PLUS_1)) { |
||||
recId = v.subtract(REPLAY_UNPROTECTED_V_BASE).byteValueExact(); |
||||
} else if (v.compareTo(REPLAY_PROTECTED_V_MIN) > 0) { |
||||
chainId = Optional.of(v.subtract(REPLAY_PROTECTED_V_BASE).divide(TWO)); |
||||
recId = |
||||
v.subtract(TWO.multiply(chainId.get()).add(REPLAY_PROTECTED_V_BASE)).byteValueExact(); |
||||
} else { |
||||
throw new RuntimeException( |
||||
String.format("An unsupported encoded `v` value of %s was found", v)); |
||||
} |
||||
final BigInteger r = input.readUInt256Scalar().toBytes().toUnsignedBigInteger(); |
||||
final BigInteger s = input.readUInt256Scalar().toBytes().toUnsignedBigInteger(); |
||||
final SECP256K1.Signature signature = SECP256K1.Signature.create(r, s, recId); |
||||
|
||||
input.leaveList(); |
||||
|
||||
chainId.ifPresent(builder::chainId); |
||||
return builder.signature(signature).build(); |
||||
}; |
||||
} |
||||
|
||||
static TransactionRLPDecoder eip1559Decoder() { |
||||
return input -> { |
||||
input.enterList(); |
||||
|
||||
final Transaction.Builder builder = |
||||
Transaction.builder() |
||||
.nonce(input.readLongScalar()) |
||||
.gasPrice(Wei.of(input.readUInt256Scalar())) |
||||
.gasLimit(input.readLongScalar()) |
||||
.to(input.readBytes(v -> v.size() == 0 ? null : Address.wrap(v))) |
||||
.value(Wei.of(input.readUInt256Scalar())) |
||||
.payload(input.readBytes()); |
||||
|
||||
final Bytes maybeGasPremiumOrV = input.readBytes(); |
||||
final Bytes maybeFeeCapOrR = input.readBytes(); |
||||
final Bytes maybeVOrS = input.readBytes(); |
||||
final BigInteger v, r, s; |
||||
// if this is the end of the list we are processing a legacy transaction
|
||||
if (input.isEndOfCurrentList()) { |
||||
v = maybeGasPremiumOrV.toUnsignedBigInteger(); |
||||
r = maybeFeeCapOrR.toUnsignedBigInteger(); |
||||
s = maybeVOrS.toUnsignedBigInteger(); |
||||
} else { |
||||
// otherwise this is an EIP-1559 transaction
|
||||
builder |
||||
.gasPremium(Wei.of(maybeGasPremiumOrV.toBigInteger())) |
||||
.feeCap(Wei.of(maybeFeeCapOrR.toBigInteger())); |
||||
v = maybeVOrS.toBigInteger(); |
||||
r = input.readUInt256Scalar().toBytes().toUnsignedBigInteger(); |
||||
s = input.readUInt256Scalar().toBytes().toUnsignedBigInteger(); |
||||
} |
||||
final byte recId; |
||||
Optional<BigInteger> chainId = Optional.empty(); |
||||
if (v.equals(REPLAY_UNPROTECTED_V_BASE) || v.equals(REPLAY_UNPROTECTED_V_BASE_PLUS_1)) { |
||||
recId = v.subtract(REPLAY_UNPROTECTED_V_BASE).byteValueExact(); |
||||
} else if (v.compareTo(REPLAY_PROTECTED_V_MIN) > 0) { |
||||
chainId = Optional.of(v.subtract(REPLAY_PROTECTED_V_BASE).divide(TWO)); |
||||
recId = |
||||
v.subtract(TWO.multiply(chainId.get()).add(REPLAY_PROTECTED_V_BASE)).byteValueExact(); |
||||
} else { |
||||
throw new RuntimeException( |
||||
String.format("An unsupported encoded `v` value of %s was found", v)); |
||||
} |
||||
final SECP256K1.Signature signature = SECP256K1.Signature.create(r, s, recId); |
||||
input.leaveList(); |
||||
chainId.ifPresent(builder::chainId); |
||||
return builder.signature(signature).build(); |
||||
}; |
||||
} |
||||
} |
@ -0,0 +1,86 @@ |
||||
/* |
||||
* 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.encoding; |
||||
|
||||
import org.hyperledger.besu.config.experimental.ExperimentalEIPs; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.core.Wei; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPOutput; |
||||
import org.hyperledger.besu.plugin.data.Quantity; |
||||
import org.hyperledger.besu.plugin.data.TransactionType; |
||||
|
||||
import com.google.common.collect.ImmutableMap; |
||||
import org.apache.tuweni.bytes.Bytes; |
||||
|
||||
public class TransactionRLPEncoder { |
||||
|
||||
private static final Encoder FRONTIER = frontierEncoder(); |
||||
private static final Encoder EIP1559 = eip1559Encoder(); |
||||
|
||||
private static final ImmutableMap<TransactionType, Encoder> ENCODERS = |
||||
ImmutableMap.of(TransactionType.FRONTIER, FRONTIER, TransactionType.EIP1559, EIP1559); |
||||
|
||||
public static void encode(final Transaction transaction, final RLPOutput output) { |
||||
ENCODERS.getOrDefault(transaction.getType(), FRONTIER).encode(transaction, output); |
||||
} |
||||
|
||||
static Encoder frontierEncoder() { |
||||
return (transaction, out) -> { |
||||
out.startList(); |
||||
out.writeLongScalar(transaction.getNonce()); |
||||
out.writeUInt256Scalar(transaction.getGasPrice()); |
||||
out.writeLongScalar(transaction.getGasLimit()); |
||||
out.writeBytes(transaction.getTo().isPresent() ? transaction.getTo().get() : Bytes.EMPTY); |
||||
out.writeUInt256Scalar(transaction.getValue()); |
||||
out.writeBytes(transaction.getPayload()); |
||||
writeSignature(transaction, out); |
||||
out.endList(); |
||||
}; |
||||
} |
||||
|
||||
static Encoder eip1559Encoder() { |
||||
return (transaction, out) -> { |
||||
if (!ExperimentalEIPs.eip1559Enabled |
||||
|| !TransactionType.EIP1559.equals(transaction.getType())) { |
||||
throw new RuntimeException("Invalid transaction format"); |
||||
} |
||||
|
||||
out.startList(); |
||||
out.writeLongScalar(transaction.getNonce()); |
||||
out.writeNull(); |
||||
out.writeLongScalar(transaction.getGasLimit()); |
||||
out.writeBytes(transaction.getTo().isPresent() ? transaction.getTo().get() : Bytes.EMPTY); |
||||
out.writeUInt256Scalar(transaction.getValue()); |
||||
out.writeBytes(transaction.getPayload()); |
||||
out.writeUInt256Scalar( |
||||
transaction.getGasPremium().map(Quantity::getValue).map(Wei::ofNumber).orElseThrow()); |
||||
out.writeUInt256Scalar( |
||||
transaction.getFeeCap().map(Quantity::getValue).map(Wei::ofNumber).orElseThrow()); |
||||
writeSignature(transaction, out); |
||||
out.endList(); |
||||
}; |
||||
} |
||||
|
||||
private static void writeSignature(final Transaction transaction, final RLPOutput out) { |
||||
out.writeBigIntegerScalar(transaction.getV()); |
||||
out.writeBigIntegerScalar(transaction.getSignature().getR()); |
||||
out.writeBigIntegerScalar(transaction.getSignature().getS()); |
||||
} |
||||
|
||||
@FunctionalInterface |
||||
interface Encoder { |
||||
void encode(Transaction transaction, RLPOutput output); |
||||
} |
||||
} |
@ -0,0 +1,68 @@ |
||||
/* |
||||
* 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.encoding; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
import org.hyperledger.besu.config.experimental.ExperimentalEIPs; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.core.Wei; |
||||
import org.hyperledger.besu.ethereum.rlp.RLP; |
||||
import org.hyperledger.besu.ethereum.rlp.RLPException; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.junit.Test; |
||||
|
||||
public class TransactionRLPDecoderTest { |
||||
|
||||
private static final String FRONTIER_TX_RLP = |
||||
"0xf901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"; |
||||
private static final String EIP1559_TX_RLP = |
||||
"0xf902028032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b5682020f8201711ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"; |
||||
|
||||
@Test |
||||
public void decodeFrontierNominalCase() { |
||||
final Transaction transaction = |
||||
TransactionRLPDecoder.decodeTransaction(RLP.input(Bytes.fromHexString(FRONTIER_TX_RLP))); |
||||
assertThat(transaction).isNotNull(); |
||||
assertThat(transaction.getGasPrice()).isEqualByComparingTo(Wei.of(50L)); |
||||
assertThat(transaction.getGasPremium()).isEmpty(); |
||||
assertThat(transaction.getFeeCap()).isEmpty(); |
||||
} |
||||
|
||||
@Test |
||||
public void decodeEIP1559NominalCase() { |
||||
ExperimentalEIPs.eip1559Enabled = true; |
||||
final Transaction transaction = |
||||
TransactionRLPDecoder.decodeTransaction(RLP.input(Bytes.fromHexString(EIP1559_TX_RLP))); |
||||
assertThat(transaction).isNotNull(); |
||||
assertThat(transaction.getGasPremium()).hasValue(Wei.of(527L)); |
||||
assertThat(transaction.getFeeCap()).hasValue(Wei.of(369L)); |
||||
ExperimentalEIPs.eip1559Enabled = ExperimentalEIPs.EIP1559_ENABLED_DEFAULT_VALUE; |
||||
} |
||||
|
||||
@Test |
||||
public void decodeEIP1559FailureWhenNotEnabled() { |
||||
ExperimentalEIPs.eip1559Enabled = false; |
||||
assertThatThrownBy( |
||||
() -> |
||||
TransactionRLPDecoder.decodeTransaction( |
||||
RLP.input(Bytes.fromHexString(EIP1559_TX_RLP)))) |
||||
.isInstanceOf(RLPException.class) |
||||
.hasMessageContaining("Not at the end of the current list"); |
||||
ExperimentalEIPs.eip1559Enabled = ExperimentalEIPs.EIP1559_ENABLED_DEFAULT_VALUE; |
||||
} |
||||
} |
@ -0,0 +1,85 @@ |
||||
/* |
||||
* 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.encoding; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; |
||||
|
||||
import org.hyperledger.besu.config.experimental.ExperimentalEIPs; |
||||
import org.hyperledger.besu.ethereum.core.Transaction; |
||||
import org.hyperledger.besu.ethereum.rlp.BytesValueRLPOutput; |
||||
import org.hyperledger.besu.ethereum.rlp.RLP; |
||||
|
||||
import org.apache.tuweni.bytes.Bytes; |
||||
import org.junit.Test; |
||||
|
||||
/* |
||||
* 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 |
||||
*/ |
||||
public class TransactionRLPEncoderTest { |
||||
private static final String FRONTIER_TX_RLP = |
||||
"0xf901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"; |
||||
private static final String EIP1559_TX_RLP = |
||||
"0xf902028032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b5682020f8201711ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884"; |
||||
|
||||
@Test |
||||
public void encodeFrontierTxNominalCase() { |
||||
final Transaction transaction = |
||||
TransactionRLPDecoder.frontierDecoder() |
||||
.decode(RLP.input(Bytes.fromHexString(FRONTIER_TX_RLP))); |
||||
final BytesValueRLPOutput output = new BytesValueRLPOutput(); |
||||
TransactionRLPEncoder.encode(transaction, output); |
||||
assertThat(FRONTIER_TX_RLP).isEqualTo(output.encoded().toHexString()); |
||||
} |
||||
|
||||
@Test |
||||
public void encodeEIP1559TxNominalCase() { |
||||
ExperimentalEIPs.eip1559Enabled = true; |
||||
final Transaction transaction = |
||||
TransactionRLPDecoder.eip1559Decoder() |
||||
.decode(RLP.input(Bytes.fromHexString(EIP1559_TX_RLP))); |
||||
final BytesValueRLPOutput output = new BytesValueRLPOutput(); |
||||
TransactionRLPEncoder.encode(transaction, output); |
||||
assertThat( |
||||
"0xf902028080830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b5682020f8201711ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884") |
||||
.isEqualTo(output.encoded().toHexString()); |
||||
ExperimentalEIPs.eip1559Enabled = ExperimentalEIPs.EIP1559_ENABLED_DEFAULT_VALUE; |
||||
} |
||||
|
||||
@Test |
||||
public void encodeEIP1559TxFailureNotEnabled() { |
||||
ExperimentalEIPs.eip1559Enabled = false; |
||||
assertThatThrownBy( |
||||
() -> |
||||
TransactionRLPEncoder.encode( |
||||
TransactionRLPDecoder.eip1559Decoder() |
||||
.decode(RLP.input(Bytes.fromHexString(EIP1559_TX_RLP))), |
||||
new BytesValueRLPOutput())) |
||||
.isInstanceOf(RuntimeException.class) |
||||
.hasMessageContaining("Invalid transaction format"); |
||||
ExperimentalEIPs.eip1559Enabled = ExperimentalEIPs.EIP1559_ENABLED_DEFAULT_VALUE; |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
/* |
||||
* 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.plugin.data; |
||||
|
||||
public enum TransactionType { |
||||
FRONTIER, |
||||
EIP1559 |
||||
} |
Loading…
Reference in new issue