Initial commit poc6 protocol update

This commit is contained in:
nicksavers 2014-09-26 16:45:41 +02:00
parent 040129799c
commit a256c12a62
72 changed files with 1151 additions and 1179 deletions

View File

@ -40,11 +40,11 @@ public class Block {
private BlockHeader header;
/* Transactions */
private List<TransactionReceipt> txReceiptList = new CopyOnWriteArrayList<TransactionReceipt>() ;
private List<Transaction> transactionsList = new CopyOnWriteArrayList<Transaction>();
private List<TransactionReceipt> txReceiptList = new CopyOnWriteArrayList<>() ;
private List<Transaction> transactionsList = new CopyOnWriteArrayList<>();
/* Uncles */
private List<BlockHeader> uncleList = new CopyOnWriteArrayList<BlockHeader>();
private List<BlockHeader> uncleList = new CopyOnWriteArrayList<>();
/* Private */
@ -257,7 +257,7 @@ public class Block {
for (Transaction tx : getTransactionsList()) {
toStringBuff.append("\n");
toStringBuff.append( tx.toString() );
toStringBuff.append(tx.toString());
}
toStringBuff.append("]");
@ -276,7 +276,7 @@ public class Block {
for (TransactionReceipt tx : getTxReceiptList()) {
toStringBuff.append("<br/>");
toStringBuff.append( tx.toStylishString() );
toStringBuff.append(tx.toStylishString());
toStringBuff.append("<br/>");
}

View File

@ -1,7 +1,6 @@
package org.ethereum.net;
package org.ethereum.core;
import org.ethereum.config.SystemProperties;
import org.ethereum.core.Block;
import org.ethereum.manager.WorldManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -26,9 +25,7 @@ public class BlockQueue {
private Timer timer = new Timer("BlockQueueTimer");
public BlockQueue() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
nudgeQueue();
}
@ -55,10 +52,10 @@ public class BlockQueue {
return;
this.lastBlock = blockList.get(i);
logger.trace("Last block now index: [ {} ]", lastBlock.getNumber());
logger.trace("Last block now index: [{}]", lastBlock.getNumber());
blockQueue.add(lastBlock);
}
logger.trace("Blocks waiting to be proceed in the queue: [ {} ]",
logger.trace("Blocks waiting to be proceed in the queue: [{}]",
blockQueue.size());
}

View File

@ -4,8 +4,8 @@ import org.ethereum.facade.Blockchain;
import org.ethereum.facade.Repository;
import org.ethereum.listener.EthereumListener;
import org.ethereum.manager.WorldManager;
import org.ethereum.net.BlockQueue;
import org.ethereum.util.AdvancedDeviceUtils;
import org.ethereum.util.ByteUtil;
import org.ethereum.vm.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -59,7 +59,8 @@ public class BlockchainImpl implements Blockchain {
private Repository repository;
private Block lastBlock;
private BigInteger totalDifficulty;
// keep the index of the chain for
// convenient usage, <block_number, block_hash>
private final Map<Long, byte[]> blockCache = new HashMap<>();
@ -70,11 +71,13 @@ public class BlockchainImpl implements Blockchain {
this.repository = repository;
}
@Override
public long getGasPrice() {
// In case of the genesis block we don't want to rely on the min gas price
return lastBlock.isGenesis() ? lastBlock.getMinGasPrice() : INITIAL_MIN_GAS_PRICE;
}
@Override
public byte[] getLatestBlockHash() {
if (blockCache.isEmpty())
return Genesis.getInstance().getHash();
@ -82,14 +85,17 @@ public class BlockchainImpl implements Blockchain {
return getLastBlock().getHash();
}
@Override
public int getSize() {
return blockCache.size();
}
@Override
public Block getBlockByNumber(long blockNr) {
return repository.getBlock(blockNr);
}
@Override
public void add(Block block) {
if (block == null)
@ -127,7 +133,7 @@ public class BlockchainImpl implements Blockchain {
ethereumListener.onBlock(block);
}
public void processBlock(Block block) {
private void processBlock(Block block) {
if(block.isValid()) {
if (!block.isGenesis()) {
if (!CONFIG.blockChainOnly()) {
@ -142,12 +148,12 @@ public class BlockchainImpl implements Blockchain {
}
}
public void applyBlock(Block block) {
private void applyBlock(Block block) {
int i = 0;
long totalGasUsed = 0;
for (TransactionReceipt txr : block.getTxReceiptList()) {
stateLogger.debug("apply block: [ {} ] tx: [ {} ] ", block.getNumber(), i);
stateLogger.debug("apply block: [{}] tx: [{}] ", block.getNumber(), i);
totalGasUsed += applyTransaction(block, txr.getTransaction());
if(block.getNumber() >= CONFIG.traceStartBlock())
repository.dumpState(block, totalGasUsed, i++, txr.getTransaction().getHash());
@ -160,11 +166,19 @@ public class BlockchainImpl implements Blockchain {
}
this.addReward(block);
this.increaseTotalDifficulty(block);
if(block.getNumber() >= CONFIG.traceStartBlock())
repository.dumpState(block, totalGasUsed, 0, null);
}
private void increaseTotalDifficulty(Block block) {
totalDifficulty.add(new BigInteger(block.getDifficulty()));
for (BlockHeader uncleHeader : block.getUncleList()) {
totalDifficulty.add(new BigInteger(uncleHeader.getDifficulty()));
}
}
/**
* Add reward to block- and every uncle coinbase
* assuming the entire block is valid.
@ -190,6 +204,7 @@ public class BlockchainImpl implements Blockchain {
repository.addBalance(block.getCoinbase(), totalBlockReward);
}
@Override
public void storeBlock(Block block) {
/* Debug check to see if the state is still as expected */
@ -433,23 +448,33 @@ public class BlockchainImpl implements Blockchain {
}
}
@Override
public BlockQueue getBlockQueue() {
return blockQueue;
}
@Override
public Map<Long, byte[]> getBlockCache() {
return this.blockCache;
}
@Override
public Block getLastBlock() {
return lastBlock;
}
@Override
public void setLastBlock(Block block) {
this.lastBlock = block;
}
@Override
public void close(){
blockQueue.close();
}
@Override
public byte[] getTotalDifficulty() {
return ByteUtil.bigIntegerToBytes(totalDifficulty);
}
}

View File

@ -164,8 +164,8 @@ public class Wallet {
sender.addPendingTransaction(transaction);
logger.info("Pending transaction added to " +
"\n account: [ {} ], " +
"\n tx: [ {} ]",
"\n account: [{}], " +
"\n tx: [{}]",
Hex.toHexString(sender.getAddress()), Hex.toHexString(transaction.getHash()));
}
@ -175,8 +175,8 @@ public class Wallet {
receiver.addPendingTransaction(transaction);
logger.info("Pending transaction added to " +
"\n account: [ {} ], " +
"\n tx: [ {} ]",
"\n account: [{}], " +
"\n tx: [{}]",
Hex.toHexString(receiver.getAddress()), Hex.toHexString(transaction.getHash()));
}
this.notifyListeners();

View File

@ -120,7 +120,7 @@ public class DatabaseImpl implements Database {
public List<ByteArrayWrapper> dumpKeys() {
DBIterator iterator = getDb().iterator();
ArrayList<ByteArrayWrapper> keys = new ArrayList<ByteArrayWrapper>();
ArrayList<ByteArrayWrapper> keys = new ArrayList<>();
while (iterator.hasNext()) {
ByteArrayWrapper key = new ByteArrayWrapper(iterator.next().getKey());

View File

@ -3,9 +3,9 @@ package org.ethereum.db;
import org.codehaus.plexus.util.FileUtils;
import org.ethereum.core.AccountState;
import org.ethereum.core.Block;
import org.ethereum.core.BlockchainImpl;
import org.ethereum.core.Genesis;
import org.ethereum.crypto.HashUtil;
import org.ethereum.facade.Blockchain;
import org.ethereum.facade.Repository;
import org.ethereum.json.EtherObjectMapper;
import org.ethereum.json.JSONHelper;
@ -128,8 +128,8 @@ public class RepositoryImpl implements Repository {
this.worldState.sync();
}
public BlockchainImpl loadBlockchain() {
BlockchainImpl blockchain = WorldManager.getInstance().getBlockchain();
public Blockchain loadBlockchain() {
Blockchain blockchain = WorldManager.getInstance().getBlockchain();
DBIterator iterator = chainDB.iterator();
try {
if (!iterator.hasNext()) {
@ -161,10 +161,9 @@ public class RepositoryImpl implements Repository {
}
logger.debug("Block #{} -> {}", block.getNumber(), block.toFlatString());
}
logger.info(
"*** Loaded up to block [ {} ] with stateRoot [ {} ]",
blockchain.getLastBlock().getNumber(),
Hex.toHexString(blockchain.getLastBlock().getStateRoot()));
logger.info("*** Loaded up to block [{}] with stateRoot [{}]",
blockchain.getLastBlock().getNumber(),
Hex.toHexString(blockchain.getLastBlock().getStateRoot()));
}
} finally {
// Make sure you close the iterator to avoid resource leaks.
@ -178,8 +177,8 @@ public class RepositoryImpl implements Repository {
if (CONFIG.rootHashStart() != null){
// update world state by dummy hash
byte[] rootHash = Hex.decode( CONFIG.rootHashStart() );
logger.info("Loading root hash from property file: [ {} ]", CONFIG.rootHashStart());
byte[] rootHash = Hex.decode(CONFIG.rootHashStart());
logger.info("Loading root hash from property file: [{}]", CONFIG.rootHashStart());
this.worldState.setRoot(rootHash);
} else{
@ -194,7 +193,7 @@ public class RepositoryImpl implements Repository {
public AccountState createAccount(byte[] addr) {
logger.trace("createAccount: [ {} ]", Hex.toHexString(addr)) ;
logger.trace("createAccount: [{}]", Hex.toHexString(addr)) ;
this.validateAddress(addr);
// 1. Save AccountState
@ -205,7 +204,7 @@ public class RepositoryImpl implements Repository {
contractDetailsDB.put(addr, details.getEncoded());
if (logger.isDebugEnabled())
logger.debug("New account created: [ {} ]", Hex.toHexString(addr));
logger.debug("New account created: [{}]", Hex.toHexString(addr));
return state;
}
@ -238,7 +237,7 @@ public class RepositoryImpl implements Repository {
this.validateAddress(addr);
if (logger.isDebugEnabled())
logger.debug("Get contract details for: [ {} ]", Hex.toHexString(addr));
logger.debug("Get contract details for: [{}]", Hex.toHexString(addr));
byte[] accountDetailsRLP = contractDetailsDB.get(addr);
@ -246,7 +245,7 @@ public class RepositoryImpl implements Repository {
return null;
if (logger.isDebugEnabled())
logger.debug("Contract details RLP: [ {} ]", Hex.toHexString(accountDetailsRLP));
logger.debug("Contract details RLP: [{}]", Hex.toHexString(accountDetailsRLP));
ContractDetails details = new ContractDetails(accountDetailsRLP);
return details;
@ -264,7 +263,7 @@ public class RepositoryImpl implements Repository {
BigInteger newBalance = state.addToBalance(value);
if (logger.isDebugEnabled())
logger.debug("Changing balance: account: [ {} ] new balance: [ {} ] delta: [ {} ]",
logger.debug("Changing balance: account: [{}] new balance: [{}] delta: [{}]",
Hex.toHexString(addr), newBalance.toString(), value);
accountStateDB.update(addr, state.getEncoded());
@ -294,7 +293,7 @@ public class RepositoryImpl implements Repository {
state.incrementNonce();
if (logger.isDebugEnabled())
logger.debug("Incerement nonce: account: [ {} ] new nonce: [ {} ]",
logger.debug("Incerement nonce: account: [{}] new nonce: [{}]",
Hex.toHexString(addr), state.getNonce().longValue());
accountStateDB.update(addr, state.getEncoded());
@ -316,7 +315,7 @@ public class RepositoryImpl implements Repository {
state.setStateRoot(storageHash);
if (logger.isDebugEnabled())
logger.debug("Storage key/value saved: account: [ {} ]\n key: [ {} ] value: [ {} ]\n new storageHash: [ {} ]",
logger.debug("Storage key/value saved: account: [{}]\n key: [{}] value: [{}]\n new storageHash: [{}]",
Hex.toHexString(addr),
Hex.toHexString(key.getNoLeadZeroesData()),
Hex.toHexString(value.getNoLeadZeroesData()),
@ -354,7 +353,7 @@ public class RepositoryImpl implements Repository {
this.validateAddress(addr);
if (logger.isDebugEnabled())
logger.debug("saveCode: \n address: [ {} ], \n code: [ {} ]",
logger.debug("saveCode: \n address: [{}], \n code: [{}]",
Hex.toHexString(addr),
Hex.toHexString(code));
@ -368,7 +367,7 @@ public class RepositoryImpl implements Repository {
state.setCodeHash(codeHash);
if (logger.isDebugEnabled())
logger.debug("Program code saved:\n account: [ {} ]\n codeHash: [ {} ] \n code: [ {} ]",
logger.debug("Program code saved:\n account: [{}]\n codeHash: [{}] \n code: [{}]",
Hex.toHexString(addr),
Hex.toHexString(codeHash),
Hex.toHexString(code));
@ -377,7 +376,7 @@ public class RepositoryImpl implements Repository {
contractDetailsDB.put(addr, details.getEncoded());
if (logger.isDebugEnabled())
logger.debug("saveCode: \n accountState: [ {} ], \n contractDetails: [ {} ]",
logger.debug("saveCode: \n accountState: [{}], \n contractDetails: [{}]",
Hex.toHexString(state.getEncoded()),
Hex.toHexString(details.getEncoded()));
}

View File

@ -1,11 +1,22 @@
package org.ethereum.facade;
import java.util.Map;
import org.ethereum.core.Block;
import org.ethereum.core.BlockQueue;
public interface Blockchain {
public int getSize();
public void add(Block block);
public void storeBlock(Block block);
public Map<Long, byte[]> getBlockCache();
public Block getBlockByNumber(long blockNr);
public long getGasPrice();
public void setLastBlock(Block block);
public Block getLastBlock();
public BlockQueue getBlockQueue();
public void close();
public byte[] getTotalDifficulty();
public byte[] getLatestBlockHash();
}

View File

@ -5,7 +5,7 @@ import org.ethereum.core.Wallet;
import org.ethereum.facade.Repository;
import org.ethereum.listener.EthereumListener;
import org.ethereum.net.client.ClientPeer;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import java.net.InetAddress;
import java.util.Set;
@ -25,7 +25,7 @@ public interface Ethereum {
* @param excludePeer - peer to exclude
* @return online peer if available otherwise null
*/
public PeerData findOnlinePeer(PeerData excludePeer) ;
public Peer findOnlinePeer(Peer excludePeer) ;
/**
* Find an online peer but not from excluded list
@ -33,12 +33,12 @@ public interface Ethereum {
* @param excludePeerSet - peers to exclude
* @return online peer if available otherwise null
*/
public PeerData findOnlinePeer(Set<PeerData> excludePeerSet) ;
public Peer findOnlinePeer(Set<Peer> excludePeerSet) ;
/**
* @return online peer if available
*/
public PeerData findOnlinePeer();
public Peer findOnlinePeer();
/**
@ -46,7 +46,7 @@ public interface Ethereum {
*
* @return online peer.
*/
public PeerData waitForOnlinePeer();
public Peer waitForOnlinePeer();
/*
*
@ -59,7 +59,7 @@ public interface Ethereum {
* }
*
*/
public Set<PeerData> getPeers();
public Set<Peer> getPeers();
public void startPeerDiscovery();
public void stopPeerDiscovery();

View File

@ -10,7 +10,7 @@ import org.ethereum.core.Wallet;
import org.ethereum.listener.EthereumListener;
import org.ethereum.manager.WorldManager;
import org.ethereum.net.client.ClientPeer;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.ethereum.net.submit.TransactionExecutor;
import org.ethereum.net.submit.TransactionTask;
import org.slf4j.Logger;
@ -37,24 +37,24 @@ public class EthereumImpl implements Ethereum {
* @return online peer
*/
@Override
public PeerData findOnlinePeer(PeerData peerData) {
public Peer findOnlinePeer(Peer peerData) {
Set<PeerData> excludePeers = new HashSet<>();
Set<Peer> excludePeers = new HashSet<>();
excludePeers.add(peerData);
return findOnlinePeer(excludePeers);
}
@Override
public PeerData findOnlinePeer() {
public Peer findOnlinePeer() {
Set<PeerData> excludePeers = new HashSet<>();
Set<Peer> excludePeers = new HashSet<>();
return findOnlinePeer(excludePeers);
}
@Override
public PeerData findOnlinePeer(Set<PeerData> excludePeers) {
public Peer findOnlinePeer(Set<Peer> excludePeers) {
logger.info("Looking for online peers...");
final EthereumListener listener = WorldManager.getInstance().getListener();
@ -64,10 +64,10 @@ public class EthereumImpl implements Ethereum {
WorldManager.getInstance().startPeerDiscovery();
final Set<PeerData> peers = WorldManager.getInstance().getPeers();
final Set<Peer> peers = WorldManager.getInstance().getPeers();
synchronized (peers) {
for (PeerData peer : peers) { // it blocks until a peer is available.
for (Peer peer : peers) { // it blocks until a peer is available.
if (peer.isOnline() && !excludePeers.contains(peer)) {
@ -85,9 +85,9 @@ public class EthereumImpl implements Ethereum {
@Override
public PeerData waitForOnlinePeer(){
public Peer waitForOnlinePeer(){
PeerData peer = null;
Peer peer = null;
while(peer == null){
try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}
@ -99,7 +99,7 @@ public class EthereumImpl implements Ethereum {
@Override
public Set<PeerData> getPeers() {
public Set<Peer> getPeers() {
return WorldManager.getInstance().getPeers();
}

View File

@ -4,7 +4,6 @@ import java.math.BigInteger;
import org.ethereum.core.AccountState;
import org.ethereum.core.Block;
import org.ethereum.core.BlockchainImpl;
import org.ethereum.db.ContractDetails;
import org.ethereum.trie.Trie;
import org.ethereum.vm.DataWord;
@ -151,7 +150,7 @@ public interface Repository {
*
* @return the <code>Blockchain</code> object
*/
public BlockchainImpl loadBlockchain();
public Blockchain loadBlockchain();
/**
* Dump the full state of the current repository into a file with JSON format

View File

@ -47,34 +47,30 @@ public class AccountState {
int size = store.keySet().size();
Object[] keys = store.keySet().toArray();
for (int i = 0; i < size; ++i){
for (int i = 0; i < size; ++i) {
String keyS = keys[i].toString();
String valS = store.get(keys[i]).toString();
ByteArrayWrapper key;
boolean hexVal = Pattern.matches("0[xX][0-9a-fA-F]+", keyS);
if (hexVal){
key = new ByteArrayWrapper( Hex.decode(keyS.substring(2)) );
if (hexVal) {
key = new ByteArrayWrapper(Hex.decode(keyS.substring(2)));
} else {
byte[] data = ByteUtil.bigIntegerToBytes( new BigInteger(keyS) );
key = new ByteArrayWrapper( data );
byte[] data = ByteUtil.bigIntegerToBytes(new BigInteger(keyS));
key = new ByteArrayWrapper(data);
}
ByteArrayWrapper value;
hexVal = Pattern.matches("0[xX][0-9a-fA-F]+", valS);
if (hexVal){
value = new ByteArrayWrapper( Hex.decode(valS.substring(2)) );
if (hexVal) {
value = new ByteArrayWrapper(Hex.decode(valS.substring(2)));
} else {
byte[] data = ByteUtil.bigIntegerToBytes( new BigInteger(valS) );
value = new ByteArrayWrapper( data );
byte[] data = ByteUtil.bigIntegerToBytes(new BigInteger(valS));
value = new ByteArrayWrapper(data);
}
storage.put(key, value);
}
}
public byte[] getAddress() {

View File

@ -42,10 +42,10 @@ public class Env {
String prevHash = env.get("previousHash").toString();
this.currentCoinbase = Hex.decode(coinbase);
this.currentDifficlty = ByteUtil.bigIntegerToBytes( new BigInteger(difficulty) );
this.currentGasLimit = ByteUtil.bigIntegerToBytes( new BigInteger(gasLimit) );
this.currentNumber = ByteUtil.bigIntegerToBytes( new BigInteger(number) );
this.currentTimestamp = ByteUtil.bigIntegerToBytes( new BigInteger(timestamp) );
this.currentDifficlty = ByteUtil.bigIntegerToBytes(new BigInteger(difficulty));
this.currentGasLimit = ByteUtil.bigIntegerToBytes(new BigInteger(gasLimit));
this.currentNumber = ByteUtil.bigIntegerToBytes(new BigInteger(number));
this.currentTimestamp = ByteUtil.bigIntegerToBytes(new BigInteger(timestamp));
this.previousHash = Hex.decode(prevHash);
}

View File

@ -55,8 +55,8 @@ public class Helper {
} else if (val instanceof Long) {
// Simple long
byte[] data = ByteUtil.bigIntegerToBytes( BigInteger.valueOf((Long)val) );
try {bos.write(data);} catch (IOException e) { logger.error("should not happen", e);}
byte[] data = ByteUtil.bigIntegerToBytes(BigInteger.valueOf((Long)val));
try {bos.write(data);} catch (IOException e) {logger.error("should not happen", e);}
} else {
throw new Error("Wrong test case JSON format");
}

View File

@ -24,16 +24,16 @@ public class TestRunner {
private Logger logger = LoggerFactory.getLogger("JSONTest");
public List<String> runTestSuite(TestSuite testSuite){
public List<String> runTestSuite(TestSuite testSuite) {
Iterator<TestCase> testIterator = testSuite.iterator();
List<String> resultCollector = new ArrayList<>();
while (testIterator.hasNext()){
while (testIterator.hasNext()) {
TestCase testCase = testIterator.next();
logger.info("Running: [ {} ]", testCase.getName());
logger.info("Running: [{}]", testCase.getName());
TestRunner runner = new TestRunner();
List<String> result = runner.runTestCase(testCase);
resultCollector.addAll(result);
@ -43,14 +43,14 @@ public class TestRunner {
}
public List<String> runTestCase(TestCase testCase){
public List<String> runTestCase(TestCase testCase) {
List<String> results = new ArrayList<>();
Repository repository = new RepositoryImpl();
/* 1. Store pre-exist accounts - Pre */
for (ByteArrayWrapper key : testCase.getPre().keySet()){
for (ByteArrayWrapper key : testCase.getPre().keySet()) {
AccountState accountState = testCase.getPre().get(key);
@ -100,7 +100,7 @@ public class TestRunner {
}
/* 5. Assert Post values */
for (ByteArrayWrapper key : testCase.getPost().keySet()){
for (ByteArrayWrapper key : testCase.getPost().keySet()) {
AccountState accountState = testCase.getPost().get(key);
@ -109,7 +109,7 @@ public class TestRunner {
byte[] expectedCode = accountState.getCode();
boolean accountExist = (null != repository.getAccountState(key.getData()));
if (!accountExist){
if (!accountExist) {
String output =
String.format("The expected account does not exist. key: [ %s ]",
@ -124,7 +124,7 @@ public class TestRunner {
byte[] actualCode = repository.getCode(key.getData());
if (actualCode == null) actualCode = "".getBytes();
if (expectedNonce != actualNonce){
if (expectedNonce != actualNonce) {
String output =
String.format("The nonce result is different. key: [ %s ], expectedNonce: [ %d ] is actualNonce: [ %d ] ",
@ -133,7 +133,7 @@ public class TestRunner {
results.add(output);
}
if (!expectedBalance.equals(actualBalance)){
if (!expectedBalance.equals(actualBalance)) {
String output =
String.format("The balance result is different. key: [ %s ], expectedBalance: [ %s ] is actualBalance: [ %s ] ",
@ -155,14 +155,14 @@ public class TestRunner {
// assert storage
Map<ByteArrayWrapper, ByteArrayWrapper> storage = accountState.getStorage();
for (ByteArrayWrapper storageKey : storage.keySet() ){
for (ByteArrayWrapper storageKey : storage.keySet() ) {
byte[] expectedStValue = storage.get(storageKey).getData();
ContractDetails contractDetails =
program.getResult().getRepository().getContractDetails(accountState.getAddress());
if (contractDetails == null){
if (contractDetails == null) {
String output =
String.format("Storage raw doesn't exist: key [ %s ], expectedValue: [ %s ]",
@ -177,7 +177,7 @@ public class TestRunner {
Map<DataWord, DataWord> testStorage = contractDetails.getStorage();
DataWord actualValue = testStorage.get(new DataWord(storageKey.getData()));
if (!Arrays.equals(expectedStValue, actualValue.getNoLeadZeroesData())){
if (!Arrays.equals(expectedStValue, actualValue.getNoLeadZeroesData())) {
String output =
String.format("Storage value different: key [ %s ], expectedValue: [ %s ], actualValue: [ %s ]",
@ -199,17 +199,16 @@ public class TestRunner {
program.getResult().getCallCreateList();
// assert call creates
for (int i = 0; i < testCase.getCallCreateList().size(); ++i){
for (int i = 0; i < testCase.getCallCreateList().size(); ++i) {
org.ethereum.vm.CallCreate resultCallCreate = null;
if (resultCallCreates != null && resultCallCreates.size() > i){
if (resultCallCreates != null && resultCallCreates.size() > i) {
resultCallCreate = resultCallCreates.get(i);
}
CallCreate expectedCallCreate =
testCase.getCallCreateList().get(i);
CallCreate expectedCallCreate = testCase.getCallCreateList().get(i);
if (resultCallCreate == null && expectedCallCreate != null){
if (resultCallCreate == null && expectedCallCreate != null) {
String output =
String.format("Missing call/create invoke: to: [ %s ], data: [ %s ], gas: [ %s ], value: [ %s ]",
@ -223,9 +222,10 @@ public class TestRunner {
continue;
}
boolean assertDestination = Arrays.equals(expectedCallCreate.getDestination(),
boolean assertDestination = Arrays.equals(
expectedCallCreate.getDestination(),
resultCallCreate.getDestination());
if (!assertDestination){
if (!assertDestination) {
String output =
String.format("Call/Create destination is different expected: [ %s ], result: [ %s ]",
@ -235,38 +235,39 @@ public class TestRunner {
results.add(output);
}
boolean assertData = Arrays.equals(expectedCallCreate.getData(),
boolean assertData = Arrays.equals(
expectedCallCreate.getData(),
resultCallCreate.getData());
if (!assertData){
if (!assertData) {
String output =
String.format("Call/Create data is different expected: [ %s ], result: [ %s ]",
Hex.toHexString( expectedCallCreate.getData() ),
Hex.toHexString(resultCallCreate.getData()) );
Hex.toHexString(expectedCallCreate.getData()),
Hex.toHexString(resultCallCreate.getData()));
logger.info(output);
results.add(output);
}
boolean assertGasLimit = Arrays.equals(expectedCallCreate.getGasLimit(),
boolean assertGasLimit = Arrays.equals(
expectedCallCreate.getGasLimit(),
resultCallCreate.getGasLimit());
if (!assertGasLimit){
if (!assertGasLimit) {
String output =
String.format("Call/Create gasLimit is different expected: [ %s ], result: [ %s ]",
Hex.toHexString( expectedCallCreate.getGasLimit() ),
Hex.toHexString( resultCallCreate.getGasLimit()) );
Hex.toHexString(expectedCallCreate.getGasLimit()),
Hex.toHexString(resultCallCreate.getGasLimit()));
logger.info(output);
results.add(output);
}
boolean assertValue = Arrays.equals(expectedCallCreate.getValue(),
boolean assertValue = Arrays.equals(
expectedCallCreate.getValue(),
resultCallCreate.getValue());
if (!assertValue){
if (!assertValue) {
String output =
String.format("Call/Create value is different expected: [ %s ], result: [ %s ]",
Hex.toHexString( expectedCallCreate.getValue() ),
Hex.toHexString( resultCallCreate.getValue() ));
Hex.toHexString(expectedCallCreate.getValue()),
Hex.toHexString(resultCallCreate.getValue()));
logger.info(output);
results.add(output);
}
@ -275,16 +276,16 @@ public class TestRunner {
// assert out
byte[] expectedHReturn = testCase.getOut();
byte[] actualHReturn = new byte[0];
if (program.getResult().getHReturn() != null){
if (program.getResult().getHReturn() != null) {
actualHReturn = program.getResult().getHReturn().array();
}
if (!Arrays.equals(expectedHReturn, actualHReturn)){
if (!Arrays.equals(expectedHReturn, actualHReturn)) {
String output =
String.format("HReturn is differnt expected hReturn: [ %s ], actual hReturn: [ %s ]",
Hex.toHexString( expectedHReturn ),
Hex.toHexString( actualHReturn ));
Hex.toHexString(expectedHReturn),
Hex.toHexString(actualHReturn));
logger.info(output);
results.add(output);
}
@ -293,7 +294,7 @@ public class TestRunner {
BigInteger expectedGas = new BigInteger(testCase.getGas());
BigInteger actualGas = new BigInteger(gas).subtract(BigInteger.valueOf(program.getResult().getGasUsed()));
if (!expectedGas.equals(actualGas)){
if (!expectedGas.equals(actualGas)) {
String output =
String.format("Gas usage is differnt expected gas usage: [ %s ], actual gas usage: [ %s ]",

View File

@ -10,10 +10,11 @@ import org.ethereum.core.BlockchainImpl;
import org.ethereum.core.Wallet;
import org.ethereum.crypto.HashUtil;
import org.ethereum.db.RepositoryImpl;
import org.ethereum.facade.Blockchain;
import org.ethereum.facade.Repository;
import org.ethereum.listener.EthereumListener;
import org.ethereum.net.client.ClientPeer;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.ethereum.net.peerdiscovery.PeerDiscovery;
/**
@ -26,13 +27,13 @@ import org.ethereum.net.peerdiscovery.PeerDiscovery;
*/
public class WorldManager {
private BlockchainImpl blockchain;
private Blockchain blockchain;
private Repository repository;
private Wallet wallet;
private PeerDiscovery peerDiscovery;
private final Set<PeerData> peers = Collections.synchronizedSet(new HashSet<PeerData>());
private final Set<Peer> peers = Collections.synchronizedSet(new HashSet<Peer>());
private ClientPeer activePeer;
@ -50,11 +51,10 @@ public class WorldManager {
this.blockchain = new BlockchainImpl(repository);
// Initialize PeerData
List<PeerData> peerDataList = parsePeerDiscoveryIpList(CONFIG.peerDiscoveryIPList());
List<Peer> peerDataList = parsePeerDiscoveryIpList(CONFIG.peerDiscoveryIPList());
peers.addAll(peerDataList);
peerDiscovery = new PeerDiscovery(peers);
}
// used for testing
@ -85,10 +85,10 @@ public class WorldManager {
this.listener = listener;
}
public void addPeers(final Set<PeerData> newPeers) {
public void addPeers(final Set<Peer> newPeers) {
synchronized (peers) {
for (final PeerData peer : newPeers) {
for (final Peer peer : newPeers) {
if (peerDiscovery.isStarted() && !peers.contains(peer)) {
peerDiscovery.addNewPeerData(peer);
}
@ -116,10 +116,10 @@ public class WorldManager {
return listener;
}
public List<PeerData> parsePeerDiscoveryIpList(final String peerDiscoveryIpList){
public List<Peer> parsePeerDiscoveryIpList(final String peerDiscoveryIpList) {
final List<String> ipList = Arrays.asList( peerDiscoveryIpList.split(",") );
final List<PeerData> peers = new ArrayList<>();
final List<String> ipList = Arrays.asList(peerDiscoveryIpList.split(","));
final List<Peer> peers = new ArrayList<>();
for (String ip : ipList){
String[] addr = ip.trim().split(":");
@ -130,13 +130,12 @@ public class WorldManager {
InetAddress iAddr = InetAddress.getByName(ip_trim);
int port = Integer.parseInt(port_trim);
PeerData peerData = new PeerData(iAddr.getAddress(), port, new byte[]{00});
Peer peerData = new Peer(iAddr.getAddress(), port, new byte[]{00});
peers.add(peerData);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
return peers;
}
@ -148,7 +147,7 @@ public class WorldManager {
return repository;
}
public BlockchainImpl getBlockchain() {
public Blockchain getBlockchain() {
return blockchain;
}
@ -168,7 +167,7 @@ public class WorldManager {
return activePeer;
}
public Set<PeerData> getPeers() {
public Set<Peer> getPeers() {
return peers;
}

View File

@ -90,7 +90,7 @@ public enum Command {
private int cmd;
private static final Map<Integer, Command> intToTypeMap = new HashMap<Integer, Command>();
private static final Map<Integer, Command> intToTypeMap = new HashMap<>();
static {
for (Command type : Command.values()) {
intToTypeMap.put(type.cmd, type);

View File

@ -9,29 +9,27 @@ import io.netty.channel.MessageSizeEstimator;
* @author: Roman Mandeleil
* Created on: 04/07/2014 13:16
*/
public class EthereumMessageSizeEstimator implements MessageSizeEstimator {
private final Handle handle = new HandleImpl();
private static final class HandleImpl implements Handle {
private HandleImpl() {
}
@Override
public int size(Object msg) {
ByteBuf buffer = ((ByteBuf)msg);
if (buffer.readableBytes() < 8) throw new RuntimeException("Not Ethereum packet");
if (buffer.readableBytes() < 8)
throw new RuntimeException("Not an Ethereum packet");
int msgSize = ((buffer.getByte(4) & 0xFF) << 24) +
((buffer.getByte(5) & 0xFF) << 16) +
((buffer.getByte(6) & 0xFF) << 8) +
((buffer.getByte(7) & 0xFF));
return msgSize;
}
}

View File

@ -55,22 +55,25 @@ public class MessageQueue {
public void receivedMessage(Message msg) {
if (logger.isDebugEnabled())
logger.debug("Recv: [ {} ] - [ {} ]",
msg.getMessageName(),
Hex.toHexString(msg.getPayload()));
logger.debug("Recv: [{}] - [{}]",
msg.getCommand().name(),
Hex.toHexString(msg.getEncoded()));
if (null != messageQueue.peek()) {
if (logger.isInfoEnabled())
logger.info("Recv: {}", msg.toString());
MessageRoundtrip messageRoundtrip = messageQueue.peek();
Message waitingMessage = messageRoundtrip.getMsg();
if (waitingMessage.getAnswerMessage() == null)
return;
if (null != messageQueue.peek()) {
if (msg.getClass() == waitingMessage.getAnswerMessage()){
messageRoundtrip.answer();
logger.debug("Message round trip covered: [ {} ] ", messageRoundtrip.getMsg().getMessageName());
}
MessageRoundtrip messageRoundtrip = messageQueue.peek();
Message waitingMessage = messageRoundtrip.getMsg();
if (waitingMessage.getAnswerMessage() == null)
return;
if (msg.getClass() == waitingMessage.getAnswerMessage()){
messageRoundtrip.answer();
logger.debug("Message round trip covered: [{}] ", messageRoundtrip.getMsg().getCommand());
}
}
}
@ -108,18 +111,21 @@ public class MessageQueue {
private void sendToWire(Message msg) {
if (logger.isDebugEnabled())
logger.debug("Send: [ {} ] - [ {} ]",
msg.getMessageName(),
Hex.toHexString(msg.getPayload()));
logger.debug("Send: [{}] - [{}]",
msg.getCommand().name(),
Hex.toHexString(msg.getEncoded()));
if (logger.isInfoEnabled())
logger.info("Send: {}", msg.toString());
ByteBuf buffer = ctx.alloc().buffer(msg.getPayload().length + 8);
int packetLength = StaticMessages.SYNC_TOKEN.length + msg.getEncoded().length;
ByteBuf buffer = ctx.alloc().buffer(packetLength);
buffer.writeBytes(StaticMessages.SYNC_TOKEN);
buffer.writeBytes(ByteUtil.calcPacketLength(msg.getPayload()));
buffer.writeBytes(msg.getPayload());
buffer.writeBytes(ByteUtil.calcPacketLength(msg.getEncoded()));
buffer.writeBytes(msg.getEncoded());
ctx.writeAndFlush(buffer);
}
private boolean containsGetBlockHashes() {
Iterator<MessageRoundtrip> iterator = messageQueue.iterator();
while(iterator.hasNext()){

View File

@ -77,7 +77,6 @@ public class ClientPeer {
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} catch (InterruptedException ie) {
logger.error("-- ClientPeer: catch (InterruptedException ie) --", ie);
} finally {
@ -85,10 +84,10 @@ public class ClientPeer {
handler.killTimers();
final Set<PeerData> peers = WorldManager.getInstance().getPeers();
final Set<Peer> peers = WorldManager.getInstance().getPeers();
synchronized (peers){
for (PeerData peer : peers){
synchronized (peers) {
for (Peer peer : peers) {
if (host.equals(peer.getInetAddress().getHostAddress()) &&
port == peer.getPort()){
peer.setOnline(false);
@ -97,10 +96,7 @@ public class ClientPeer {
}
EthereumListener listener = WorldManager.getInstance().getListener();
if (listener != null){
listener.onPeerDisconnect(host, port);
}
if (listener != null) listener.onPeerDisconnect(host, port);
}
}
@ -108,25 +104,20 @@ public class ClientPeer {
this.peerListener = peerListener;
}
/*
* The wire gets data for signed transactions and
* sends it to the net.
*/
public void sendTransaction(Transaction transaction) {
transaction.getEncoded();
java.util.List<Transaction> txList = new ArrayList<Transaction>();
List<Transaction> txList = new ArrayList<>();
txList.add(transaction);
TransactionsMessage transactionsMessage = new TransactionsMessage(txList);
byte[] payload = transactionsMessage.getEncoded();
byte[] payload = transactionsMessage.getPayload();
if (peerListener != null)
peerListener.console("Send msg: [ " +
Hex.toHexString(payload) +
" ]");
if (peerListener != null)
peerListener.console("Send msg: [" + Hex.toHexString(payload) + "]");
handler.sendMsg(transactionsMessage);
}

View File

@ -37,19 +37,19 @@ public class EthereumFrameDecoder extends ByteToMessageDecoder {
// TODO: normally , if it's happens to often , than
// TODO: it's an attack and I should drop the peer.
logger.error("abandon garbage, wrong magic bytes: [ {} ] msgSize: [ {} ]", magicBytes, msgSize);
logger.error("abandon garbage, wrong magic bytes: [{}] msgSize: [{}]", magicBytes, msgSize);
ctx.close();
}
// Don't have the full packet yet
if (msgSize > in.readableBytes()) {
logger.trace("msg decode: magicBytes: [ {} ], readBytes: [ {} ] / msgSize: [ {} ] ", magicBytes, in.readableBytes(), msgSize);
logger.trace("msg decode: magicBytes: [{}], readBytes: [{}] / msgSize: [{}] ", magicBytes, in.readableBytes(), msgSize);
in.resetReaderIndex();
return;
}
logger.trace("message fully constructed go handle it: readBytes: [ {} ] / msgSize: [ {} ]", in.readableBytes(), msgSize);
logger.trace("message fully constructed go handle it: readBytes: [{}] / msgSize: [{}]", in.readableBytes(), msgSize);
byte[] decoded = new byte[(int)msgSize];
in.readBytes(decoded);

View File

@ -1,24 +1,21 @@
package org.ethereum.net.client;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOption;
import io.netty.channel.FixedRecvByteBufAllocator;
import org.ethereum.config.SystemProperties;
import org.ethereum.core.Block;
import org.ethereum.core.Transaction;
import org.ethereum.listener.EthereumListener;
import org.ethereum.manager.WorldManager;
import org.ethereum.net.Command;
import org.ethereum.net.MessageQueue;
import org.ethereum.net.PeerListener;
import org.ethereum.net.message.*;
import org.ethereum.net.peerdiscovery.PeerProtocolHandler;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import java.util.List;
import java.util.Timer;
@ -31,59 +28,39 @@ import static org.ethereum.net.message.StaticMessages.*;
* @author: Roman Mandeleil
* Created on: 10/04/14 08:19
*/
public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
public class EthereumProtocolHandler extends PeerProtocolHandler {
private Logger logger = LoggerFactory.getLogger("wire");
private Timer blocksAskTimer = new Timer("ChainAskTimer");
private final Timer timer = new Timer("MiscMessageTimer");
private int secToAskForBlocks = 1;
private boolean tearDown = false;
private PeerListener peerListener;
private MessageQueue msgQueue = null;
public EthereumProtocolHandler() { }
public EthereumProtocolHandler(PeerListener peerListener) {
this.peerListener = peerListener;
super(peerListener);
}
@Override
public void channelActive(final ChannelHandlerContext ctx) {
msgQueue = new MessageQueue(ctx);
logger.info("Send: " + StaticMessages.HELLO_MESSAGE.toString());
msgQueue.sendMessage(StaticMessages.HELLO_MESSAGE);
sendPing();
// sample for pinging in background
super.channelActive(ctx);
sendGetBlockHashes();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
if (tearDown) this.cancel();
sendPing();
}
}, 2000, 5000);
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendGetPeers();
}
}, 2000, 60000);
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendGetTransactions();
}
}, 2000, 10000);
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendGetBlockHashes();
}
}, 2000, 10000);
blocksAskTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendGetBlocks();
}
@ -91,168 +68,115 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
}
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws InterruptedException {
super.channelRead(ctx, msg);
byte[] payload = (byte[]) msg;
logger.info("[Recv msg: [{}] ]", Hex.toHexString(payload));
EthereumListener listener = WorldManager.getInstance().getListener();
byte commandCode = RLP.getCommandCode(payload);
Command receivedCommand = Command.fromInt(commandCode);
logger.info("[Recv: {}]", receivedCommand.name());
Command receivedCommand = Command.fromInt(RLP.getCommandCode(payload));
if (peerListener != null) peerListener.console("[Recv: " + receivedCommand.name() + "]");
switch(receivedCommand) {
case HELLO:
RLPList rlpList = RLP.decode2(payload);
HelloMessage helloMessage = new HelloMessage(rlpList);
logger.info(helloMessage.toString());
if (peerListener != null) peerListener.console(helloMessage.toString());
case HELLO:
sendStatus();
break;
case TRANSACTIONS:
TransactionsMessage transactionsMessage = new TransactionsMessage(payload);
msgQueue.receivedMessage(transactionsMessage);
if (peerListener != null) peerListener.console(transactionsMessage.toString());
List<Transaction> txList = transactionsMessage.getTransactions();
for(Transaction tx : txList)
// WorldManager.getInstance().getBlockchain().applyTransaction(null, tx);
WorldManager.getInstance().getWallet().addTransaction(tx);
if (listener != null)
listener.onRecvMessage(transactionsMessage);
break;
case BLOCKS:
BlocksMessage blocksMessage = new BlocksMessage(payload);
List<Block> blockList = blocksMessage.getBlockDataList();
msgQueue.receivedMessage(blocksMessage);
if (peerListener != null) peerListener.console(blocksMessage.toString());
// If we get one block from a peer we ask less greedy
if (blockList.size() <= 1 && secToAskForBlocks != 10) {
logger.info("Now we ask for blocks every 10 seconds");
updateBlockAskTimer(10);
}
// If we get more blocks from a peer we ask more greedy
if (blockList.size() > 2 && secToAskForBlocks != 1) {
logger.info("Now we ask for a chain every 1 seconds");
updateBlockAskTimer(1);
}
if (blockList.isEmpty()) return;
WorldManager.getInstance().getBlockchain().getBlockQueue().addBlocks(blockList);
if (listener != null)
listener.onRecvMessage(blocksMessage);
break;
case GET_TRANSACTIONS:
// TODO Implement GET_TRANSACTIONS command
// List<Transaction> pendingTxList =
// WorldManager.getInstance().getBlockchain().getPendingTransactionList();
// TransactionsMessage txMsg = new TransactionsMessage(pendingTxList);
// sendMsg(txMsg, ctx);
if (listener != null)
listener.onRecvMessage(GET_TRANSACTIONS_MESSAGE);
break;
case GET_BLOCK_HASHES:
GetBlockHashesMessage getBlockHashesMessage = new GetBlockHashesMessage(payload);
msgQueue.receivedMessage(getBlockHashesMessage);
if (peerListener != null) peerListener.console(getBlockHashesMessage.toString());
if (listener != null){
listener.trace(String.format("Got handshake: [ %s ]", helloMessage.toString()));
listener.onRecvMessage(helloMessage);
}
break;
case DISCONNECT:
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
msgQueue.receivedMessage(disconnectMessage);
sendBlockHashes();
if (listener != null)
listener.onRecvMessage(getBlockHashesMessage);
break;
case BLOCK_HASHES:
BlockHashesMessage blockHashesMessage = new BlockHashesMessage(payload);
msgQueue.receivedMessage(blockHashesMessage);
if (peerListener != null) peerListener.console(blockHashesMessage.toString());
logger.info(disconnectMessage.toString());
if (peerListener != null) peerListener.console(disconnectMessage.toString());
// TODO Process Block Hashes
if (listener != null)
listener.onRecvMessage(blockHashesMessage);
break;
case GET_BLOCKS:
GetBlocksMessage getBlocksMessage = new GetBlocksMessage(payload);
msgQueue.receivedMessage(getBlocksMessage);
if (listener != null)
listener.onRecvMessage(disconnectMessage);
break;
case PING:
msgQueue.receivedMessage(PING_MESSAGE);
sendPong();
sendBlocks();
if (listener != null)
listener.onRecvMessage(PING_MESSAGE);
break;
case PONG:
msgQueue.receivedMessage(PONG_MESSAGE);
if (listener != null)
listener.onRecvMessage(PONG_MESSAGE);
break;
case GET_PEERS:
msgQueue.receivedMessage(GET_PEERS_MESSAGE);
// TODO: send peer list
if (listener != null)
listener.onRecvMessage(GET_PEERS_MESSAGE);
break;
case PEERS:
PeersMessage peersMessage = new PeersMessage(payload);
msgQueue.receivedMessage(peersMessage);
WorldManager.getInstance().addPeers(peersMessage.getPeers());
logger.info(peersMessage.toString());
if (peerListener != null) peerListener.console(peersMessage.toString());
if (listener != null)
listener.onRecvMessage(peersMessage);
break;
case TRANSACTIONS:
TransactionsMessage transactionsMessage = new TransactionsMessage(payload);
msgQueue.receivedMessage(transactionsMessage);
List<Transaction> txList = transactionsMessage.getTransactions();
for(Transaction tx : txList)
// WorldManager.getInstance().getBlockchain()
// .applyTransaction(null, tx);
WorldManager.getInstance().getWallet().addTransaction(tx);
logger.info(transactionsMessage.toString());
if (peerListener != null) peerListener.console(transactionsMessage.toString());
if (listener != null)
listener.onRecvMessage(transactionsMessage);
break;
case BLOCKS:
BlocksMessage blocksMessage = new BlocksMessage(payload);
List<Block> blockList = blocksMessage.getBlockDataList();
msgQueue.receivedMessage(blocksMessage);
// If we get one block from a peer we ask less greedy
if (blockList.size() <= 1 && secToAskForBlocks != 10) {
logger.info("Now we ask for blocks each 10 seconds");
secToAskForBlocks = 10;
blocksAskTimer.cancel();
blocksAskTimer.purge();
blocksAskTimer = new Timer();
blocksAskTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendGetBlocks();
}
}, 3000, secToAskForBlocks * 1000);
}
// If we get more blocks from a peer we ask more greedy
if (blockList.size() > 2 && secToAskForBlocks != 1) {
logger.info("Now we ask for a chain each 1 seconds");
secToAskForBlocks = 1;
blocksAskTimer.cancel();
blocksAskTimer.purge();
blocksAskTimer = new Timer();
blocksAskTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendGetBlocks();
}
}, 3000, secToAskForBlocks * 1000);
}
if (blockList.isEmpty()) return;
WorldManager.getInstance().getBlockchain().getBlockQueue().addBlocks(blockList);
if (peerListener != null) peerListener.console(blocksMessage.toString());
if (listener != null)
listener.onRecvMessage(blocksMessage);
break;
case GET_TRANSACTIONS:
// TODO Implement GET_TRANSACTIONS command
// List<Transaction> pendingTxList =
// WorldManager.getInstance().getBlockchain().getPendingTransactionList();
// TransactionsMessage txMsg = new TransactionsMessage(pendingTxList);
// sendMsg(txMsg, ctx);
if (listener != null)
listener.onRecvMessage(GET_TRANSACTIONS_MESSAGE);
break;
case GET_BLOCK_HASHES:
// TODO Implement GET_BLOCK_HASHES command
break;
case BLOCK_HASHES:
// TODO Implement BLOCK_HASHES command
break;
case GET_BLOCKS:
// TODO Implement GET_BLOCKS command
break;
default:
// do nothing and ignore this command
break;
if (listener != null)
listener.onRecvMessage(getBlocksMessage);
break;
default:
// do nothing and ignore this command
break;
}
}
@Override
private void updateBlockAskTimer(int seconds) {
secToAskForBlocks = seconds;
blocksAskTimer.cancel();
blocksAskTimer.purge();
blocksAskTimer = new Timer();
blocksAskTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
sendGetBlocks();
}
}, 3000, secToAskForBlocks * 1000);
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
// limit the size of recieving buffer to 1024
ctx.channel().config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(32368));
@ -260,37 +184,33 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws InterruptedException {
this.tearDown = true;
logger.info("Lost connection to the server");
logger.error(cause.getMessage(), cause);
ctx.close().sync();
timer.cancel();
}
public void sendMsg(Message msg) {
msgQueue.sendMessage(msg);
EthereumListener listener = WorldManager.getInstance().getListener();
if (listener != null)
listener.onSendMessage(msg);
}
private void sendPing() {
sendMsg(PING_MESSAGE);
}
private void sendPong() {
sendMsg(PONG_MESSAGE);
}
private void sendGetPeers() {
sendMsg(GET_PEERS_MESSAGE);
protected void sendStatus() {
byte protocolVersion = 0, networkId = 0;
byte[] totalDifficulty = WorldManager.getInstance().getBlockchain().getTotalDifficulty();
byte[] bestHash = WorldManager.getInstance().getBlockchain().getLatestBlockHash();
byte[] genesisHash = StaticMessages.GENESIS_HASH;
StatusMessage peersMessage = new StatusMessage(protocolVersion, networkId,
totalDifficulty, bestHash, genesisHash);
sendMsg(peersMessage);
}
private void sendGetTransactions() {
sendMsg(GET_TRANSACTIONS_MESSAGE);
}
private void sendGetBlockHashes() {
byte[] lastHash = WorldManager.getInstance().getBlockchain().getLatestBlockHash();
GetBlockHashesMessage getBlockHashesMessage = new GetBlockHashesMessage(lastHash, 128);
sendMsg(getBlockHashesMessage);
}
private void sendGetBlocks() {
@ -305,6 +225,14 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
SystemProperties.CONFIG.maxBlocksAsk(), hash);
sendMsg(getBlocksMessage);
}
private void sendBlocks() {
// TODO: Send blocks
}
private void sendBlockHashes() {
// TODO: Send block hashes
}
public void killTimers(){
blocksAskTimer.cancel();

View File

@ -1,31 +1,35 @@
package org.ethereum.net.client;
import org.ethereum.net.message.HelloMessage;
import org.ethereum.util.RLP;
import org.spongycastle.util.encoders.Hex;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
/**
* www.ethereumJ.com
* @author: Roman Mandeleil
* Created on: 13/04/14 17:36
*/
public class PeerData {
public class Peer {
private byte[] ip;
private int port;
private short port;
private byte[] peerId;
private byte capabilities;
private List<String> capabilities;
private HelloMessage handshake;
private transient boolean isOnline = false;
private transient long lastCheckTime = 0;
public PeerData(byte[] ip, int port, byte[] peerId) {
public Peer(byte[] ip, int port, byte[] peerId) {
this.ip = ip;
this.port = port & 0xFFFF;
this.port = (short) (port & 0xFFFF);
this.peerId = peerId;
this.capabilities = new ArrayList<>();
}
public InetAddress getInetAddress() {
@ -52,7 +56,7 @@ public class PeerData {
}
public boolean isOnline() {
if (getCapabilities() < 7) return false;
if (getCapabilities().size() < 0) return false;
return isOnline;
}
@ -68,12 +72,12 @@ public class PeerData {
this.lastCheckTime = lastCheckTime;
}
public byte getCapabilities() {
public List<String> getCapabilities() {
if (handshake != null)
return handshake.getCapabilities();
else
return 0;
return new ArrayList<String>();
}
public HelloMessage getHandshake() {
@ -83,17 +87,31 @@ public class PeerData {
public void setHandshake(HelloMessage handshake) {
this.handshake = handshake;
}
public byte[] getEncoded() {
byte[] ip = RLP.encodeElement(this.ip);
byte[] port = RLP.encodeShort(this.port);
byte[] peerId = RLP.encodeElement(this.peerId);
byte[][] encodedCaps = new byte[this.capabilities.size()][];
for (int i = 0; i < this.capabilities.size(); i++) {
encodedCaps[i] = RLP.encodeString(this.capabilities.get(i));
}
byte[] capabilities = RLP.encodeList(encodedCaps);
return RLP.encodeList(ip, port, peerId, capabilities);
}
@Override
public String toString() {
return "Peer: [ip=" + getInetAddress().getHostAddress() + ", port=" + getPort() +
", peerId=" + (getPeerId() == null ? "": Hex.toHexString(getPeerId())) + "]";
return "[ip=" + getInetAddress().getHostAddress() +
", port=" + getPort() +
", peerId=" + (getPeerId() == null ? "" : Hex.toHexString(getPeerId()))
+ "]";
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
PeerData peerData = (PeerData) obj;
Peer peerData = (Peer) obj;
return this.getInetAddress().equals(peerData.getInetAddress());
}

View File

@ -1,29 +1,47 @@
package org.ethereum.net.message;
import static org.ethereum.net.Command.BLOCK_HASHES;
import java.util.List;
import org.ethereum.db.ByteArrayWrapper;
import org.ethereum.net.Command;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import com.google.common.base.Joiner;
public class BlockHashesMessage extends Message {
private List<ByteArrayWrapper> hashes;
public BlockHashesMessage(byte[] payload) {
super(payload);
}
private void parse() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
this.encoded = new byte[0]; // TODO
}
@Override
public void parseRLP() {
// TODO Auto-generated method stub
public Command getCommand() {
return BLOCK_HASHES;
}
@Override
public byte[] getEncoded() {
return encoded;
}
@Override
public byte[] getPayload() {
// TODO Auto-generated method stub
public Class<?> getAnswerMessage() {
return null;
}
@Override
public String getMessageName() {
// TODO Auto-generated method stub
return null;
}
@Override
public Class getAnswerMessage() {
// TODO Auto-generated method stub
return null;
}
public String toString() {
if (!parsed) parse();
return "[command=" + this.getCommand().name() + " hashes=" + Joiner.on("\n").join(hashes) + " ]";
}
}

View File

@ -18,25 +18,18 @@ import org.ethereum.util.RLPList;
*/
public class BlocksMessage extends Message {
private List<Block> blockDataList = new ArrayList<Block>();
private List<Block> blockDataList = new ArrayList<>();
public BlocksMessage(RLPList rawData) {
super(rawData);
}
public BlocksMessage(byte[] payload) {
super(RLP.decode2(payload));
this.payload = payload;
public BlocksMessage(byte[] encoded) {
super(encoded);
}
public void parse() {
public void parseRLP() {
RLPList paramsList = (RLPList) rawData.get(0);
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
if (Command.fromInt(((RLPItem) (paramsList).get(0)).getRLPData()[0]) != BLOCKS) {
throw new Error("BlocksMessage: parsing for mal data");
}
if ( (((RLPItem)(paramsList).get(0)).getRLPData()[0] & 0xFF) != BLOCKS.asByte())
throw new RuntimeException("Not a BlocksMessage command");
for (int i = 1; i < paramsList.size(); ++i) {
RLPList rlpData = ((RLPList) paramsList.get(i));
@ -45,35 +38,34 @@ public class BlocksMessage extends Message {
}
parsed = true;
}
@Override
public Command getCommand() {
return BLOCKS;
}
@Override
public byte[] getPayload() {
return payload;
public byte[] getEncoded() {
return encoded;
}
public List<Block> getBlockDataList() {
if (!parsed) parseRLP();
if (!parsed) parse();
return blockDataList;
}
@Override
public String getMessageName() {
return "Block";
}
@Override
public Class getAnswerMessage() {
@Override
public Class<?> getAnswerMessage() {
return null;
}
public String toString() {
if (!parsed) parseRLP();
if (!parsed) parse();
StringBuffer sb = new StringBuffer();
for (Block blockData : this.getBlockDataList()) {
sb.append(" ").append(blockData.toFlatString()).append("\n");
}
return "Blocks Message [\n" + sb.toString() + " ]";
return "[command=" + getCommand().name() + "\n" + sb.toString() + " ]";
}
}

View File

@ -17,57 +17,45 @@ public class DisconnectMessage extends Message {
private ReasonCode reason;
public DisconnectMessage(byte[] payload) {
super(RLP.decode2(payload));
this.payload = payload;
public DisconnectMessage(byte[] encoded) {
super(encoded);
}
public DisconnectMessage(RLPList rawData) {
super(rawData);
}
private void parse() {
@Override
public void parseRLP() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
RLPList paramsList = (RLPList) rawData.get(0);
if (Command.fromInt(((RLPItem)(paramsList).get(0)).getRLPData()[0]) != DISCONNECT) {
throw new Error("Disconnect: parsing for mal data");
}
byte[] reasonB = ((RLPItem)paramsList.get(1)).getRLPData();
if (reasonB == null) {
byte[] reasonB = ((RLPItem) paramsList.get(1)).getRLPData();
if (reasonB == null)
this.reason = REQUESTED;
} else {
else
this.reason = ReasonCode.fromInt(reasonB[0]);
}
this.parsed = true;
// TODO: what to do when mal data ?
}
@Override
public Command getCommand() {
return DISCONNECT;
}
@Override
public byte[] getPayload() {
public byte[] getEncoded() {
return encoded;
}
@Override
public Class<?> getAnswerMessage() {
return null;
}
public ReasonCode getReason() {
if (!parsed) parseRLP();
if (!parsed) parse();
return reason;
}
@Override
public String getMessageName() {
return "Disconnect";
}
@Override
public Class getAnswerMessage() {
return null;
}
public String toString() {
if (!parsed) parseRLP();
return "Disconnect Message [ reason=" + reason + " ]";
if (!parsed) parse();
return "[command=" + this.getCommand().name() + " reason=" + reason + "]";
}
}
}

View File

@ -1,19 +1,57 @@
package org.ethereum.net.message;
import java.math.BigInteger;
import static org.ethereum.net.Command.GET_BLOCK_HASHES;
import org.ethereum.net.Command;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
public class GetBlockHashesMessage extends Message {
/** The hash from the block of which parent hash to start sending */
private byte[] hash;
/** The maximum number of blocks to return. Note: the peer could return fewer. */
private int maxBlocks;
@Override
public void parseRLP() {
public GetBlockHashesMessage(byte[] encoded) {
super(encoded);
}
public GetBlockHashesMessage(byte[] hash, int maxBlocks) {
this.hash = hash;
this.maxBlocks = maxBlocks;
this.parsed = true;
this.encode();
}
private void encode() {
byte[] command = RLP.encodeByte(this.getCommand().asByte());
byte[] hash = RLP.encodeElement(this.hash);
byte[] maxBlocks = RLP.encodeInt(this.maxBlocks);
this.encoded = RLP.encodeList(command, hash, maxBlocks);
}
public void parse() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
this.hash = ((RLPItem) paramsList.get(1)).getRLPData();
byte[] maxBlocksBytes = ((RLPItem) paramsList.get(2)).getRLPData();
this.maxBlocks = new BigInteger(1, maxBlocksBytes).intValue();
this.parsed = true;
}
@Override
public byte[] getPayload() {
return null;
public byte[] getEncoded() {
return encoded;
}
@Override
public String getMessageName() {
return "GetBlockHashes";
public Command getCommand() {
return GET_BLOCK_HASHES;
}
@Override
@ -21,4 +59,19 @@ public class GetBlockHashesMessage extends Message {
return BlockHashesMessage.class;
}
}
public byte[] getHash() {
if (!parsed) parse();
return hash;
}
public int getMaxBlocks() {
if (!parsed) parse();
return maxBlocks;
}
@Override
public String toString() {
return "[command=" + this.getCommand().name() + "]"; //TODO
}
}

View File

@ -14,19 +14,19 @@ import org.spongycastle.util.encoders.Hex;
public class GetBlocksMessage extends Message {
private List<byte[]> blockHashList = new ArrayList<byte[]>();
private List<byte[]> blockHashList = new ArrayList<>();
private BigInteger blockNum;
public GetBlocksMessage(RLPList rawData) {
super(rawData);
public GetBlocksMessage(byte[] encoded) {
super(encoded);
}
// TODO: it get's byte for now change it to int
// TODO: it get's byte for now. change it to int
public GetBlocksMessage(byte number , byte[]... blockHashList) {
byte[][] encodedElements = new byte[blockHashList.length + 2][];
encodedElements[0] = new byte[]{0x14};
encodedElements[0] = new byte[]{GET_BLOCKS.asByte()};
int i = 1;
for (byte[] hash : blockHashList) {
this.blockHashList.add(hash);
@ -36,17 +36,16 @@ public class GetBlocksMessage extends Message {
}
encodedElements[i] = RLP.encodeByte(number);
this.payload = RLP.encodeList(encodedElements);
this.encoded = RLP.encodeList(encodedElements);
this.parsed = true;
}
@Override
public void parseRLP() {
RLPList paramsList = (RLPList) rawData.get(0);
if (Command.fromInt(((RLPItem) (paramsList).get(0)).getRLPData()[0]) != GET_BLOCKS)
throw new Error("GetBlocks: parsing for mal data");
public void parse() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
if ( (((RLPItem)(paramsList).get(0)).getRLPData()[0] & 0xFF) != GET_BLOCKS.asByte())
throw new RuntimeException("Not a GetBlockssMessage command");
int size = paramsList.size();
for (int i = 1; i < size - 1; ++i) {
blockHashList.add(((RLPItem) paramsList.get(i)).getRLPData());
@ -57,17 +56,16 @@ public class GetBlocksMessage extends Message {
this.blockNum = new BigInteger(blockNumB);
this.parsed = true;
// TODO: what to do when mal data ?
}
@Override
public byte[] getPayload() {
return payload;
public byte[] getEncoded() {
return encoded;
}
@Override
public String getMessageName() {
return "GetBlocks";
public Command getCommand() {
return GET_BLOCKS;
}
@Override
@ -76,12 +74,13 @@ public class GetBlocksMessage extends Message {
}
public String toString() {
if (!parsed) parseRLP();
if (!parsed) parse();
StringBuffer sb = new StringBuffer();
for (byte[] blockHash : blockHashList)
sb.append("").append(Hex.toHexString(blockHash)).append(", ");
for (byte[] blockHash : blockHashList) {
sb.append("").append(Hex.toHexString(blockHash)).append("\n ");
}
sb.append(" blockNum=").append(blockNum);
return "GetBlocks Message [" + sb.toString() + " ]";
return "[command=" + this.getCommand().name() + " " + sb.toString() + " ]";
}
}

View File

@ -1,5 +1,8 @@
package org.ethereum.net.message;
import static org.ethereum.net.Command.GET_PEERS;
import org.ethereum.net.Command;
import org.spongycastle.util.encoders.Hex;
/**
@ -9,26 +12,27 @@ import org.spongycastle.util.encoders.Hex;
*/
public class GetPeersMessage extends Message {
public GetPeersMessage() {
this.payload = Hex.decode("C110");
/** GetPeers message is always a the same single command payload */
private final static byte[] FIXED_PAYLOAD = Hex.decode("C104");
@Override
public byte[] getEncoded() {
return FIXED_PAYLOAD;
}
@Override
public void parseRLP() {
}
public byte[] getPayload() {
return payload;
}
@Override
public String getMessageName(){
return "GetPeers";
public Command getCommand(){
return GET_PEERS;
}
@Override
public Class<PeersMessage> getAnswerMessage() {
return PeersMessage.class;
}
@Override
public String toString() {
return "[command=" + this.getCommand().name() + "]";
}
}

View File

@ -1,5 +1,8 @@
package org.ethereum.net.message;
import static org.ethereum.net.Command.GET_TRANSACTIONS;
import org.ethereum.net.Command;
import org.spongycastle.util.encoders.Hex;
/**
@ -9,26 +12,26 @@ import org.spongycastle.util.encoders.Hex;
*/
public class GetTransactionsMessage extends Message {
public GetTransactionsMessage() {
this.payload = Hex.decode("C116");
/** GetTransactions message is always a the same single command payload */
private static byte[] FIXED_PAYLOAD = Hex.decode("C116");
public byte[] getEncoded() {
return FIXED_PAYLOAD;
}
@Override
public Command getCommand() {
return GET_TRANSACTIONS;
}
@Override
public void parseRLP() {
public Class<TransactionsMessage> getAnswerMessage() {
return TransactionsMessage.class;
}
public byte[] getPayload() {
return payload;
}
@Override
public String getMessageName(){
return "GetTransactions";
}
@Override
public Class getAnswerMessage() {
return null;
public String toString() {
return "[command=" + this.getCommand().name() + "]";
}
}

View File

@ -1,15 +1,19 @@
package org.ethereum.net.message;
import org.spongycastle.util.encoders.Hex;
import static org.ethereum.net.Command.HELLO;
import static org.ethereum.util.ByteUtil.EMPTY_BYTE_ARRAY;
import org.ethereum.net.Command;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
import org.spongycastle.util.encoders.Hex;
import com.google.common.base.Joiner;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
/**
* Wrapper around an Ethereum HelloMessage on the network
@ -26,18 +30,18 @@ public class HelloMessage extends Message {
private String clientId;
/** A peer-network capability code, readable ASCII and 3 letters.
* Currently only "eth" and "shh" are known. */
private byte capabilities;
private List<String> capabilities;
/** The port on which the peer is listening for an incoming connection */
private short listenPort;
/** The identity and public key of the peer */
private byte[] peerId;
public HelloMessage(RLPList rawData) {
super(rawData);
public HelloMessage(byte[] encoded) {
super(encoded);
}
public HelloMessage(byte p2pVersion, String clientId,
byte capabilities, short listenPort, byte[] peerId) {
List<String> capabilities, short listenPort, byte[] peerId) {
this.p2pVersion = p2pVersion;
this.clientId = clientId;
this.capabilities = capabilities;
@ -46,81 +50,87 @@ public class HelloMessage extends Message {
this.parsed = true;
}
@Override
public void parseRLP() {
public void parse() {
RLPList paramsList = (RLPList) rawData.get(0);
// the message does no distinguish between the 0 and null so here I check command code for null
// TODO: find out if it can be 00
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
// TODO: find out if it can be 00. Do we need to check for this?
// The message does not distinguish between 0 and null,
// so we check command code for null.
if (((RLPItem) paramsList.get(0)).getRLPData() != null)
throw new Error("HelloMessage: parsing for mal data");
throw new Error("HelloMessage: parsing for mal data");
this.p2pVersion = ((RLPItem) paramsList.get(1)).getRLPData()[0];
byte[] p2pVersionBytes = ((RLPItem) paramsList.get(1)).getRLPData();
this.p2pVersion = p2pVersionBytes != null ? p2pVersionBytes[0] : 0;
byte[] clientIdBytes = ((RLPItem) paramsList.get(2)).getRLPData();
this.clientId = new String(clientIdBytes != null ? clientIdBytes : EMPTY_BYTE_ARRAY);
this.capabilities = ((RLPItem) paramsList.get(3)).getRLPData()[0];
RLPList capabilityList = (RLPList) paramsList.get(3);
this.capabilities = new ArrayList<>();
for (int i = 0; i < capabilityList.size(); i++) {
this.capabilities.add(new String(capabilityList.get(i).getRLPData()));
}
byte[] peerPortBytes = ((RLPItem) paramsList.get(4)).getRLPData();
this.listenPort = new BigInteger(peerPortBytes).shortValue();
this.listenPort = new BigInteger(peerPortBytes).shortValue();
this.peerId = ((RLPItem) paramsList.get(5)).getRLPData();
this.parsed = true;
// TODO: what to do when mal data ?
}
@Override
public byte[] getEncoded() {
if (encoded == null) this.encode();
return encoded;
}
public byte[] getPayload() {
private void encode() {
byte[] command = RLP.encodeByte(HELLO.asByte());
byte[] protocolVersion = RLP.encodeByte(this.p2pVersion);
byte[] p2pVersion = RLP.encodeByte(this.p2pVersion);
byte[] clientId = RLP.encodeString(this.clientId);
byte[] capabilities = RLP.encodeByte(this.capabilities);
byte[][] capabilities = new byte[this.capabilities.size()][];
for (int i = 0; i < this.capabilities.size(); i++) {
capabilities[i] = RLP.encode(this.capabilities.get(i).getBytes());
}
byte[] capabilityList = RLP.encodeList(capabilities);
byte[] peerPort = RLP.encodeShort(this.listenPort);
byte[] peerId = RLP.encodeElement(this.peerId);
byte[] data = RLP.encodeList(command, protocolVersion,
clientId, capabilities, peerPort, peerId);
return data;
}
public byte getCommandCode() {
if (!parsed) parseRLP();
return HELLO.asByte();
}
this.encoded = RLP.encodeList(command, p2pVersion,
clientId, capabilityList, peerPort, peerId);
}
public byte getP2PVersion() {
if (!parsed) parseRLP();
if (!parsed) parse();
return p2pVersion;
}
public String getClientId() {
if (!parsed) parseRLP();
if (!parsed) parse();
return clientId;
}
public byte getCapabilities() {
if (!parsed) parseRLP();
public List<String> getCapabilities() {
if (!parsed) parse();
return capabilities;
}
public short getListenPort() {
if (!parsed) parseRLP();
if (!parsed) parse();
return listenPort;
}
public byte[] getPeerId() {
if (!parsed) parseRLP();
if (!parsed) parse();
return peerId;
}
@Override
public String getMessageName() {
return "HelloMessage";
}
public Command getCommand() {
return HELLO;
}
@Override
public Class<?> getAnswerMessage() {
@ -128,14 +138,13 @@ public class HelloMessage extends Message {
}
public String toString() {
if (!parsed) parseRLP();
return "Hello Message [ command=" + HELLO.asByte() + " " +
" p2pVersion=" + this.p2pVersion + " " +
" clientId=" + this.clientId + " " +
" capabilities=" + this.capabilities + " " +
if (!parsed) parse();
return "[command=" + this.getCommand().name() +
" p2pVersion=" + this.p2pVersion +
" clientId=" + this.clientId +
" capabilities=[" + Joiner.on(" ").join(this.capabilities) + "]" +
" peerPort=" + this.listenPort + " " +
" peerId=" + Hex.toHexString(this.peerId) + " " +
"]";
}
}
}

View File

@ -1,30 +1,41 @@
package org.ethereum.net.message;
import org.ethereum.util.RLPList;
import org.ethereum.net.Command;
/**
* Abstract message class for all messages on the Ethereum network
*
* www.ethereumJ.com
* @author: Roman Mandeleil
* Created on: 06/04/14 14:58
*/
public abstract class Message {
RLPList rawData;
boolean parsed = false;
byte[] payload;
protected boolean parsed;
protected byte[] encoded;
public Message() {}
public Message(RLPList rawData) {
this.rawData = rawData;
public Message(byte[] encoded) {
this.encoded = encoded;
parsed = false;
}
public abstract void parseRLP();
public abstract byte[] getPayload();
public abstract String getMessageName();
public abstract Command getCommand();
/**
* Gets the RLP encoded byte array of this message
*
* @return RLP encoded byte array representation of this message
*/
public abstract byte[] getEncoded();
public abstract Class<?> getAnswerMessage();
/**
* Returns the message in String format
*
* @return A string with all attributes of the message
*/
public abstract String toString();
}

View File

@ -3,11 +3,13 @@ package org.ethereum.net.message;
import static org.ethereum.net.Command.PEERS;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.ethereum.net.Command;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
@ -21,32 +23,29 @@ public class PeersMessage extends Message {
private boolean parsed = false;
private final Set<PeerData> peers = new LinkedHashSet<PeerData>();
private Set<Peer> peers = new LinkedHashSet<>();
public PeersMessage(byte[] payload) {
super(RLP.decode2(payload));
this.payload = payload;
super(payload);
}
public PeersMessage(Set<Peer> peers) {
this.peers = peers;
this.parsed = true;
}
public PeersMessage(RLPList rawData) {
this.rawData = rawData;
parsed = false;
}
public void parse() {
@Override
public void parseRLP() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
RLPList paramsList = (RLPList) rawData.get(0);
if (Command.fromInt(((RLPItem)(paramsList).get(0)).getRLPData()[0] & 0xFF) != PEERS) {
throw new Error("PeersMessage: parsing for mal data");
}
if ( (((RLPItem)(paramsList).get(0)).getRLPData()[0] & 0xFF) != PEERS.asByte())
throw new RuntimeException("Not a PeersMessage command");
for (int i = 1; i < paramsList.size(); ++i) {
RLPList peerParams = (RLPList)paramsList.get(i);
byte[] ip = ((RLPItem) peerParams.get(0)).getRLPData();
byte[] shortData = ((RLPItem) peerParams.get(1)).getRLPData();
RLPList peerParams = (RLPList) paramsList.get(i);
byte[] ip = ((RLPItem) peerParams.get(0)).getRLPData();
byte[] shortData = ((RLPItem) peerParams.get(1)).getRLPData();
short peerPort = 0;
if (shortData.length == 1)
peerPort = shortData[0];
@ -55,42 +54,51 @@ public class PeersMessage extends Message {
peerPort = bb.getShort();
}
byte[] peerId = ((RLPItem) peerParams.get(2)).getRLPData();
PeerData peer = new PeerData(ip, peerPort, peerId);
Peer peer = new Peer(ip, peerPort, peerId);
peers.add(peer);
}
this.parsed = true;
// TODO: what to do when mal data ?
}
@Override
public Command getCommand() {
return PEERS;
}
@Override
public byte[] getPayload() {
return payload;
public byte[] getEncoded() {
if (encoded == null) this.encode();
return encoded;
}
private void encode() {
byte[][] encodedByteArrays = new byte[this.peers.size()+1][];
encodedByteArrays[0] = RLP.encodeByte(this.getCommand().asByte());
List<Peer> peerList = new ArrayList<>();
peerList.addAll(this.peers);
for (int i = 0; i < peerList.size(); i++) {
encodedByteArrays[i+1] = peerList.get(i).getEncoded();
}
this.encoded = RLP.encodeList(encodedByteArrays);
}
public Set<PeerData> getPeers() {
if (!parsed)
parseRLP();
public Set<Peer> getPeers() {
if (!parsed) this.parse();
return peers;
}
@Override
public String getMessageName() {
return "Peers";
}
@Override
public Class getAnswerMessage() {
public Class<?> getAnswerMessage() {
return null;
}
public String toString() {
if (!parsed)
parseRLP();
if (!parsed) this.parse();
StringBuffer sb = new StringBuffer();
for (PeerData peerData : peers) {
sb.append("[").append(peerData).append("] \n ");
for (Peer peerData : peers) {
sb.append("\n [").append(peerData).append("]");
}
return "Peers Message [\n " + sb.toString() + "]";
return "[command=" + this.getCommand().name() + sb.toString() + "]";
}
}

View File

@ -1,5 +1,8 @@
package org.ethereum.net.message;
import static org.ethereum.net.Command.PING;
import org.ethereum.net.Command;
import org.spongycastle.util.encoders.Hex;
/**
@ -9,26 +12,25 @@ import org.spongycastle.util.encoders.Hex;
*/
public class PingMessage extends Message {
public PingMessage() {
this.payload = Hex.decode("C102");
/** Ping message is always a the same single command payload */
private static byte[] FIXED_PAYLOAD = Hex.decode("C102");
public byte[] getEncoded() {
return FIXED_PAYLOAD;
}
@Override
public void parseRLP() {
}
public byte[] getPayload() {
return payload;
}
@Override
public String getMessageName(){
return "Ping";
}
@Override
public Command getCommand() {
return PING;
}
@Override
public Class<PongMessage> getAnswerMessage() {
return PongMessage.class;
}
}
@Override
public String toString() {
return "[command=" + getCommand().name() + "]";
}
}

View File

@ -1,5 +1,8 @@
package org.ethereum.net.message;
import static org.ethereum.net.Command.PONG;
import org.ethereum.net.Command;
import org.spongycastle.util.encoders.Hex;
/**
@ -9,25 +12,26 @@ import org.spongycastle.util.encoders.Hex;
*/
public class PongMessage extends Message {
public PongMessage() {
this.payload = Hex.decode("C103");
}
/** Pong message is always a the same single command payload */
private static byte[] FIXED_PAYLOAD = Hex.decode("C103");
@Override
public byte[] getEncoded() {
return FIXED_PAYLOAD;
}
@Override
public Command getCommand() {
return PONG;
}
@Override
public Class<?> getAnswerMessage() {
return null;
}
@Override
public void parseRLP() {
public String toString() {
return "[command=PONG]";
}
public byte[] getPayload() {
return payload;
}
public String getMessageName(){
return "Pong";
}
@Override
public Class getAnswerMessage() {
return null;
}
}
}

View File

@ -22,7 +22,7 @@ public enum ReasonCode {
private int reason;
private static final Map<Integer, ReasonCode> intToTypeMap = new HashMap<Integer, ReasonCode>();
private static final Map<Integer, ReasonCode> intToTypeMap = new HashMap<>();
static {
for (ReasonCode type : ReasonCode.values()) {
intToTypeMap.put(type.reason, type);

View File

@ -1,5 +1,9 @@
package org.ethereum.net.message;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.ethereum.config.SystemProperties;
import org.ethereum.core.Genesis;
import org.ethereum.crypto.HashUtil;
@ -18,31 +22,31 @@ public class StaticMessages {
public final static GetPeersMessage GET_PEERS_MESSAGE = new GetPeersMessage();
public final static GetTransactionsMessage GET_TRANSACTIONS_MESSAGE = new GetTransactionsMessage();
public static final byte[] PING_PACKET = Hex.decode("2240089100000002C102");
public static final byte[] PONG_PACKET = Hex.decode("2240089100000002C103");
public static final byte[] GET_PEERS_PACKET = Hex.decode("2240089100000002C110");
public static final byte[] GET_TRANSACTIONS = Hex.decode("2240089100000002C116");
public static final byte[] DISCONNECT_08 = Hex.decode("2240089100000003C20108");
public static final byte[] DISCONNECT_PEER_QUITTING = Hex.decode("2240089100000003C20108");
public static final byte[] SYNC_TOKEN = Hex.decode("22400891");
public static final byte[] GENESIS_HASH = Genesis.getInstance().getHash();
private static HelloMessage generateHelloMessage() {
String helloAnnouncement = buildHelloAnnouncement();
byte p2pVersion = 0x00;
List<String> capabilities = new ArrayList<>(Arrays.asList("eth"));
short listenPort = (short) 30303;
byte[] peerIdBytes = HashUtil.randomPeerId();
return new HelloMessage(p2pVersion, helloAnnouncement,
capabilities, listenPort, peerIdBytes);
}
private static String buildHelloAnnouncement() {
String version = SystemProperties.CONFIG.projectVersion();
String system = System.getProperty("os.name");
if (system.contains(" "))
system = system.substring(0, system.indexOf(" "));
if (System.getProperty("java.vm.vendor").contains("Android"))
system = "Android";
String phrase = SystemProperties.CONFIG.helloPhrase();
String helloAnnouncement = String.format("Ethereum(J)/v%s/%s/%s/Java", version, phrase, system);
return new HelloMessage((byte) 0x21, helloAnnouncement,
Byte.parseByte("00000111", 2), (short) 30303, peerIdBytes);
return String.format("Ethereum(J)/v%s/%s/%s/Java", version, phrase, system);
}
}

View File

@ -2,9 +2,12 @@ package org.ethereum.net.message;
import static org.ethereum.net.Command.STATUS;
import org.ethereum.net.Command;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
import org.spongycastle.util.encoders.Hex;
/**
* Wrapper around an Ethereum StatusMessage on the network
@ -23,8 +26,8 @@ public class StatusMessage extends Message {
/** The hash of the Genesis block */
private byte[] genesisHash;
public StatusMessage(RLPList rawData) {
super(rawData);
public StatusMessage(byte[] encoded) {
super(encoded);
}
public StatusMessage(byte protocolVersion, byte networkId,
@ -35,18 +38,18 @@ public class StatusMessage extends Message {
this.bestHash = bestHash;
this.genesisHash = genesisHash;
this.parsed = true;
this.encode();
}
@Override
public void parseRLP() {
public void parse() {
RLPList paramsList = (RLPList) rawData.get(0);
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
/* the message does not distinguish between the 0 and null
* so check command code for null */
// TODO: find out if it can be 00
if (((RLPItem) paramsList.get(0)).getRLPData() != null)
throw new Error("StaticMessage: parsing for mal data");
if ( (((RLPItem)(paramsList).get(0)).getRLPData()[0] & 0xFF) != STATUS.asByte())
throw new RuntimeException("Not a StatusMessage command");
this.protocolVersion = ((RLPItem) paramsList.get(1)).getRLPData()[0];
byte[] networkIdBytes = ((RLPItem) paramsList.get(2)).getRLPData();
@ -59,7 +62,12 @@ public class StatusMessage extends Message {
}
@Override
public byte[] getPayload() {
public byte[] getEncoded() {
if (encoded == null) this.encode();
return encoded;
}
private void encode() {
byte[] command = RLP.encodeByte(STATUS.asByte());
byte[] protocolVersion = RLP.encodeByte(this.protocolVersion);
byte[] networkId = RLP.encodeByte(this.networkId);
@ -67,19 +75,54 @@ public class StatusMessage extends Message {
byte[] bestHash = RLP.encodeElement(this.bestHash);
byte[] genesisHash = RLP.encodeElement(this.genesisHash);
byte[] data = RLP.encodeList(command, protocolVersion, networkId,
this.encoded = RLP.encodeList(command, protocolVersion, networkId,
totalDifficulty, bestHash, genesisHash);
return data;
}
@Override
public String getMessageName() {
return "StatusMessage";
public Command getCommand() {
return STATUS;
}
@Override
public Class<?> getAnswerMessage() {
return null;
}
public byte getProtocolVersion() {
if (!parsed) this.parse();
return protocolVersion;
}
public byte getNetworkId() {
if (!parsed) this.parse();
return networkId;
}
public byte[] getTotalDifficulty() {
if (!parsed) this.parse();
return totalDifficulty;
}
public byte[] getBestHash() {
if (!parsed) this.parse();
return bestHash;
}
public byte[] getGenesisHash() {
if (!parsed) this.parse();
return genesisHash;
}
@Override
public String toString() {
if (!parsed) parse();
return "[command=" + this.getCommand().name() +
" protocolVersion=" + this.protocolVersion +
" networkId=" + this.networkId +
" totalDifficulty=" + ByteUtil.toHexString(this.totalDifficulty) +
" bestHash=" + Hex.toHexString(this.bestHash) + " " +
" genesisHash=" + Hex.toHexString(this.genesisHash) + " " +
"]";
}
}

View File

@ -7,11 +7,7 @@ import org.ethereum.net.Command;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPItem;
import org.ethereum.util.RLPList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -22,52 +18,39 @@ import java.util.List;
*/
public class TransactionsMessage extends Message {
private Logger logger = LoggerFactory.getLogger("wire");
private List<Transaction> transactions = new ArrayList<Transaction>();
private List<Transaction> transactions = new ArrayList<>();
public TransactionsMessage() {
public TransactionsMessage(byte[] encoded) {
super(encoded);
}
public TransactionsMessage(List<Transaction> transactionList) {
this.transactions = transactionList;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
for (Transaction tx : transactionList) {
byte[] txPayload = tx.getEncoded();
try {
baos.write(txPayload);
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
byte[][] elements = new byte[transactionList.size() + 1][];
elements[0] = new byte[]{Command.TRANSACTIONS.asByte()};
for (int i = 0; i < transactionList.size(); ++i)
elements[i + 1] = transactionList.get(i).getEncoded();
payload = RLP.encodeList(elements);
}
public TransactionsMessage(byte[] payload) {
super(RLP.decode2(payload));
this.payload = payload;
}
public TransactionsMessage(RLPList rawData) {
this.rawData = rawData;
parsed = false;
}
@Override
public void parseRLP() {
RLPList paramsList = (RLPList) rawData.get(0);
public byte[] getEncoded() {
if (encoded == null) this.encode();
return encoded;
}
if (Command.fromInt(((RLPItem) (paramsList).get(0)).getRLPData()[0] & 0xFF) != TRANSACTIONS)
throw new Error("TransactionMessage: parsing for mal data");
private void encode() {
byte[][] encodedTransactions = new byte[transactions.size()][];
byte[] command = new byte[]{Command.TRANSACTIONS.asByte()};
for (int i = 0; i < transactions.size(); ++i)
encodedTransactions[i + 1] = transactions.get(i).getEncoded();
byte[] encodedTxsList = RLP.encodeList(encodedTransactions);
this.encoded = RLP.encodeList(command, encodedTxsList);
}
transactions = new ArrayList<Transaction>();
private void parse() {
RLPList paramsList = (RLPList) RLP.decode2(encoded).get(0);
int commandByte = ((RLPItem) (paramsList).get(0)).getRLPData()[0] & 0xFF;
if (Command.fromInt(commandByte) != TRANSACTIONS)
throw new RuntimeException("Not a TransactionMessage: " + Integer.toHexString(commandByte));
transactions = new ArrayList<>();
int size = paramsList.size();
for (int i = 1; i < size; ++i) {
RLPList rlpTxData = (RLPList) paramsList.get(i);
@ -78,27 +61,22 @@ public class TransactionsMessage extends Message {
}
public List<Transaction> getTransactions() {
if (!parsed) parseRLP();
if (!parsed) parse();
return transactions;
}
@Override
public String getMessageName() {
return "Transactions";
}
@Override
public Command getCommand() {
return TRANSACTIONS;
}
@Override
public Class getAnswerMessage() {
public Class<?> getAnswerMessage() {
return null;
}
@Override
public byte[] getPayload() {
return payload;
}
public String toString() {
if(!parsed) parseRLP();
if(!parsed) parse();
StringBuffer sb = new StringBuffer();
for (Transaction transaction : transactions)
sb.append(" ").append(transaction).append("\n");

View File

@ -1,178 +0,0 @@
package org.ethereum.net.peerdiscovery;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelOption;
import io.netty.channel.FixedRecvByteBufAllocator;
import org.ethereum.manager.WorldManager;
import org.ethereum.net.Command;
import org.ethereum.net.PeerListener;
import org.ethereum.net.message.DisconnectMessage;
import org.ethereum.net.message.HelloMessage;
import org.ethereum.net.message.PeersMessage;
import org.ethereum.net.message.StaticMessages;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.encoders.Hex;
import static org.ethereum.net.Command.*;
/**
* www.ethereumJ.com
* @author: Roman Mandeleil
* Created on: 10/04/14 08:19
*/
public class EthereumPeerTasterHandler extends ChannelInboundHandlerAdapter {
private final static Logger logger = LoggerFactory.getLogger("peerdiscovery");
private final static byte[] MAGIC_PREFIX = {(byte)0x22, (byte)0x40, (byte)0x08, (byte)0x91};
private long lastPongTime = 0;
private boolean tearDown = false;
private PeerListener peerListener;
private HelloMessage handshake = null;
public EthereumPeerTasterHandler() { }
public EthereumPeerTasterHandler(PeerListener peerListener) {
this.peerListener = peerListener;
}
@Override
public void channelActive(final ChannelHandlerContext ctx) {
// Here we send the hello message with random id each time
// to not interrupt active peer
HelloMessage helloMessage = StaticMessages.HELLO_MESSAGE;
byte[] helloLength =ByteUtil.calcPacketLength(helloMessage.getPayload());
final ByteBuf buffer = ctx.alloc().buffer(helloMessage.getPayload().length + 8);
buffer.writeBytes(MAGIC_PREFIX);
buffer.writeBytes(helloLength);
buffer.writeBytes(helloMessage.getPayload());
logger.info("Send: " + helloMessage.toString());
ctx.writeAndFlush(buffer);
}
@Override
public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception {
byte[] payload = (byte[]) msg;
logger.info("[Send msg: [{}] ]", Hex.toHexString(payload));
byte command = RLP.getCommandCode(payload);
// got HELLO
if (Command.fromInt(command) == HELLO) {
logger.info("[Recv: HELLO]" );
RLPList rlpList = RLP.decode2(payload);
HelloMessage helloMessage = new HelloMessage(rlpList);
handshake = helloMessage;
logger.info(helloMessage.toString());
sendGetPeers(ctx);
}
// got DISCONNECT
if (Command.fromInt(command) == DISCONNECT) {
logger.info("[Recv: DISCONNECT]");
if (peerListener != null) peerListener.console("[Recv: DISCONNECT]");
RLPList rlpList = RLP.decode2(payload);
DisconnectMessage disconnectMessage = new DisconnectMessage(rlpList);
logger.info(disconnectMessage.toString());
}
// got PING send pong
if (Command.fromInt(command) == PING) {
logger.info("[Recv: PING]");
if (peerListener != null) peerListener.console("[Recv: PING]");
sendPong(ctx);
}
// got PONG mark it
if (Command.fromInt(command) == PONG) {
logger.info("[Recv: PONG]" );
if (peerListener != null) peerListener.console("[Recv: PONG]");
this.lastPongTime = System.currentTimeMillis();
}
// got PEERS
if (Command.fromInt(command) == PEERS) {
logger.info("[Recv: PEERS]");
if (peerListener != null) peerListener.console("[Recv: PEERS]");
RLPList rlpList = RLP.decode2(payload);
PeersMessage peersMessage = new PeersMessage(rlpList);
WorldManager.getInstance().addPeers(peersMessage.getPeers());
logger.info(peersMessage.toString());
sendDisconnectNice(ctx);
ctx.close().sync();
ctx.disconnect().sync();
}
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
// limit the size of recieving buffer to 1024
ctx.channel().config().setRecvByteBufAllocator(new FixedRecvByteBufAllocator(32368));
ctx.channel().config().setOption(ChannelOption.SO_RCVBUF, 32368);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
this.tearDown = true;
logger.info("Lost connection to the server");
logger.error(cause.getMessage(), cause);
ctx.close().sync();
ctx.disconnect().sync();
}
private void sendPing(ChannelHandlerContext ctx) {
ByteBuf buffer = ctx.alloc().buffer(StaticMessages.PING_PACKET.length);
buffer.writeBytes(StaticMessages.PING_PACKET);
ctx.writeAndFlush(buffer);
}
private void sendPong(ChannelHandlerContext ctx) {
logger.info("[Send: PONG]");
ByteBuf buffer = ctx.alloc().buffer(StaticMessages.PONG_PACKET.length);
buffer.writeBytes(StaticMessages.PONG_PACKET);
ctx.writeAndFlush(buffer);
}
private void sendDisconnectNice(ChannelHandlerContext ctx) {
logger.info("[Send: DISCONNECT]");
ByteBuf buffer = ctx.alloc().buffer(StaticMessages.DISCONNECT_08.length);
buffer.writeBytes(StaticMessages.DISCONNECT_08);
ctx.writeAndFlush(buffer);
}
private void sendGetPeers(ChannelHandlerContext ctx) {
ByteBuf buffer = ctx.alloc().buffer(StaticMessages.GET_PEERS_PACKET.length);
buffer.writeBytes(StaticMessages.GET_PEERS_PACKET);
ctx.writeAndFlush(buffer);
}
public HelloMessage getHandshake(){
return this.handshake;
}
}

View File

@ -1,6 +1,6 @@
package org.ethereum.net.peerdiscovery;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -24,11 +24,11 @@ public class PeerDiscovery {
private ThreadPoolExecutor executorPool;
private PeerDiscoveryMonitorThread monitor;
private final Set<PeerData> peers;
private final Set<Peer> peers;
private final AtomicBoolean started = new AtomicBoolean(false);
public PeerDiscovery(Set<PeerData> peers) {
public PeerDiscovery(Set<Peer> peers) {
this.peers = peers;
}
@ -49,14 +49,14 @@ public class PeerDiscovery {
Thread monitorThread = new Thread(monitor);
monitorThread.start();
for (PeerData peerData : this.peers) {
for (Peer peerData : this.peers) {
executorPool.execute(new WorkerThread(peerData, executorPool));
}
started.set(true);
}
public void addNewPeerData(PeerData peerData) {
public void addNewPeerData(Peer peerData) {
logger.debug("add new peer for discovery: {}", peerData);
executorPool.execute(new WorkerThread(peerData, executorPool));
}

View File

@ -20,7 +20,7 @@ import org.ethereum.manager.WorldManager;
import org.ethereum.net.Command;
import org.ethereum.net.MessageQueue;
import org.ethereum.net.PeerListener;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.ethereum.net.message.DisconnectMessage;
import org.ethereum.net.message.HelloMessage;
import org.ethereum.net.message.Message;
@ -194,7 +194,7 @@ public class PeerProtocolHandler extends ChannelInboundHandlerAdapter {
}
protected void sendPeers() {
Set<PeerData> peers = WorldManager.getInstance().getPeers();
Set<Peer> peers = WorldManager.getInstance().getPeers();
PeersMessage peersMessage = new PeersMessage(peers);
sendMsg(peersMessage);
}

View File

@ -20,11 +20,8 @@ import static org.ethereum.config.SystemProperties.CONFIG;
public class PeerTaster {
private final static Logger logger = LoggerFactory.getLogger("peerdiscovery");
final EthereumPeerTasterHandler handler = new EthereumPeerTasterHandler();
public PeerTaster() {
}
private final PeerProtocolHandler handler = new PeerProtocolHandler();
public void connect(String host, int port) {
logger.debug("connecting: {}:{}", host, port);
@ -34,7 +31,6 @@ public class PeerTaster {
Bootstrap b = new Bootstrap();
b.group(workerGroup);
b.channel(NioSocketChannel.class);
b.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
public void initChannel(NioSocketChannel ch) throws Exception {
@ -43,14 +39,14 @@ public class PeerTaster {
ch.pipeline().addLast(handler);
}
});
// Start the client.
b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONFIG.peerDiscoveryTimeout());
// Start the client.
ChannelFuture f = b.connect(host, port).sync(); // (5)
// Wait until the connection is closed.
f.channel().closeFuture().sync();
logger.debug("connection is closed");
logger.debug("Connection is closed");
} catch (InterruptedException ie) {
logger.info("-- ClientPeer: catch (InterruptedException ie) --");
@ -66,5 +62,4 @@ public class PeerTaster {
public HelloMessage getHandshake() {
return handler.getHandshake();
}
}
}

View File

@ -14,7 +14,7 @@ import java.util.concurrent.ThreadPoolExecutor;
public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler {
private static final Logger logger = LoggerFactory.getLogger("peerdiscovery");
private static final Logger logger = LoggerFactory.getLogger("peerdiscovery");
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

View File

@ -1,6 +1,6 @@
package org.ethereum.net.peerdiscovery;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -16,28 +16,26 @@ public class WorkerThread implements Runnable {
private final static Logger logger = LoggerFactory.getLogger("peerdiscovery");
ThreadPoolExecutor poolExecutor;
private PeerData peerData;
private Peer peerData;
private PeerTaster peerTaster;
public WorkerThread(PeerData peerData, ThreadPoolExecutor poolExecutor) {
public WorkerThread(Peer peerData, ThreadPoolExecutor poolExecutor) {
this.poolExecutor = poolExecutor;
this.peerData = peerData;
}
@Override
public void run() {
logger.info(Thread.currentThread().getName()+" Start. Command = "+ peerData.toString());
logger.info("{} start", Thread.currentThread().getName());
processCommand();
logger.info(Thread.currentThread().getName()+" End.");
logger.info("{} end", Thread.currentThread().getName());
try {Thread.sleep(10000); } catch (InterruptedException e) {logger.error("sleep interrupted");}
poolExecutor.execute(this);
}
private void processCommand() {
try {
peerTaster = new PeerTaster();
peerTaster.connect(peerData.getInetAddress().getHostAddress(), peerData.getPort());
@ -47,9 +45,8 @@ public class WorkerThread implements Runnable {
}
catch (Throwable e) {
if (peerData.isOnline() == true)
logger.info("Peer: [ {} ] got offline, due: [ {} ]",
peerData.getInetAddress().getHostAddress(),
e);
logger.info("Peer: [{}] went offline, due to: [{}]",
peerData.getInetAddress().getHostAddress(), e);
logger.info("Peer: " + peerData.toString() + " isOnline: false");
peerData.setOnline(false);
} finally {

View File

@ -12,6 +12,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -77,7 +78,7 @@ public class SerpentCompiler {
String[] lexaArr = code.split("\\s+");
List<String> lexaList = new ArrayList<String>();
List<String> lexaList = new ArrayList<>();
Collections.addAll(lexaList, lexaArr);
// Encode push_n numbers
@ -134,7 +135,7 @@ public class SerpentCompiler {
}
// calc label pos & remove labels
HashMap<String, Integer> labels = new HashMap<String, Integer>();
Map<String, Integer> labels = new HashMap<>();
for (int i = 0; i < lexaList.size(); ++i) {
@ -164,7 +165,7 @@ public class SerpentCompiler {
String labelNum = ref.split("REF_")[1];
Integer pos = labels.get(labelNum);
int bytesNum = ByteUtil.numBytes( pos.toString() );
int bytesNum = ByteUtil.numBytes(pos.toString());
lexaList.add(i, pos.toString());
@ -178,8 +179,8 @@ public class SerpentCompiler {
for (String lexa : lexaList) {
if (OpCode.contains(lexa))
baos.write( OpCode.byteVal(lexa) );
else{
baos.write(OpCode.byteVal(lexa));
else {
// TODO: support for number more than one byte
baos.write(Integer.parseInt(lexa) & 0xFF);
}

View File

@ -8,6 +8,7 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -19,10 +20,10 @@ import java.util.regex.Pattern;
public class SerpentToAssemblyCompiler extends SerpentBaseVisitor<String> {
private int labelIndex = 0;
private ArrayList<String> vars = new ArrayList<String>();
private List<String> vars = new ArrayList<>();
private HashMap<String, Integer> arraysSize = new HashMap<String, Integer>();
private List<String> arraysIndex = new ArrayList<String>();
private Map<String, Integer> arraysSize = new HashMap<>();
private List<String> arraysIndex = new ArrayList<>();
@Override
public String visitParse(@NotNull SerpentParser.ParseContext ctx) {

View File

@ -133,11 +133,10 @@ public class TrieImpl implements Trie {
* @return value
*/
public byte[] get(byte[] key) {
if(logger.isDebugEnabled()) {
logger.debug("Retrieving key {}", Hex.toHexString(key));
}
if (logger.isDebugEnabled())
logger.debug("Retrieving key {}", Hex.toHexString(key));
byte[] k = binToNibbles(key);
Value c = new Value( this.get(this.root, k) );
Value c = new Value(this.get(this.root, k));
return (c == null)? null : c.asBytes();
}
@ -468,11 +467,11 @@ public class TrieImpl implements Trie {
this.getCache().delete(key.getData());
if (logger.isTraceEnabled())
logger.trace("Garbage collected node: [ {} ]",
Hex.toHexString( key.getData() ));
logger.trace("Garbage collected node: [{}]",
Hex.toHexString(key.getData()));
}
logger.info("Garbage collected node list, size: [ {} ]", toRemoveSet.size());
logger.info("Garbage collection time: [ {}ms ]", System.currentTimeMillis() - startTime);
logger.info("Garbage collected node list, size: [{}]", toRemoveSet.size());
logger.info("Garbage collection time: [{}ms]", System.currentTimeMillis() - startTime);
}
public void scanTree(byte[] hash, ScanAction scanAction) {

View File

@ -33,7 +33,7 @@ public class TrieIterator {
this.workNode(currentNode.get(1));
} else {
if (k[k.length-1] == 16) {
this.values.add( currentNode.get(1).asString() );
this.values.add(currentNode.get(1).asString());
} else {
this.shas.add(currentNode.get(1).asBytes());
this.getNode(currentNode.get(1).asBytes());
@ -42,7 +42,7 @@ public class TrieIterator {
} else {
for (int i = 0; i < currentNode.length(); i++) {
if (i == 16 && currentNode.get(i).length() != 0) {
this.values.add( currentNode.get(i).asString() );
this.values.add(currentNode.get(i).asString());
} else {
if (currentNode.get(i).asString() == "") {
this.workNode(currentNode.get(i));

View File

@ -22,8 +22,8 @@ public class ByteUtil {
}
/**
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: it appends a
* leading zero to indicate that the number is positive and may need padding.
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need:
* it appends a leading zero to indicate that the number is positive and may need padding.
*
* @param b the integer to format into a byte array
* @param numBytes the desired size of the resulting byte array
@ -41,10 +41,10 @@ public class ByteUtil {
}
/**
* emitting sign indication byte
* Omitting sign indication byte
*
* @param b - any big integer number
* @return
* @return a byte array representation of this number without a sign byte
*/
public static byte[] bigIntegerToBytes(BigInteger b) {
if (b == null)
@ -84,7 +84,7 @@ public class ByteUtil {
}
public static String toHexString(byte[] data) {
if (data == null) return "null";
if (data == null) return "";
else return Hex.toHexString(data);
}
@ -129,11 +129,17 @@ public class ByteUtil {
public static String nibblesToPrettyString(byte[] nibbles){
StringBuffer buffer = new StringBuffer();
for (byte nibble : nibbles) {
String nibleString = Utils.oneByteToHexString(nibble);
String nibleString = oneByteToHexString(nibble);
buffer.append("\\x" + nibleString);
}
return buffer.toString();
}
public static String oneByteToHexString(byte value) {
String retVal = Integer.toString(value & 0xFF, 16);
if (retVal.length() == 1) retVal = "0" + retVal;
return retVal;
}
/**
* Calculate the number of bytes need
@ -154,6 +160,22 @@ public class ByteUtil {
if (bytes == 0) ++bytes;
return bytes;
}
/**
* Convert an array of byte arrays to a single string
* <br/>
* Example: "eth" or "eth shh bzz"
*
* @return byte arrays as String
*/
public static String toString(byte[][] arrays) {
StringBuilder sb = new StringBuilder();
for (byte[] array : arrays) {
sb.append(new String(array)).append(" ");
}
if(sb.length() > 0) sb.deleteCharAt(sb.length()-1);
return sb.toString();
}
/**
* @param arg - not more that 32 bits

View File

@ -627,7 +627,7 @@ public class RLP {
// It's an item less than 55 bytes long,
// data[0] - 0x80 == length of the item
if ((msgData[pos] & 0xFF) > OFFSET_SHORT_ITEM
&& (msgData[pos] & 0xFF) < OFFSET_LONG_ITEM) {
&& (msgData[pos] & 0xFF) <= OFFSET_LONG_ITEM) {
byte length = (byte) ((msgData[pos] & 0xFF) - OFFSET_SHORT_ITEM);
@ -706,7 +706,7 @@ public class RLP {
}
private static DecodeResult decodeList(byte[] data, int pos, int prevPos, int len) {
List<Object> slice = new ArrayList<Object>();
List<Object> slice = new ArrayList<>();
for (int i = 0; i < len;) {
// Get the next item in the data list and append it
DecodeResult result = decode(data, pos);
@ -825,12 +825,10 @@ public class RLP {
public static byte[] encodeElement(byte[] srcData) {
if ( srcData == null ||
(srcData.length == 1 && srcData[0] == 0) ) {
(srcData.length == 1 && srcData[0] == 0)) {
return new byte[]{(byte) 0x80};
} if (srcData.length == 1 && (srcData[0] & 0xFF) < 0x80) {
return srcData;
} else if (srcData.length < SIZE_THRESHOLD) {
// length = 8X
byte length = (byte) (OFFSET_SHORT_ITEM + srcData.length);

View File

@ -119,13 +119,6 @@ public class Utils {
return Double.parseDouble (version.substring (0, pos - 1));
}
public static String oneByteToHexString(byte value) {
String retVal = Integer.toString(value & 0xFF, 16);
if (retVal.length() == 1) retVal = "0" + retVal;
return retVal;
}
public static String getFromUrl(String urlToRead) {
URL url;
HttpURLConnection conn;

View File

@ -263,9 +263,9 @@ public class Value {
output.append("'");
for (byte oneByte : asBytes()) {
if (oneByte < 16) {
output.append("\\x").append(Utils.oneByteToHexString(oneByte));
output.append("\\x").append(ByteUtil.oneByteToHexString(oneByte));
} else {
output.append( Character.valueOf((char)oneByte) );
output.append(Character.valueOf((char)oneByte));
}
}
output.append("'");
@ -278,17 +278,16 @@ public class Value {
return "Unexpected type";
}
public int countYourBranchNodes(){
if (this.isList()){
public int countBranchNodes() {
if (this.isList()) {
List<Object> objList = this.asList();
int i = 0;
for (Object obj : objList){
i += (new Value(obj)).countYourBranchNodes();
for (Object obj : objList) {
i += (new Value(obj)).countBranchNodes();
}
return i;
} else if (this.isBytes()){
} else if (this.isBytes()) {
this.asBytes();
}
return 0;

View File

@ -312,8 +312,8 @@ public enum OpCode {
private byte opcode;
private static final Map<Byte, OpCode> intToTypeMap = new HashMap<Byte, OpCode>();
private static final Map<String, Byte> stringToByteMap = new HashMap<String, Byte>();
private static final Map<Byte, OpCode> intToTypeMap = new HashMap<>();
private static final Map<String, Byte> stringToByteMap = new HashMap<>();
static {
for (OpCode type : OpCode.values()) {

View File

@ -4,7 +4,6 @@ import org.ethereum.crypto.HashUtil;
import org.ethereum.db.ContractDetails;
import org.ethereum.facade.Repository;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.Utils;
import org.ethereum.vm.MessageCall.MsgType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -257,7 +256,7 @@ public class Program {
DataWord balance = getBalance(this.getOwnerAddress());
// 1) pass full endowment to the obtainer
if (logger.isInfoEnabled())
logger.info("Transfer to: [ {} ] heritage: [ {} ]",
logger.info("Transfer to: [{}] heritage: [{}]",
Hex.toHexString(obtainer.getLast20Bytes()),
balance.longValue());
@ -342,7 +341,7 @@ public class Program {
this.refundGas(refundGas, "remain gas from the internal call");
if (logger.isInfoEnabled()){
logger.info("The remaining gas is refunded, account: [ {} ], gas: [ {} ] ",
logger.info("The remaining gas is refunded, account: [{}], gas: [{}] ",
Hex.toHexString(this.getOwnerAddress().getLast20Bytes()),
refundGas);
}
@ -374,7 +373,7 @@ public class Program {
byte[] programCode = this.result.getRepository().getCode(codeAddress);
if (logger.isInfoEnabled())
logger.info(msg.getType().name() + " for existing contract: address: [ {} ], outDataOffs: [ {} ], outDataSize: [ {} ] ",
logger.info(msg.getType().name() + " for existing contract: address: [{}], outDataOffs: [{}], outDataSize: [{}] ",
Hex.toHexString(contextAddress), msg.getOutDataOffs().longValue(), msg.getOutDataSize().longValue());
// 2.1 PERFORM THE GAS VALUE TX
@ -465,7 +464,7 @@ public class Program {
if (refundGas.compareTo(BigInteger.ZERO) == 1) {
this.refundGas(refundGas.intValue(), "remaining gas from the internal call");
logger.info("The remaining gas refunded, account: [ {} ], gas: [ {} ] ",
logger.info("The remaining gas refunded, account: [{}], gas: [{}] ",
Hex.toHexString(senderAddress), refundGas.toString());
}
} else {
@ -474,7 +473,7 @@ public class Program {
}
public void spendGas(long gasValue, String cause) {
gasLogger.info("[{}] Spent for cause: [ {} ], gas: [ {} ]", invokeHash, cause, gasValue);
gasLogger.info("[{}] Spent for cause: [{}], gas: [{}]", invokeHash, cause, gasValue);
long afterSpend = invokeData.getGas().longValue() - gasValue - result.getGasUsed();
if (afterSpend < 0)
@ -483,7 +482,7 @@ public class Program {
}
public void refundGas(long gasValue, String cause) {
gasLogger.info("[{}] Refund for cause: [ {} ], gas: [ {} ]", invokeHash, cause, gasValue);
gasLogger.info("[{}] Refund for cause: [{}], gas: [{}]", invokeHash, cause, gasValue);
result.refundGas(gasValue);
}
@ -606,7 +605,7 @@ public class Program {
// Check if value is ASCII
String character = ((byte) 0x20 <= value && value <= (byte) 0x7e) ? new String(new byte[] { value }) : "?";
firstLine.append(character).append("");
secondLine.append(Utils.oneByteToHexString(value)).append(" ");
secondLine.append(ByteUtil.oneByteToHexString(value)).append(" ");
if ((i + 1) % 8 == 0) {
String tmp = String.format("%4s", Integer.toString(i - 7, 16)).replace(" ", "0");
@ -650,7 +649,7 @@ public class Program {
for (int i = 0; memory != null && i < memory.limit(); ++i) {
byte value = memory.get(i);
oneLine.append(Utils.oneByteToHexString(value)).append(" ");
oneLine.append(ByteUtil.oneByteToHexString(value)).append(" ");
if ((i + 1) % 16 == 0) {
String tmp = String.format("[%4s]-[%4s]", Integer.toString(i - 15, 16),
@ -682,7 +681,7 @@ public class Program {
logger.trace(" -- STACK -- {}", stackData);
logger.trace(" -- MEMORY -- {}", memoryData);
logger.trace(" -- STORAGE -- {}\n", storageData);
logger.trace("\n Spent Gas: [ {} ]/[ {} ]\n Left Gas: [ {} ]\n",
logger.trace("\n Spent Gas: [{}]/[{}]\n Left Gas: [{}]\n",
result.getGasUsed(),
invokeData.getGas().longValue(),
getGas().longValue());

View File

@ -970,12 +970,12 @@ public class VM {
vmCounter++;
} catch (RuntimeException e) {
if(e instanceof OutOfGasException)
logger.warn("OutOfGasException occurred", e);
else
if(e instanceof OutOfGasException)
logger.warn("OutOfGasException occurred", e);
else
logger.error("VM halted", e);
program.stop();
throw e;
program.stop();
throw e;
}
}

View File

@ -66,13 +66,13 @@ public class TransactionTest {
System.out.println("r\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().r)));
System.out.println("s\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().s)));
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString( tx.getEncoded() ));
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString(tx.getEncoded()));
// retrieve the signer/sender of the transaction
ECKey key = ECKey.signatureToKey(tx.getHash(), tx.getSignature().toBase64());
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString( tx.getEncodedRaw()));
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString( tx.getEncoded() ));
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString(tx.getEncodedRaw()));
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString(tx.getEncoded()));
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
@ -107,13 +107,13 @@ public class TransactionTest {
System.out.println("r\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().r)));
System.out.println("s\t\t\t: " + Hex.toHexString(BigIntegers.asUnsignedByteArray(tx.getSignature().s)));
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString( tx.getEncoded() ));
System.out.println("RLP encoded tx\t\t: " + Hex.toHexString(tx.getEncoded()));
// retrieve the signer/sender of the transaction
ECKey key = ECKey.signatureToKey(tx.getHash(), tx.getSignature().toBase64());
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString( tx.getEncodedRaw()));
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString( tx.getEncoded() ));
System.out.println("Tx unsigned RLP\t\t: " + Hex.toHexString(tx.getEncodedRaw()));
System.out.println("Tx signed RLP\t\t: " + Hex.toHexString(tx.getEncoded()));
System.out.println("Signature public key\t: " + Hex.toHexString(key.getPubKey()));
System.out.println("Sender is\t\t: " + Hex.toHexString(key.getAddress()));
@ -252,17 +252,17 @@ public class TransactionTest {
Transaction tx2 = new Transaction(payload);
// tx2.getSender();
String plainTx1 = Hex.toHexString( tx1.getEncodedRaw() );
String plainTx2 = Hex.toHexString( tx2.getEncodedRaw() );
String plainTx1 = Hex.toHexString(tx1.getEncodedRaw());
String plainTx2 = Hex.toHexString(tx2.getEncodedRaw());
// Transaction tx = new Transaction(Hex.decode(rlp));
System.out.println("tx1.hash: " + Hex.toHexString( tx1.getHash() ));
System.out.println("tx2.hash: " + Hex.toHexString( tx2.getHash() ));
System.out.println("tx1.hash: " + Hex.toHexString(tx1.getHash()));
System.out.println("tx2.hash: " + Hex.toHexString(tx2.getHash()));
System.out.println();
System.out.println("plainTx1: " + plainTx1 );
System.out.println("plainTx2: " + plainTx2 );
System.out.println( Hex.toHexString( tx2.getSender() ));
System.out.println( Hex.toHexString(tx2.getSender()));
}
}

View File

@ -16,7 +16,7 @@ import org.iq80.leveldb.WriteOptions;
public class MockDB implements DB {
Map<ByteArrayWrapper, byte[]> storage = new HashMap<ByteArrayWrapper, byte[]>();
Map<ByteArrayWrapper, byte[]> storage = new HashMap<>();
@Override
public void close() throws IOException {

View File

@ -38,11 +38,11 @@ public class JSONTestSuiteTest {
String expectedBalance = "0de0b6b3a763ff6c";
String expectedCode = "6000600060006000604a3360c85c03f1";
ByteArrayWrapper expectedKey1 = new ByteArrayWrapper( Hex.decode("ffaa") );
ByteArrayWrapper expectedKey2 = new ByteArrayWrapper( Hex.decode("ffab") );
ByteArrayWrapper expectedKey1 = new ByteArrayWrapper(Hex.decode("ffaa"));
ByteArrayWrapper expectedKey2 = new ByteArrayWrapper(Hex.decode("ffab"));
ByteArrayWrapper expectedVal1 = new ByteArrayWrapper( Hex.decode("c8") );
ByteArrayWrapper expectedVal2 = new ByteArrayWrapper( Hex.decode("b2b2b2") );
ByteArrayWrapper expectedVal1 = new ByteArrayWrapper(Hex.decode("c8"));
ByteArrayWrapper expectedVal2 = new ByteArrayWrapper(Hex.decode("b2b2b2"));
JSONParser parser = new JSONParser();
String accountString = "{'balance':999999999999999852,'nonce':1," +
@ -60,10 +60,10 @@ public class JSONTestSuiteTest {
Assert.assertEquals(expectedBalance, Hex.toHexString(state.balance));
Assert.assertEquals(expectedCode, Hex.toHexString(state.code));
Assert.assertTrue( state.storage.keySet().contains(expectedKey1) );
Assert.assertTrue(state.storage.keySet().contains(expectedKey1));
Assert.assertTrue(state.storage.keySet().contains(expectedKey2));
Assert.assertTrue( state.storage.values().contains(expectedVal1) );
Assert.assertTrue(state.storage.values().contains(expectedVal1));
Assert.assertTrue(state.storage.values().contains(expectedVal2));
}
@ -130,11 +130,11 @@ public class JSONTestSuiteTest {
Env env = new Env(envJSONObj);
Assert.assertEquals(expectedCurrentCoinbase, Hex.toHexString(env.getCurrentCoinbase()));
Assert.assertEquals(expectedCurrentDifficulty, new BigInteger( env.getCurrentDifficlty()).toString());
Assert.assertEquals(expectedCurrentGasLimit, new BigInteger( env.getCurrentGasLimit()).toString());
Assert.assertEquals(expectedCurrentNumber, new BigInteger( env.getCurrentNumber()).toString());
Assert.assertEquals(expectedCurrentTimestamp, new BigInteger( env.getCurrentTimestamp()).toString());
Assert.assertEquals(expectedCurrentCoinbase, Hex.toHexString(env.getCurrentCoinbase()));
Assert.assertEquals(expectedCurrentDifficulty, new BigInteger(env.getCurrentDifficlty()).toString());
Assert.assertEquals(expectedCurrentGasLimit, new BigInteger(env.getCurrentGasLimit()).toString());
Assert.assertEquals(expectedCurrentNumber, new BigInteger(env.getCurrentNumber()).toString());
Assert.assertEquals(expectedCurrentTimestamp, new BigInteger(env.getCurrentTimestamp()).toString());
Assert.assertEquals(expectedPreviousHash, Hex.toHexString(env.getPreviousHash()));
}

File diff suppressed because one or more lines are too long

View File

@ -4,8 +4,6 @@ import static org.junit.Assert.assertEquals;
import org.ethereum.net.message.DisconnectMessage;
import org.ethereum.net.message.ReasonCode;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
@ -13,27 +11,25 @@ public class DisconnectMessageTest {
/* DISCONNECT_MESSAGE */
@Test /* DisconnectMessage 1 */
public void test_3() {
@Test /* DisconnectMessage 1 - Requested */
public void test_1() {
String disconnectMessageRaw = "C20100";
byte[] payload = Hex.decode(disconnectMessageRaw);
RLPList rlpList = RLP.decode2(payload);
DisconnectMessage disconnectMessage = new DisconnectMessage(rlpList);
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
System.out.println(disconnectMessage);
assertEquals(disconnectMessage.getReason(), ReasonCode.REQUESTED);
}
@Test /* DisconnectMessage 2 */
public void test_4() {
@Test /* DisconnectMessage 2 - TCP Error */
public void test_2() {
String disconnectMessageRaw = "C20101";
byte[] payload = Hex.decode(disconnectMessageRaw);
RLPList rlpList = RLP.decode2(payload);
DisconnectMessage disconnectMessage = new DisconnectMessage(rlpList);
DisconnectMessage disconnectMessage = new DisconnectMessage(payload);
System.out.println(disconnectMessage);
assertEquals(disconnectMessage.getReason(), ReasonCode.TCP_ERROR);

View File

@ -2,9 +2,11 @@ package org.ethereum.net;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.ethereum.net.message.HelloMessage;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
@ -12,51 +14,76 @@ public class HelloMessageTest {
/* HELLO_MESSAGE */
@Test /* HelloMessage 1 */
public void test_1() {
String helloMessageRaw = "F8 77 80 0C 80 AD 45 74 " +
"68 65 72 65 75 6D 28 2B 2B 29 2F 5A 65 72 6F 47 " +
"6F 78 2F 76 30 2E 35 2E 31 2F 6E 63 75 72 73 65 " +
"73 2F 4C 69 6E 75 78 2F 67 2B 2B 07 82 76 5F B8 " +
"40 D8 83 3B 83 56 0E 0B 12 17 0E 91 69 DC 43 78 " +
"42 23 A5 98 42 DE 23 59 E6 D0 3D B3 4C 30 A9 66 " +
"C2 DE 3B 4B 25 52 FB 0D 75 95 A1 85 D5 58 F2 E6 " +
"69 B5 95 67 4F 52 17 C9 96 EE 14 88 84 82 8B E0 FD";
@Test /* HelloMessage 1 from PeerServer */
public void testPeer() {
String helloMessageRaw = "F8 80 80 80 B7 45 74 68 " +
"65 72 65 75 6D 28 2B 2B 29 2F 50 65 65 72 20 53 " +
"65 72 76 65 72 20 5A 65 72 6F 2F 76 30 2E 36 2E " +
"38 64 2F 52 65 6C 65 61 73 65 2F 4C 69 6E 75 78 " +
"2F 67 2B 2B C0 82 76 5F B8 40 20 17 B9 5D 55 86 " +
"AD D0 53 E7 C5 DC C8 11 2D B1 D5 57 ED 83 58 9C " +
"4E 0B D2 54 42 F3 9E 41 11 65 5A 48 72 57 AA 7E " +
"4E D3 09 E8 B4 D5 5B E5 FA 8D 8D 6E 97 B7 2C 67 " +
"D7 6A A0 3E B6 9A D9 81 ED 60";
byte[] payload = Hex.decode(helloMessageRaw);
RLPList rlpList = RLP.decode2(payload);
HelloMessage helloMessage = new HelloMessage(rlpList);
helloMessage.parseRLP();
HelloMessage helloMessage = new HelloMessage(payload);
System.out.println(helloMessage);
assertEquals(12, helloMessage.getP2PVersion());
assertEquals("Ethereum(++)/ZeroGox/v0.5.1/ncurses/Linux/g++", helloMessage.getClientId());
assertEquals(7, helloMessage.getCapabilities());
assertEquals(0, helloMessage.getP2PVersion());
assertEquals("Ethereum(++)/Peer Server Zero/v0.6.8d/Release/Linux/g++", helloMessage.getClientId());
assertEquals(0, helloMessage.getCapabilities().size());
assertEquals(30303, helloMessage.getListenPort());
assertEquals(
"D8833B83560E0B12170E9169DC43784223A59842DE2359E6D03DB34C30A966C2DE3B4B2552FB0D7595A185D558F2E669B595674F5217C996EE148884828BE0FD",
Hex.toHexString(helloMessage.getPeerId()).toUpperCase() );
"2017B95D5586ADD053E7C5DCC8112DB1D557ED83589C4E0BD25442F39E4111655A487257AA7E4ED309E8B4D55BE5FA8D8D6E97B72C67D76AA03EB69AD981ED60",
Hex.toHexString(helloMessage.getPeerId()).toUpperCase());
}
@Test /* HelloMessage 2 */
public void test_2() {
String helloMessageRaw = "F87F800B80B5457468657265756D282B2B292F76302E342E332F4554485F4255494C445F545950452F4554485F4255494C445F504C4154464F524D0782765FB840E02B18FBA6B887FB9258469C3AF8E445CC9AE2B5386CAC5F60C4170F822086224E3876555C745A7EC8AC181C7F9701776D94A779604EA12651DE5F4A748D29E1";
@Test /* HelloMessage 2 from Node */
public void testNode() {
String helloMessageRaw = "F8 7B 80 80 AE 4E 45 74 68 65 72 65 "
+ "75 6D 28 2B 2B 29 2F 5A 65 72 6F 47 6F 78 2F 76 30 "
+ "2E 36 2E 39 2F 6E 63 75 72 73 65 73 2F 4C 69 6E 75 "
+ "78 2F 67 2B 2B C4 83 65 74 68 82 76 5F B8 40 CA DF "
+ "B9 3D 2B B5 FB E2 94 35 84 D9 3E D9 0E 37 46 67 C9 "
+ "E8 B2 50 2E 97 46 93 CC C6 B3 D3 70 BD 4C DE 77 38 "
+ "D0 B6 26 E3 D2 F3 CA EC C5 9E 13 02 D1 71 1B F5 95 "
+ "71 10 60 D7 B4 92 1E 18 B9 76 56";
byte[] payload = Hex.decode(helloMessageRaw);
RLPList rlpList = RLP.decode2(payload);
HelloMessage helloMessage = new HelloMessage(rlpList);
helloMessage.parseRLP();
HelloMessage helloMessage = new HelloMessage(payload);
helloMessage.parse();
System.out.println(helloMessage);
assertEquals(11, helloMessage.getP2PVersion());
assertEquals("Ethereum(++)/v0.4.3/ETH_BUILD_TYPE/ETH_BUILD_PLATFORM", helloMessage.getClientId());
assertEquals(7, helloMessage.getCapabilities());
assertEquals(0, helloMessage.getP2PVersion());
assertEquals("NEthereum(++)/ZeroGox/v0.6.9/ncurses/Linux/g++", helloMessage.getClientId());
assertEquals(1, helloMessage.getCapabilities().size());
assertEquals("eth", helloMessage.getCapabilities().get(0));
assertEquals(30303, helloMessage.getListenPort());
assertEquals(
"E02B18FBA6B887FB9258469C3AF8E445CC9AE2B5386CAC5F60C4170F822086224E3876555C745A7EC8AC181C7F9701776D94A779604EA12651DE5F4A748D29E1",
Hex.toHexString(helloMessage.getPeerId()).toUpperCase() );
assertEquals("cadfb93d2bb5fbe2943584d93ed90e374667c9e8b2502e974693ccc6b3d370bd4cde7738d0b626e3d2f3caecc59e1302d1711bf595711060d7b4921e18b97656",
Hex.toHexString(helloMessage.getPeerId()));
}
@Test /* HelloMessage 3 from new */
public void testFromNew() {
String helloAnnouncement = "Ethereum(J)/0.6.0/dev/Windows/Java";
byte p2pVersion = 0x00;
List<String> capabilities = new ArrayList<>(Arrays.asList("eth", "shh"));
short listenPort = (short) 30303;
byte[] peerIdBytes = Hex.decode("CAB0D93EEE1F44EF1286367101F1553450E3DDCE"
+ "EA45ABCAB0AC21E1EFB48A6610EBE88CE7317EB09229558311BA8B7250911D"
+ "7E49562C3988CA3143329DA3EA");
HelloMessage helloMessage = new HelloMessage(p2pVersion, helloAnnouncement,
capabilities, listenPort, peerIdBytes);
System.out.println(helloMessage);
// rlp encoded hello message
String expected = "F8738080A2457468657265756D284A292F302E362E302F6465762F5"
+ "7696E646F77732F4A617661C8836574688373686882765FB840CAB0D93EEE1F"
+ "44EF1286367101F1553450E3DDCEEA45ABCAB0AC21E1EFB48A6610EBE88CE73"
+ "17EB09229558311BA8B7250911D7E49562C3988CA3143329DA3EA";
assertEquals(expected, Hex.toHexString(helloMessage.getEncoded()).toUpperCase());
}
}

View File

@ -2,59 +2,98 @@ package org.ethereum.net;
import static org.junit.Assert.assertEquals;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.ethereum.net.message.GetPeersMessage;
import org.ethereum.net.message.PeersMessage;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
public class PeersMessageTest {
/* GET_PEERS */
@Test /* GetPeersMessage */
public void testGetPeers() {
GetPeersMessage getPeersMessage = new GetPeersMessage();
System.out.println(getPeersMessage);
assertEquals(PeersMessage.class, getPeersMessage.getAnswerMessage());
}
/* PEERS */
@Test /* PeersMessage 1*/
public void test_5() {
@Test /* PeersMessage 1 from RLP */
public void testPeers_1() {
String peersMessageRaw = "F89911F84A84364845B482765FB840430BB21ECF73A54AEF511404948C016532406B371EDABD20A478C3ECD22052A0065A7399A6D19594E24B153930E63A3B12B3BA4F30A3CDA1977D60D4060FFF25F84A845163E11282765FB8405F1DBE5E50E92A6B67377E079D986155C0D82D964E65332F524810ED7831A52837F1C0FB042EA2A25548E3B444C337F54C7547B2D877734E2899F40BFA23ED51";
String peersMessageRaw = "F8 99 05 F8 4A 84 36 48 45 B4 82 76 "
+ "5F B8 40 43 0B B2 1E CF 73 A5 4A EF 51 14 04 94 8C "
+ "01 65 32 40 6B 37 1E DA BD 20 A4 78 C3 EC D2 20 52 "
+ "A0 06 5A 73 99 A6 D1 95 94 E2 4B 15 39 30 E6 3A 3B "
+ "12 B3 BA 4F 30 A3 CD A1 97 7D 60 D4 06 0F FF 25 F8 "
+ "4A 84 51 63 E1 12 82 76 5F B8 40 5F 1D BE 5E 50 E9 "
+ "2A 6B 67 37 7E 07 9D 98 61 55 C0 D8 2D 96 4E 65 33 "
+ "2F 52 48 10 ED 78 31 A5 28 37 F1 C0 FB 04 2E A2 A2 "
+ "55 48 E3 B4 44 C3 37 F5 4C 75 47 B2 D8 77 73 4E 28 "
+ "99 F4 0B FA 23 ED 51";
byte[] payload = Hex.decode(peersMessageRaw);
RLPList rlpList = RLP.decode2(payload);
PeersMessage peersMessage= new PeersMessage(rlpList);
PeersMessage peersMessage= new PeersMessage(payload);
System.out.println(peersMessage);
assertEquals(2, peersMessage.getPeers().size());
Iterator<PeerData> it = peersMessage.getPeers().iterator(); it.next();
PeerData peerData = it.next();
Iterator<Peer> it = peersMessage.getPeers().iterator(); it.next();
Peer peerData = it.next();
assertEquals("/81.99.225.18", peerData.getInetAddress().toString());
assertEquals(30303, peerData.getPort());
assertEquals("5F1DBE5E50E92A6B67377E079D986155C0D82D964E65332F524810ED7831A52837F1C0FB042EA2A25548E3B444C337F54C7547B2D877734E2899F40BFA23ED51",
Hex.toHexString( peerData.getPeerId() ).toUpperCase());
Hex.toHexString(peerData.getPeerId()).toUpperCase());
}
@Test /* PeersMessage 2 from constructor */
public void testPeers_2() throws UnknownHostException {
Set<Peer> peers = new HashSet<>();
peers.add(new Peer(InetAddress.getByName("82.217.72.169").getAddress(), 30303, Hex.decode("585764a3c49a3838c69ad0855abfeb5672f71b072af62082b5679961781100814b8de88a8fbc1da7c73791f88159d73b5d2a13a5579535d603e045c3db5cbb75")));
peers.add(new Peer(InetAddress.getByName("192.168.1.193").getAddress(), 30303, new byte[0]));
PeersMessage peersMessage = new PeersMessage(peers);
System.out.println(peersMessage.toString());
@Test /* Peers msg parsing performance*/
public void test_7() throws UnknownHostException {
String expected = "f85905f84b8452d948a982765fb840585764a3c49a3838c69ad0855abfeb5672f71b072af62082b5679961781100814b8de88a8fbc1da7c73791f88159d73b5d2a13a5579535d603e045c3db5cbb75c0ca84c0a801c182765f80c0";
assertEquals(expected, Hex.toHexString(peersMessage.getEncoded()));
}
@Test /* Peers msg parsing performance */
public void testPeersPerformance() throws UnknownHostException {
long time1 = System.currentTimeMillis();
for (int i = 0; i < 20000; ++i) {
String peersPacketRaw = "F89911F84A84364845B482765FB840430BB21ECF73A54AEF511404948C016532406B371EDABD20A478C3ECD22052A0065A7399A6D19594E24B153930E63A3B12B3BA4F30A3CDA1977D60D4060FFF25F84A845163E11282765FB8405F1DBE5E50E92A6B67377E079D986155C0D82D964E65332F524810ED7831A52837F1C0FB042EA2A25548E3B444C337F54C7547B2D877734E2899F40BFA23ED51";
String peersPacketRaw = "F8 99 05 F8 4A 84 36 48 45 B4 82 76 "
+ "5F B8 40 43 0B B2 1E CF 73 A5 4A EF 51 14 04 94 "
+ "8C 01 65 32 40 6B 37 1E DA BD 20 A4 78 C3 EC D2 "
+ "20 52 A0 06 5A 73 99 A6 D1 95 94 E2 4B 15 39 30 "
+ "E6 3A 3B 12 B3 BA 4F 30 A3 CD A1 97 7D 60 D4 06 "
+ "0F FF 25 F8 4A 84 51 63 E1 12 82 76 5F B8 40 5F "
+ "1D BE 5E 50 E9 2A 6B 67 37 7E 07 9D 98 61 55 C0 "
+ "D8 2D 96 4E 65 33 2F 52 48 10 ED 78 31 A5 28 37 "
+ "F1 C0 FB 04 2E A2 A2 55 48 E3 B4 44 C3 37 F5 4C "
+ "75 47 B2 D8 77 73 4E 28 99 F4 0B FA 23 ED 51";
byte[] payload = Hex.decode(peersPacketRaw);
RLPList rlpList = RLP.decode2(payload);
PeersMessage peersMessage = new PeersMessage(rlpList);
peersMessage.parseRLP();
PeersMessage peersMessage = new PeersMessage(payload);
peersMessage.parse();
}
long time2 = System.currentTimeMillis();
System.out.println("20,000 PEERS packets parsing: " + (time2 - time1) + "(msec)");
}
}
}

View File

@ -2,7 +2,6 @@ package org.ethereum.net;
import static org.junit.Assert.assertEquals;
import org.ethereum.net.message.HelloMessage;
import org.ethereum.net.message.StatusMessage;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
@ -10,47 +9,41 @@ import org.spongycastle.util.encoders.Hex;
public class StatusMessageTest {
/* STATUS_MESSAGE */
@Test /* StatusMessage 1 from PeerServer */
public void testPeer() {
@Test /* StatusMessage 1 from network */
public void test_1() {
String statusMessageRaw = "";
byte[] payload = Hex.decode(statusMessageRaw);
StatusMessage statusMessage = new StatusMessage(payload);
System.out.println(statusMessage);
assertEquals(0, statusMessage.getGenesisHash());
assertEquals(0, statusMessage.getNetworkId());
assertEquals(0, statusMessage.getProtocolVersion());
assertEquals(0, statusMessage.getTotalDifficulty());
assertEquals(0, statusMessage.getBestHash());
assertEquals(0, statusMessage.getNetworkId());
assertEquals("", Hex.toHexString(statusMessage.getTotalDifficulty()));
assertEquals("", Hex.toHexString(statusMessage.getBestHash()));
assertEquals("", Hex.toHexString(statusMessage.getGenesisHash()));
}
@Test /* HelloMessage 2 from Node */
public void testNode() {
String helloMessageRaw = "F8 80 80 80 B7 45 74 68 " +
"65 72 65 75 6D 28 2B 2B 29 2F 50 65 65 72 20 53 " +
"65 72 76 65 72 20 5A 65 72 6F 2F 76 30 2E 36 2E " +
"38 64 2F 52 65 6C 65 61 73 65 2F 4C 69 6E 75 78 " +
"2F 67 2B 2B C0 82 76 5F B8 40 20 17 B9 5D 55 86 " +
"AD D0 53 E7 C5 DC C8 11 2D B1 D5 57 ED 83 58 9C " +
"4E 0B D2 54 42 F3 9E 41 11 65 5A 48 72 57 AA 7E " +
"4E D3 09 E8 B4 D5 5B E5 FA 8D 8D 6E 97 B7 2C 67 " +
"D7 6A A0 3E B6 9A D9 81 ED 60";
@Test /* StatusMessage 1 from new */
public void test_2() {
byte protocolVersion = 0, networkId = 0;
byte[] totalDifficulty = Hex.decode("ff");
byte[] bestHash = Hex.decode("ff");
byte[] genesisHash = Hex.decode("ff");
byte[] payload = Hex.decode(helloMessageRaw);
HelloMessage helloMessage = new HelloMessage(payload);
helloMessage.parse();
System.out.println(helloMessage);
assertEquals(0, helloMessage.getP2PVersion());
assertEquals("Ethereum(++)/Nick/v0.6.8d/Release/Linux/g++", helloMessage.getClientId());
assertEquals(3, helloMessage.getCapabilities().size());
assertEquals(30303, helloMessage.getListenPort());
assertEquals(
"2017B95D5586ADD053E7C5DCC8112DB1D557ED83589C4E0BD25442F39E4111655A487257AA7E4ED309E8B4D55BE5FA8D8D6E97B72C67D76AA03EB69AD981ED60",
Hex.toHexString(helloMessage.getPeerId()).toUpperCase() );
StatusMessage statusMessage = new StatusMessage(protocolVersion,
networkId, totalDifficulty, bestHash, genesisHash);
System.out.println(statusMessage);
String expected = "ff";
assertEquals(expected, statusMessage.getEncoded());
assertEquals(0, statusMessage.getProtocolVersion());
assertEquals(0, statusMessage.getNetworkId());
assertEquals("", Hex.toHexString(statusMessage.getTotalDifficulty()));
assertEquals("", Hex.toHexString(statusMessage.getBestHash()));
assertEquals("", Hex.toHexString(statusMessage.getGenesisHash()));
}
}

View File

@ -12,8 +12,6 @@ import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.message.TransactionsMessage;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.RLP;
import org.ethereum.util.RLPList;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
@ -22,7 +20,7 @@ public class TransactionsMessageTest {
/* TRANSACTIONS */
@Test /* Transactions message 1 */
public void test_8() {
public void test_1() {
String txsPacketRaw = "f86e12f86b04648609184e72a00094cd2a3d9f938e13cd947ec05abc7fe734df8dd826"
+ "881bc16d674ec80000801ba05c89ebf2b77eeab88251e553f6f9d53badc1d800"
@ -30,9 +28,8 @@ public class TransactionsMessageTest {
+ "daa3653a8d9f424c6a3265f06c";
byte[] payload = Hex.decode(txsPacketRaw);
RLPList rlpList = RLP.decode2(payload);
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
TransactionsMessage transactionsMessage = new TransactionsMessage(payload);
System.out.println(transactionsMessage);
assertEquals(1, transactionsMessage.getTransactions().size());
@ -45,7 +42,7 @@ public class TransactionsMessageTest {
assertEquals("cd2a3d9f938e13cd947ec05abc7fe734df8dd826", Hex.toHexString(tx.getReceiveAddress()));
assertEquals("64", Hex.toHexString(tx.getGasPrice()));
assertEquals("09184e72a000", Hex.toHexString(tx.getGasLimit()));
assertEquals("null", ByteUtil.toHexString(tx.getData()));
assertEquals("", ByteUtil.toHexString(tx.getData()));
assertEquals("1b", Hex.toHexString(new byte[] { tx.getSignature().v }));
assertEquals("5c89ebf2b77eeab88251e553f6f9d53badc1d800bbac02d830801c2aa94a4c9f", Hex.toHexString(tx.getSignature().r.toByteArray()));
@ -53,7 +50,7 @@ public class TransactionsMessageTest {
}
@Test /* Transactions message 2 */
public void test_9() {
public void test_2() {
String txsPacketRaw = "f9025012f89d8080940000000000000000000000000000000000000000860918"
+ "4e72a000822710b3606956330c0d630000003359366000530a0d630000003359"
@ -76,15 +73,13 @@ public class TransactionsMessageTest {
+ "d7393152a7fbe41530e5bb8ac8f35433e5931b";
byte[] payload = Hex.decode(txsPacketRaw);
RLPList rlpList = RLP.decode2(payload);
TransactionsMessage transactionsMessage = new TransactionsMessage(rlpList);
TransactionsMessage transactionsMessage = new TransactionsMessage(payload);
System.out.println(transactionsMessage);
assertEquals(3, transactionsMessage.getTransactions().size());
Transaction tx =
transactionsMessage.getTransactions().get(0);
Transaction tx = transactionsMessage.getTransactions().get(0);
assertEquals("1b9d9456293cbcbc2f28a0fdc67028128ea571b033fb0e21d0ee00bcd6167e5d",
Hex.toHexString(tx.getHash()));
@ -98,7 +93,7 @@ public class TransactionsMessageTest {
assertEquals("09184e72a000",
Hex.toHexString(tx.getReceiveAddress()));
assertNull( tx.getGasPrice() );
assertNull(tx.getGasPrice());
assertEquals("0000000000000000000000000000000000000000",
Hex.toHexString(tx.getGasLimit()));
@ -148,7 +143,7 @@ public class TransactionsMessageTest {
}
@Test /* Transactions msg encode */
public void test15() throws Exception {
public void test_3() throws Exception {
String expected = "f87312f870808b00d3c21bcecceda10000009479b08ad8787060333663d19704909ee7b1903e588609184e72a000824255801ca00f410a70e42b2c9854a8421d32c87c370a2b9fff0a27f9f031bb4443681d73b5a018a7dc4c4f9dee9f3dc35cb96ca15859aa27e219a8e4a8547be6bd3206979858";
@ -166,11 +161,11 @@ public class TransactionsMessageTest {
tx.sign(privKey);
tx.getEncoded();
List<Transaction> txList = new ArrayList<Transaction>();
List<Transaction> txList = new ArrayList<>();
txList.add(tx);
TransactionsMessage transactionsMessage = new TransactionsMessage(txList);
assertEquals(expected, Hex.toHexString( transactionsMessage.getPayload()) );
assertEquals(expected, Hex.toHexString(transactionsMessage.getEncoded()));
}
}

View File

@ -595,7 +595,7 @@ public class TrieTest {
}
System.out.println( "root_1: => " + Hex.toHexString( trieSingle.getRootHash() ));
System.out.println("root_1: => " + Hex.toHexString(trieSingle.getRootHash()));
// *** Part - 2 ***
// pre. we use the same data from massive-upload.dmp
@ -630,7 +630,7 @@ public class TrieTest {
trie2.update(keyVal[0].trim(), keyVal[1].trim());
}
System.out.println( "root_2: => " + Hex.toHexString( trie2.getRootHash() ));
System.out.println("root_2: => " + Hex.toHexString( trie2.getRootHash()));
assertEquals(trieSingle.getRootHash(), trie2.getRootHash());
@ -642,7 +642,7 @@ public class TrieTest {
if(massiveUpdateFromDBEnabled) {
List<String> randomWords = Arrays.asList(randomDictionary.split(","));
HashMap<String, String> testerMap = new HashMap<>();
Map<String, String> testerMap = new HashMap<>();
TrieImpl trie = new TrieImpl(mockDb);
Random generator = new Random();
@ -850,19 +850,19 @@ public class TrieTest {
String dmp = trie.getTrieDump();
System.out.println(dmp);
System.out.println();
Assert.assertEquals("ed6e08740e4a267eca9d4740f71f573e9aabbcc739b16a2fa6c1baed5ec21278", Hex.toHexString( trie.getRootHash() ));
Assert.assertEquals("ed6e08740e4a267eca9d4740f71f573e9aabbcc739b16a2fa6c1baed5ec21278", Hex.toHexString(trie.getRootHash()));
trie.update("do", "verb");
dmp = trie.getTrieDump();
System.out.println(dmp);
System.out.println();
Assert.assertEquals("779db3986dd4f38416bfde49750ef7b13c6ecb3e2221620bcad9267e94604d36", Hex.toHexString( trie.getRootHash() ));
Assert.assertEquals("779db3986dd4f38416bfde49750ef7b13c6ecb3e2221620bcad9267e94604d36", Hex.toHexString(trie.getRootHash()));
trie.update("doggiestan", "aeswome_place");
dmp = trie.getTrieDump();
System.out.println(dmp);
System.out.println();
Assert.assertEquals("8bd5544747b4c44d1274aa99a6293065fe319b3230e800203317e4c75a770099", Hex.toHexString( trie.getRootHash() ));
Assert.assertEquals("8bd5544747b4c44d1274aa99a6293065fe319b3230e800203317e4c75a770099", Hex.toHexString(trie.getRootHash()));
}
}

View File

@ -22,10 +22,34 @@ public class ByteUtilTest {
// public void testBigIntegerToBytes() {
// fail("Not yet implemented");
// }
@Test
public void testToStringDoubleByteArray_1() {
String expected = "eth";
byte[][] input = new byte[][]{"eth".getBytes()};
String result = ByteUtil.toString(input);
assertEquals(expected, result);
}
@Test
public void testToStringDoubleByteArray_2() {
String expected = "eth shh";
byte[][] input = new byte[][]{"eth".getBytes(), "shh".getBytes()};
String result = ByteUtil.toString(input);
assertEquals(expected, result);
}
@Test
public void testToStringDoubleByteArray_3() {
String expected = "";
byte[][] input = new byte[0][];
String result = ByteUtil.toString(input);
assertEquals(expected, result);
}
@Test
public void testToHexString() {
assertEquals("null", ByteUtil.toHexString(null));
assertEquals("", ByteUtil.toHexString(null));
}
@Test

View File

@ -305,7 +305,7 @@ public class RLPTest {
String tx = "F86E12F86B80881BC16D674EC8000094CD2A3D9F938E13CD947EC05ABC7FE734DF8DD8268609184E72A00064801BA0C52C114D4F5A3BA904A9B3036E5E118FE0DBB987FE3955DA20F2CD8F6C21AB9CA06BA4C2874299A55AD947DBC98A25EE895AABF6B625C26C435E84BFD70EDF2F69";
byte[] payload = Hex.decode(tx);
Queue<Integer> index = new LinkedList<Integer>();
Queue<Integer> index = new LinkedList<>();
RLP.fullTraverse(payload, 0, 0, payload.length, 1, index);
// TODO: assert lenght overflow while parsing list in RLP

View File

@ -50,10 +50,9 @@ public class ValueTest {
String testRlp = "f7808080d387206f72726563748a626574656c676575736580d387207870726573738a70726564696361626c658080808080808080808080";
Value val =
Value.fromRlpEncoded(Hex.decode(testRlp));
Value val = Value.fromRlpEncoded(Hex.decode(testRlp));
assertEquals( testRlp, Hex.toHexString( val.encode() ));
assertEquals(testRlp, Hex.toHexString(val.encode()));
}

View File

@ -7,7 +7,6 @@ import org.ethereum.core.Wallet;
import org.ethereum.db.ContractDetails;
import org.ethereum.util.ByteUtil;
import org.ethereum.util.Utils;
import org.ethereum.vm.DataWord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.util.BigIntegers;
@ -26,8 +25,6 @@ import java.math.BigInteger;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Pattern;
/**
* www.ethereumJ.com
* @author: Roman Mandeleil

View File

@ -10,7 +10,7 @@ import javax.swing.table.AbstractTableModel;
import org.ethereum.geo.IpGeoDB;
import org.ethereum.net.client.PeerData;
import org.ethereum.net.client.Peer;
import org.ethereum.net.message.HelloMessage;
import org.ethereum.util.Utils;
@ -23,7 +23,7 @@ import com.maxmind.geoip.Location;
*/
public class PeersTableModel extends AbstractTableModel {
private List<PeerInfo> peerInfoList = new ArrayList<PeerInfo>();
private List<PeerInfo> peerInfoList = new ArrayList<>();
Timer updater = new Timer();
public PeersTableModel() {
@ -111,11 +111,11 @@ public class PeersTableModel extends AbstractTableModel {
synchronized (peerInfoList) {
peerInfoList.clear();
final Set<PeerData> peers = UIEthereumManager.ethereum.getPeers();
final Set<Peer> peers = UIEthereumManager.ethereum.getPeers();
synchronized (peers){
for (PeerData peer : peers) {
for (Peer peer : peers) {
InetAddress addr = peer.getInetAddress();
Location cr = IpGeoDB.getLocationForIp(addr);
peerInfoList.add(new PeerInfo(cr, addr, peer.isOnline(), peer.getHandshake(), peer.getLastCheckTime()));

View File

@ -2,7 +2,6 @@ package org.ethereum.gui;
import org.ethereum.core.Block;
import org.ethereum.core.Transaction;
import org.ethereum.facade.Repository;
import org.ethereum.manager.WorldManager;
import org.ethereum.vm.*;
import org.spongycastle.util.encoders.Hex;

View File

@ -38,7 +38,6 @@ import org.ethereum.manager.WorldManager;
import org.ethereum.util.Utils;
import org.ethereum.vm.DataWord;
import org.ethereum.vm.Program;
import org.spongycastle.util.encoders.DecoderException;
import org.spongycastle.util.encoders.Hex;
import java.awt.Component;