Skip to content

Commit

Permalink
Merge pull request #1033 from rsksmart/genesis-hash-fix
Browse files Browse the repository at this point in the history
Genesis instance is retrieved when decoding block 0
  • Loading branch information
lsebrie authored Oct 22, 2019
2 parents b80eba6 + 98244f5 commit 668a925
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 44 deletions.
32 changes: 27 additions & 5 deletions rskj-core/src/main/java/org/ethereum/core/BlockFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ private Block decodeBlock(byte[] rawData, boolean sealed) {
List<BlockHeader> uncleList = uncleHeadersRlp.stream()
.map(uncleHeader -> decodeHeader((RLPList) uncleHeader, sealed))
.collect(Collectors.toList());

return newBlock(header, transactionList, uncleList, sealed);
}

Expand Down Expand Up @@ -139,7 +138,7 @@ public BlockHeader decodeHeader(byte[] encoded) {
return decodeHeader(RLP.decodeList(encoded), true);
}

public BlockHeader decodeHeader(RLPList rlpHeader, boolean sealed) {
private BlockHeader decodeHeader(RLPList rlpHeader, boolean sealed) {
// TODO fix old tests that have other sizes
if (rlpHeader.size() != RLP_HEADER_SIZE && rlpHeader.size() != RLP_HEADER_SIZE_WITH_MERGED_MINING) {
throw new IllegalArgumentException(String.format(
Expand All @@ -150,7 +149,8 @@ public BlockHeader decodeHeader(RLPList rlpHeader, boolean sealed) {

byte[] parentHash = rlpHeader.get(0).getRLPData();
byte[] unclesHash = rlpHeader.get(1).getRLPData();
RskAddress coinbase = RLP.parseRskAddress(rlpHeader.get(2).getRLPData());
byte[] coinBaseBytes = rlpHeader.get(2).getRLPData();
RskAddress coinbase = RLP.parseRskAddress(coinBaseBytes);
byte[] stateRoot = rlpHeader.get(3).getRLPData();
if (stateRoot == null) {
stateRoot = EMPTY_TRIE_HASH;
Expand All @@ -167,7 +167,8 @@ public BlockHeader decodeHeader(RLPList rlpHeader, boolean sealed) {
}

byte[] logsBloom = rlpHeader.get(6).getRLPData();
BlockDifficulty difficulty = RLP.parseBlockDifficulty(rlpHeader.get(7).getRLPData());
byte[] difficultyBytes = rlpHeader.get(7).getRLPData();
BlockDifficulty difficulty = RLP.parseBlockDifficulty(difficultyBytes);

byte[] nrBytes = rlpHeader.get(8).getRLPData();
byte[] glBytes = rlpHeader.get(9).getRLPData();
Expand All @@ -182,7 +183,8 @@ public BlockHeader decodeHeader(RLPList rlpHeader, boolean sealed) {
byte[] extraData = rlpHeader.get(12).getRLPData();

Coin paidFees = RLP.parseCoin(rlpHeader.get(13).getRLPData());
Coin minimumGasPrice = RLP.parseSignedCoinNonNullZero(rlpHeader.get(14).getRLPData());
byte[] minimumGasPriceBytes = rlpHeader.get(14).getRLPData();
Coin minimumGasPrice = RLP.parseSignedCoinNonNullZero(minimumGasPriceBytes);

int r = 15;

Expand All @@ -205,6 +207,26 @@ public BlockHeader decodeHeader(RLPList rlpHeader, boolean sealed) {
boolean includeForkDetectionData = activationConfig.isActive(ConsensusRule.RSKIP110, number) &&
number >= MiningConfig.REQUIRED_NUMBER_OF_BLOCKS_FOR_FORK_DETECTION_CALCULATION;

if (number == Genesis.NUMBER) {
return new GenesisHeader(
parentHash,
unclesHash,
logsBloom,
difficultyBytes,
number,
glBytes,
gasUsed,
timestamp,
extraData,
bitcoinMergedMiningHeader,
bitcoinMergedMiningMerkleProof,
bitcoinMergedMiningCoinbaseTransaction,
minimumGasPriceBytes,
useRskip92Encoding,
coinBaseBytes,
stateRoot);
}

return new BlockHeader(
parentHash, unclesHash, coinbase, stateRoot,
txTrieRoot, receiptTrieRoot, logsBloom, difficulty,
Expand Down
34 changes: 5 additions & 29 deletions rskj-core/src/main/java/org/ethereum/core/Genesis.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,14 @@

package org.ethereum.core;

import co.rsk.core.BlockDifficulty;
import co.rsk.core.Coin;
import co.rsk.core.RskAddress;
import co.rsk.crypto.Keccak256;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.vm.DataWord;

import java.util.Arrays;
import java.util.Collections;
import java.util.Map;

import static org.ethereum.crypto.HashUtil.EMPTY_TRIE_HASH;

/**
* The genesis block is the first block in the chain and has fixed values according to
* the protocol specification. The genesis block is 13 items, and is specified thus:
Expand All @@ -60,31 +53,13 @@ public class Genesis extends Block {
private static final byte[] ZERO_HASH_2048 = new byte[256];
protected static final long NUMBER = 0;

public Genesis(byte[] parentHash, byte[] unclesHash, byte[] coinbase, byte[] logsBloom,
byte[] difficulty, long number, long gasLimit,
long gasUsed, long timestamp,
byte[] extraData,
byte[] bitcoinMergedMiningHeader, byte[] bitcoinMergedMiningMerkleProof,
byte[] bitcoinMergedMiningCoinbaseTransaction, byte[] minimumGasPrice,
boolean useRskip92Encoding, boolean isRskip126Enabled,
public Genesis(boolean isRskip126Enabled,
Map<RskAddress, AccountState> initialAccounts,
Map<RskAddress, byte[]> initialCodes,
Map<RskAddress, Map<DataWord, byte[]>> initialStorages){
Map<RskAddress, Map<DataWord, byte[]>> initialStorages,
BlockHeader header){
super(
new BlockHeader(
parentHash, unclesHash, new RskAddress(coinbase), ByteUtils.clone(EMPTY_TRIE_HASH),
ByteUtils.clone(EMPTY_TRIE_HASH), ByteUtils.clone(EMPTY_TRIE_HASH), logsBloom, RLP.parseBlockDifficulty(difficulty),
number, ByteUtil.longToBytesNoLeadZeroes(gasLimit), gasUsed, timestamp, extraData, Coin.ZERO,
bitcoinMergedMiningHeader, bitcoinMergedMiningMerkleProof,
bitcoinMergedMiningCoinbaseTransaction, new byte[0],
RLP.parseSignedCoinNonNullZero(minimumGasPrice), 0, false,
useRskip92Encoding, false) {

@Override
protected byte[] encodeBlockDifficulty(BlockDifficulty ignored) {
return RLP.encodeElement(difficulty);
}
},
header,
Collections.emptyList(),
Collections.emptyList(),
isRskip126Enabled,
Expand Down Expand Up @@ -128,4 +103,5 @@ public Map<RskAddress, byte[]> getCodes() {
public Map<RskAddress, Map<DataWord, byte[]>> getStorages() {
return initialStorages;
}

}
104 changes: 104 additions & 0 deletions rskj-core/src/main/java/org/ethereum/core/GenesisHeader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package org.ethereum.core;

import co.rsk.core.BlockDifficulty;
import co.rsk.core.Coin;
import co.rsk.core.RskAddress;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
import org.ethereum.crypto.HashUtil;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;

public class GenesisHeader extends BlockHeader {

private final byte[] difficulty;

public GenesisHeader(byte[] parentHash,
byte[] unclesHash,
byte[] logsBloom,
byte[] difficulty,
long number,
byte[] gasLimit,
long gasUsed,
long timestamp,
byte[] extraData,
byte[] bitcoinMergedMiningHeader,
byte[] bitcoinMergedMiningMerkleProof,
byte[] bitcoinMergedMiningCoinbaseTransaction,
byte[] minimumGasPrice,
boolean useRskip92Encoding,
byte[] coinbase,
byte[] stateRootHash) {
super(
parentHash,
unclesHash,
new RskAddress(coinbase),
stateRootHash,
ByteUtils.clone(HashUtil.EMPTY_TRIE_HASH),
ByteUtils.clone(HashUtil.EMPTY_TRIE_HASH),
logsBloom,
RLP.parseBlockDifficulty(difficulty),
number,
ByteUtil.stripLeadingZeroes(gasLimit),
gasUsed,
timestamp,
extraData,
Coin.ZERO,
bitcoinMergedMiningHeader,
bitcoinMergedMiningMerkleProof,
bitcoinMergedMiningCoinbaseTransaction,
new byte[0],
RLP.parseSignedCoinNonNullZero(minimumGasPrice),
0,
false,
useRskip92Encoding,
false);
this.difficulty = ByteUtils.clone(difficulty);
}

public GenesisHeader(byte[] parentHash,
byte[] unclesHash,
byte[] logsBloom,
byte[] difficulty,
long number,
byte[] gasLimit,
long gasUsed,
long timestamp,
byte[] extraData,
byte[] bitcoinMergedMiningHeader,
byte[] bitcoinMergedMiningMerkleProof,
byte[] bitcoinMergedMiningCoinbaseTransaction,
byte[] minimumGasPrice,
boolean useRskip92Encoding,
byte[] coinbase) {
super(
parentHash,
unclesHash,
new RskAddress(coinbase),
ByteUtils.clone(HashUtil.EMPTY_TRIE_HASH),
ByteUtils.clone(HashUtil.EMPTY_TRIE_HASH),
ByteUtils.clone(HashUtil.EMPTY_TRIE_HASH),
logsBloom,
RLP.parseBlockDifficulty(difficulty),
number,
ByteUtil.stripLeadingZeroes(gasLimit),
gasUsed,
timestamp,
extraData,
Coin.ZERO,
bitcoinMergedMiningHeader,
bitcoinMergedMiningMerkleProof,
bitcoinMergedMiningCoinbaseTransaction,
new byte[0],
RLP.parseSignedCoinNonNullZero(minimumGasPrice),
0,
false,
useRskip92Encoding,
false);
this.difficulty = ByteUtils.clone(difficulty);
}

@Override
protected byte[] encodeBlockDifficulty(BlockDifficulty ignored) {
return RLP.encodeElement(difficulty);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.ethereum.config.blockchain.upgrades.ConsensusRule;
import org.ethereum.core.AccountState;
import org.ethereum.core.Genesis;
import org.ethereum.core.GenesisHeader;
import org.ethereum.core.Repository;
import org.ethereum.crypto.HashUtil;
import org.ethereum.db.MutableRepository;
Expand Down Expand Up @@ -190,11 +191,23 @@ private Genesis mapFromJson(GenesisJson json) {
}
}

return new Genesis(parentHash, EMPTY_LIST_HASH, coinbase, Genesis.getZeroHash(),
difficulty, 0, gasLimit, 0, timestamp, extraData,
bitcoinMergedMiningHeader, bitcoinMergedMiningMerkleProof,
bitcoinMergedMiningCoinbaseTransaction, minGasPrice, useRskip92Encoding,
isRskip126Enabled, accounts, codes, storages);
GenesisHeader header = new GenesisHeader(
parentHash,
EMPTY_LIST_HASH,
Genesis.getZeroHash(),
difficulty,
0,
ByteUtil.longToBytes(gasLimit),
0,
timestamp,
extraData,
bitcoinMergedMiningHeader,
bitcoinMergedMiningMerkleProof,
bitcoinMergedMiningCoinbaseTransaction,
minGasPrice,
useRskip92Encoding,
coinbase);
return new Genesis(isRskip126Enabled, accounts, codes, storages, header);
}

private Trie loadGenesisTrie(Genesis genesis) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest;
import org.ethereum.core.*;
import org.ethereum.crypto.HashUtil;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPElement;
import org.ethereum.util.RLPList;
Expand Down Expand Up @@ -99,10 +100,23 @@ private Genesis getNewGenesisBlock(long initialGasLimit, Map<RskAddress, Account

boolean isRskip126Enabled = activationConfig.isActive(ConsensusRule.RSKIP126, 0);
boolean useRskip92Encoding = activationConfig.isActive(ConsensusRule.RSKIP92, 0);
return new Genesis(parentHash, EMPTY_LIST_HASH, coinbase, getZeroHash(),
difficulty, 0, gasLimit, 0, timestamp, extraData,
null, null, null, BigInteger.valueOf(100L).toByteArray(), useRskip92Encoding,
isRskip126Enabled, accounts, Collections.emptyMap(), Collections.emptyMap()
return new Genesis(
isRskip126Enabled, accounts, Collections.emptyMap(), Collections.emptyMap(), new GenesisHeader(
parentHash,
EMPTY_LIST_HASH,
getZeroHash(),
difficulty,
0,
ByteUtil.longToBytes(gasLimit),
0,
timestamp,
extraData,
null,
null,
null,
BigInteger.valueOf(100L).toByteArray(),
useRskip92Encoding,
coinbase)
);
}

Expand Down
29 changes: 28 additions & 1 deletion rskj-core/src/test/java/co/rsk/core/BlockFactoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@
import co.rsk.config.RskMiningConstants;
import co.rsk.crypto.Keccak256;
import co.rsk.peg.PegTestUtils;
import org.bouncycastle.util.encoders.Hex;
import org.ethereum.TestUtils;
import org.ethereum.config.blockchain.upgrades.ActivationConfig;
import org.ethereum.config.blockchain.upgrades.ConsensusRule;
import org.ethereum.core.Block;
import org.ethereum.core.BlockFactory;
import org.ethereum.core.BlockHeader;
import org.ethereum.core.Bloom;
Expand Down Expand Up @@ -56,6 +58,12 @@ public void setUp() {
factory = new BlockFactory(activationConfig);
}

@Test
public void decodeGenesisBlock() {
enableRulesAt(0L, RSKIP92);
assertThat(factory.decodeBlock(genesisRaw()).getHash().getBytes(), is(genesisRawHash()));
}

@Test
public void newHeaderWithNoForkDetectionDataAndRskip110On() {
long number = 20L;
Expand Down Expand Up @@ -246,4 +254,23 @@ private BlockHeader createBlockHeader(
Coin.valueOf(10L).getBytes(),
0);
}
}


private static byte[] genesisRawHash() {
return Hex.decode("cabb7fbe88cd6d922042a32ffc08ce8b1fbb37d650b9d4e7dbfe2a7469adfa42");
}

private static byte[] genesisRaw() {
return Hex.decode("f901dbf901d6a00000000000000000000000000000000000000000000000000000000000000000a01dcc" +
"4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479433333333333333333333333333333333333" +
"33333a045bce5168430c42b3d568331753f900a32457b4f3748697cbd8375ff4da72641a056e81f171bcc55a6ff8345e6" +
"92c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb" +
"5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"00000000000000000000000000000000000000000085000010000080834c4b40808085434d272841800080000000c0c0");

}
}

0 comments on commit 668a925

Please sign in to comment.