commit
0c8f1f40e3
|
@ -45,7 +45,6 @@
|
||||||
<groupId>com.cedarsoftware</groupId>
|
<groupId>com.cedarsoftware</groupId>
|
||||||
<artifactId>java-util</artifactId>
|
<artifactId>java-util</artifactId>
|
||||||
<version>1.8.0</version>
|
<version>1.8.0</version>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fifesoft</groupId>
|
<groupId>com.fifesoft</groupId>
|
||||||
|
|
|
@ -293,14 +293,14 @@ public class ECKey implements Serializable {
|
||||||
this.s = s;
|
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));
|
return new ECDSASignature(new BigInteger(r), new BigInteger(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ECDSASignature fromComponents(byte[] r, byte[] s, byte v) {
|
public static ECDSASignature fromComponents(byte[] r, byte[] s, byte v) {
|
||||||
ECDSASignature signature = new ECDSASignature(new BigInteger(r), new BigInteger(s));
|
ECDSASignature signature = fromComponents(r, s);
|
||||||
signature.v = v;
|
signature.v = v;
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -30,7 +30,7 @@ public enum Command {
|
||||||
private Command(int cmd) {
|
private Command(int cmd) {
|
||||||
this.cmd = cmd;
|
this.cmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Command fromInt(int i) {
|
public static Command fromInt(int i) {
|
||||||
Command type = intToTypeMap.get(Integer.valueOf(i));
|
Command type = intToTypeMap.get(Integer.valueOf(i));
|
||||||
if (type == null)
|
if (type == null)
|
||||||
|
|
|
@ -9,7 +9,7 @@ public class MessageDeserializer {
|
||||||
/**
|
/**
|
||||||
* Get exactly one message payload
|
* Get exactly one message payload
|
||||||
*/
|
*/
|
||||||
public static void deserialize(byte [] msgData, int level, int startPos, int endPos){
|
private static void deserialize(byte [] msgData, int level, int startPos, int endPos){
|
||||||
|
|
||||||
if (msgData == null || msgData.length == 0) return ;
|
if (msgData == null || msgData.length == 0) return ;
|
||||||
int pos = startPos;
|
int pos = startPos;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,6 @@ public class ClientPeer {
|
||||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Bootstrap b = new Bootstrap();
|
Bootstrap b = new Bootstrap();
|
||||||
b.group(workerGroup);
|
b.group(workerGroup);
|
||||||
b.channel(NioSocketChannel.class);
|
b.channel(NioSocketChannel.class);
|
||||||
|
@ -58,18 +57,14 @@ public class ClientPeer {
|
||||||
|
|
||||||
// Start the client.
|
// Start the client.
|
||||||
ChannelFuture f = b.connect(host, port).sync(); // (5)
|
ChannelFuture f = b.connect(host, port).sync(); // (5)
|
||||||
|
|
||||||
// Wait until the connection is closed.
|
// Wait until the connection is closed.
|
||||||
f.channel().closeFuture().sync();
|
f.channel().closeFuture().sync();
|
||||||
|
|
||||||
} catch (InterruptedException ie){
|
} catch (InterruptedException ie){
|
||||||
|
|
||||||
System.out.println("-- ClientPeer: catch (InterruptedException ie) --");
|
System.out.println("-- ClientPeer: catch (InterruptedException ie) --");
|
||||||
ie.printStackTrace();
|
ie.printStackTrace();
|
||||||
} finally {
|
} finally {
|
||||||
workerGroup.shutdownGracefully();
|
workerGroup.shutdownGracefully();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.ethereum.net.client;
|
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.DISCONNECT;
|
||||||
import static org.ethereum.net.Command.GET_CHAIN;
|
import static org.ethereum.net.Command.GET_CHAIN;
|
||||||
import static org.ethereum.net.Command.GET_PEERS;
|
import static org.ethereum.net.Command.GET_PEERS;
|
||||||
|
@ -55,16 +55,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
private long lastPongTime = 0;
|
private long lastPongTime = 0;
|
||||||
private boolean tearDown = false;
|
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;
|
private PeerListener peerListener;
|
||||||
|
|
||||||
public EthereumProtocolHandler() { }
|
public EthereumProtocolHandler() { }
|
||||||
|
@ -75,7 +65,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelActive(final ChannelHandlerContext ctx) {
|
public void channelActive(final ChannelHandlerContext ctx) {
|
||||||
|
|
||||||
// TODO: send hello
|
// TODO: send hello
|
||||||
// TODO: send ping schedule another ping
|
// TODO: send ping schedule another ping
|
||||||
// TODO: ByteBuf vs Stream vs new byte ???
|
// TODO: ByteBuf vs Stream vs new byte ???
|
||||||
|
@ -96,12 +85,10 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
long currTime = System.currentTimeMillis();
|
long currTime = System.currentTimeMillis();
|
||||||
if (currTime - lastPongTime > 30000){
|
if (currTime - lastPongTime > 30000){
|
||||||
|
|
||||||
System.out.println("No ping answer for [30 sec]");
|
System.out.println("No ping answer for [30 sec]");
|
||||||
throw new Error("No ping return for 30 [sec]");
|
throw new Error("No ping return for 30 [sec]");
|
||||||
// TODO: shutdown the handler
|
// TODO: shutdown the handler
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("[Send: PING]");
|
System.out.println("[Send: PING]");
|
||||||
if (peerListener != null) peerListener.console("[Send: PING]");
|
if (peerListener != null) peerListener.console("[Send: PING]");
|
||||||
sendPing(ctx);
|
sendPing(ctx);
|
||||||
|
@ -111,7 +98,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
System.out.println("[Send: GET_PEERS]");
|
System.out.println("[Send: GET_PEERS]");
|
||||||
sendGetPeers(ctx);
|
sendGetPeers(ctx);
|
||||||
}
|
}
|
||||||
|
@ -120,7 +106,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
System.out.println("[Send: GET_TRANSACTIONS]");
|
System.out.println("[Send: GET_TRANSACTIONS]");
|
||||||
sendGetTransactions(ctx);
|
sendGetTransactions(ctx);
|
||||||
}
|
}
|
||||||
|
@ -129,7 +114,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
timer.schedule(new TimerTask() {
|
timer.schedule(new TimerTask() {
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
System.out.println("[Send: GET_CHAIN]");
|
System.out.println("[Send: GET_CHAIN]");
|
||||||
sendGetChain(ctx);
|
sendGetChain(ctx);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +122,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
timer.schedule(new TimerTask() {
|
timer.schedule(new TimerTask() {
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
System.out.println("[Send: TX]");
|
System.out.println("[Send: TX]");
|
||||||
sendTx(ctx);
|
sendTx(ctx);
|
||||||
}
|
}
|
||||||
|
@ -156,26 +139,16 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
byte command = RLP.getCommandCode(payload);
|
byte command = RLP.getCommandCode(payload);
|
||||||
// got HELLO
|
// got HELLO
|
||||||
if (Command.fromInt(command) == HELLO) {
|
if (Command.fromInt(command) == HELLO) {
|
||||||
|
|
||||||
System.out.println("[Recv: HELLO]" );
|
System.out.println("[Recv: HELLO]" );
|
||||||
RLPList rlpList = new RLPList();
|
RLPList rlpList = new RLPList();
|
||||||
RLP.parseObjects(payload, rlpList);
|
RLP.parseObjects(payload, rlpList);
|
||||||
|
|
||||||
HelloMessage helloMessage = new HelloMessage(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());
|
System.out.println(helloMessage.toString());
|
||||||
if (peerListener != null) peerListener.console(helloMessage.toString());
|
if (peerListener != null) peerListener.console(helloMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// got DISCONNECT
|
// got DISCONNECT
|
||||||
if (Command.fromInt(command) == DISCONNECT) {
|
if (Command.fromInt(command) == DISCONNECT) {
|
||||||
|
|
||||||
System.out.println("[Recv: DISCONNECT]");
|
System.out.println("[Recv: DISCONNECT]");
|
||||||
if (peerListener != null) peerListener.console("[Recv: DISCONNECT]");
|
if (peerListener != null) peerListener.console("[Recv: DISCONNECT]");
|
||||||
|
|
||||||
|
@ -186,21 +159,18 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
System.out.println(disconnectMessage);
|
System.out.println(disconnectMessage);
|
||||||
if (peerListener != null) peerListener.console(disconnectMessage.toString());
|
if (peerListener != null) peerListener.console(disconnectMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// got PING send pong
|
// got PING send pong
|
||||||
if (Command.fromInt(command) == PING) {
|
if (Command.fromInt(command) == PING) {
|
||||||
System.out.println("[Recv: PING]");
|
System.out.println("[Recv: PING]");
|
||||||
if (peerListener != null) peerListener.console("[Recv: PING]");
|
if (peerListener != null) peerListener.console("[Recv: PING]");
|
||||||
sendPong(ctx);
|
sendPong(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// got PONG mark it
|
// got PONG mark it
|
||||||
if (Command.fromInt(command) == PONG) {
|
if (Command.fromInt(command) == PONG) {
|
||||||
System.out.println("[Recv: PONG]" );
|
System.out.println("[Recv: PONG]" );
|
||||||
if (peerListener != null) peerListener.console("[Recv: PONG]");
|
if (peerListener != null) peerListener.console("[Recv: PONG]");
|
||||||
this.lastPongTime = System.currentTimeMillis();
|
this.lastPongTime = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
// got GETPEERS send peers
|
// got GETPEERS send peers
|
||||||
if (Command.fromInt(command) == GET_PEERS) {
|
if (Command.fromInt(command) == GET_PEERS) {
|
||||||
System.out.println("[Recv: GETPEERS]" );
|
System.out.println("[Recv: GETPEERS]" );
|
||||||
|
@ -223,10 +193,8 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
buffer.writeBytes(answerBytes);
|
buffer.writeBytes(answerBytes);
|
||||||
ctx.writeAndFlush(buffer);
|
ctx.writeAndFlush(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// got PEERS
|
// got PEERS
|
||||||
if (Command.fromInt(command) == PEERS) {
|
if (Command.fromInt(command) == PEERS) {
|
||||||
|
|
||||||
System.out.println("[Recv: PEERS]");
|
System.out.println("[Recv: PEERS]");
|
||||||
if (peerListener != null) peerListener.console("[Recv: PEERS]");
|
if (peerListener != null) peerListener.console("[Recv: PEERS]");
|
||||||
|
|
||||||
|
@ -239,10 +207,8 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
System.out.println(peersMessage);
|
System.out.println(peersMessage);
|
||||||
if (peerListener != null) peerListener.console(peersMessage.toString());
|
if (peerListener != null) peerListener.console(peersMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// got TRANSACTIONS
|
// got TRANSACTIONS
|
||||||
if (Command.fromInt(command) == TRANSACTIONS) {
|
if (Command.fromInt(command) == TRANSACTIONS) {
|
||||||
|
|
||||||
System.out.println("Recv: TRANSACTIONS]");
|
System.out.println("Recv: TRANSACTIONS]");
|
||||||
if (peerListener != null) peerListener.console("Recv: TRANSACTIONS]");
|
if (peerListener != null) peerListener.console("Recv: TRANSACTIONS]");
|
||||||
|
|
||||||
|
@ -254,9 +220,7 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
// todo: if you got transactions send it to your peers
|
// todo: if you got transactions send it to your peers
|
||||||
System.out.println(transactionsMessage);
|
System.out.println(transactionsMessage);
|
||||||
if (peerListener != null) peerListener.console(transactionsMessage.toString());
|
if (peerListener != null) peerListener.console(transactionsMessage.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// got BLOCKS
|
// got BLOCKS
|
||||||
if (Command.fromInt(command) == BLOCKS) {
|
if (Command.fromInt(command) == BLOCKS) {
|
||||||
System.out.println("[Recv: BLOCKS]");
|
System.out.println("[Recv: BLOCKS]");
|
||||||
|
@ -272,7 +236,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
System.out.println(blocksMessage);
|
System.out.println(blocksMessage);
|
||||||
if (peerListener != null) peerListener.console(blocksMessage.toString());
|
if (peerListener != null) peerListener.console(blocksMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// got GETCHAIN
|
// got GETCHAIN
|
||||||
if (Command.fromInt(command) == GET_CHAIN) {
|
if (Command.fromInt(command) == GET_CHAIN) {
|
||||||
System.out.println("[Recv: GET_CHAIN]");
|
System.out.println("[Recv: GET_CHAIN]");
|
||||||
|
@ -285,7 +248,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
System.out.println(getChainMessage);
|
System.out.println(getChainMessage);
|
||||||
if (peerListener != null) peerListener.console(getChainMessage.toString());
|
if (peerListener != null) peerListener.console(getChainMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// got NOTINCHAIN
|
// got NOTINCHAIN
|
||||||
if (Command.fromInt(command) == NOT_IN_CHAIN) {
|
if (Command.fromInt(command) == NOT_IN_CHAIN) {
|
||||||
System.out.println("[Recv: NOT_IN_CHAIN]");
|
System.out.println("[Recv: NOT_IN_CHAIN]");
|
||||||
|
@ -298,15 +260,12 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
System.out.println(notInChainMessage);
|
System.out.println(notInChainMessage);
|
||||||
if (peerListener != null) peerListener.console(notInChainMessage.toString());
|
if (peerListener != null) peerListener.console(notInChainMessage.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// got GETTRANSACTIONS
|
// got GETTRANSACTIONS
|
||||||
if (Command.fromInt(command) == GET_TRANSACTIONS) {
|
if (Command.fromInt(command) == GET_TRANSACTIONS) {
|
||||||
System.out.println("[Recv: GET_TRANSACTIONS]");
|
System.out.println("[Recv: GET_TRANSACTIONS]");
|
||||||
if (peerListener != null) peerListener.console("[Recv: GET_TRANSACTIONS]");
|
if (peerListener != null) peerListener.console("[Recv: GET_TRANSACTIONS]");
|
||||||
|
|
||||||
// todo: send the queue of the transactions
|
// todo: send the queue of the transactions
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -337,7 +296,6 @@ public class EthereumProtocolHandler extends ChannelInboundHandlerAdapter {
|
||||||
ctx.writeAndFlush(buffer);
|
ctx.writeAndFlush(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void sendPing(ChannelHandlerContext ctx){
|
private void sendPing(ChannelHandlerContext ctx){
|
||||||
ByteBuf buffer = ctx.alloc().buffer(StaticMessages.PING.length);
|
ByteBuf buffer = ctx.alloc().buffer(StaticMessages.PING.length);
|
||||||
buffer.writeBytes(StaticMessages.PING);
|
buffer.writeBytes(StaticMessages.PING);
|
||||||
|
|
|
@ -61,7 +61,6 @@ public class BlocksMessage extends Message {
|
||||||
sb.append("[").append(transactionData).append("]\n");
|
sb.append("[").append(transactionData).append("]\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Blocks Message [\n" +
|
return "Blocks Message [\n" +
|
||||||
sb.toString()
|
sb.toString()
|
||||||
+ " ]";
|
+ " ]";
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class TransactionsMessage extends Message {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if(!parsed) parseRLP();
|
if(!parsed) parseRLP();
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
for (Transaction transactionData : transactions) {
|
for (Transaction transactionData : transactions){
|
||||||
sb.append(" ").append(transactionData).append("\n");
|
sb.append(" ").append(transactionData).append("\n");
|
||||||
}
|
}
|
||||||
return "Transactions Message [\n" + sb.toString() + " ]";
|
return "Transactions Message [\n" + sb.toString() + " ]";
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,12 +20,10 @@ public class RLPList implements RLPElement{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addItem(RLPElement element){
|
public void addItem(RLPElement element){
|
||||||
|
|
||||||
list.add(element);
|
list.add(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RLPElement getElement(int index){
|
public RLPElement getElement(int index){
|
||||||
|
|
||||||
return list.get(index);
|
return list.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,17 +50,13 @@ public class RLPList implements RLPElement{
|
||||||
if (element instanceof RLPList) {
|
if (element instanceof RLPList) {
|
||||||
|
|
||||||
RLPList rlpList = (RLPList) element;
|
RLPList rlpList = (RLPList) element;
|
||||||
|
System.out.print("[");
|
||||||
System.out.print("[");
|
|
||||||
|
|
||||||
for (RLPElement singleElement : rlpList.getList()) {
|
for (RLPElement singleElement : rlpList.getList()) {
|
||||||
recursivePrint(singleElement);
|
recursivePrint(singleElement);
|
||||||
}
|
}
|
||||||
System.out.print("]");
|
System.out.print("]");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
String hex = Utils.toHexString(((RLPItem) element).getData());
|
String hex = Utils.toHexString(((RLPItem) element).getData());
|
||||||
|
|
||||||
System.out.print(hex + ", ");
|
System.out.print(hex + ", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ public class Block {
|
||||||
private static double EMA_FACTOR = 1.5;
|
private static double EMA_FACTOR = 1.5;
|
||||||
/* A scalar value equal to the current limit of gas expenditure per block */
|
/* A scalar value equal to the current limit of gas expenditure per block */
|
||||||
private static int GAS_LIMIT = (int) Math.pow(10, 6);
|
private static int GAS_LIMIT = (int) Math.pow(10, 6);
|
||||||
|
|
||||||
private RLPList rawData;
|
private RLPList rawData;
|
||||||
private boolean parsed = false;
|
private boolean parsed = false;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ public class Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
// [parent_hash, uncles_hash, coinbase, state_root, tx_list_hash, difficulty, timestamp, extradata, nonce]
|
// [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());
|
this.hash = HashUtil.sha3(rawData.getRLPData());
|
||||||
|
|
||||||
|
@ -110,7 +110,6 @@ public class Block {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getHash(){
|
public byte[] getHash(){
|
||||||
|
|
||||||
if (!parsed) parseRLP();
|
if (!parsed) parseRLP();
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,13 +66,13 @@ public class PeerData {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Peer: [ ip=" + getInetAddress()+ ", port=" + getPort() + ", peerId=" + Hex.toHexString( getPeerId() ) + "]";
|
return "Peer: [ip=" + getInetAddress() + ", port=" + getPort() + ", peerId=" + Hex.toHexString(getPeerId()) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
PeerData peerData2 = (PeerData)obj;
|
PeerData peerData = (PeerData) obj;
|
||||||
return this.getInetAddress().equals(peerData2.getInetAddress());
|
return this.getInetAddress().equals(peerData.getInetAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -70,7 +70,6 @@ public class Transaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rlpParse(){
|
public void rlpParse(){
|
||||||
|
|
||||||
this.hash = HashUtil.sha3(rawData.getRLPData());
|
this.hash = HashUtil.sha3(rawData.getRLPData());
|
||||||
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
|
this.nonce = ((RLPItem) rawData.getElement(0)).getData();
|
||||||
this.value = ((RLPItem) rawData.getElement(1)).getData();
|
this.value = ((RLPItem) rawData.getElement(1)).getData();
|
||||||
|
@ -91,7 +90,6 @@ public class Transaction {
|
||||||
byte[] s = ((RLPItem) rawData.getElement(9)).getData();
|
byte[] s = ((RLPItem) rawData.getElement(9)).getData();
|
||||||
this.signature = ECDSASignature.fromComponents(r, s, v);
|
this.signature = ECDSASignature.fromComponents(r, s, v);
|
||||||
} else throw new Error("Wrong tx data element list size");
|
} else throw new Error("Wrong tx data element list size");
|
||||||
|
|
||||||
this.parsed = true;
|
this.parsed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +146,10 @@ public class Transaction {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isContract() {
|
||||||
|
return this.receiveAddress.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
* Crypto
|
* Crypto
|
||||||
*/
|
*/
|
||||||
|
@ -172,7 +174,7 @@ public class Transaction {
|
||||||
ECKey key = ECKey.fromPrivate(privKeyBytes);
|
ECKey key = ECKey.fromPrivate(privKeyBytes);
|
||||||
this.signature = key.sign(hash);
|
this.signature = key.sign(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (!parsed) rlpParse();
|
if (!parsed) rlpParse();
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
package org.ethereum.vm;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instruction set for the Ethereum Virtual Machine
|
||||||
|
*/
|
||||||
|
public enum OpCode {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop and Arithmetic Operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
STOP(0x00),
|
||||||
|
ADD(0x01),
|
||||||
|
MUL(0x02),
|
||||||
|
SUB(0x03),
|
||||||
|
DIV(0x04),
|
||||||
|
SDIV(0x05),
|
||||||
|
MOD(0x06),
|
||||||
|
SMOD(0x07),
|
||||||
|
EXP(0x08),
|
||||||
|
NEG(0x09),
|
||||||
|
LT(0x0a),
|
||||||
|
GT(0x0b),
|
||||||
|
EQ(0x0c),
|
||||||
|
NOT(0x0d),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitwise Logic Operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
AND(0x10),
|
||||||
|
OR(0x11),
|
||||||
|
XOR(0x12),
|
||||||
|
BYTE(0x13),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SHA3
|
||||||
|
*/
|
||||||
|
|
||||||
|
SHA3(0x20),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Environmental Information
|
||||||
|
*/
|
||||||
|
|
||||||
|
ADDRESS(0x30),
|
||||||
|
BALANCE(0x31),
|
||||||
|
ORIGIN(0x32),
|
||||||
|
CALLER(0x33),
|
||||||
|
CALLVALUE(0x34),
|
||||||
|
CALLDATALOAD(0x35),
|
||||||
|
CALLDATASIZE(0x36),
|
||||||
|
CALLDATACOPY(0x37),
|
||||||
|
CODESIZE(0x38),
|
||||||
|
CODECOPY(0x39),
|
||||||
|
GASPRICE(0x3a),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Block Information
|
||||||
|
*/
|
||||||
|
|
||||||
|
PREVHASH(0x40),
|
||||||
|
COINBASE(0x41),
|
||||||
|
TIMESTAMP(0x42),
|
||||||
|
NUMBER(0x43),
|
||||||
|
DIFFICULTY(0x44),
|
||||||
|
GASLIMIT(0x45),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory, Storage and Flow Operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
POP(0x50),
|
||||||
|
DUP(0x51),
|
||||||
|
SWAP(0x52),
|
||||||
|
MLOAD(0x53),
|
||||||
|
MSTORE(0x54),
|
||||||
|
MSTORE8(0x55),
|
||||||
|
SLOAD(0x56),
|
||||||
|
SSTORE(0x57),
|
||||||
|
JUMP(0x58),
|
||||||
|
JUMPI(0x59),
|
||||||
|
PC(0x5a),
|
||||||
|
MSIZE(0x5b),
|
||||||
|
GAS(0x5c),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Push Operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
PUSH1(0x60),
|
||||||
|
PUSH2(0x61),
|
||||||
|
PUSH3(0x62),
|
||||||
|
PUSH4(0x63),
|
||||||
|
PUSH5(0x64),
|
||||||
|
PUSH6(0x65),
|
||||||
|
PUSH7(0x66),
|
||||||
|
PUSH8(0x67),
|
||||||
|
PUSH9(0x68),
|
||||||
|
PUSH10(0x69),
|
||||||
|
PUSH11(0x6a),
|
||||||
|
PUSH12(0x6b),
|
||||||
|
PUSH13(0x6c),
|
||||||
|
PUSH14(0x6d),
|
||||||
|
PUSH15(0x6e),
|
||||||
|
PUSH16(0x6f),
|
||||||
|
PUSH17(0x70),
|
||||||
|
PUSH18(0x71),
|
||||||
|
PUSH19(0x72),
|
||||||
|
PUSH20(0x73),
|
||||||
|
PUSH21(0x74),
|
||||||
|
PUSH22(0x75),
|
||||||
|
PUSH23(0x76),
|
||||||
|
PUSH24(0x77),
|
||||||
|
PUSH25(0x78),
|
||||||
|
PUSH26(0x79),
|
||||||
|
PUSH27(0x7a),
|
||||||
|
PUSH28(0x7b),
|
||||||
|
PUSH29(0x7c),
|
||||||
|
PUSH30(0x7d),
|
||||||
|
PUSH31(0x7e),
|
||||||
|
PUSH32(0x7f),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* System operations
|
||||||
|
*/
|
||||||
|
|
||||||
|
CREATE(0xf0),
|
||||||
|
CALL(0xf1),
|
||||||
|
RETURN(0xf2),
|
||||||
|
SUICIDE(0xff);
|
||||||
|
|
||||||
|
private byte opcode;
|
||||||
|
|
||||||
|
private static final Map<Byte, OpCode> intToTypeMap = new HashMap<Byte, OpCode>();
|
||||||
|
static {
|
||||||
|
for (OpCode type : OpCode.values()) {
|
||||||
|
intToTypeMap.put(type.opcode, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpCode(int op) {
|
||||||
|
this.opcode = (byte) op;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OpCode fromInt(int i) {
|
||||||
|
OpCode type = intToTypeMap.get(i);
|
||||||
|
if (type == null)
|
||||||
|
return OpCode.STOP;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int asInt() {
|
||||||
|
return opcode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -117,8 +117,7 @@ public class ECKeyTest {
|
||||||
ECKey key = ECKey.fromPublicOnly(pubKey);
|
ECKey key = ECKey.fromPublicOnly(pubKey);
|
||||||
BigInteger r = new BigInteger("28157690258821599598544026901946453245423343069728565040002908283498585537001");
|
BigInteger r = new BigInteger("28157690258821599598544026901946453245423343069728565040002908283498585537001");
|
||||||
BigInteger s = new BigInteger("30212485197630673222315826773656074299979444367665131281281249560925428307087");
|
BigInteger s = new BigInteger("30212485197630673222315826773656074299979444367665131281281249560925428307087");
|
||||||
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
|
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 28);
|
||||||
sig.v = 28;
|
|
||||||
key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
|
key.verify(HashUtil.sha3(exampleMessage.getBytes()), sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,8 +125,7 @@ public class ECKeyTest {
|
||||||
public void testVerifySignature2() {
|
public void testVerifySignature2() {
|
||||||
BigInteger r = new BigInteger("c52c114d4f5a3ba904a9b3036e5e118fe0dbb987fe3955da20f2cd8f6c21ab9c", 16);
|
BigInteger r = new BigInteger("c52c114d4f5a3ba904a9b3036e5e118fe0dbb987fe3955da20f2cd8f6c21ab9c", 16);
|
||||||
BigInteger s = new BigInteger("6ba4c2874299a55ad947dbc98a25ee895aabf6b625c26c435e84bfd70edf2f69", 16);
|
BigInteger s = new BigInteger("6ba4c2874299a55ad947dbc98a25ee895aabf6b625c26c435e84bfd70edf2f69", 16);
|
||||||
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray());
|
ECDSASignature sig = ECDSASignature.fromComponents(r.toByteArray(), s.toByteArray(), (byte) 0x1b);
|
||||||
sig.v = 0x1b;
|
|
||||||
byte[] rawtx = Hex.decode("f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480");
|
byte[] rawtx = Hex.decode("f82804881bc16d674ec8000094cd2a3d9f938e13cd947ec05abc7fe734df8dd8268609184e72a0006480");
|
||||||
try {
|
try {
|
||||||
ECKey key = ECKey.signatureToKey(HashUtil.sha3(rawtx), sig.toBase64());
|
ECKey key = ECKey.signatureToKey(HashUtil.sha3(rawtx), sig.toBase64());
|
||||||
|
|
|
@ -378,7 +378,6 @@ public class MessagesTest {
|
||||||
List<Block> list = blocksMessage.getBlockDataList();
|
List<Block> list = blocksMessage.getBlockDataList();
|
||||||
System.out.println(blocksMessage);
|
System.out.println(blocksMessage);
|
||||||
|
|
||||||
|
|
||||||
assertEquals(32, list.size());
|
assertEquals(32, list.size());
|
||||||
|
|
||||||
Block block = list.get(31);
|
Block block = list.get(31);
|
||||||
|
|
Loading…
Reference in New Issue