Adaptation of Block/BlockHeader/Genesis/AccountState - for 0.7.8 version

This commit is contained in:
romanman 2014-11-03 08:27:38 -05:00
parent 549882bc03
commit 60eb716383
13 changed files with 118 additions and 54 deletions

View File

@ -4,7 +4,7 @@
<groupId>org.ethereum</groupId>
<artifactId>ethereumj</artifactId>
<packaging>jar</packaging>
<version>0.7.6</version>
<version>0.7.8</version>
<name>EthereumJ</name>
<url>http://www.ethereumj.org</url>

View File

@ -2,7 +2,10 @@ package org.ethereum.core;
import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
import static org.ethereum.crypto.HashUtil.EMPTY_DATA_HASH;
import static org.ethereum.util.ByteUtil.EMTPY_SHA3_RLP_ELEMENT_HASH;
import static org.ethereum.util.ByteUtil.EMTPY_TRIE_HASH;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import org.spongycastle.util.Arrays;
@ -32,7 +35,7 @@ public class AccountState {
* I define a convenient equivalence TRIE (σ[a] s ) σ[a] s .
* It shall be understood that σ[a] s is not a physical member
* of the account and does not contribute to its later serialisation */
private byte[] stateRoot = EMPTY_BYTE_ARRAY;
private byte[] stateRoot = EMTPY_TRIE_HASH;
/* The hash of the EVM code of this contractthis is the code
* that gets executed should this address receive a message call;
@ -40,7 +43,7 @@ public class AccountState {
* after construction. All such code fragments are contained in
* the state database under their corresponding hashes for later
* retrieval */
private byte[] codeHash = EMPTY_BYTE_ARRAY;
private byte[] codeHash = EMTPY_SHA3_RLP_ELEMENT_HASH;
public AccountState() {
this(BigInteger.ZERO, BigInteger.ZERO);

View File

@ -61,11 +61,11 @@ public class Block {
this.parsed = false;
}
public Block(byte[] parentHash, byte[] unclesHash, byte[] coinbase,
public Block(byte[] parentHash, byte[] unclesHash, byte[] coinbase, byte[] logsBloom,
byte[] difficulty, long number, long minGasPrice, long gasLimit,
long gasUsed, long timestamp, byte[] extraData, byte[] nonce,
List<Transaction> transactionsList, List<BlockHeader> uncleList) {
this.header = new BlockHeader(parentHash, unclesHash, coinbase,
this.header = new BlockHeader(parentHash, unclesHash, coinbase, logsBloom,
difficulty, number, minGasPrice, gasLimit, gasUsed,
timestamp, extraData, nonce);
@ -241,7 +241,7 @@ public class Block {
if (!parsed) parseRLP();
toStringBuff.setLength(0);
toStringBuff.append(Hex.toHexString(this.rlpEncoded)).append("\n");
toStringBuff.append(Hex.toHexString(this.getEncoded())).append("\n");
toStringBuff.append("BlockData [\n");
toStringBuff.append("hash=" + ByteUtil.toHexString(this.getHash())).append("\n");
toStringBuff.append(header.toString());
@ -310,6 +310,7 @@ public class Block {
new TransactionReceipt(tx, pstTxState.getRLPData(), cummGas.getRLPData());
this.addTxReceipt(i, txReceipt);
}
String calculatedRoot = Hex.toHexString(txsState.getRootHash());
if(!calculatedRoot.equals(Hex.toHexString(expectedRoot)))
logger.error("Added tx receipts don't match the given txsStateRoot");

View File

@ -6,13 +6,10 @@ import static org.ethereum.util.ByteUtil.*;
import org.ethereum.crypto.HashUtil;
import org.ethereum.manager.WorldManager;
import org.ethereum.util.FastByteComparisons;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
import org.ethereum.util.Utils;
import org.ethereum.util.*;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.BigIntegers;
import org.spongycastle.util.encoders.Hex;
/**
* Block header is a value object containing
@ -34,11 +31,19 @@ public class BlockHeader {
* after all transactions are executed and finalisations applied */
private byte[] stateRoot;
/* The SHA3 256-bit hash of the root node of the trie structure
* populated with each transaction recipe in the transaction recipes
* populated with each transaction in the transaction
* list portion, the trie is populate by [key, val] --> [rlp(index), rlp(tx_reciepe)]
* of the block */
private byte[] txTrieRoot;
/* A scalar value corresponding to the difficulty level of this block.
/* The SHA3 256-bit hash of the root node of the trie structure
* populated with each transaction recipe in the transaction recipes
* list portion, the trie is populate by [key, val] --> [rlp(index), rlp(tx_reciepe)]
* of the block */
private byte[] recieptTrieRoot;
/*todo: comment it when you know what the fuck it is*/
private byte[] logsBloom;
/* A scalar value corresponding to the difficulty level of this block.
* This can be calculated from the previous blocks difficulty level
* and the timestamp */
private byte[] difficulty;
@ -71,15 +76,20 @@ public class BlockHeader {
this.txTrieRoot = ((RLPItem) rlpHeader.get(4)).getRLPData();
if(this.txTrieRoot == null)
this.txTrieRoot = EMPTY_BYTE_ARRAY;
this.difficulty = ((RLPItem) rlpHeader.get(5)).getRLPData();
this.txTrieRoot = EMTPY_SHA3_RLP_ELEMENT_HASH;
this.recieptTrieRoot = ((RLPItem) rlpHeader.get(5)).getRLPData();
if(this.recieptTrieRoot == null)
this.recieptTrieRoot = EMTPY_SHA3_RLP_ELEMENT_HASH;
this.logsBloom = ((RLPItem) rlpHeader.get(6)).getRLPData();
this.difficulty = ((RLPItem) rlpHeader.get(7)).getRLPData();
byte[] nrBytes = ((RLPItem) rlpHeader.get(6)).getRLPData();
byte[] gpBytes = ((RLPItem) rlpHeader.get(7)).getRLPData();
byte[] glBytes = ((RLPItem) rlpHeader.get(8)).getRLPData();
byte[] guBytes = ((RLPItem) rlpHeader.get(9)).getRLPData();
byte[] tsBytes = ((RLPItem) rlpHeader.get(10)).getRLPData();
byte[] nrBytes = ((RLPItem) rlpHeader.get(8)).getRLPData();
byte[] gpBytes = ((RLPItem) rlpHeader.get(9)).getRLPData();
byte[] glBytes = ((RLPItem) rlpHeader.get(10)).getRLPData();
byte[] guBytes = ((RLPItem) rlpHeader.get(11)).getRLPData();
byte[] tsBytes = ((RLPItem) rlpHeader.get(12)).getRLPData();
this.number = nrBytes == null ? 0 : (new BigInteger(1, nrBytes)).longValue();
this.minGasPrice = gpBytes == null ? 0 : (new BigInteger(1, gpBytes)).longValue();
@ -87,16 +97,18 @@ public class BlockHeader {
this.gasUsed = guBytes == null ? 0 : (new BigInteger(1, guBytes)).longValue();
this.timestamp = tsBytes == null ? 0 : (new BigInteger(1, tsBytes)).longValue();
this.extraData = ((RLPItem) rlpHeader.get(11)).getRLPData();
this.nonce = ((RLPItem) rlpHeader.get(12)).getRLPData();
this.extraData = ((RLPItem) rlpHeader.get(13)).getRLPData();
this.nonce = ((RLPItem) rlpHeader.get(14)).getRLPData();
}
public BlockHeader(byte[] parentHash, byte[] unclesHash, byte[] coinbase,
byte[] difficulty, long number, long minGasPrice, long gasLimit,
long gasUsed, long timestamp, byte[] extraData, byte[] nonce) {
byte[] logsBloom, byte[] difficulty, long number,
long minGasPrice, long gasLimit, long gasUsed, long timestamp,
byte[] extraData, byte[] nonce) {
this.parentHash = parentHash;
this.unclesHash = unclesHash;
this.coinbase = coinbase;
this.logsBloom = logsBloom;
this.difficulty = difficulty;
this.number = number;
this.minGasPrice = minGasPrice;
@ -204,7 +216,13 @@ public class BlockHeader {
public void setTxTrieRoot(byte[] txTrieRoot) {
this.txTrieRoot = txTrieRoot;
}
public byte[] getDifficulty() {
public byte[] getRecieptTrieRoot() {
return recieptTrieRoot;
}
public void setRecieptTrieRoot(byte[] recieptTrieRoot) {
this.recieptTrieRoot = recieptTrieRoot;
}
public byte[] getDifficulty() {
return difficulty;
}
public void setDifficulty(byte[] difficulty) {
@ -263,10 +281,25 @@ public class BlockHeader {
public byte[] getEncoded(boolean withNonce) {
byte[] parentHash = RLP.encodeElement(this.parentHash);
byte[] unclesHash = RLP.encodeElement(this.unclesHash);
byte[] coinbase = RLP.encodeElement(this.coinbase);
byte[] stateRoot = RLP.encodeElement(this.stateRoot);
byte[] txTrieRoot = RLP.encodeElement(this.txTrieRoot);
if (this.txTrieRoot == null)
this.txTrieRoot = ByteUtil.EMTPY_TRIE_HASH;
byte[] txTrieRoot = RLP.encodeElement(this.txTrieRoot);
if (this.recieptTrieRoot == null)
this.recieptTrieRoot = ByteUtil.EMTPY_TRIE_HASH;
byte[] recieptTrieRoot = RLP.encodeElement(this.txTrieRoot);
byte[] logsBloom = RLP.encodeElement(this.logsBloom);
byte[] difficulty = RLP.encodeElement(this.difficulty);
byte[] number = RLP.encodeBigInteger(BigInteger.valueOf(this.number));
byte[] minGasPrice = RLP.encodeBigInteger(BigInteger.valueOf(this.minGasPrice));
@ -277,11 +310,11 @@ public class BlockHeader {
if(withNonce) {
byte[] nonce = RLP.encodeElement(this.nonce);
return RLP.encodeList(parentHash, unclesHash, coinbase,
stateRoot, txTrieRoot, difficulty, number,
stateRoot, txTrieRoot, recieptTrieRoot, logsBloom, difficulty, number,
minGasPrice, gasLimit, gasUsed, timestamp, extraData, nonce);
} else {
return RLP.encodeList(parentHash, unclesHash, coinbase,
stateRoot, txTrieRoot, difficulty, number,
stateRoot, txTrieRoot, recieptTrieRoot, logsBloom, difficulty, number,
minGasPrice, gasLimit, gasUsed, timestamp, extraData);
}
}
@ -296,6 +329,7 @@ public class BlockHeader {
toStringBuff.append(" coinbase=" + toHexString(coinbase)).append("\n");
toStringBuff.append(" stateRoot=" + toHexString(stateRoot)).append("\n");
toStringBuff.append(" txTrieHash=" + toHexString(txTrieRoot)).append("\n");
toStringBuff.append(" reciptsTrieHash=" + toHexString(recieptTrieRoot)).append("\n");
toStringBuff.append(" difficulty=" + toHexString(difficulty)).append("\n");
toStringBuff.append(" number=" + number).append("\n");
toStringBuff.append(" minGasPrice=" + minGasPrice).append("\n");

View File

@ -1,8 +1,11 @@
package org.ethereum.core;
import org.ethereum.crypto.HashUtil;
import org.ethereum.crypto.SHA3Helper;
import org.ethereum.trie.Trie;
import org.ethereum.trie.TrieImpl;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.spongycastle.util.encoders.Hex;
import java.math.BigInteger;
@ -30,45 +33,48 @@ public class Genesis extends Block {
private static String[] premine = new String[] {
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
"e4157b34ea9615cfbde6b4fda419828124b70c78", // # (CH)
"b9c015918bdaba24b4ff057a92a3873d6eb201be", // # (V)
"6c386a4b26f73c802f34673f7248bb118f97424a", // # (HH)
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826", // # (R)
"2ef47100e0787b915105fd5e3f4ff6752079d5cb", // # (M)
"e6716f9544a56c530d868e4bfbacb172315bdead", // # (J)
"b9c015918bdaba24b4ff057a92a3873d6eb201be", // # (V)
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4", // # (A)
"2ef47100e0787b915105fd5e3f4ff6752079d5cb", // # (M)
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826", // # (R)
"6c386a4b26f73c802f34673f7248bb118f97424a", // # (HH)
"e4157b34ea9615cfbde6b4fda419828124b70c78", // # (CH)
};
private static byte[] zeroHash256 = new byte[32];
private static byte[] zeroHash160 = new byte[20];
private static byte[] zeroHash512 = new byte[64];
public static byte[] PARENT_HASH = zeroHash256;
public static byte[] UNCLES_HASH = new byte[0];
public static byte[] UNCLES_HASH = ByteUtil.EMTPY_SHA3_RLP_ELEMENT_HASH;
public static byte[] COINBASE = zeroHash160;
public static byte[] LOG_BLOOM = zeroHash512;
public static byte[] DIFFICULTY = BigInteger.valueOf(2).pow(17).toByteArray();
public static long NUMBER = 0;
public static long MIN_GAS_PRICE = 0;
public static long GAS_LIMIT = 1000000;
public static long GAS_USED = 0;
public static long TIMESTAMP = 0;
public static long NUMBER = 0;
public static long MIN_GAS_PRICE = 0;
public static long GAS_LIMIT = 1000000;
public static long GAS_USED = 0;
public static long TIMESTAMP = 0;
public static byte[] EXTRA_DATA = new byte[0];
public static byte[] NONCE = HashUtil.sha3(new byte[]{42});
private static Block instance;
private Genesis() {
super(PARENT_HASH, UNCLES_HASH, COINBASE, DIFFICULTY,
super(PARENT_HASH, UNCLES_HASH, COINBASE, LOG_BLOOM, DIFFICULTY,
NUMBER, MIN_GAS_PRICE, GAS_LIMIT, GAS_USED, TIMESTAMP,
EXTRA_DATA, NONCE, null, null);
Trie state = new TrieImpl(null);
// The proof-of-concept series include a development premine, making the state root hash
// The proof-of-concept series include a development pre-mine, making the state root hash
// some value stateRoot. The latest documentation should be consulted for the value of the state root.
for (String address : premine) {
AccountState acctState = new AccountState();
acctState.addToBalance(PREMINE_AMOUNT);
state.update(Hex.decode(address), acctState.getEncoded());
}
setStateRoot(state.getRootHash());
}

View File

@ -15,6 +15,7 @@ import org.ethereum.util.ByteUtil;
import org.ethereum.util.FastByteComparisons;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import java.math.BigInteger;
import java.util.*;
@ -38,7 +39,7 @@ import static org.ethereum.net.message.StaticMessages.GET_TRANSACTIONS_MESSAGE;
*/
public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
public final static byte VERSION = 0x24;
public final static byte VERSION = 0x26;
public final static byte NETWORK_ID = 0x0;
private final static Logger logger = LoggerFactory.getLogger("net");
@ -184,8 +185,13 @@ public class EthHandler extends SimpleChannelInboundHandler<EthMessage> {
BlockQueue chainQueue = blockchain.getQueue();
BigInteger peerTotalDifficulty = new BigInteger(1, msg.getTotalDifficulty());
BigInteger highestKnownTotalDifficulty = blockchain.getTotalDifficulty();
if (highestKnownTotalDifficulty == null
|| peerTotalDifficulty.compareTo(highestKnownTotalDifficulty) > 0) {
if ( highestKnownTotalDifficulty == null ||
peerTotalDifficulty.compareTo(highestKnownTotalDifficulty) > 0) {
logger.info(" Their chain is better: total difficulty : {} vs {}",
peerTotalDifficulty.toString(),
highestKnownTotalDifficulty == null ? "0" : highestKnownTotalDifficulty.toString());
hashRetrievalLock = this.peerId;
chainQueue.setHighestTotalDifficulty(peerTotalDifficulty);
chainQueue.setBestHash(msg.getBestHash());

View File

@ -155,7 +155,7 @@ public class TrieImpl implements Trie {
if (root == null
|| (root instanceof byte[] && ((byte[]) root).length == 0)
|| (root instanceof String && "".equals((String) root))) {
return ByteUtil.EMPTY_BYTE_ARRAY;
return ByteUtil.EMTPY_TRIE_HASH;
} else if (root instanceof byte[]) {
return (byte[]) this.getRoot();
} else {

View File

@ -6,12 +6,16 @@ import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.ethereum.crypto.SHA3Helper;
import org.ethereum.trie.TrieImpl;
import org.spongycastle.util.encoders.Hex;
public class ByteUtil {
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
public static final byte[] EMTPY_SHA3_RLP_ELEMENT_HASH = SHA3Helper.sha3("");
public static final byte[] EMTPY_TRIE_HASH = SHA3Helper.sha3(RLP.encodeElement(ByteUtil.EMPTY_BYTE_ARRAY));
/**
* Creates a copy of bytes and appends b to the end of it
*/

View File

@ -146,7 +146,7 @@ max.blocks.ask = 100
max.blocks.queued = 300
# project version auto copied during build phase
project.version = 0.7.6
project.version = 0.7.8
# hello phrase will be included in
# the hello message of the peer

View File

@ -6,6 +6,8 @@ import org.ethereum.manager.WorldManager;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import org.junit.Test;
@ -13,6 +15,9 @@ import static org.junit.Assert.*;
public class BlockTest {
private static final Logger logger = LoggerFactory.getLogger("test");
@BeforeClass
public static void setUp() {
if (WorldManager.getInstance().getRepository().isClosed())
@ -25,8 +30,8 @@ public class BlockTest {
}
// https://ethereum.etherpad.mozilla.org/12
private String PoC7_GENESIS_HEX_RLP_ENCODED = "f88bf887a0000000000000000000000000000000000000000000000000000000000000000080940000000000000000000000000000000000000000a008bf6a98374f333b84e7d063d607696ac7cbbd409bd20fbe6a741c2dfc0eb28580830200008080830f4240808080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0";
private String PoC7_GENESIS_HEX_HASH = "9f0eb5da696ede7b44b22a8ef3a998f19e422195fdc9a8b3c82457858d310d6c";
private String PoC7_GENESIS_HEX_RLP_ENCODED = "f9012ff9012aa00000000000000000000000000000000000000000000000000000000000000000a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470940000000000000000000000000000000000000000a0c67c70f5d7d3049337d1dcc0503a249881120019a8e7322774dbfe57b463718ca056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b84000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008080830f4240808080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0";
private String PoC7_GENESIS_HEX_HASH = "19039f385f269fae48d497fba579d7079c761cec5643ec1096e98bdda4ffcf00";
String block_2 = "f8b5f8b1a0cf4b25b08b39350304fe12a16e4216c01a426f8f3dbf0d392b5b45"
+ "8ffb6a399da01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a1"
@ -69,7 +74,8 @@ public class BlockTest {
public void testGenesisFromNew() {
/* From: https://ethereum.etherpad.mozilla.org/11
Genesis block is:
(
(
todo: update it
B32(0, 0, ...),
B32(sha3(B())),
B20(0, 0, ...),
@ -86,6 +92,8 @@ public class BlockTest {
)
*/
Block genesis = Genesis.getInstance();
logger.info("genesis hash: [{}]", Hex.toHexString(genesis.getHash()));
logger.info("genesis rlp: [{}]", Hex.toHexString(genesis.getEncoded()));
assertEquals(PoC7_GENESIS_HEX_HASH, Hex.toHexString(genesis.getHash()));
assertEquals(PoC7_GENESIS_HEX_RLP_ENCODED, Hex.toHexString(genesis.getEncoded()));
}

View File

@ -55,7 +55,7 @@ public class MinerTest {
long gasLimit = 969216;
long gasUsed = 0;
long timestamp = 1401421088;
Block newBlock = new Block(parentHash, unclesHash, coinbase,
Block newBlock = new Block(parentHash, unclesHash, coinbase, null,
difficulty, number, minGasPrice, gasLimit, gasUsed, timestamp,
null, nonce, null, null);
// Setting stateRoot manually, because don't have state available.

View File

@ -14,7 +14,7 @@ import org.spongycastle.util.encoders.Hex;
public class StateTest {
private static final String GENESIS_STATE_ROOT = "08bf6a98374f333b84e7d063d607696ac7cbbd409bd20fbe6a741c2dfc0eb285";
private static final String GENESIS_STATE_ROOT = "c67c70f5d7d3049337d1dcc0503a249881120019a8e7322774dbfe57b463718c";
@Test
public void testGenesisAccounts() {

View File

@ -2,6 +2,7 @@ package org.ethereum.db;
import org.ethereum.core.AccountState;
import org.ethereum.facade.Repository;
import org.ethereum.util.ByteUtil;
import org.ethereum.vm.DataWord;
import org.junit.*;
import org.junit.runners.MethodSorters;
@ -9,6 +10,7 @@ import org.spongycastle.util.encoders.Hex;
import java.math.BigInteger;
import static org.ethereum.util.ByteUtil.EMTPY_SHA3_RLP_ELEMENT_HASH;
import static org.junit.Assert.*;
/**
@ -182,7 +184,7 @@ public class RepositoryTest {
AccountState accountState = repository.getAccountState(addr);
assertTrue(code0 == null);
assertNull(code1);
assertNull(accountState.getCodeHash());
assertEquals(EMTPY_SHA3_RLP_ELEMENT_HASH, accountState.getCodeHash());
} finally {
repository.close();
}