Bloom filters, Logs, Transaction receipts.
This commit is contained in:
parent
23a7f75266
commit
55c7a9c088
|
@ -217,6 +217,8 @@ public class BlockchainImpl implements Blockchain {
|
||||||
|
|
||||||
this.processBlock(block);
|
this.processBlock(block);
|
||||||
track.commit();
|
track.commit();
|
||||||
|
repository.flush(); // saving to the disc
|
||||||
|
|
||||||
|
|
||||||
// Remove all wallet transactions as they already approved by the net
|
// Remove all wallet transactions as they already approved by the net
|
||||||
worldManager.getWallet().removeTransactions(block.getTransactionsList());
|
worldManager.getWallet().removeTransactions(block.getTransactionsList());
|
||||||
|
@ -326,9 +328,21 @@ public class BlockchainImpl implements Blockchain {
|
||||||
long totalGasUsed = 0;
|
long totalGasUsed = 0;
|
||||||
for (Transaction tx : block.getTransactionsList()) {
|
for (Transaction tx : block.getTransactionsList()) {
|
||||||
stateLogger.debug("apply block: [{}] tx: [{}] ", block.getNumber(), i);
|
stateLogger.debug("apply block: [{}] tx: [{}] ", block.getNumber(), i);
|
||||||
totalGasUsed += applyTransaction(block, tx);
|
|
||||||
if(block.getNumber() >= CONFIG.traceStartBlock())
|
TransactionReceipt receipt = applyTransaction(block, tx);
|
||||||
repository.dumpState(block, totalGasUsed, i++, tx.getHash());
|
totalGasUsed += receipt.getCumulativeGasLong();
|
||||||
|
receipt.setCumulativeGas(totalGasUsed);
|
||||||
|
|
||||||
|
track.commit();
|
||||||
|
receipt.setPostTxState(repository.getRoot());
|
||||||
|
|
||||||
|
if(block.getNumber() >= CONFIG.traceStartBlock())
|
||||||
|
repository.dumpState(block, totalGasUsed, i++, tx.getHash());
|
||||||
|
|
||||||
|
// todo: (!!!). save the receipt
|
||||||
|
// todo: cache all the receipts and
|
||||||
|
// todo: save them to the disc together
|
||||||
|
// todo: with the block afterwards
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addReward(block);
|
this.addReward(block);
|
||||||
|
@ -398,10 +412,12 @@ public class BlockchainImpl implements Blockchain {
|
||||||
* @param tx - the transaction to be applied
|
* @param tx - the transaction to be applied
|
||||||
* @return gasUsed - the total amount of gas used for this transaction.
|
* @return gasUsed - the total amount of gas used for this transaction.
|
||||||
*/
|
*/
|
||||||
public long applyTransaction(Block block, Transaction tx) {
|
public TransactionReceipt applyTransaction(Block block, Transaction tx) {
|
||||||
|
|
||||||
logger.info("applyTransaction: [{}]", Hex.toHexString(tx.getHash()));
|
logger.info("applyTransaction: [{}]", Hex.toHexString(tx.getHash()));
|
||||||
|
|
||||||
|
TransactionReceipt receipt = new TransactionReceipt();
|
||||||
|
|
||||||
byte[] coinbase = block.getCoinbase();
|
byte[] coinbase = block.getCoinbase();
|
||||||
|
|
||||||
// VALIDATE THE SENDER
|
// VALIDATE THE SENDER
|
||||||
|
@ -416,7 +432,9 @@ public class BlockchainImpl implements Blockchain {
|
||||||
if (stateLogger.isWarnEnabled())
|
if (stateLogger.isWarnEnabled())
|
||||||
stateLogger.warn("Invalid nonce account.nonce={} tx.nonce={}",
|
stateLogger.warn("Invalid nonce account.nonce={} tx.nonce={}",
|
||||||
nonce, txNonce);
|
nonce, txNonce);
|
||||||
return 0;
|
|
||||||
|
receipt.setCumulativeGas(0);
|
||||||
|
return receipt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATE THE NONCE
|
// UPDATE THE NONCE
|
||||||
|
@ -474,7 +492,9 @@ public class BlockchainImpl implements Blockchain {
|
||||||
if (track.getBalance(senderAddress).compareTo(gasDebit) == -1) {
|
if (track.getBalance(senderAddress).compareTo(gasDebit) == -1) {
|
||||||
logger.debug("No gas to start the execution: sender={}",
|
logger.debug("No gas to start the execution: sender={}",
|
||||||
Hex.toHexString(senderAddress));
|
Hex.toHexString(senderAddress));
|
||||||
return 0;
|
|
||||||
|
receipt.setCumulativeGas(0);
|
||||||
|
return receipt;
|
||||||
}
|
}
|
||||||
track.addBalance(senderAddress, gasDebit.negate());
|
track.addBalance(senderAddress, gasDebit.negate());
|
||||||
|
|
||||||
|
@ -529,7 +549,9 @@ public class BlockchainImpl implements Blockchain {
|
||||||
|
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
trackTx.rollback();
|
trackTx.rollback();
|
||||||
return new BigInteger(1, tx.getGasLimit()).longValue();
|
|
||||||
|
receipt.setCumulativeGas(tx.getGasLimit());
|
||||||
|
return receipt;
|
||||||
}
|
}
|
||||||
trackTx.commit();
|
trackTx.commit();
|
||||||
} else {
|
} else {
|
||||||
|
@ -543,7 +565,9 @@ public class BlockchainImpl implements Blockchain {
|
||||||
track.addBalance(coinbase, refund.negate());
|
track.addBalance(coinbase, refund.negate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gasUsed;
|
|
||||||
|
receipt.setCumulativeGas(gasUsed);
|
||||||
|
return receipt;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package org.ethereum.core;
|
||||||
|
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* www.etherj.com
|
||||||
|
*
|
||||||
|
* @author: Roman Mandeleil
|
||||||
|
* Created on: 20/11/2014 11:10
|
||||||
|
*
|
||||||
|
* http://www.herongyang.com/Java/Bit-String-Set-Bit-to-Byte-Array.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class Bloom {
|
||||||
|
|
||||||
|
byte[] data = new byte[512];
|
||||||
|
|
||||||
|
|
||||||
|
public Bloom(byte[] data){
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bloom create(byte[] toBloom){
|
||||||
|
|
||||||
|
int mov1 = (toBloom[0] & 1) * 256 + (toBloom[1] & 255);
|
||||||
|
int mov2 = (toBloom[2] & 1) * 256 + (toBloom[3] & 255);
|
||||||
|
int mov3 = (toBloom[4] & 1) * 256 + (toBloom[5] & 255);
|
||||||
|
|
||||||
|
byte[] data = new byte[512];
|
||||||
|
Bloom bloom = new Bloom(data);
|
||||||
|
|
||||||
|
bloom.setBit(mov1, 1);
|
||||||
|
bloom.setBit(mov2, 1);
|
||||||
|
bloom.setBit(mov3, 1);
|
||||||
|
|
||||||
|
return bloom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void or(Bloom bloom){
|
||||||
|
|
||||||
|
for (int i = 0; i < data.length; ++i){
|
||||||
|
data[i] |= bloom.data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBit(int pos, int val) {
|
||||||
|
|
||||||
|
if (data.length - 1 < pos )
|
||||||
|
throw new Error("outside bloom limit, pos: " + pos);
|
||||||
|
|
||||||
|
int posByte = (pos - 1) / 8;
|
||||||
|
int posBit = (pos - 1) % 8;
|
||||||
|
byte oldByte = data[posByte];
|
||||||
|
oldByte = (byte) (((0xFF7F >> (( posBit + 1)) & oldByte) & 0x00FF));
|
||||||
|
byte newByte = (byte) ((val << ( 8 - ( posBit + 1))) | oldByte);
|
||||||
|
data[posByte] = newByte;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBit(int pos) {
|
||||||
|
|
||||||
|
if (data.length - 1 < pos )
|
||||||
|
throw new Error("outside bloom limit, pos: " + pos);
|
||||||
|
|
||||||
|
int posByte = pos / 8;
|
||||||
|
int posBit = pos % 8;
|
||||||
|
byte valByte = data[posByte];
|
||||||
|
int valInt = valByte >> (8 - (posBit + 1)) & 0x0001;
|
||||||
|
return valInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return Hex.toHexString(data);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,60 +1,118 @@
|
||||||
package org.ethereum.core;
|
package org.ethereum.core;
|
||||||
|
|
||||||
import org.ethereum.util.RLP;
|
import org.ethereum.util.RLP;
|
||||||
|
import org.ethereum.vm.LogInfo;
|
||||||
|
import org.spongycastle.util.BigIntegers;
|
||||||
import org.spongycastle.util.encoders.Hex;
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The transaction receipt is a tuple of three items
|
* The transaction receipt is a tuple of three items
|
||||||
* comprising the transaction, together with the post-transaction state,
|
* comprising the transaction, together with the post-transaction state,
|
||||||
* and the cumulative gas used in the block containing the transaction receipt
|
* and the cumulative gas used in the block containing the transaction receipt
|
||||||
* as of immediately after the transaction has happened,
|
* as of immediately after the transaction has happened,
|
||||||
*
|
*
|
||||||
* ** not todo: the transaction receipt was removed from the game but don't remove it
|
|
||||||
* as it will be used in the very near future.
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TransactionReceipt {
|
public class TransactionReceipt {
|
||||||
|
|
||||||
private Transaction transaction;
|
|
||||||
private byte[] postTxState;
|
private byte[] postTxState;
|
||||||
private byte[] cumulativeGas;
|
private byte[] cumulativeGas;
|
||||||
|
private Bloom bloomFilter;
|
||||||
|
private List<LogInfo> logInfoList;
|
||||||
|
|
||||||
/* Tx Receipt in encoded form */
|
/* Tx Receipt in encoded form */
|
||||||
private byte[] rlpEncoded;
|
private byte[] rlpEncoded;
|
||||||
|
|
||||||
public TransactionReceipt(Transaction transaction, byte[] postTxState, byte[] cumulativeGas) {
|
public TransactionReceipt() {
|
||||||
this.transaction = transaction;
|
|
||||||
this.postTxState = postTxState;
|
|
||||||
this.cumulativeGas = cumulativeGas;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Transaction getTransaction() {
|
|
||||||
return transaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getPostTxState() {
|
|
||||||
return postTxState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TransactionReceipt(byte[] postTxState, byte[] cumulativeGas,
|
||||||
|
Bloom bloomFilter, List<LogInfo> logInfoList) {
|
||||||
|
this.postTxState = postTxState;
|
||||||
|
this.cumulativeGas = cumulativeGas;
|
||||||
|
this.bloomFilter = bloomFilter;
|
||||||
|
this.logInfoList = logInfoList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getPostTxState() {
|
||||||
|
return postTxState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getCumulativeGas() {
|
||||||
|
return cumulativeGas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCumulativeGasLong() {
|
||||||
|
return new BigInteger(1, cumulativeGas).longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Bloom getBloomFilter() {
|
||||||
|
return bloomFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LogInfo> getLogInfoList() {
|
||||||
|
return logInfoList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* [postTxState, cumulativeGas, bloomFilter, logInfoList] */
|
||||||
public byte[] getEncoded() {
|
public byte[] getEncoded() {
|
||||||
|
|
||||||
if(rlpEncoded != null) return rlpEncoded;
|
if(rlpEncoded != null) return rlpEncoded;
|
||||||
|
|
||||||
byte[] transactionEl = transaction.getEncoded();
|
byte[] postTxStateRLP = RLP.encodeElement(this.postTxState);
|
||||||
byte[] postTxStateEl = RLP.encodeElement(this.postTxState);
|
byte[] cumulativeGasRLP = RLP.encodeElement(this.cumulativeGas);
|
||||||
byte[] cumulativeGasEl = RLP.encodeElement(this.cumulativeGas);
|
byte[] bloomRLP = RLP.encodeElement(this.bloomFilter.data);
|
||||||
|
|
||||||
rlpEncoded = RLP.encodeList(transactionEl, postTxStateEl, cumulativeGasEl);
|
byte[][] logInfoListE = new byte[logInfoList.size()][];
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (LogInfo logInfo : logInfoList){
|
||||||
|
logInfoListE[i] = logInfo.getEncoded();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
byte[] logInfoListRLP = RLP.encodeList(logInfoListE);
|
||||||
|
|
||||||
|
rlpEncoded = RLP.encodeList(postTxStateRLP, cumulativeGasRLP, bloomRLP, logInfoListRLP);
|
||||||
|
|
||||||
return rlpEncoded;
|
return rlpEncoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPostTxState(byte[] postTxState) {
|
||||||
|
this.postTxState = postTxState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCumulativeGas(long cumulativeGas) {
|
||||||
|
this.cumulativeGas = BigIntegers.asUnsignedByteArray( BigInteger.valueOf( cumulativeGas ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCumulativeGas(byte[] cumulativeGas) {
|
||||||
|
this.cumulativeGas = cumulativeGas;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBloomFilter(Bloom bloomFilter) {
|
||||||
|
this.bloomFilter = bloomFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogInfoList(List<LogInfo> logInfoList) {
|
||||||
|
this.logInfoList = logInfoList;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
||||||
|
// todo: fix that
|
||||||
|
|
||||||
return "TransactionReceipt[" +
|
return "TransactionReceipt[" +
|
||||||
"\n " + transaction +
|
|
||||||
"\n , postTxState=" + Hex.toHexString(postTxState) +
|
"\n , postTxState=" + Hex.toHexString(postTxState) +
|
||||||
"\n , cumulativeGas=" + Hex.toHexString(cumulativeGas) +
|
"\n , cumulativeGas=" + Hex.toHexString(cumulativeGas) +
|
||||||
|
"\n , bloom=" + bloomFilter.toString() +
|
||||||
|
"\n , logs=" + logInfoList +
|
||||||
']';
|
']';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,9 +126,14 @@ public class RepositoryImpl implements Repository {
|
||||||
accountState.setDeleted(false);
|
accountState.setDeleted(false);
|
||||||
accountState.setDirty(false);
|
accountState.setDirty(false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush(){
|
||||||
worldState.sync();
|
worldState.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rollback() {
|
public void rollback() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
|
|
@ -178,6 +178,12 @@ public class RepositoryTrack implements Repository {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush(){
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commit() {
|
public void commit() {
|
||||||
logger.debug("commit changes");
|
logger.debug("commit changes");
|
||||||
|
|
|
@ -146,6 +146,9 @@ public interface Repository {
|
||||||
*/
|
*/
|
||||||
public Repository startTracking();
|
public Repository startTracking();
|
||||||
|
|
||||||
|
public void flush();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store all the temporary changes made
|
* Store all the temporary changes made
|
||||||
* to the repository in the actual database
|
* to the repository in the actual database
|
||||||
|
|
|
@ -16,6 +16,7 @@ import java.util.List;
|
||||||
import org.ethereum.util.RLP;
|
import org.ethereum.util.RLP;
|
||||||
import org.ethereum.util.RLPItem;
|
import org.ethereum.util.RLPItem;
|
||||||
import org.ethereum.util.RLPList;
|
import org.ethereum.util.RLPList;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursive Length Prefix (RLP) encoding.
|
* Recursive Length Prefix (RLP) encoding.
|
||||||
|
@ -865,9 +866,14 @@ public class RLP {
|
||||||
|
|
||||||
public static byte[] encodeList(byte[]... elements) {
|
public static byte[] encodeList(byte[]... elements) {
|
||||||
|
|
||||||
|
if (elements == null){
|
||||||
|
return new byte[] {(byte)OFFSET_SHORT_LIST };
|
||||||
|
}
|
||||||
|
|
||||||
int totalLength = 0;
|
int totalLength = 0;
|
||||||
for (int i = 0; i < elements.length; ++i) {
|
for (int i = 0;
|
||||||
totalLength += elements[i].length;
|
elements != null && i < elements.length; ++i) {
|
||||||
|
totalLength += elements[i].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] data;
|
byte[] data;
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package org.ethereum.vm;
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import org.ethereum.core.BlockHeader;
|
||||||
|
import org.ethereum.util.RLP;
|
||||||
import org.spongycastle.util.encoders.Hex;
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -15,12 +18,15 @@ import java.util.List;
|
||||||
public class LogInfo {
|
public class LogInfo {
|
||||||
|
|
||||||
byte[] address;
|
byte[] address;
|
||||||
List<byte[]> topics;
|
List<byte[]> topics = new ArrayList<>();
|
||||||
byte[] data;
|
byte[] data;
|
||||||
|
|
||||||
|
/* Log info in encoded form */
|
||||||
|
private byte[] rlpEncoded;
|
||||||
|
|
||||||
public LogInfo(byte[] address, List<byte[]> topics, byte[] data) {
|
public LogInfo(byte[] address, List<byte[]> topics, byte[] data) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.topics = topics;
|
this.topics = (topics == null) ? new ArrayList<byte[]>() : topics;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +42,26 @@ public class LogInfo {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* [address, [topic, topic ...] data] */
|
||||||
|
public byte[] getEncoded() {
|
||||||
|
|
||||||
|
|
||||||
|
byte[] addressEncoded = RLP.encodeElement(this.address);
|
||||||
|
|
||||||
|
byte[][] topicsEncoded = null;
|
||||||
|
if (topics != null){
|
||||||
|
topicsEncoded = new byte[topics.size()][];
|
||||||
|
int i = 0;
|
||||||
|
for( byte[] topic : topics ){
|
||||||
|
topicsEncoded[i] = topic;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] dataEncoded = RLP.encodeElement(data);
|
||||||
|
return RLP.encodeList(addressEncoded, RLP.encodeList(topicsEncoded), dataEncoded);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package test.ethereum.core;
|
||||||
|
|
||||||
|
import org.ethereum.core.Bloom;
|
||||||
|
import org.ethereum.crypto.SHA3Helper;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* www.etherj.com
|
||||||
|
*
|
||||||
|
* @author: Roman Mandeleil
|
||||||
|
* Created on: 20/11/2014 11:29
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class BloomTest {
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test1(){
|
||||||
|
|
||||||
|
byte[] key = SHA3Helper.sha3(Hex.decode("CD2A3D9F938E13CD947EC05ABC7FE734DF8DD826"));
|
||||||
|
|
||||||
|
Bloom bloom = Bloom.create(key);
|
||||||
|
System.out.println(bloom);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test2(){
|
||||||
|
|
||||||
|
byte[] key = Hex.decode("0954D2BEF0CA79C1A988AE5FF3072C2AEA90F3967A9596065123F2A15AA37EF3");
|
||||||
|
|
||||||
|
Bloom bloom = Bloom.create(key);
|
||||||
|
System.out.println(bloom);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test3(){
|
||||||
|
|
||||||
|
byte[] key = SHA3Helper.sha3(Hex.decode("22341AE42D6DD7384BC8584E50419EA3AC75B83F "));
|
||||||
|
|
||||||
|
Bloom bloom = Bloom.create(key);
|
||||||
|
System.out.println(bloom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -34,32 +34,6 @@ public class StateTest {
|
||||||
assertEquals(GENESIS_STATE_ROOT, Hex.toHexString(trie.getRootHash()));
|
assertEquals(GENESIS_STATE_ROOT, Hex.toHexString(trie.getRootHash()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test // right way to calc tx trie hash
|
|
||||||
public void testCalculatePostTxState() {
|
|
||||||
|
|
||||||
/* txTrieHash */
|
|
||||||
String expected = "a77691cf47bec9021d3f027fc8ef2d51b758b600a79967154354b8e37108896f";
|
|
||||||
Transaction tx = new Transaction(
|
|
||||||
new byte[]{},
|
|
||||||
Hex.decode("09184E72A000"),
|
|
||||||
Hex.decode("03E8"),
|
|
||||||
Hex.decode("0000000000000000000000000000000000000000"),
|
|
||||||
Hex.decode("03e8"),
|
|
||||||
Hex.decode("60016000546006601160003960066000f261778e600054")
|
|
||||||
);
|
|
||||||
byte[] cowPrivKey = Hex.decode("c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4");
|
|
||||||
tx.sign(cowPrivKey);
|
|
||||||
|
|
||||||
byte[] postTxState = Hex.decode("7fa5bd00f6e03b5a5718560f1e25179b227167585a3c3da06a48f554365fb527");
|
|
||||||
byte[] cumGas = Hex.decode("0272");
|
|
||||||
|
|
||||||
TransactionReceipt tr = new TransactionReceipt(tx, postTxState, cumGas);
|
|
||||||
|
|
||||||
Trie trie = new TrieImpl(new MockDB());
|
|
||||||
trie.update(RLP.encodeInt(0), tr.getEncoded());
|
|
||||||
String txTrieRoot = Hex.toHexString(trie.getRootHash());
|
|
||||||
assertEquals(expected, txTrieRoot);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test // calc state after applying first tx on genesis
|
@Test // calc state after applying first tx on genesis
|
||||||
public void test2() {
|
public void test2() {
|
||||||
|
|
|
@ -8,7 +8,12 @@ import java.math.BigInteger;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.ethereum.core.Bloom;
|
||||||
|
import org.ethereum.core.TransactionReceipt;
|
||||||
|
import org.ethereum.vm.LogInfo;
|
||||||
import test.ethereum.TestContext;
|
import test.ethereum.TestContext;
|
||||||
import org.ethereum.core.Transaction;
|
import org.ethereum.core.Transaction;
|
||||||
import org.ethereum.crypto.ECKey;
|
import org.ethereum.crypto.ECKey;
|
||||||
|
@ -89,7 +94,7 @@ public class TransactionTest {
|
||||||
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
||||||
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
||||||
|
|
||||||
Assert.assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
||||||
Hex.toHexString(key.getAddress()));
|
Hex.toHexString(key.getAddress()));
|
||||||
|
|
||||||
System.out.println(tx.toString());
|
System.out.println(tx.toString());
|
||||||
|
@ -130,7 +135,7 @@ public class TransactionTest {
|
||||||
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
|
||||||
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
|
||||||
|
|
||||||
Assert.assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
|
||||||
Hex.toHexString(key.getAddress()));
|
Hex.toHexString(key.getAddress()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,4 +282,29 @@ public class TransactionTest {
|
||||||
|
|
||||||
System.out.println( Hex.toHexString(tx2.getSender()));
|
System.out.println( Hex.toHexString(tx2.getSender()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void encodeReceiptTest(){
|
||||||
|
|
||||||
|
String data = "f90244a0f5ff3fbd159773816a7c707a9b8cb6bb778b934a8f6466c7830ed970498f4b688301e848b902000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000dbda94cd2a3d9f938e13cd947ec05abc7fe734df8dd826c083a1a1a1";
|
||||||
|
|
||||||
|
byte[] stateRoot = Hex.decode("f5ff3fbd159773816a7c707a9b8cb6bb778b934a8f6466c7830ed970498f4b68");
|
||||||
|
byte[] gasUsed = Hex.decode("01E848");
|
||||||
|
Bloom bloom = new Bloom(Hex.decode("0000000000000000800000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
|
||||||
|
|
||||||
|
LogInfo logInfo1 = new LogInfo(
|
||||||
|
Hex.decode("cd2a3d9f938e13cd947ec05abc7fe734df8dd826"),
|
||||||
|
null,
|
||||||
|
Hex.decode("a1a1a1")
|
||||||
|
);
|
||||||
|
|
||||||
|
List<LogInfo> logs = new ArrayList<>();
|
||||||
|
logs.add(logInfo1);
|
||||||
|
|
||||||
|
TransactionReceipt receipt = new TransactionReceipt(stateRoot, gasUsed, bloom, logs);
|
||||||
|
|
||||||
|
assertEquals(data,
|
||||||
|
Hex.toHexString(receipt.getEncoded()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -799,4 +799,5 @@ public class RLPTest {
|
||||||
System.out.println(Hex.toHexString(encodedData));
|
System.out.println(Hex.toHexString(encodedData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@ log4j.logger.peermonitor = ERROR
|
||||||
log4j.logger.java.nio = ERROR
|
log4j.logger.java.nio = ERROR
|
||||||
log4j.logger.io.netty = ERROR
|
log4j.logger.io.netty = ERROR
|
||||||
log4j.logger.wire = ERROR
|
log4j.logger.wire = ERROR
|
||||||
log4j.logger.VM = TRACE
|
log4j.logger.VM = ERROR
|
||||||
log4j.logger.main = ERROR
|
log4j.logger.main = ERROR
|
||||||
log4j.logger.trie = ERROR
|
log4j.logger.trie = ERROR
|
||||||
log4j.logger.state = INFO
|
log4j.logger.state = INFO
|
||||||
|
|
Loading…
Reference in New Issue