From 871d5d006ed2ea9a563db7308d77454b89d83744 Mon Sep 17 00:00:00 2001 From: Jason Frame <909467+jframe@users.noreply.github.com> Date: Thu, 6 Jun 2019 12:41:55 +1000 Subject: [PATCH] Fix estimate gas RPC failing for clique when no blocks have been created (#1528) Signed-off-by: Adrian Sutton --- .../consensus/clique/CliqueBlockHashing.java | 4 +- .../clique/CliqueBlockHashingTest.java | 39 +++++++++++++++++++ .../pantheon/ethereum/core/Address.java | 2 + 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashing.java b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashing.java index de342cfa2f..148ffc8487 100644 --- a/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashing.java +++ b/consensus/clique/src/main/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashing.java @@ -23,7 +23,6 @@ import tech.pegasys.pantheon.util.bytes.BytesValue; import java.util.function.Supplier; public class CliqueBlockHashing { - /** * Constructs a hash of the block header, suitable for use when creating the proposer seal. The * extra data is modified to have a null proposer seal and empty list of committed seals. @@ -49,6 +48,9 @@ public class CliqueBlockHashing { public static Address recoverProposerAddress( final BlockHeader header, final CliqueExtraData cliqueExtraData) { if (!cliqueExtraData.getProposerSeal().isPresent()) { + if (header.getNumber() == BlockHeader.GENESIS_BLOCK_NUMBER) { + return Address.ZERO; + } throw new IllegalArgumentException( "Supplied cliqueExtraData does not include a proposer " + "seal"); } diff --git a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashingTest.java b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashingTest.java index 518b93e9fc..11d7bac9b6 100644 --- a/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashingTest.java +++ b/consensus/clique/src/test/java/tech/pegasys/pantheon/consensus/clique/CliqueBlockHashingTest.java @@ -55,6 +55,16 @@ public class CliqueBlockHashingTest { assertThat(VALIDATORS_IN_HEADER.contains(proposerAddress)).isTrue(); } + @Test + public void recoverProposerAddressForGenesisBlockReturnsAddressZero() { + final BlockHeader genesisBlockHeader = createGenesisBlock(); + final CliqueExtraData cliqueExtraData = CliqueExtraData.decode(genesisBlockHeader); + final Address proposerAddress = + CliqueBlockHashing.recoverProposerAddress(genesisBlockHeader, cliqueExtraData); + + assertThat(proposerAddress).isEqualTo(Address.ZERO); + } + @Test public void readValidatorListFromExtraData() { final CliqueExtraData cliqueExtraData = CliqueExtraData.decode(expectedHeader); @@ -101,4 +111,33 @@ public class CliqueBlockHashingTest { return builder.buildBlockHeader(); } + + private BlockHeader createGenesisBlock() { + // The following was taken from the Rinkeby genesis file + final BlockHeaderBuilder builder = new BlockHeaderBuilder(); + builder.difficulty(UInt256.of(1)); + builder.extraData( + BytesValue.fromHexString( + "0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); + builder.gasLimit(4700000); + builder.gasUsed(0); + // Do not do Hash. + builder.logsBloom( + LogsBloomFilter.fromHexString( + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")); + builder.coinbase(Address.fromHexString("0x0000000000000000000000000000000000000000")); + builder.mixHash(Hash.ZERO); + builder.nonce(0); + builder.number(0); + builder.parentHash(Hash.ZERO); + builder.receiptsRoot(Hash.ZERO); + builder.ommersHash(Hash.ZERO); + builder.stateRoot(Hash.ZERO); + builder.timestamp(1492009146); + builder.transactionsRoot(Hash.ZERO); + + builder.blockHeaderFunctions(new CliqueBlockHeaderFunctions()); + + return builder.buildBlockHeader(); + } } diff --git a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/Address.java b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/Address.java index 7ee773b860..cdff337d75 100644 --- a/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/Address.java +++ b/ethereum/core/src/main/java/tech/pegasys/pantheon/ethereum/core/Address.java @@ -42,6 +42,8 @@ public class Address extends DelegatingBytesValue { public static final Integer PRIVACY = Byte.MAX_VALUE - 1; public static final Address DEFAULT_PRIVACY = Address.precompiled(PRIVACY); + public static final Address ZERO = Address.fromHexString("0x0"); + protected Address(final BytesValue bytes) { super(bytes); checkArgument(