Skip to content

Commit

Permalink
[EIP-1559] Step 1 - Apply block structure modification (#619)
Browse files Browse the repository at this point in the history
* Added changelog entries for PR:
- #430
- #440

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* ### Description
BlockHeader object needs to be modified in order to add the new field (baseFee) as specified in the EIP.
We should take care about the RLP encoding/decoding of this structure since it has to include or not the new fields depending on whether we are pre fork or post fork.

- Update `core.BlockHeader.java`
    - Add `baseFee`
    - Update `readFrom` method for RLP decoding
    - Update `writeTo` method for RLP encoding
- Update `plugin.data.BlockHeader.java`
    - Add `getBaseFee` method

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* TODO Add CLI command line flag `--Xeip1559-enabled`.

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* TODO Add CLI command line flag `--Xeip1559-enabled`.

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* Added unstable annotation for getBaseFee. Moved from long to `Optional<Long>`

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* Spotless apply

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* Fixed error

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* fix plugin API hash

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* RLP encoding / decoding operations are guarded with the feature flag.

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>

* spotless apply

Signed-off-by: Abdelhamid Bakhta <abdelhamid.bakhta@consensys.net>
  • Loading branch information
AbdelStark authored Apr 3, 2020
1 parent 82c8909 commit 2148116
Show file tree
Hide file tree
Showing 12 changed files with 98 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public static BlockHeader createBlockHeader(
block.getGasUsed().longValue(),
block.getTimestamp().longValue(),
Bytes.fromHexString(block.getExtraData()),
null,
mixHash,
block.getNonce().longValue(),
blockHeaderFunctions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ private void setSyncTarget() {
syncState.setSyncTarget(
mock(EthPeer.class),
new org.hyperledger.besu.ethereum.core.BlockHeader(
null, null, null, null, null, null, null, null, 1, 1, 1, 1, null, null, 1, null));
null, null, null, null, null, null, null, null, 1, 1, 1, 1, null, null, null, 1, null));
}

private void clearSyncTarget() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ public enum JsonRpcResponseKey {
STATE_ROOT,
TIMESTAMP,
TOTAL_DIFFICULTY,
TRANSACTION_ROOT
TRANSACTION_ROOT,
BASEFEE
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc;

import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.BASEFEE;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.COINBASE;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.DIFFICULTY;
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcResponseKey.EXTRA_DATA;
Expand Down Expand Up @@ -91,6 +92,7 @@ public JsonRpcResponse response(
final long gasUsed = unsignedLong(values.get(GAS_USED));
final long timestamp = unsignedLong(values.get(TIMESTAMP));
final long nonce = unsignedLong(values.get(NONCE));
final Long baseFee = values.containsKey(BASEFEE) ? unsignedLong(values.get(BASEFEE)) : null;
final Difficulty totalDifficulty = Difficulty.of(unsignedInt256(values.get(TOTAL_DIFFICULTY)));
final int size = unsignedInt(values.get(SIZE));

Expand All @@ -111,6 +113,7 @@ public JsonRpcResponse response(
gasUsed,
timestamp,
extraData,
baseFee,
mixHash,
nonce,
blockHeaderFunctions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public void setup() {
0,
0,
Bytes.EMPTY,
null,
Hash.EMPTY,
0,
new MainnetBlockHeaderFunctions());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/
package org.hyperledger.besu.ethereum.core;

import org.hyperledger.besu.config.experimental.ExperimentalEIPs;
import org.hyperledger.besu.ethereum.rlp.RLPInput;
import org.hyperledger.besu.ethereum.rlp.RLPOutput;

Expand Down Expand Up @@ -53,6 +54,7 @@ public BlockHeader(
final long gasUsed,
final long timestamp,
final Bytes extraData,
final Long baseFee,
final Hash mixHash,
final long nonce,
final BlockHeaderFunctions blockHeaderFunctions) {
Expand All @@ -69,7 +71,8 @@ public BlockHeader(
gasLimit,
gasUsed,
timestamp,
extraData);
extraData,
baseFee);
this.mixHash = mixHash;
this.nonce = nonce;
this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this));
Expand Down Expand Up @@ -142,33 +145,53 @@ public void writeTo(final RLPOutput out) {
out.writeBytes(extraData);
out.writeBytes(mixHash);
out.writeLong(nonce);

if (ExperimentalEIPs.eip1559Enabled && baseFee != null) {
out.writeLongScalar(baseFee);
}
out.endList();
}

public static BlockHeader readFrom(
final RLPInput input, final BlockHeaderFunctions blockHeaderFunctions) {
input.enterList();
final BlockHeader blockHeader =
new BlockHeader(
Hash.wrap(input.readBytes32()),
Hash.wrap(input.readBytes32()),
Address.readFrom(input),
Hash.wrap(input.readBytes32()),
Hash.wrap(input.readBytes32()),
Hash.wrap(input.readBytes32()),
LogsBloomFilter.readFrom(input),
Difficulty.of(input.readUInt256Scalar()),
input.readLongScalar(),
input.readLongScalar(),
input.readLongScalar(),
input.readLongScalar(),
input.readBytes(),
Hash.wrap(input.readBytes32()),
input.readLong(),
blockHeaderFunctions);
final Hash parentHash = Hash.wrap(input.readBytes32());
final Hash ommersHash = Hash.wrap(input.readBytes32());
final Address coinbase = Address.readFrom(input);
final Hash stateRoot = Hash.wrap(input.readBytes32());
final Hash transactionsRoot = Hash.wrap(input.readBytes32());
final Hash receiptsRoot = Hash.wrap(input.readBytes32());
final LogsBloomFilter logsBloom = LogsBloomFilter.readFrom(input);
final Difficulty difficulty = Difficulty.of(input.readUInt256Scalar());
final long number = input.readLongScalar();
final long gasLimit = input.readLongScalar();
final long gasUsed = input.readLongScalar();
final long timestamp = input.readLongScalar();
final Bytes extraData = input.readBytes();
final Hash mixHash = Hash.wrap(input.readBytes32());
final long nonce = input.readLong();
final Long baseFee =
ExperimentalEIPs.eip1559Enabled && !input.isEndOfCurrentList()
? input.readLongScalar()
: null;
input.leaveList();
return blockHeader;
return new BlockHeader(
parentHash,
ommersHash,
coinbase,
stateRoot,
transactionsRoot,
receiptsRoot,
logsBloom,
difficulty,
number,
gasLimit,
gasUsed,
timestamp,
extraData,
baseFee,
mixHash,
nonce,
blockHeaderFunctions);
}

@Override
Expand Down Expand Up @@ -206,6 +229,7 @@ public String toString() {
sb.append("gasUsed=").append(gasUsed).append(", ");
sb.append("timestamp=").append(timestamp).append(", ");
sb.append("extraData=").append(extraData).append(", ");
sb.append("baseFee=").append(baseFee).append(", ");
sb.append("mixHash=").append(mixHash).append(", ");
sb.append("nonce=").append(nonce);
return sb.append("}").toString();
Expand All @@ -229,6 +253,7 @@ public static org.hyperledger.besu.ethereum.core.BlockHeader convertPluginBlockH
pluginBlockHeader.getGasUsed(),
pluginBlockHeader.getTimestamp(),
pluginBlockHeader.getExtraData(),
pluginBlockHeader.getBaseFee().orElse(null),
Hash.fromHexString(pluginBlockHeader.getMixHash().toHexString()),
pluginBlockHeader.getNonce(),
blockHeaderFunctions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public class BlockHeaderBuilder {

private Bytes extraData;

private Long baseFee = null;

private Hash mixHash;

private BlockHeaderFunctions blockHeaderFunctions;
Expand Down Expand Up @@ -79,6 +81,7 @@ public static BlockHeaderBuilder fromHeader(final BlockHeader header) {
.gasUsed(header.getGasUsed())
.timestamp(header.getTimestamp())
.extraData(header.getExtraData())
.baseFee(header.getBaseFee().orElse(null))
.mixHash(header.getMixHash())
.nonce(header.getNonce());
}
Expand Down Expand Up @@ -122,6 +125,7 @@ public BlockHeader buildBlockHeader() {
gasUsed,
timestamp < 0 ? Instant.now().getEpochSecond() : timestamp,
extraData,
baseFee,
mixHash,
nonce.getAsLong(),
blockHeaderFunctions);
Expand Down Expand Up @@ -150,7 +154,8 @@ public SealableBlockHeader buildSealableBlockHeader() {
gasLimit,
gasUsed,
timestamp,
extraData);
extraData,
baseFee);
}

private void validateBlockHeader() {
Expand Down Expand Up @@ -303,4 +308,9 @@ public BlockHeaderBuilder blockHeaderFunctions(final BlockHeaderFunctions blockH
this.blockHeaderFunctions = blockHeaderFunctions;
return this;
}

public BlockHeaderBuilder baseFee(final Long baseFee) {
this.baseFee = baseFee;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
*/
package org.hyperledger.besu.ethereum.core;

import java.util.Optional;

import org.apache.tuweni.bytes.Bytes;

/** A block header capable of being sealed. */
Expand All @@ -31,6 +33,7 @@ public class SealableBlockHeader extends ProcessableBlockHeader {
protected final long gasUsed;

protected final Bytes extraData;
protected final Long baseFee;

protected SealableBlockHeader(
final Hash parentHash,
Expand All @@ -45,7 +48,8 @@ protected SealableBlockHeader(
final long gasLimit,
final long gasUsed,
final long timestamp,
final Bytes extraData) {
final Bytes extraData,
final Long baseFee) {
super(parentHash, coinbase, difficulty, number, gasLimit, timestamp);
this.ommersHash = ommersHash;
this.stateRoot = stateRoot;
Expand All @@ -54,6 +58,7 @@ protected SealableBlockHeader(
this.logsBloom = logsBloom;
this.gasUsed = gasUsed;
this.extraData = extraData;
this.baseFee = baseFee;
}

/**
Expand Down Expand Up @@ -118,4 +123,13 @@ public long getGasUsed() {
public Bytes getExtraData() {
return extraData;
}

/**
* Returns the basefee of the block.
*
* @return the raw bytes of the extra data field
*/
public Optional<Long> getBaseFee() {
return Optional.ofNullable(baseFee);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public BlockHeaderMock(
0L,
Long.decode(timestamp),
Bytes.EMPTY,
0L,
Hash.ZERO,
0L,
new MainnetBlockHeaderFunctions());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ public BlockHeaderMock(
@JsonProperty("gasUsed") final String gasUsed,
@JsonProperty("timestamp") final String timestamp,
@JsonProperty("extraData") final String extraData,
@JsonProperty("baseFee") final String baseFee,
@JsonProperty("mixHash") final String mixHash,
@JsonProperty("nonce") final String nonce,
@JsonProperty("hash") final String hash) {
Expand All @@ -169,6 +170,7 @@ public BlockHeaderMock(
Long.decode(gasUsed), // gasUsed
Long.decode(timestamp), // timestamp
Bytes.fromHexString(extraData), // extraData
baseFee != null ? Long.decode(baseFee) : null, // baseFee
Hash.fromHexString(mixHash), // mixHash
Bytes.fromHexString(nonce).getLong(0),
new BlockHeaderFunctions() {
Expand Down
2 changes: 1 addition & 1 deletion plugin-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Calculated : ${currentHash}
tasks.register('checkAPIChanges', FileStateChecker) {
description = "Checks that the API for the Plugin-API project does not change without deliberate thought"
files = sourceSets.main.allJava.files
knownHash = 'fL4EQBDRXnw1hiUIUMscLxRG/uWznpZSNJGSIp9+mFo='
knownHash = 'nUbCiB6FbQJavvvmlnnZBAPWErD7aKyxR+Qpk24ZtrE='
}
check.dependsOn('checkAPIChanges')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
*/
package org.hyperledger.besu.plugin.data;

import org.hyperledger.besu.plugin.Unstable;

import java.util.Optional;

import org.apache.tuweni.bytes.Bytes;

/**
Expand Down Expand Up @@ -154,4 +158,14 @@ public interface BlockHeader {
* @return The Keccak 256-bit hash of this header.
*/
Hash getBlockHash();

/**
* The BASEFEE of this header.
*
* @return TheBASEFEE of this header.
*/
@Unstable
default Optional<Long> getBaseFee() {
return Optional.empty();
}
}

0 comments on commit 2148116

Please sign in to comment.