From 2ed6c61f6bd66521ab01cc62f62da8df8b85b8d4 Mon Sep 17 00:00:00 2001 From: garyschulte Date: Thu, 25 Nov 2021 10:17:37 -0800 Subject: [PATCH] merge of Blockheader changes to support random field (#3104) * merge of Blockheader changes to support random field Signed-off-by: garyschulte --- .../besu/ethereum/core/BlockHeader.java | 27 +++++++++--------- .../ethereum/core/BlockHeaderBuilder.java | 28 +++++++++++++------ .../ethereum/core/ProcessableBlockHeader.java | 18 ++++++++++-- .../ethereum/core/SealableBlockHeader.java | 6 ++-- .../ethereum/mainnet/KeccakHasherTest.java | 8 ++++-- plugin-api/build.gradle | 2 +- .../besu/plugin/data/BlockHeader.java | 12 +++++++- 7 files changed, 71 insertions(+), 30 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java index 5776abf39b7..738d7b2ef9c 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeader.java @@ -26,6 +26,7 @@ import com.google.common.base.Suppliers; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; /** A mined Ethereum block header. */ public class BlockHeader extends SealableBlockHeader @@ -35,8 +36,6 @@ public class BlockHeader extends SealableBlockHeader public static final long GENESIS_BLOCK_NUMBER = 0L; - private final Hash mixHash; - private final long nonce; private final Supplier hash; @@ -60,7 +59,7 @@ public BlockHeader( final long timestamp, final Bytes extraData, final Long baseFee, - final Hash mixHash, + final Bytes32 mixHashOrRandom, final long nonce, final BlockHeaderFunctions blockHeaderFunctions, final Optional privateLogsBloom) { @@ -78,8 +77,8 @@ public BlockHeader( gasUsed, timestamp, extraData, - baseFee); - this.mixHash = mixHash; + baseFee, + mixHashOrRandom); this.nonce = nonce; this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this)); this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this)); @@ -101,7 +100,7 @@ public BlockHeader( final long timestamp, final Bytes extraData, final Long baseFee, - final Hash mixHash, + final Bytes32 mixHashOrRandom, final long nonce, final BlockHeaderFunctions blockHeaderFunctions) { super( @@ -118,8 +117,8 @@ public BlockHeader( gasUsed, timestamp, extraData, - baseFee); - this.mixHash = mixHash; + baseFee, + mixHashOrRandom); this.nonce = nonce; this.hash = Suppliers.memoize(() -> blockHeaderFunctions.hash(this)); this.parsedExtraData = Suppliers.memoize(() -> blockHeaderFunctions.parseExtraData(this)); @@ -133,7 +132,7 @@ public BlockHeader( */ @Override public Hash getMixHash() { - return mixHash; + return Hash.wrap(mixHashOrRandom); } /** @@ -215,7 +214,7 @@ public void writeTo(final RLPOutput out) { out.writeLongScalar(gasUsed); out.writeLongScalar(timestamp); out.writeBytes(extraData); - out.writeBytes(mixHash); + out.writeBytes(mixHashOrRandom); out.writeLong(nonce); if (baseFee != null) { out.writeLongScalar(baseFee); @@ -239,7 +238,7 @@ public static BlockHeader readFrom( final long gasUsed = input.readLongScalar(); final long timestamp = input.readLongScalar(); final Bytes extraData = input.readBytes(); - final Hash mixHash = Hash.wrap(input.readBytes32()); + final Bytes32 mixHashOrRandom = input.readBytes32(); final long nonce = input.readLong(); final Long baseFee = !input.isEndOfCurrentList() ? input.readLongScalar() : null; input.leaveList(); @@ -258,7 +257,7 @@ public static BlockHeader readFrom( timestamp, extraData, baseFee, - mixHash, + mixHashOrRandom, nonce, blockHeaderFunctions); } @@ -299,7 +298,7 @@ public String toString() { 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("mixHashOrRandom=").append(mixHashOrRandom).append(", "); sb.append("nonce=").append(nonce); return sb.append("}").toString(); } @@ -322,7 +321,7 @@ public static org.hyperledger.besu.ethereum.core.BlockHeader convertPluginBlockH pluginBlockHeader.getTimestamp(), pluginBlockHeader.getExtraData(), pluginBlockHeader.getBaseFee().orElse(null), - Hash.fromHexString(pluginBlockHeader.getMixHash().toHexString()), + pluginBlockHeader.getRandom().orElse(null), pluginBlockHeader.getNonce(), blockHeaderFunctions); } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java index 055ab095bf5..b2ab3766305 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/BlockHeaderBuilder.java @@ -26,6 +26,7 @@ import java.util.OptionalLong; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; /** A utility class for building block headers. */ public class BlockHeaderBuilder { @@ -58,7 +59,7 @@ public class BlockHeaderBuilder { private Long baseFee = null; - private Hash mixHash; + private Bytes32 mixHashOrRandom = null; private BlockHeaderFunctions blockHeaderFunctions; @@ -87,7 +88,8 @@ public static BlockHeaderBuilder fromHeader(final BlockHeader header) { .extraData(header.getExtraData()) .baseFee(header.getBaseFee().orElse(null)) .mixHash(header.getMixHash()) - .nonce(header.getNonce()); + .nonce(header.getNonce()) + .random(header.getRandom().orElse(null)); } public static BlockHeaderBuilder fromBuilder(final BlockHeaderBuilder fromBuilder) { @@ -106,8 +108,8 @@ public static BlockHeaderBuilder fromBuilder(final BlockHeaderBuilder fromBuilde .gasUsed(fromBuilder.gasUsed) .timestamp(fromBuilder.timestamp) .extraData(fromBuilder.extraData) - .mixHash(fromBuilder.mixHash) .baseFee(fromBuilder.baseFee) + .random(fromBuilder.mixHashOrRandom) .blockHeaderFunctions(fromBuilder.blockHeaderFunctions); toBuilder.nonce = fromBuilder.nonce; return toBuilder; @@ -131,7 +133,7 @@ public BlockHeader buildBlockHeader() { timestamp < 0 ? Instant.now().getEpochSecond() : timestamp, extraData, baseFee, - mixHash, + mixHashOrRandom, nonce.getAsLong(), blockHeaderFunctions); } @@ -140,7 +142,7 @@ public ProcessableBlockHeader buildProcessableBlockHeader() { validateProcessableBlockHeader(); return new ProcessableBlockHeader( - parentHash, coinbase, difficulty, number, gasLimit, timestamp, baseFee); + parentHash, coinbase, difficulty, number, gasLimit, timestamp, baseFee, mixHashOrRandom); } public SealableBlockHeader buildSealableBlockHeader() { @@ -160,12 +162,13 @@ public SealableBlockHeader buildSealableBlockHeader() { gasUsed, timestamp, extraData, - baseFee); + baseFee, + mixHashOrRandom); } private void validateBlockHeader() { validateSealableBlockHeader(); - checkState(this.mixHash != null, "Missing mixHash"); + checkState(this.mixHashOrRandom != null, "Missing mixHash or random"); checkState(this.nonce.isPresent(), "Missing nonce"); checkState(this.blockHeaderFunctions != null, "Missing blockHeaderFunctions"); } @@ -199,6 +202,7 @@ public BlockHeaderBuilder populateFrom(final ProcessableBlockHeader processableB gasLimit(processableBlockHeader.getGasLimit()); timestamp(processableBlockHeader.getTimestamp()); baseFee(processableBlockHeader.getBaseFee().orElse(null)); + processableBlockHeader.getRandom().ifPresent(this::random); return this; } @@ -218,6 +222,7 @@ public BlockHeaderBuilder populateFrom(final SealableBlockHeader sealableBlockHe timestamp(sealableBlockHeader.getTimestamp()); extraData(sealableBlockHeader.getExtraData()); baseFee(sealableBlockHeader.getBaseFee().orElse(null)); + sealableBlockHeader.getRandom().ifPresent(this::random); return this; } @@ -302,7 +307,7 @@ public BlockHeaderBuilder extraData(final Bytes data) { public BlockHeaderBuilder mixHash(final Hash mixHash) { checkNotNull(mixHash); - this.mixHash = mixHash; + this.mixHashOrRandom = mixHash; return this; } @@ -320,4 +325,11 @@ public BlockHeaderBuilder baseFee(final Long baseFee) { this.baseFee = baseFee; return this; } + + public BlockHeaderBuilder random(final Bytes32 random) { + if (random != null) { + this.mixHashOrRandom = random; + } + return this; + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java index 12a63dad92d..ee066f80bdd 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/ProcessableBlockHeader.java @@ -21,6 +21,7 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; /** A block header capable of being processed. */ public class ProcessableBlockHeader implements BlockValues { @@ -39,6 +40,8 @@ public class ProcessableBlockHeader implements BlockValues { protected final long timestamp; // base fee is included for post EIP-1559 blocks protected final Long baseFee; + // random is included for post-merge blocks + protected final Bytes32 mixHashOrRandom; protected ProcessableBlockHeader( final Hash parentHash, @@ -47,7 +50,8 @@ protected ProcessableBlockHeader( final long number, final long gasLimit, final long timestamp, - final Long baseFee) { + final Long baseFee, + final Bytes32 mixHashOrRandom) { this.parentHash = parentHash; this.coinbase = coinbase; this.difficulty = difficulty; @@ -55,6 +59,7 @@ protected ProcessableBlockHeader( this.gasLimit = gasLimit; this.timestamp = timestamp; this.baseFee = baseFee; + this.mixHashOrRandom = mixHashOrRandom; } /** @@ -127,10 +132,19 @@ public long getTimestamp() { /** * Returns the basefee of the block. * - * @return the raw bytes of the extra data field + * @return the optional long value for base fee */ @Override public Optional getBaseFee() { return Optional.ofNullable(baseFee); } + + /** + * Returns the random of the block. + * + * @return the raw bytes of the random field + */ + public Optional getRandom() { + return Optional.ofNullable(mixHashOrRandom); + } } diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java index 611e4ce5aef..30db2c41051 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/core/SealableBlockHeader.java @@ -19,6 +19,7 @@ import org.hyperledger.besu.evm.log.LogsBloomFilter; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; /** A block header capable of being sealed. */ public class SealableBlockHeader extends ProcessableBlockHeader { @@ -50,8 +51,9 @@ protected SealableBlockHeader( final long gasUsed, final long timestamp, final Bytes extraData, - final Long baseFee) { - super(parentHash, coinbase, difficulty, number, gasLimit, timestamp, baseFee); + final Long baseFee, + final Bytes32 mixHashOrRandom) { + super(parentHash, coinbase, difficulty, number, gasLimit, timestamp, baseFee, mixHashOrRandom); this.ommersHash = ommersHash; this.stateRoot = stateRoot; this.transactionsRoot = transactionsRoot; diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/KeccakHasherTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/KeccakHasherTest.java index ab5c3a75c88..8c229913a53 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/KeccakHasherTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/mainnet/KeccakHasherTest.java @@ -23,6 +23,7 @@ import org.hyperledger.besu.evm.log.LogsBloomFilter; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; import org.junit.Test; public class KeccakHasherTest { @@ -43,7 +44,8 @@ protected KeccakSealableBlockHeader( final long gasUsed, final long timestamp, final Bytes extraData, - final Long baseFee) { + final Long baseFee, + final Bytes32 random) { super( parentHash, ommersHash, @@ -58,7 +60,8 @@ protected KeccakSealableBlockHeader( gasUsed, timestamp, extraData, - baseFee); + baseFee, + random); } } @@ -103,6 +106,7 @@ public void testHasherFromBlock() { 7987824L, 1538483791L, Bytes.fromHexString("0xd88301080f846765746888676f312e31302e31856c696e7578"), + null, null); PoWSolution result = diff --git a/plugin-api/build.gradle b/plugin-api/build.gradle index 587bfbccc35..55307be4cd9 100644 --- a/plugin-api/build.gradle +++ b/plugin-api/build.gradle @@ -64,7 +64,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 = 'Z78NXPRIv33CBOfuUaAfgEr55ZrmxDWqVT8DVJ+FxA4=' + knownHash = '/M23BAhwqtMpjhcoHDMJvbHyhJ4z39z2jJMWUGOBO14=' } check.dependsOn('checkAPIChanges') diff --git a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java index 12a4a51d8cf..47e8f88f04a 100644 --- a/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java +++ b/plugin-api/src/main/java/org/hyperledger/besu/plugin/data/BlockHeader.java @@ -19,6 +19,7 @@ import java.util.Optional; import org.apache.tuweni.bytes.Bytes; +import org.apache.tuweni.bytes.Bytes32; /** * The minimum set of data for a BlockHeader, as defined in the getBaseFee() { return Optional.empty(); } + + /** + * Optional 32 bytes of random data. + * + * @return Optional random bytes from this header. + */ + default Optional getRandom() { + return Optional.empty(); + } }