Clean and use ReasonCode enum

This commit is contained in:
nicksavers 2014-05-05 02:29:41 +02:00
parent f4ae933ab3
commit 3a660658a2
16 changed files with 274 additions and 321 deletions

View File

@ -27,7 +27,6 @@ import java.util.Arrays;
import javax.annotation.Nullable;
import org.ethereum.util.ByteUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spongycastle.asn1.sec.SECNamedCurves;
@ -294,10 +293,16 @@ public class ECKey implements Serializable {
this.s = s;
}
public static ECDSASignature fromComponents(byte[] r, byte[] s) {
private static ECDSASignature fromComponents(byte[] r, byte[] s) {
return new ECDSASignature(new BigInteger(r), new BigInteger(s));
}
public static ECDSASignature fromComponents(byte[] r, byte[] s, byte v) {
ECDSASignature signature = fromComponents(r, s);
signature.v = v;
return signature;
}
/**
* Will automatically adjust the S component to be less than or equal to half the curve order, if necessary.
* This is required because for every signature (r,s) the signature (r, -s (mod N)) is a valid signature of

View File

@ -3,9 +3,9 @@ package org.ethereum.manager;
import com.maxmind.geoip.Location;
import org.ethereum.geodb.IpGeoDB;
import org.ethereum.net.vo.BlockData;
import org.ethereum.net.vo.Block;
import org.ethereum.net.vo.PeerData;
import org.ethereum.net.vo.TransactionData;
import org.ethereum.net.vo.Transaction;
import java.util.*;
@ -30,6 +30,6 @@ public class MainData {
}
}
public void addBlocks(List<BlockData> blocks) {}
public void addTransactions(List<TransactionData> transactions) {}
public void addBlocks(List<Block> blocks) {}
public void addTransactions(List<Transaction> transactions) {}
}

View File

@ -0,0 +1,42 @@
package org.ethereum.net;
import java.util.HashMap;
import java.util.Map;
public enum ReasonCode {
REASON_DISCONNECT_REQUESTED(0x00),
REASON_TCP_ERROR(0x01),
REASON_BAD_PROTOCOL(0x02),
REASON_USELESS_PEER(0x03),
REASON_TOO_MANY_PEERS(0x04),
REASON_ALREADY_CONNECTED(0x05),
REASON_WRONG_GENESIS(0x06),
REASON_INCOMPATIBLE_PROTOCOL(0x07),
REASON_PEER_QUITING(0x08),
UNKNOWN(0xFF);
private int reason;
private static final Map<Integer, ReasonCode> intToTypeMap = new HashMap<Integer, ReasonCode>();
static {
for (ReasonCode type : ReasonCode.values()) {
intToTypeMap.put(type.reason, type);
}
}
private ReasonCode(int reason) {
this.reason = reason;
}
public static ReasonCode fromInt(int i) {
ReasonCode type = intToTypeMap.get(Integer.valueOf(i));
if (type == null)
return ReasonCode.UNKNOWN;
return type;
}
public byte asByte() {
return (byte) reason;
}
}

View File

@ -1,6 +1,6 @@
package org.ethereum.net.client;
import static org.ethereum.net.Command.BLOCKS;
import static org.ethereum.net.Command.*;
import static org.ethereum.net.Command.DISCONNECT;
import static org.ethereum.net.Command.GET_CHAIN;
import static org.ethereum.net.Command.GET_PEERS;
@ -24,7 +24,6 @@ import java.util.TimerTask;
import org.ethereum.gui.PeerListener;
import org.ethereum.manager.MainData;
import org.ethereum.net.Command;
import org.ethereum.net.RLP;
import org.ethereum.net.message.BlocksMessage;
import org.ethereum.net.message.DisconnectMessage;
import org.ethereum.net.message.GetChainMessage;
@ -34,8 +33,9 @@ import org.ethereum.net.message.NotInChainMessage;
import org.ethereum.net.message.PeersMessage;
import org.ethereum.net.message.StaticMessages;
import org.ethereum.net.message.TransactionsMessage;
import org.ethereum.net.rlp.RLP;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.net.vo.BlockData;
import org.ethereum.net.vo.Block;
import org.ethereum.util.Utils;
import org.spongycastle.util.encoders.Hex;
@ -55,16 +55,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
private long lastPongTime = 0;
private boolean tearDown = false;
// hello data
private boolean handShaked = false;
private byte protocolVersion;
private byte networkId;
private String clientId;
private byte capabilities;
private short peerPort;
private byte[] peerId;
private PeerListener peerListener;
public EthereumProtocolHandler() { }
@ -75,7 +65,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(final ChannelHandlerContext ctx) {
// TODO: send hello
// TODO: send ping schedule another ping
// TODO: ByteBuf vs Stream vs new byte ???
@ -96,12 +85,10 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
long currTime = System.currentTimeMillis();
if (currTime - lastPongTime > 30000){
System.out.println("No ping answer for [30 sec]");
throw new Error("No ping return for 30 [sec]");
// TODO: shutdown the handler
}
System.out.println("[Send: PING]");
if (peerListener != null) peerListener.console("[Send: PING]");
sendPing(ctx);
@ -111,7 +98,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("[Send: GET_PEERS]");
sendGetPeers(ctx);
}
@ -120,7 +106,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("[Send: GET_TRANSACTIONS]");
sendGetTransactions(ctx);
}
@ -129,7 +114,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
timer.schedule(new TimerTask() {
public void run() {
System.out.println("[Send: GET_CHAIN]");
sendGetChain(ctx);
}
@ -156,26 +140,16 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
byte command = RLP.getCommandCode(payload);
// got HELLO
if (Command.fromInt(command) == HELLO) {
System.out.println("[Recv: HELLO]" );
RLPList rlpList = new RLPList();
RLP.parseObjects(payload, rlpList);
HelloMessage helloMessage = new HelloMessage(rlpList);
this.protocolVersion = helloMessage.getProtocolVersion();
this.networkId = helloMessage.getNetworkId();
this.clientId = helloMessage.getClientId();
this.capabilities = helloMessage.getCapabilities();
this.peerPort = helloMessage.getPeerPort();
this.peerId = helloMessage.getPeerId();
System.out.println(helloMessage.toString());
if (peerListener != null) peerListener.console(helloMessage.toString());
}
// got DISCONNECT
if (Command.fromInt(command) == DISCONNECT) {
System.out.println("[Recv: DISCONNECT]");
if (peerListener != null) peerListener.console("[Recv: DISCONNECT]");
@ -186,21 +160,18 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
System.out.println(disconnectMessage);
if (peerListener != null) peerListener.console(disconnectMessage.toString());
}
// got PING send pong
if (Command.fromInt(command) == PING) {
System.out.println("[Recv: PING]");
if (peerListener != null) peerListener.console("[Recv: PING]");
sendPong(ctx);
}
// got PONG mark it
if (Command.fromInt(command) == PONG) {
System.out.println("[Recv: PONG]" );
if (peerListener != null) peerListener.console("[Recv: PONG]");
this.lastPongTime = System.currentTimeMillis();
}
// got GETPEERS send peers
if (Command.fromInt(command) == GET_PEERS) {
System.out.println("[Recv: GETPEERS]" );
@ -223,10 +194,8 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
buffer.writeBytes(answerBytes);
ctx.writeAndFlush(buffer);
}
// got PEERS
if (Command.fromInt(command) == PEERS) {
System.out.println("[Recv: PEERS]");
if (peerListener != null) peerListener.console("[Recv: PEERS]");
@ -239,10 +208,8 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
System.out.println(peersMessage);
if (peerListener != null) peerListener.console(peersMessage.toString());
}
// got TRANSACTIONS
if (Command.fromInt(command) == TRANSACTIONS) {
System.out.println("Recv: TRANSACTIONS]");
if (peerListener != null) peerListener.console("Recv: TRANSACTIONS]");
@ -254,9 +221,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
// todo: if you got transactions send it to your peers
System.out.println(transactionsMessage);
if (peerListener != null) peerListener.console(transactionsMessage.toString());
}
// got BLOCKS
if (Command.fromInt(command) == BLOCKS) {
System.out.println("[Recv: BLOCKS]");
@ -266,13 +231,12 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
RLP.parseObjects(payload, rlpList);
BlocksMessage blocksMessage = new BlocksMessage(rlpList);
List<BlockData> blockList = blocksMessage.getBlockDataList();
List<Block> blockList = blocksMessage.getBlockDataList();
MainData.instance.addBlocks(blockList);
System.out.println(blocksMessage);
if (peerListener != null) peerListener.console(blocksMessage.toString());
}
// got GETCHAIN
if (Command.fromInt(command) == GET_CHAIN) {
System.out.println("[Recv: GET_CHAIN]");
@ -285,7 +249,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
System.out.println(getChainMessage);
if (peerListener != null) peerListener.console(getChainMessage.toString());
}
// got NOTINCHAIN
if (Command.fromInt(command) == NOT_IN_CHAIN) {
System.out.println("[Recv: NOT_IN_CHAIN]");
@ -298,15 +261,12 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
System.out.println(notInChainMessage);
if (peerListener != null) peerListener.console(notInChainMessage.toString());
}
// got GETTRANSACTIONS
if (Command.fromInt(command) == GET_TRANSACTIONS) {
System.out.println("[Recv: GET_TRANSACTIONS]");
if (peerListener != null) peerListener.console("[Recv: GET_TRANSACTIONS]");
// todo: send the queue of the transactions
}
}
@Override
@ -337,7 +297,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
ctx.writeAndFlush(buffer);
}
private void sendPing(ChannelHandlerContext ctx){
ByteBuf buffer = ctx.alloc().buffer(StaticMessages.PING.length);
buffer.writeBytes(StaticMessages.PING);

View File

@ -8,8 +8,8 @@ import static org.ethereum.net.Command.BLOCKS;
import org.ethereum.net.Command;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.net.vo.BlockData;
import org.ethereum.net.vo.TransactionData;
import org.ethereum.net.vo.Block;
import org.ethereum.net.vo.Transaction;
/**
* www.ethereumJ.com
@ -18,7 +18,7 @@ import org.ethereum.net.vo.TransactionData;
*/
public class BlocksMessage extends Message {
private List<BlockData> blockDataList = new ArrayList<BlockData>();
private List<Block> blockDataList = new ArrayList<Block>();
public BlocksMessage(RLPList rawData) {
super(rawData);
@ -34,7 +34,7 @@ public class BlocksMessage extends Message {
for (int i = 1; i < paramsList.size(); ++i){
RLPList rlpData = ((RLPList)paramsList.getElement(i));
BlockData blockData = new BlockData(rlpData);
Block blockData = new Block(rlpData);
this.blockDataList.add(blockData);
}
parsed = true;
@ -45,7 +45,7 @@ public class BlocksMessage extends Message {
return null;
}
public List<BlockData> getBlockDataList() {
public List<Block> getBlockDataList() {
if (!parsed) parseRLP();
return blockDataList;
}
@ -53,11 +53,11 @@ public class BlocksMessage extends Message {
public String toString() {
StringBuffer sb = new StringBuffer();
for (BlockData blockData : this.getBlockDataList()){
for (Block blockData : this.getBlockDataList()){
sb.append(" ").append( blockData.toString() ).append("\n");
List<TransactionData> transactions = blockData.getTransactionsList();
for (TransactionData transactionData : transactions){
List<Transaction> transactions = blockData.getTransactionsList();
for (Transaction transactionData : transactions){
sb.append("[").append(transactionData).append("]\n");
}
}

View File

@ -1,8 +1,10 @@
package org.ethereum.net.message;
import org.spongycastle.util.encoders.Hex;
import static org.ethereum.net.Command.HELLO;
import org.ethereum.net.RLP;
import org.ethereum.net.rlp.RLP;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;

View File

@ -4,7 +4,7 @@ import static org.ethereum.net.Command.TRANSACTIONS;
import org.ethereum.net.Command;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.net.vo.TransactionData;
import org.ethereum.net.vo.Transaction;
import java.util.ArrayList;
import java.util.List;
@ -16,7 +16,7 @@ import java.util.List;
*/
public class TransactionsMessage extends Message {
private List<TransactionData> transactions = new ArrayList<TransactionData>();
private List<Transaction> transactions = new ArrayList<Transaction>();
public TransactionsMessage() {
}
@ -33,17 +33,17 @@ public class TransactionsMessage extends Message {
throw new Error("TransactionMessage: parsing for mal data");
}
transactions = new ArrayList<TransactionData>();
transactions = new ArrayList<Transaction>();
int size = paramsList.getList().size();
for (int i = 1; i < size; ++i){
RLPList rlpTxData = (RLPList) paramsList.getElement(i);
TransactionData tx = new TransactionData(rlpTxData);
Transaction tx = new Transaction(rlpTxData);
transactions.add(tx);
}
parsed = true;
}
public List<TransactionData> getTransactions() {
public List<Transaction> getTransactions() {
if (!parsed) parseRLP();
return transactions;
}
@ -56,7 +56,7 @@ public class TransactionsMessage extends Message {
public String toString(){
if(!parsed) parseRLP();
StringBuffer sb = new StringBuffer();
for (TransactionData transactionData : transactions){
for (Transaction transactionData : transactions){
sb.append(" ").append(transactionData).append("\n");
}
return "Transactions Message [\n" + sb.toString() + " ]";

View File

@ -1,4 +1,4 @@
package org.ethereum.net;
package org.ethereum.net.rlp;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
@ -8,9 +8,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Queue;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;
public class RLP {
public static byte decodeOneByteItem(byte[] data, int index) {

View File

@ -7,7 +7,6 @@ import org.ethereum.net.rlp.RLPList;
import org.ethereum.util.Utils;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@ -16,10 +15,10 @@ import java.util.List;
* User: Roman Mandeleil
* Created on: 13/04/14 19:34
*/
public class BlockData {
public class Block {
RLPList rawData;
boolean parsed = false;
private RLPList rawData;
private boolean parsed = false;
private byte[] hash;
private byte[] parentHash;
@ -33,15 +32,15 @@ public class BlockData {
private byte[] extraData;
private byte[] nonce;
List<TransactionData> transactionsList = new ArrayList<TransactionData>();
List<BlockData> uncleList = new ArrayList<BlockData>();
private List<Transaction> transactionsList = new ArrayList<Transaction>();
private List<Block> uncleList = new ArrayList<Block>();
public BlockData(RLPList rawData) {
public Block(RLPList rawData) {
this.rawData = rawData;
this.parsed = false;
}
public BlockData(byte[] parentHash, byte[] unclesHash, byte[] coinbase, byte[] stateHash, byte[] txListHash, byte[] difficulty, long timestamp, byte[] extraData, byte[] nonce, List<TransactionData> transactionsList, List uncleList) {
public Block(byte[] parentHash, byte[] unclesHash, byte[] coinbase, byte[] stateHash, byte[] txListHash, byte[] difficulty, long timestamp, byte[] extraData, byte[] nonce, List<Transaction> transactionsList, List<Block> uncleList) {
this.parentHash = parentHash;
this.unclesHash = unclesHash;
this.coinbase = coinbase;
@ -54,11 +53,10 @@ public class BlockData {
this.transactionsList = transactionsList;
this.uncleList = uncleList;
this.parsed = true;
}
// [parent_hash, uncles_hash, coinbase, state_root, tx_list_hash, difficulty, timestamp, extradata, nonce]
private void parseRLP(){
private void parseRLP() {
this.hash = HashUtil.sha3(rawData.getRLPData());
@ -76,29 +74,24 @@ public class BlockData {
this.extraData = ((RLPItem) params.get(7)).getData();
this.nonce = ((RLPItem) params.get(8)).getData();
// parse transactions
List<RLPElement> transactions = ((RLPList) rawData.getElement(1)).getList();
for (RLPElement rlpTx : transactions){
TransactionData tx = new TransactionData((RLPList)rlpTx);
Transaction tx = new Transaction((RLPList)rlpTx);
this.transactionsList.add(tx);
}
// parse uncles
List<RLPElement> uncleBlocks = ((RLPList) rawData.getElement(2)).getList();
for (RLPElement rawUncle : uncleBlocks){
BlockData blockData = new BlockData((RLPList)rawUncle);
Block blockData = new Block((RLPList)rawUncle);
this.uncleList.add(blockData);
}
this.parsed = true;
}
public byte[] getHash(){
if (!parsed) parseRLP();
return hash;
}
@ -148,12 +141,12 @@ public class BlockData {
return nonce;
}
public List<TransactionData> getTransactionsList() {
public List<Transaction> getTransactionsList() {
if (!parsed) parseRLP();
return transactionsList;
}
public List<BlockData> getUncleList() {
public List<Block> getUncleList() {
if (!parsed) parseRLP();
return uncleList;
}

View File

@ -77,7 +77,6 @@ public class PeerData {
this.lastCheckTime = lastCheckTime;
}
@Override
public String toString() {
return "Peer: [ ip=" + getInetAddress()+ ", port=" + getPort() + ", peerId=" + Hex.toHexString( getPeerId() ) + "]";

View File

@ -0,0 +1,161 @@
package org.ethereum.net.vo;
import org.ethereum.crypto.ECKey.ECDSASignature;
import org.ethereum.crypto.ECKey;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.util.Utils;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 21/04/14 09:19
*/
public class Transaction {
private RLPList rawData;
private boolean parsed = false;
// creation contract tx or simple send tx
// [ nonce, value, receiveAddress, gasPrice, gasDeposit, data, signatureV, signatureR, signatureS ]
// or
// [ nonce, endowment, 0, gasPrice, gasDeposit (for init), body, init, signatureV, signatureR, signatureS ]
private byte[] hash;
private byte[] nonce;
private byte[] value;
// In creation transaction the receive address is - 0
private byte[] receiveAddress;
private byte[] gasPrice;
private byte[] gas;
// Contract creation [data] will hold the contract
// for other transaction [data] can hold data
private byte[] data;
private byte[] init;
// Signature
private ECDSASignature signature;
public Transaction(RLPList rawData) {
this.rawData = rawData;
parsed = false;
}
public Transaction(byte[] nonce, byte[] value, byte[] recieveAddress, byte[] gasPrice, byte[] gas, byte[] data, byte v, byte[] r, byte[] s) {
this.nonce = nonce;
this.value = value;
this.receiveAddress = recieveAddress;
this.gasPrice = gasPrice;
this.gas = gas;
this.data = data;
this.signature = ECDSASignature.fromComponents(r, s, v);
parsed = true;
}
public void rlpParse() {
this.hash = HashUtil.sha3(rawData.getRLPData());
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
this.value = ((RLPItem) rawData.getElement(1)).getData();
this.receiveAddress = ((RLPItem) rawData.getElement(2)).getData();
this.gasPrice = ((RLPItem) rawData.getElement(3)).getData();
this.gas = ((RLPItem) rawData.getElement(4)).getData();
this.data = ((RLPItem) rawData.getElement(5)).getData();
if (rawData.size() == 9){ // Simple transaction
byte v = ((RLPItem) rawData.getElement(6)).getData()[0];
byte[] r = ((RLPItem) rawData.getElement(7)).getData();
byte[] s = ((RLPItem) rawData.getElement(8)).getData();
this.signature = ECDSASignature.fromComponents(r, s, v);
} else if (rawData.size() == 10){ // Contract creation transaction
this.init = ((RLPItem) rawData.getElement(6)).getData();
byte v = ((RLPItem) rawData.getElement(7)).getData()[0];
byte[] r = ((RLPItem) rawData.getElement(8)).getData();
byte[] s = ((RLPItem) rawData.getElement(9)).getData();
this.signature = ECDSASignature.fromComponents(r, s, v);
} else
throw new Error("Wrong tx data element list size");
this.parsed = true;
}
public RLPList getRawData() {
return rawData;
}
public boolean isParsed() {
return parsed;
}
public byte[] getHash() {
if (!parsed) rlpParse();
return hash;
}
public byte[] getNonce() {
if (!parsed) rlpParse();
return nonce;
}
public byte[] getValue() {
if (!parsed) rlpParse();
return value;
}
public byte[] getReceiveAddress() {
if (!parsed) rlpParse();
return receiveAddress;
}
public byte[] getGasPrice() {
if (!parsed) rlpParse();
return gasPrice;
}
public byte[] getGas() {
if (!parsed) rlpParse();
return gas;
}
public byte[] getData() {
if (!parsed) rlpParse();
return data;
}
public byte[] getInit() {
if (!parsed) rlpParse();
return init;
}
public ECDSASignature getSignature() {
if (!parsed) rlpParse();
return signature;
}
public boolean isContract() {
return this.receiveAddress.length == 0;
}
@Override
public String toString() {
if (!parsed) rlpParse();
return "TransactionData [" + " hash=" + Utils.toHexString(hash) +
" nonce=" + Utils.toHexString(nonce) +
", value=" + Utils.toHexString(value) +
", receiveAddress=" + Utils.toHexString(receiveAddress) +
", gasPrice=" + Utils.toHexString(gasPrice) +
", gas=" + Utils.toHexString(gas) +
", data=" + Utils.toHexString(data) +
", init=" + Utils.toHexString(init) +
", signatureV=" + signature.v +
", signatureR=" + Utils.toHexString(signature.r.toByteArray()) +
", signatureS=" + Utils.toHexString(signature.s.toByteArray()) +
']';
}
}

View File

@ -1,188 +0,0 @@
package org.ethereum.net.vo;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.rlp.RLPItem;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.util.Utils;
/**
* www.ethereumJ.com
* User: Roman Mandeleil
* Created on: 21/04/14 09:19
*/
public class TransactionData {
RLPList rawData;
boolean parsed = false;
// creation contract tx or simple send tx
// [ nonce, value, receiveAddress, gasPrice, gasDeposit, data, signatureV, signatureR, signatureS ]
// or
// [ nonce, endowment, 0, gasPrice, gasDeposit (for init), body, init, signatureV, signatureR, signatureS ]
byte[] hash;
byte[] nonce;
byte[] value;
// In creation transaction the receive address is - 0
byte[] receiveAddress;
byte[] gasPrice;
byte[] gas;
// Contract creation [data] will hold the contract
// for other transaction [data] can hold data
byte[] data;
byte[] init;
// Signature
byte signatureV;
byte[] signatureR;
byte[] signatureS;
public TransactionData(RLPList rawData) {
this.rawData = rawData;
parsed = false;
}
public TransactionData(byte[] nonce, byte[] value, byte[] recieveAddress, byte[] gasPrice, byte[] gas, byte[] data, byte signatureV, byte[] signatureR, byte[] signatureS) {
this.nonce = nonce;
this.value = value;
this.receiveAddress = recieveAddress;
this.gasPrice = gasPrice;
this.gas = gas;
this.data = data;
this.signatureV = signatureV;
this.signatureR = signatureR;
this.signatureS = signatureS;
parsed = true;
}
public void rlpParse(){
if (rawData.size() == 9){ // Simple transaction
this.hash = HashUtil.sha3(rawData.getRLPData());
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
this.value = ((RLPItem) rawData.getElement(1)).getData();
this.receiveAddress = ((RLPItem) rawData.getElement(2)).getData();
this.gasPrice = ((RLPItem) rawData.getElement(3)).getData();
this.gas = ((RLPItem) rawData.getElement(4)).getData();
this.data = ((RLPItem) rawData.getElement(5)).getData();
this.signatureV = ((RLPItem) rawData.getElement(6)).getData()[0];
this.signatureR = ((RLPItem) rawData.getElement(7)).getData();
this.signatureS = ((RLPItem) rawData.getElement(8)).getData();
} else if (rawData.size() == 10){ // Contract creation transaction
this.hash = HashUtil.sha3(rawData.getRLPData());
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
this.value = ((RLPItem) rawData.getElement(1)).getData();
this.receiveAddress = ((RLPItem) rawData.getElement(2)).getData();
this.gasPrice = ((RLPItem) rawData.getElement(3)).getData();
this.gas = ((RLPItem) rawData.getElement(4)).getData();
this.data = ((RLPItem) rawData.getElement(5)).getData();
this.init = ((RLPItem) rawData.getElement(6)).getData();
this.signatureV = ((RLPItem) rawData.getElement(7)).getData()[0];
this.signatureR = ((RLPItem) rawData.getElement(8)).getData();
this.signatureS = ((RLPItem) rawData.getElement(9)).getData();
} else throw new Error("Wrong tx data element list size");
this.parsed = true;
}
public RLPList getRawData() {
return rawData;
}
public boolean isParsed() {
return parsed;
}
public byte[] getHash() {
if (!parsed) rlpParse();
return hash;
}
public byte[] getNonce() {
if (!parsed) rlpParse();
return nonce;
}
public byte[] getValue() {
if (!parsed) rlpParse();
return value;
}
public byte[] getReceiveAddress() {
if (!parsed) rlpParse();
return receiveAddress;
}
public byte[] getGasPrice() {
if (!parsed) rlpParse();
return gasPrice;
}
public byte[] getGas() {
if (!parsed) rlpParse();
return gas;
}
public byte[] getData() {
if (!parsed) rlpParse();
return data;
}
public byte[] getInit() {
if (!parsed) rlpParse();
return init;
}
public byte getSignatureV() {
if (!parsed) rlpParse();
return signatureV;
}
public byte[] getSignatureR() {
if (!parsed) rlpParse();
return signatureR;
}
public byte[] getSignatureS() {
if (!parsed) rlpParse();
return signatureS;
}
@Override
public String toString() {
if (!parsed) rlpParse();
return "TransactionData [" + " hash=" + Utils.toHexString(hash) +
" nonce=" + Utils.toHexString(nonce) +
", value=" + Utils.toHexString(value) +
", receiveAddress=" + Utils.toHexString(receiveAddress) +
", gasPrice=" + Utils.toHexString(gasPrice) +
", gas=" + Utils.toHexString(gas) +
", data=" + Utils.toHexString(data) +
", init=" + Utils.toHexString(init) +
", signatureV=" + signatureV +
", signatureR=" + Utils.toHexString(signatureR) +
", signatureS=" + Utils.toHexString(signatureS) +
']';
}
}

View File

@ -2,9 +2,9 @@ package org.ethereum.block;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.RLP;
import org.ethereum.net.rlp.RLP;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.net.vo.BlockData;
import org.ethereum.net.vo.Block;
import org.junit.Test;
import java.io.IOException;
@ -131,7 +131,7 @@ public class BlockTest {
RLPList rlpList = new RLPList();
RLP.parseObjects(payload, rlpList);
BlockData blockData = new BlockData(rlpList);
Block blockData = new Block(rlpList);
RLPList.recursivePrint(rlpList);
}
}

View File

@ -117,8 +117,7 @@ public class ECKeyTest {
ECKey key = ECKey.fromPublicOnly(pubKey);
BigInteger r = new BigInteger("28157690258821599598544026901946453245423343069728565040002908283498585537001");
BigInteger s = new BigInteger("30212485197630673222315826773656074299979444367665131281281249560925428307087");
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
sig.v = 28;
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 28);
key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
}
@ -126,8 +125,7 @@ public class ECKeyTest {
public void testVerifySignature2() {
BigInteger r = new BigInteger("c52c114d4f5a3ba904a9b3036e5e118fe0dbb987fe3955da20f2cd8f6c21ab9c", 16);
BigInteger s = new BigInteger("6ba4c2874299a55ad947dbc98a25ee895aabf6b625c26c435e84bfd70edf2f69", 16);
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
sig.v = 0x1b;
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 0x1b);
byte[] rawtx = Hex.decode("f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480");
try {
ECKey key = ECKey.signatureToKey(HashUtil.sha3(rawtx), sig.toBase64());

View File

@ -12,10 +12,11 @@ import org.ethereum.net.message.HelloMessage;
import org.ethereum.net.message.NotInChainMessage;
import org.ethereum.net.message.PeersMessage;
import org.ethereum.net.message.TransactionsMessage;
import org.ethereum.net.rlp.RLP;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.net.vo.BlockData;
import org.ethereum.net.vo.Block;
import org.ethereum.net.vo.PeerData;
import org.ethereum.net.vo.TransactionData;
import org.ethereum.net.vo.Transaction;
import org.ethereum.util.Utils;
import org.junit.Test;
import org.spongycastle.util.encoders.Hex;
@ -109,7 +110,6 @@ public class MessagesTest {
DisconnectMessage.REASON_TCP_ERROR);
}
/* PEERS */
@Test /* PeersMessage 1*/
@ -131,7 +131,6 @@ public class MessagesTest {
assertEquals(30303, peerData.getPort());
assertEquals("82A8A5831D3B4FB76CF130CDC8A2B162A85D005D82A1DCC9B73239035EADE6347EDE2FFC86571ABE348EA38699CE886AA3D425FE58182C433434AB4CFD7B5B88",
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
}
@Test /* PeersMessage 2 */
@ -160,7 +159,6 @@ public class MessagesTest {
assertEquals(30303, peerData.getPort());
assertEquals("F6155F1A60143B7D9D5D1A440D7D52FE6809F69E0C6F1E0024457E0D71DD88ADE3B13AAA940C89AC0610952B48BD832C42E343A13E61FFDB06010CFFC345E053",
Utils.toHexString( peerData.getPeerId() ).toUpperCase());
}
@Test /* Peers msg parsing performance*/
@ -199,7 +197,7 @@ public class MessagesTest {
assertEquals(1, transactionsMessage.getTransactions().size());
TransactionData tx =
Transaction tx =
transactionsMessage.getTransactions().get(0);
assertEquals("558A3797E0DD3FBFAF761F1ADD6749C7D5DB313FDAC5CBA59F40E28AF7BBACD1",
@ -227,16 +225,15 @@ public class MessagesTest {
Utils.toHexString( tx.getInit() ).toUpperCase());
assertEquals("1B",
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
Utils.toHexString( new byte[] {tx.getSignature().v} ).toUpperCase());
assertEquals("5E3868194605F1647593B842725818CCFA6A38651A728715133A8E97CDCFAC54",
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
Utils.toHexString( tx.getSignature().r.toByteArray() ).toUpperCase());
assertEquals("0FF91628D04B215EBCCFD5F4FC34CC1B45DF32F6B4609FBB0DE42E8522264467",
Utils.toHexString( tx.getSignatureS() ).toUpperCase());
Utils.toHexString( tx.getSignature().s.toByteArray() ).toUpperCase());
}
@Test /* Transactions message 2 */
public void test_9(){
@ -251,7 +248,7 @@ public class MessagesTest {
assertEquals(3, transactionsMessage.getTransactions().size());
TransactionData tx =
Transaction tx =
transactionsMessage.getTransactions().get(0);
assertEquals("4B7D9670A92BF120D5B43400543B69304A14D767CF836A7F6ABFF4EDDE092895",
@ -279,14 +276,13 @@ public class MessagesTest {
Utils.toHexString( tx.getInit() ).toUpperCase());
assertEquals("1C",
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
Utils.toHexString( new byte[] {tx.getSignature().v} ).toUpperCase());
assertEquals("7F6EB94576346488C6253197BDE6A7E59DDC36F2773672C849402AA9C402C3C4",
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
Utils.toHexString( tx.getSignature().r.toByteArray() ).toUpperCase());
assertEquals("6D254E662BF7450DD8D835160CBB053463FED0B53F2CDD7F3EA8731919C8E8CC",
Utils.toHexString( tx.getSignatureS() ).toUpperCase());
Utils.toHexString( tx.getSignature().s.toByteArray() ).toUpperCase());
tx = transactionsMessage.getTransactions().get(2);
@ -315,17 +311,16 @@ public class MessagesTest {
Utils.toHexString( tx.getInit() ).toUpperCase());
assertEquals("1B",
Utils.toHexString( new byte[] {tx.getSignatureV()} ).toUpperCase());
Utils.toHexString( new byte[] {tx.getSignature().v} ).toUpperCase());
assertEquals("D05887574456C6DE8F7A0D172342C2CBDD4CF7AFE15D9DBB8B75B748BA6791C9",
Utils.toHexString( tx.getSignatureR() ).toUpperCase());
Utils.toHexString( tx.getSignature().r.toByteArray() ).toUpperCase());
assertEquals("1E87172A861F6C37B5A9E3A5D0D7393152A7FBE41530E5BB8AC8F35433E5931B",
Utils.toHexString(tx.getSignatureS()).toUpperCase());
Utils.toHexString( tx.getSignature().s.toByteArray() ).toUpperCase());
}
/* BLOCKS */
@Test /* BlocksMessage parsing 1*/
@ -339,12 +334,12 @@ public class MessagesTest {
RLP.parseObjects(payload, rlpList);
BlocksMessage blocksMessage = new BlocksMessage(rlpList);
List<BlockData> list = blocksMessage.getBlockDataList();
List<Block> list = blocksMessage.getBlockDataList();
System.out.println(blocksMessage);
assertEquals(1, list.size());
BlockData block = list.get(0);
Block block = list.get(0);
assertEquals("36A24B56C6104E5A5C0E70B0553F1A4D6109D065D718D7443A6A475EC8C83905",
Utils.toHexString(block.getHash()).toUpperCase());
@ -373,7 +368,6 @@ public class MessagesTest {
Utils.toHexString(block.getNonce()).toUpperCase());
}
@Test /* BlocksMessage really big message parsing */
public void test11(){
@ -384,13 +378,12 @@ public class MessagesTest {
RLP.parseObjects(payload, rlpList);
BlocksMessage blocksMessage = new BlocksMessage(rlpList);
List<BlockData> list = blocksMessage.getBlockDataList();
List<Block> list = blocksMessage.getBlockDataList();
System.out.println(blocksMessage);
assertEquals(32, list.size());
BlockData block = list.get(31);
Block block = list.get(31);
assertEquals("518916DFB79C390BD7BFF75712174512C2F96BEC42A3F573355507AD1588CE0C",
Utils.toHexString(block.getHash()).toUpperCase());
@ -419,11 +412,8 @@ public class MessagesTest {
Utils.toHexString(block.getNonce()).toUpperCase());
System.out.println(blocksMessage);
}
/* GET_CHAIN */
@Test /* GET_CHAIN message parsing*/
@ -449,12 +439,8 @@ public class MessagesTest {
assertEquals("03AF21F3939C29C231200B1F790F16421A8923254CBF2A90455B9B8F28BE4562",
Utils.toHexString( getChainMessage.getBlockHashList().get(25) ).toUpperCase());
}
/* NOT_IN_CHAIN */
@Test /* NotInChainMessage parsing 1 */
@ -472,7 +458,5 @@ public class MessagesTest {
assertEquals("E5E441F0877116011CCDECE2501A50B40C40418377037E16D0282B2B5E347138",
Utils.toHexString(notInChainMessage.getHash()).toUpperCase());
}
}

View File

@ -2,6 +2,7 @@ package org.ethereum.net;
import org.spongycastle.util.encoders.Hex;
import org.ethereum.crypto.HashUtil;
import org.ethereum.net.rlp.RLP;
import org.ethereum.net.rlp.RLPList;
import org.ethereum.util.Utils;
import org.junit.Test;