From 40b0749304b783acdad97a931fab4b8fec134f42 Mon Sep 17 00:00:00 2001 From: Yaroslav Dmytrotsa Date: Tue, 16 Jun 2015 16:45:28 +0300 Subject: [PATCH] add JOSN-RPC methods. many of them have questions to Roman, shh_ method must wait till Roman finish create whisper protocol. Will try to schedule online meeting with Roman today to get answers / advice. --- .../android/jsonrpc/JsonRpcServer.java | 45 ++++ .../android/jsonrpc/JsonRpcServerMethod.java | 180 ++++++++++++++++ .../android/jsonrpc/filter/FilterBase.java | 30 +++ .../android/jsonrpc/filter/FilterBlock.java | 38 ++++ .../android/jsonrpc/filter/FilterLog.java | 199 ++++++++++++++++++ .../android/jsonrpc/filter/FilterManager.java | 98 +++++++++ .../jsonrpc/filter/FilterTransaction.java | 38 ++++ .../android/jsonrpc/method/db_getHex.java | 23 ++ .../android/jsonrpc/method/db_getString.java | 23 ++ .../android/jsonrpc/method/db_putHex.java | 23 ++ .../android/jsonrpc/method/db_putString.java | 23 ++ .../android/jsonrpc/method/eth_call.java | 61 ++++++ .../jsonrpc/method/eth_compileLLL.java | 33 +++ .../jsonrpc/method/eth_compileSerpent.java | 55 +++++ .../jsonrpc/method/eth_compileSolidity.java | 33 +++ .../jsonrpc/method/eth_estimateGas.java | 61 ++++++ .../jsonrpc/method/eth_getBlockByHash.java | 39 ++++ .../jsonrpc/method/eth_getBlockByNumber.java | 47 +++++ .../jsonrpc/method/eth_getCompilers.java | 27 +++ .../jsonrpc/method/eth_getFilterChanges.java | 31 +++ .../jsonrpc/method/eth_getFilterLogs.java | 31 +++ .../android/jsonrpc/method/eth_getLogs.java | 30 +++ ...eth_getTransactionByBlockHashAndIndex.java | 49 +++++ ...h_getTransactionByBlockNumberAndIndex.java | 57 +++++ .../method/eth_getTransactionByHash.java | 37 ++++ .../eth_getUncleByBlockHashAndIndex.java | 41 ++++ .../eth_getUncleByBlockNumberAndIndex.java | 49 +++++ .../eth_getUncleCountByBlockNumber.java | 2 +- .../android/jsonrpc/method/eth_getWork.java | 23 ++ .../jsonrpc/method/eth_newBlockFilter.java | 24 +++ .../android/jsonrpc/method/eth_newFilter.java | 32 +++ .../eth_newPendingTransactionFilter.java | 25 +++ .../jsonrpc/method/eth_sendTransaction.java | 62 +----- .../jsonrpc/method/eth_submitWork.java | 35 +++ .../jsonrpc/method/eth_uninstallFilter.java | 31 +++ .../jsonrpc/method/shh_addToGroup.java | 32 +++ .../jsonrpc/method/shh_getFilterChanges.java | 32 +++ .../jsonrpc/method/shh_getMessages.java | 32 +++ .../jsonrpc/method/shh_hasIdentity.java | 32 +++ .../android/jsonrpc/method/shh_newFilter.java | 38 ++++ .../android/jsonrpc/method/shh_newGroup.java | 23 ++ .../jsonrpc/method/shh_newIdentity.java | 23 ++ .../android/jsonrpc/method/shh_post.java | 60 ++++++ .../jsonrpc/method/shh_uninstallFilter.java | 32 +++ .../android/jsonrpc/method/shh_version.java | 22 ++ .../android/jsonrpc/whisper/Filter.java | 86 ++++++++ .../jsonrpc/whisper/FilterManager.java | 80 +++++++ 47 files changed, 2068 insertions(+), 59 deletions(-) create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBase.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBlock.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterLog.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterManager.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterTransaction.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getHex.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getString.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putHex.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putString.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_call.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileLLL.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSerpent.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSolidity.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_estimateGas.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByHash.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByNumber.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCompilers.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterChanges.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterLogs.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getLogs.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockHashAndIndex.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockNumberAndIndex.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByHash.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockHashAndIndex.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockNumberAndIndex.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getWork.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newBlockFilter.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newFilter.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newPendingTransactionFilter.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_submitWork.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_uninstallFilter.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_addToGroup.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getFilterChanges.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getMessages.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_hasIdentity.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newFilter.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newGroup.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newIdentity.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_post.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_uninstallFilter.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_version.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/Filter.java create mode 100644 ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/FilterManager.java diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java index 1d9dd968..c46cf2b3 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServer.java @@ -28,6 +28,7 @@ import io.netty.util.CharsetUtil; import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.channel.ChannelFuture; +import org.ethereum.android.jsonrpc.filter.FilterManager; import org.ethereum.facade.Ethereum; import com.thetransactioncompany.jsonrpc2.*; import com.thetransactioncompany.jsonrpc2.server.*; @@ -48,11 +49,14 @@ public final class JsonRpcServer { this.ethereum = ethereum; this.dispatcher = new Dispatcher(); + this.dispatcher.register(new web3_clientVersion(this.ethereum)); this.dispatcher.register(new web3_sha3(this.ethereum)); + this.dispatcher.register(new net_version(this.ethereum)); this.dispatcher.register(new net_listening(this.ethereum)); this.dispatcher.register(new net_peerCount(this.ethereum)); + this.dispatcher.register(new eth_protocolVersion(this.ethereum)); this.dispatcher.register(new eth_coinbase(this.ethereum)); this.dispatcher.register(new eth_mining(this.ethereum)); @@ -70,6 +74,47 @@ public final class JsonRpcServer { this.dispatcher.register(new eth_getCode(this.ethereum)); this.dispatcher.register(new eth_sign(this.ethereum)); this.dispatcher.register(new eth_sendTransaction(this.ethereum)); + this.dispatcher.register(new eth_call(this.ethereum)); + this.dispatcher.register(new eth_estimateGas(this.ethereum)); + this.dispatcher.register(new eth_getBlockByHash(this.ethereum)); + this.dispatcher.register(new eth_getBlockByNumber(this.ethereum)); + this.dispatcher.register(new eth_getTransactionByHash(this.ethereum)); + this.dispatcher.register(new eth_getTransactionByBlockHashAndIndex(this.ethereum)); + this.dispatcher.register(new eth_getTransactionByBlockNumberAndIndex(this.ethereum)); + this.dispatcher.register(new eth_getUncleByBlockHashAndIndex(this.ethereum)); + this.dispatcher.register(new eth_getUncleByBlockNumberAndIndex(this.ethereum)); + this.dispatcher.register(new eth_getCompilers(this.ethereum)); + this.dispatcher.register(new eth_compileSolidity(this.ethereum)); + this.dispatcher.register(new eth_compileLLL(this.ethereum)); + this.dispatcher.register(new eth_compileSerpent(this.ethereum)); + this.dispatcher.register(new eth_newFilter(this.ethereum)); + this.dispatcher.register(new eth_newBlockFilter(this.ethereum)); + this.dispatcher.register(new eth_newPendingTransactionFilter(this.ethereum)); + this.dispatcher.register(new eth_uninstallFilter(this.ethereum)); + this.dispatcher.register(new eth_getFilterChanges(this.ethereum)); + this.dispatcher.register(new eth_getFilterLogs(this.ethereum)); + this.dispatcher.register(new eth_getLogs(this.ethereum)); + this.dispatcher.register(new eth_getWork(this.ethereum)); + this.dispatcher.register(new eth_submitWork(this.ethereum)); + + this.dispatcher.register(new db_putString(this.ethereum)); + this.dispatcher.register(new db_getString(this.ethereum)); + this.dispatcher.register(new db_putHex(this.ethereum)); + this.dispatcher.register(new db_getHex(this.ethereum)); + + this.dispatcher.register(new shh_version(this.ethereum)); + this.dispatcher.register(new shh_post(this.ethereum)); + this.dispatcher.register(new shh_newIdentity(this.ethereum)); + this.dispatcher.register(new shh_hasIdentity(this.ethereum)); + this.dispatcher.register(new shh_newGroup(this.ethereum)); + this.dispatcher.register(new shh_addToGroup(this.ethereum)); + this.dispatcher.register(new shh_newFilter(this.ethereum)); + this.dispatcher.register(new shh_uninstallFilter(this.ethereum)); + this.dispatcher.register(new shh_getFilterChanges(this.ethereum)); + this.dispatcher.register(new shh_getMessages(this.ethereum)); + + FilterManager.getInstance(); + org.ethereum.android.jsonrpc.whisper.FilterManager.getInstance(); } public void start() throws Exception { diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java index d6e801cb..dbe755f0 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/JsonRpcServerMethod.java @@ -3,11 +3,18 @@ package org.ethereum.android.jsonrpc; import com.thetransactioncompany.jsonrpc2.*; import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; + import org.ethereum.android.jsonrpc.JsonRpcServer; import org.ethereum.core.Account; import org.ethereum.core.AccountState; +import org.ethereum.core.Block; +import org.ethereum.core.BlockHeader; import org.ethereum.core.Transaction; +import org.ethereum.crypto.HashUtil; import org.ethereum.facade.Ethereum; +import org.ethereum.util.RLP; import org.ethereum.vm.DataWord; import org.spongycastle.util.encoders.Hex; @@ -15,6 +22,8 @@ import java.math.BigInteger; import java.util.Arrays; import java.util.List; +import static org.ethereum.core.Denomination.SZABO; + public abstract class JsonRpcServerMethod implements RequestHandler { private String name = ""; @@ -74,4 +83,175 @@ public abstract class JsonRpcServerMethod implements RequestHandler { protected BigInteger jsToBigInteger(String data) { return new BigInteger(data.substring(2), 16); } + + protected Transaction jsToTransaction(JSONObject obj) throws Exception { + if ((!obj.containsKey("to") || ((String)obj.get("to")).equals("")) && (!obj.containsKey("data") || ((String)obj.get("data")).equals(""))) { + throw new Exception(""); + } + + byte[] from = ((Account) ethereum.getWallet().getAccountCollection().toArray()[1]).getEcKey().getAddress(); + if (obj.containsKey("from") && !((String)obj.get("from")).equals("")) { + from = jsToAddress((String) obj.get("from")); + } + Account acc = null; + for (Account ac : ethereum.getWallet().getAccountCollection()) { + if (Arrays.equals(ac.getAddress(), from)) { + acc = ac; + break; + } + } + if (acc == null) { + throw new Exception(""); + } + + byte[] senderPrivKey = acc.getEcKey().getPrivKeyBytes(); + + // default - from ethereumj-studio + byte[] to = null; + if (obj.containsKey("to") && !((String)obj.get("to")).equals("")) { + to = jsToAddress((String) obj.get("to")); + } + + // default - from ethereumj-studio + BigInteger gasPrice = SZABO.value().multiply(BigInteger.TEN); + if (obj.containsKey("gasPrice") && !((String)obj.get("gasPrice")).equals("")) { + gasPrice = jsToBigInteger((String) obj.get("gasPrice")); + } + + // default - from cpp-ethereum + BigInteger gas = acc.getBalance().divide(gasPrice); + BigInteger gasBBRemaining = new BigInteger(Long.toString((ethereum.getBlockchain().getBestBlock().getGasLimit() - ethereum.getBlockchain().getBestBlock().getGasUsed()) / 5)); + if (gasBBRemaining.compareTo(gas) < 0) + gas = gasBBRemaining; + if (obj.containsKey("gas") && !((String)obj.get("gas")).equals("")) { + gas = jsToBigInteger((String) obj.get("gas")); + } + + // default - from ethereumj-studio + BigInteger value = new BigInteger("1000"); + if (obj.containsKey("value") && !((String)obj.get("value")).equals("")) { + value = jsToBigInteger((String) obj.get("value")); + } + + // default - from ethereumj-studio + BigInteger nonce = ethereum.getRepository().getNonce(acc.getAddress()); + if (obj.containsKey("nonce") && !((String)obj.get("nonce")).equals("")) { + nonce = jsToBigInteger((String) obj.get("nonce")); + } + + // default - from ethereumj-studio + byte[] data = new byte[]{}; + if (obj.containsKey("data") && !((String)obj.get("data")).equals("")) { + data = jsToAddress((String) obj.get("data")); + } + + Transaction tx = ethereum.createTransaction(nonce, gasPrice, gas, to, value, data); + + tx.sign(senderPrivKey); + + return tx; + } + + protected JSONObject blockToJS (Block block, Boolean detailed) { + JSONObject res = new JSONObject(); + if (block == null) + return null; + + res.put("number", "0x" + Long.toHexString(block.getNumber())); + + res.put("hash", "0x" + Hex.toHexString(block.getHash())); + + res.put("parentHash", "0x" + Hex.toHexString(block.getParentHash())); + + res.put("nonce", "0x" + Hex.toHexString(block.getNonce())); + + res.put("sha3Uncles", "0x" + Hex.toHexString(block.getUnclesHash())); + + res.put("logsBloom", "0x" + Hex.toHexString(block.getLogBloom())); + + res.put("transactionsRoot", "0x" + Hex.toHexString(block.getHeader().getTxTrieRoot())); + + res.put("stateRoot", "0x" + Hex.toHexString(block.getStateRoot())); + + res.put("miner", "0x" + Hex.toHexString(block.getCoinbase())); + + res.put("difficulty", "0x" + block.getDifficultyBI().toString(16)); + + res.put("totalDifficulty", "0x" + block.getCumulativeDifficulty().toString(16)); + + res.put("extraData", "0x" + Hex.toHexString(block.getExtraData())); + + // No way to get size of block in bytes, so I try calculate it using formula from getEncoded + byte[] header = block.getHeader().getEncoded(); + byte[] transactions = RLP.encodeList(); + byte[][] unclesEncoded = new byte[block.getUncleList().size()][]; + int i = 0; + for (BlockHeader uncle : block.getUncleList()) { + unclesEncoded[i] = uncle.getEncoded(); + ++i; + } + byte[] uncles = RLP.encodeList(unclesEncoded); + byte[] rlpEncoded = RLP.encodeList(header, transactions, uncles); + res.put("size", "0x" + Integer.toHexString(rlpEncoded.length)); + + res.put("gasLimit", "0x" + Long.toHexString(block.getGasLimit())); + + res.put("gasUsed", "0x" + Long.toHexString(block.getGasUsed())); + + res.put("timestamp", "0x" + Long.toHexString(block.getTimestamp())); + + JSONArray transactionsJA = new JSONArray(); + i = 0; + for (Transaction transaction : block.getTransactionsList()) { + if (detailed) { + JSONObject tx = transactionToJS(transaction); + tx.put("transactionIndex", "0x" + Integer.toHexString(i)); + tx.put("blockHash", "0x" + Hex.toHexString(block.getHash())); + tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber())); + transactionsJA.add(tx); + } else { + transactionsJA.add("0x" + Hex.toHexString(transaction.getHash())); + } + ++i; + } + res.put("transactions", transactionsJA); + + //TODO: ask if I correctly get uncle's hash (takes form -core right now) + JSONArray unclesJA = new JSONArray(); + for (BlockHeader uncle : block.getUncleList()) { + unclesJA.add("0x" + Hex.toHexString(HashUtil.sha3(uncle.getEncoded()))); + } + res.put("uncles", unclesJA); + + return res; + } + + protected JSONObject transactionToJS (Transaction transaction) { + JSONObject res = new JSONObject(); + + res.put("hash", "0x" + Hex.toHexString(transaction.getHash())); + + res.put("nonce", "0x" + Hex.toHexString(transaction.getNonce())); + + res.put("from", "0x" + Hex.toHexString(transaction.getSender())); + + res.put("to", "0x" + Hex.toHexString(transaction.getReceiveAddress())); + + res.put("value", "0x" + Hex.toHexString(transaction.getValue())); + + res.put("gasPrice", "0x" + Hex.toHexString(transaction.getGasPrice())); + + res.put("gas", "0x" + Hex.toHexString(transaction.getGasLimit())); + + res.put("input", "0x" + Hex.toHexString(transaction.getData())); + +/* + No way to get this data from inside of transaction. + TODO: Ask roman to include it into transaction class. + res.put("transactionIndex", "0x" + ""); + res.put("blockHash", "0x" + ""); + res.put("blockNumber", "0x" + ""); +*/ + return res; + } } \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBase.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBase.java new file mode 100644 index 00000000..3f3d83fb --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBase.java @@ -0,0 +1,30 @@ +package org.ethereum.android.jsonrpc.filter; + +import net.minidev.json.JSONArray; + +import org.ethereum.facade.Ethereum; + +public abstract class FilterBase { + protected int id; + protected long lastRequest = System.currentTimeMillis(); + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public long getLastRequestTime() { + return lastRequest; + } + + protected void updateLastRequest() { + lastRequest = System.currentTimeMillis(); + } + + public abstract void processEvent(Object data); + public abstract JSONArray toJS(); + public abstract JSONArray toJS(Ethereum ethereum); +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBlock.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBlock.java new file mode 100644 index 00000000..dab9cdba --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterBlock.java @@ -0,0 +1,38 @@ +package org.ethereum.android.jsonrpc.filter; + +import net.minidev.json.JSONArray; +import org.ethereum.core.Block; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.util.ArrayList; + + +public class FilterBlock extends FilterBase { + + private ArrayList blocks = new ArrayList(); + + public void processEvent(Object data) { + if (data instanceof Block) { + synchronized (blocks) { + blocks.add("0x" + Hex.toHexString(((Block) data).getHash())); + } + } + } + + public JSONArray toJS() { + updateLastRequest(); + JSONArray res = new JSONArray(); + synchronized (blocks) { + for(String item : blocks) { + res.add(item); + } + blocks.clear(); + } + return res; + } + + public JSONArray toJS(Ethereum ethereum) { + return null; + } + +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterLog.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterLog.java new file mode 100644 index 00000000..a2c2c09b --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterLog.java @@ -0,0 +1,199 @@ +package org.ethereum.android.jsonrpc.filter; + +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; + +import org.ethereum.core.Block; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionReceipt; +import org.ethereum.facade.Ethereum; +import org.ethereum.vm.DataWord; +import org.ethereum.vm.LogInfo; +import org.spongycastle.util.encoders.Hex; +import java.util.ArrayList; +import java.util.Arrays; + +/* +Right now LogInfo not contains information about Transaction and Transaction not have information about block. +TODO: talk to Roman about create links between LogInfo and Transaction and between Transaction and Block. +*/ +public class FilterLog extends FilterBase { + + private ArrayList logs = new ArrayList(); + + long blockFrom; + long blockTo; + ArrayList addresses = new ArrayList<>(); + ArrayList topics = new ArrayList<>(); + + public FilterLog (Ethereum ethereum, JSONObject data) { + blockFrom = ethereum.getBlockchain().getBestBlock().getNumber(); + if (data.containsKey("fromBlock") && !((String)data.get("fromBlock")).equals("")) { + String fromS = (String)data.get("fromBlock"); + if (fromS.equals("latest")) { + } else if (fromS.equals("pending") || fromS.equals("earliest")) { + blockFrom = -1; + } else { + blockFrom = Long.parseLong(fromS.substring(2), 16); + } + } + + blockTo = ethereum.getBlockchain().getBestBlock().getNumber(); + if (data.containsKey("toBlock") && !((String)data.get("toBlock")).equals("")) { + String fromS = (String)data.get("toBlock"); + if (fromS.equals("latest")) { + } else if (fromS.equals("pending") || fromS.equals("earliest")) { + blockTo = -1; + } else { + blockTo = Long.parseLong(fromS.substring(2), 16); + } + } + + if (data.containsKey("address")) { + if (data.get("address") instanceof String) { + addresses.add(Hex.decode(((String) data.get("address")).substring(2))); + } else if (data.get("address") instanceof JSONArray){ + for (Object item : (JSONArray)data.get("address")) { + if (item instanceof String) { + addresses.add(Hex.decode(((String) item).substring(2))); + } + } + } + } + + if (data.containsKey("topics")) { + if (data.get("topics") instanceof String) { + topics.add(Hex.decode(((String) data.get("topics")).substring(2))); + } else if (data.get("topics") instanceof JSONArray){ + for (Object item : (JSONArray)data.get("topics")) { + if (item instanceof String) { + topics.add(Hex.decode(((String) item).substring(2))); + } + } + } + } + } + +/* +TODO: Right now Bloom from -core can be used only to check total mach of 2 same class objects. Will be nice to have possibility to check contains. +*/ + public void processEvent(Object data) { + if (data instanceof LogInfo) { + synchronized (logs) { + LogInfo li = (LogInfo)data; + //TODO: check if li inside blockFrom - blockTo + + if (checkLogInfo(li)) + logs.add(li); + } + } + } + + public JSONArray toJS() { + updateLastRequest(); + JSONArray res = new JSONArray(); + synchronized (logs) { + for(LogInfo item : logs) { + res.add(logInfoToJS(item)); + } + logs.clear(); + } + return res; + } + + public JSONArray toJS(Ethereum ethereum) { + JSONArray res = new JSONArray(); + +// Process mined blocks + if (blockFrom >= 0) { + long i = blockFrom; + while (true) { + Block block = ethereum.getBlockchain().getBlockByNumber(i); + if (block == null) + break; + for (Transaction tx : block.getTransactionsList()) { + TransactionReceipt txr = ethereum.getBlockchain().getTransactionReceiptByHash(tx.getHash()); + if (txr != null) { + for (LogInfo li : txr.getLogInfoList()) { + if (checkLogInfo(li)) + res.add(logInfoToJS(li)); + } + } + } + i++; + } + } + +/* +Process pending transactions. But not sure if BlockChain can return TransactionReceipt for pending transaction. +*/ + if (blockFrom < 0 || blockTo < 0) { + for (Transaction tx : ethereum.getPendingTransactions()) { + TransactionReceipt txr = ethereum.getBlockchain().getTransactionReceiptByHash(tx.getHash()); + if (txr != null) { + for (LogInfo li : txr.getLogInfoList()) { + if (checkLogInfo(li)) + res.add(logInfoToJS(li)); + } + } + } + } + + return res; + } + + + private boolean checkLogInfo(LogInfo li) { + boolean found = false; + for (byte[] address : addresses) { + if (Arrays.equals(address, li.getAddress())) { + found = true; + break; + } + } + if (!found) + return false; + + found = false; + for (byte[] topic : topics) { + for (DataWord litopic : li.getTopics()) { + if (Arrays.equals(topic, litopic.getData())) { + found = true; + break; + } + } + if (found) + break; + } + if (!found) + return false; + + return true; + } + + private JSONObject logInfoToJS(LogInfo li) { + JSONObject res = new JSONObject(); + +/* +TODO: check here if log's transaction / block mined or pending. +*/ + res.put("type", "pending"); + res.put("logIndex", null); + res.put("transactionIndex", null); + res.put("transactionHash", null); + res.put("blockHash", null); + res.put("blockNumber", null); + + res.put("address", Hex.toHexString(li.getAddress())); + + res.put("data", Hex.toHexString(li.getData())); + + JSONArray topics = new JSONArray(); + for (DataWord topic : li.getTopics()) { + topics.add(Hex.toHexString(topic.getData())); + } + res.put("topics", topics); + + return res; + } +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterManager.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterManager.java new file mode 100644 index 00000000..ba95d74c --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterManager.java @@ -0,0 +1,98 @@ +package org.ethereum.android.jsonrpc.filter; + +import net.minidev.json.JSONArray; + +import org.ethereum.facade.Ethereum; + +import java.util.Hashtable; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +/* +This class must receive notification from -core about new log, Block, Transaction. Right now I not see the way todo that. +TODO: ask advice from Roman about how to send notification to this class. +*/ +public class FilterManager { + + protected static FilterManager instance = null; + + public static FilterManager getInstance() { + if (instance == null) + instance = new FilterManager(); + return instance; + } + + private Timer timer = null; + private long filterAutoUninstall = TimeUnit.MINUTES.toMillis(5); + + protected Hashtable filters; + protected int last_id = 0; + + private FilterManager() { + filters = new Hashtable(); + + timer = new Timer(); + timer.schedule(new TimerTask() { + @Override + public void run() { + long now = System.currentTimeMillis(); + synchronized (filters) { + for (Map.Entry item : filters.entrySet()) { + if (now - item.getValue().getLastRequestTime() >= filterAutoUninstall) { + filters.remove(item.getKey()); + } + } + } + } + }, TimeUnit.MINUTES.toMillis(1)); + } + + public void processEvent(Object data) { + synchronized (filters) { + for (Map.Entry item : filters.entrySet()) { + item.getValue().processEvent(data); + } + } + } + + public int addFilter(FilterBase filter) { + filter.setId(++last_id); + filters.put(filter.getId(), filter); + return filter.getId(); + } + + public FilterBase getFilter(int id) { + if (filters.containsKey(id)) { + return filters.get(id); + } + return null; + } + + public boolean uninstallFilter(int id) { + synchronized (filters) { + if (!filters.containsKey(id)) + return false; + filters.remove(id); + } + return true; + } + + public JSONArray toJS(int id) { + synchronized (filters) { + if (!filters.containsKey(id)) + return null; + return filters.get(id).toJS(); + } + } + + public JSONArray toJS(int id, Ethereum ethereum) { + synchronized (filters) { + if (!filters.containsKey(id)) + return null; + return filters.get(id).toJS(ethereum); + } + } + +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterTransaction.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterTransaction.java new file mode 100644 index 00000000..ec2ce3aa --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/filter/FilterTransaction.java @@ -0,0 +1,38 @@ +package org.ethereum.android.jsonrpc.filter; + +import net.minidev.json.JSONArray; +import org.ethereum.core.Transaction; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.util.ArrayList; + + +public class FilterTransaction extends FilterBase { + + private ArrayList transactions = new ArrayList(); + + public void processEvent(Object data) { + if (data instanceof Transaction) { + synchronized (transactions) { + transactions.add("0x" + Hex.toHexString(((Transaction) data).getHash())); + } + } + } + + public JSONArray toJS() { + updateLastRequest(); + JSONArray res = new JSONArray(); + synchronized (transactions) { + for(String item : transactions) { + res.add(item); + } + transactions.clear(); + } + return res; + } + + public JSONArray toJS(Ethereum ethereum) { + return null; + } + +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getHex.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getHex.java new file mode 100644 index 00000000..fd924ce6 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getHex.java @@ -0,0 +1,23 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +/* +Deprecated +*/ +public class db_getHex extends JsonRpcServerMethod { + + public db_getHex (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getString.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getString.java new file mode 100644 index 00000000..9d68fef5 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_getString.java @@ -0,0 +1,23 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +/* +Deprecated +*/ +public class db_getString extends JsonRpcServerMethod { + + public db_getString (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putHex.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putHex.java new file mode 100644 index 00000000..db36d9ca --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putHex.java @@ -0,0 +1,23 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +/* +Deprecated +*/ +public class db_putHex extends JsonRpcServerMethod { + + public db_putHex (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putString.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putString.java new file mode 100644 index 00000000..d542f6c6 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/db_putString.java @@ -0,0 +1,23 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +/* +Deprecated +*/ +public class db_putString extends JsonRpcServerMethod { + + public db_putString (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_call.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_call.java new file mode 100644 index 00000000..b1b68317 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_call.java @@ -0,0 +1,61 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONObject; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.Transaction; +import org.ethereum.facade.Ethereum; +import org.ethereum.vm.Program; +import org.ethereum.vm.VM; +import org.spongycastle.util.encoders.Hex; +import java.util.List; + +/* +It's magic here, not sure if -core have this possibility at all. I found this in test and studio. But not sure that getHReturn it's what specification mean. +TODO: get advice from Roman +*/ +public class eth_call extends JsonRpcServerMethod { + + public eth_call (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + JSONObject obj = (JSONObject)params.get(0); + Transaction tx; + try { + tx = jsToTransaction(obj); + } catch (Exception e) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } + + String height = (String)params.get(1); + long blockNumber = getBlockNumber(height); + byte[] root = ethereum.getBlockchain().getBestBlock().getStateRoot(); + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(ethereum.getBlockchain().getBlockByNumber(blockNumber).getStateRoot()); + } + + VM vm = new VM(); + Program program = new Program(tx.getData(), null); + vm.play(program); + byte[] result = program.getResult().getHReturn(); + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(root); + } + + String tmp = "0x" + Hex.toHexString(result); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileLLL.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileLLL.java new file mode 100644 index 00000000..1bc571c7 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileLLL.java @@ -0,0 +1,33 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; + +/* +TODO: -core not have lll compiler +*/ +public class eth_compileLLL extends JsonRpcServerMethod { + + public eth_compileLLL (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String code = (String)params.get(0); + + return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSerpent.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSerpent.java new file mode 100644 index 00000000..fbf88f46 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSerpent.java @@ -0,0 +1,55 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.facade.Ethereum; +import org.ethereum.serpent.SerpentCompiler; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/* +Example taken from -studio. Not sure if we must call encodeMachineCodeForVMRun in end +TODO: get advice from Roman about encodeMachineCodeForVMRun +*/ +public class eth_compileSerpent extends JsonRpcServerMethod { + + public eth_compileSerpent (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String code = (String)params.get(0); + String asmResult = ""; + byte[] machineCode = null; + + try { + Pattern pattern = Pattern.compile("(.*?)init:(.*?)code:(.*?)", Pattern.DOTALL); + Matcher matcher = pattern.matcher(code); + if (matcher.find()) { + asmResult = SerpentCompiler.compileFullNotion(code); + machineCode = SerpentCompiler.compileFullNotionAssemblyToMachine(asmResult); + } else { + asmResult = SerpentCompiler.compile(code); + machineCode = SerpentCompiler.compileAssemblyToMachine(asmResult); +// machineCode = SerpentCompiler.encodeMachineCodeForVMRun(machineCode, null); + } + } catch (Throwable th) { + return new JSONRPC2Response(JSONRPC2Error.INTERNAL_ERROR, req.getID()); + } + + + return new JSONRPC2Response("0x" + Hex.toHexString(machineCode), req.getID()); + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSolidity.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSolidity.java new file mode 100644 index 00000000..8f68be9b --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_compileSolidity.java @@ -0,0 +1,33 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; + +/* +TODO: -core not have solidity compiler +*/ +public class eth_compileSolidity extends JsonRpcServerMethod { + + public eth_compileSolidity (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String code = (String)params.get(0); + + return new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_estimateGas.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_estimateGas.java new file mode 100644 index 00000000..c8edab44 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_estimateGas.java @@ -0,0 +1,61 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONObject; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.Transaction; +import org.ethereum.facade.Ethereum; +import org.ethereum.vm.Program; +import org.ethereum.vm.VM; +import org.spongycastle.util.encoders.Hex; +import java.util.List; + +/* +It's magic here, not sure if -core have this possibility at all. I found this in test and studio. But not sure that getHReturn it's what specification mean. +TODO: get advice from Roman +*/ +public class eth_estimateGas extends JsonRpcServerMethod { + + public eth_estimateGas (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + JSONObject obj = (JSONObject)params.get(0); + Transaction tx; + try { + tx = jsToTransaction(obj); + } catch (Exception e) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } + + String height = (String)params.get(1); + long blockNumber = getBlockNumber(height); + byte[] root = ethereum.getBlockchain().getBestBlock().getStateRoot(); + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(ethereum.getBlockchain().getBlockByNumber(blockNumber).getStateRoot()); + } + + VM vm = new VM(); + Program program = new Program(tx.getData(), null); + vm.play(program); + long result = program.getResult().getGasUsed(); + + if (blockNumber >= 0) { + ethereum.getRepository().syncToRoot(root); + } + + String tmp = "0x" + Long.toHexString(result); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByHash.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByHash.java new file mode 100644 index 00000000..252ffe4c --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByHash.java @@ -0,0 +1,39 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.core.Block; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; + +/* +By specification this method can receive hash of pending block but from -core it's not possible. +TODO: get advice from Roman about pending block +*/ +public class eth_getBlockByHash extends JsonRpcServerMethod { + + public eth_getBlockByHash (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String) params.get(0)); + Boolean detailed = (Boolean)params.get(1); + + Block block = ethereum.getBlockchain().getBlockByHash(address); + + JSONRPC2Response res = new JSONRPC2Response(blockToJS(block, detailed), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByNumber.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByNumber.java new file mode 100644 index 00000000..e2352088 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getBlockByNumber.java @@ -0,0 +1,47 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.core.Block; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; + +/* +By specification this method can receive number of pending block but from -core it's not possible. +TODO: get advice from Roman about pending block +*/ +public class eth_getBlockByNumber extends JsonRpcServerMethod { + + public eth_getBlockByNumber (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String height = (String)params.get(0); + long blockNumber = getBlockNumber(height); + Boolean detailed = (Boolean)params.get(1); + + if (blockNumber == -1) { + blockNumber = ethereum.getBlockchain().getBestBlock().getNumber(); + } + // TODO: here we must load pending block but -core not "group" it. + if (blockNumber == -2) { + } + + Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber); + + JSONRPC2Response res = new JSONRPC2Response(blockToJS(block, detailed), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCompilers.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCompilers.java new file mode 100644 index 00000000..c5156e7b --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getCompilers.java @@ -0,0 +1,27 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; +import java.util.ArrayList; + +/* +As I see right now -core have only serpent compiler +*/ +public class eth_getCompilers extends JsonRpcServerMethod { + + public eth_getCompilers (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + ArrayList tmp = new ArrayList(); + tmp.add("serpent"); + //TODO: add lll and solidity when they will be implemented in -core + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterChanges.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterChanges.java new file mode 100644 index 00000000..3a60af7c --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterChanges.java @@ -0,0 +1,31 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONObject; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterBase; +import org.ethereum.android.jsonrpc.filter.FilterLog; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.facade.Ethereum; +import java.util.List; + +public class eth_getFilterChanges extends JsonRpcServerMethod { + + public eth_getFilterChanges (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + int id = jsToInt((String) params.get(0)); + JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJS(id), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterLogs.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterLogs.java new file mode 100644 index 00000000..204330ca --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getFilterLogs.java @@ -0,0 +1,31 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONObject; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterBase; +import org.ethereum.android.jsonrpc.filter.FilterLog; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.facade.Ethereum; +import java.util.List; + +public class eth_getFilterLogs extends JsonRpcServerMethod { + + public eth_getFilterLogs (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + int id = jsToInt((String) params.get(0)); + JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJS(id, ethereum), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getLogs.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getLogs.java new file mode 100644 index 00000000..2b129f0d --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getLogs.java @@ -0,0 +1,30 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONObject; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterLog; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.facade.Ethereum; +import java.util.List; + +public class eth_getLogs extends JsonRpcServerMethod { + + public eth_getLogs (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + JSONObject obj = (JSONObject)params.get(0); + JSONRPC2Response res = new JSONRPC2Response((new FilterLog(ethereum, obj)).toJS(ethereum), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockHashAndIndex.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockHashAndIndex.java new file mode 100644 index 00000000..7f0bcdd0 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockHashAndIndex.java @@ -0,0 +1,49 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; + +import net.minidev.json.JSONObject; + +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.core.Block; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; + +public class eth_getTransactionByBlockHashAndIndex extends JsonRpcServerMethod { + + public eth_getTransactionByBlockHashAndIndex (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String) params.get(0)); + int index = jsToInt((String) params.get(1)); + + Block block = ethereum.getBlockchain().getBlockByHash(address); + + if (block == null) + return new JSONRPC2Response(null, req.getID()); + + if (block.getTransactionsList().size() <= index) + return new JSONRPC2Response(null, req.getID()); + + JSONObject tx = transactionToJS(block.getTransactionsList().get(index)); + tx.put("transactionIndex", "0x" + Integer.toHexString(index)); + tx.put("blockHash", "0x" + Hex.toHexString(block.getHash())); + tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber())); + + JSONRPC2Response res = new JSONRPC2Response(tx, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockNumberAndIndex.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockNumberAndIndex.java new file mode 100644 index 00000000..260f0293 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByBlockNumberAndIndex.java @@ -0,0 +1,57 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; + +import net.minidev.json.JSONObject; + +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.AccountState; +import org.ethereum.core.Block; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; +import java.math.BigInteger; +import java.util.List; + +public class eth_getTransactionByBlockNumberAndIndex extends JsonRpcServerMethod { + + public eth_getTransactionByBlockNumberAndIndex (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String height = (String)params.get(0); + long blockNumber = getBlockNumber(height); + int index = jsToInt((String) params.get(1)); + + if (blockNumber == -1) { + blockNumber = ethereum.getBlockchain().getBestBlock().getNumber(); + } + // TODO: here we must load pending block but -core not "group" it. + if (blockNumber == -2) { + } + + Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber); + + if (block == null) + return new JSONRPC2Response(null, req.getID()); + + if (block.getTransactionsList().size() <= index) + return new JSONRPC2Response(null, req.getID()); + + JSONObject tx = transactionToJS(block.getTransactionsList().get(index)); + tx.put("transactionIndex", "0x" + Integer.toHexString(index)); + tx.put("blockHash", "0x" + Hex.toHexString(block.getHash())); + tx.put("blockNumber", "0x" + Long.toHexString(block.getNumber())); + + JSONRPC2Response res = new JSONRPC2Response(tx, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByHash.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByHash.java new file mode 100644 index 00000000..c9e1fc47 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getTransactionByHash.java @@ -0,0 +1,37 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.TransactionReceipt; +import org.ethereum.facade.Ethereum; +import java.util.List; + +/* +TODO: get advice from Roman about get block from transaction. +*/ +public class eth_getTransactionByHash extends JsonRpcServerMethod { + + public eth_getTransactionByHash (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String) params.get(0)); + + TransactionReceipt transaction = ethereum.getBlockchain().getTransactionReceiptByHash(address); + + if (transaction == null) + return new JSONRPC2Response(null, req.getID()); + + JSONRPC2Response res = new JSONRPC2Response(transactionToJS(transaction.getTransaction()), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockHashAndIndex.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockHashAndIndex.java new file mode 100644 index 00000000..86bb6656 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockHashAndIndex.java @@ -0,0 +1,41 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.Block; +import org.ethereum.crypto.HashUtil; +import org.ethereum.facade.Ethereum; +import java.util.List; + +public class eth_getUncleByBlockHashAndIndex extends JsonRpcServerMethod { + + public eth_getUncleByBlockHashAndIndex (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] address = jsToAddress((String) params.get(0)); + int index = jsToInt((String) params.get(1)); + + Block block = ethereum.getBlockchain().getBlockByHash(address); + + if (block == null) + return new JSONRPC2Response(null, req.getID()); + + if (block.getUncleList().size() <= index) + return new JSONRPC2Response(null, req.getID()); + + Block uncle = ethereum.getBlockchain().getBlockByHash(HashUtil.sha3(block.getUncleList().get(index).getEncoded())); + + JSONRPC2Response res = new JSONRPC2Response(blockToJS(uncle, false), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockNumberAndIndex.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockNumberAndIndex.java new file mode 100644 index 00000000..6238dd9b --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleByBlockNumberAndIndex.java @@ -0,0 +1,49 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.core.Block; +import org.ethereum.crypto.HashUtil; +import org.ethereum.facade.Ethereum; +import java.util.List; + +public class eth_getUncleByBlockNumberAndIndex extends JsonRpcServerMethod { + + public eth_getUncleByBlockNumberAndIndex (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 2) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + String height = (String)params.get(0); + long blockNumber = getBlockNumber(height); + int index = jsToInt((String) params.get(1)); + + if (blockNumber == -1) { + blockNumber = ethereum.getBlockchain().getBestBlock().getNumber(); + } + // TODO: here we must load pending block but -core not "group" it. + if (blockNumber == -2) { + } + + Block block = ethereum.getBlockchain().getBlockByNumber(blockNumber); + + if (block == null) + return new JSONRPC2Response(null, req.getID()); + + if (block.getUncleList().size() <= index) + return new JSONRPC2Response(null, req.getID()); + + Block uncle = ethereum.getBlockchain().getBlockByHash(HashUtil.sha3(block.getUncleList().get(index).getEncoded())); + + JSONRPC2Response res = new JSONRPC2Response(blockToJS(uncle, false), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java index d91fff91..c7e754d6 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getUncleCountByBlockNumber.java @@ -22,7 +22,7 @@ public class eth_getUncleCountByBlockNumber extends JsonRpcServerMethod { if (params.size() != 1) { return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); } else { - String height = (String)params.get(1); + String height = (String)params.get(0); long blockNumber = getBlockNumber(height); if (blockNumber == -1) diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getWork.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getWork.java new file mode 100644 index 00000000..871908d8 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_getWork.java @@ -0,0 +1,23 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +/* +TODO: right now -core not auto start mining so no way to get information about state +*/ +public class eth_getWork extends JsonRpcServerMethod { + + public eth_getWork (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newBlockFilter.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newBlockFilter.java new file mode 100644 index 00000000..14d982f0 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newBlockFilter.java @@ -0,0 +1,24 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterBlock; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.facade.Ethereum; + +public class eth_newBlockFilter extends JsonRpcServerMethod { + + public eth_newBlockFilter (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + int id = FilterManager.getInstance().addFilter(new FilterBlock()); + String tmp = "0x" + Integer.toHexString(id); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newFilter.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newFilter.java new file mode 100644 index 00000000..7fa16046 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newFilter.java @@ -0,0 +1,32 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONObject; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterLog; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.facade.Ethereum; +import java.util.List; + +public class eth_newFilter extends JsonRpcServerMethod { + + public eth_newFilter (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + JSONObject obj = (JSONObject)params.get(0); + int id = FilterManager.getInstance().addFilter(new FilterLog(ethereum, obj)); + String tmp = "0x" + Integer.toHexString(id); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newPendingTransactionFilter.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newPendingTransactionFilter.java new file mode 100644 index 00000000..1e7dc844 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_newPendingTransactionFilter.java @@ -0,0 +1,25 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterBlock; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.android.jsonrpc.filter.FilterTransaction; +import org.ethereum.facade.Ethereum; + +public class eth_newPendingTransactionFilter extends JsonRpcServerMethod { + + public eth_newPendingTransactionFilter (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + int id = FilterManager.getInstance().addFilter(new FilterTransaction()); + String tmp = "0x" + Integer.toHexString(id); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java index 4b1a5f00..dd659d8c 100644 --- a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_sendTransaction.java @@ -32,67 +32,13 @@ public class eth_sendTransaction extends JsonRpcServerMethod { return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); } else { JSONObject obj = (JSONObject)params.get(0); - if (!obj.containsKey("from") || (!obj.containsKey("to") && !obj.containsKey("data"))) { + Transaction tx; + try { + tx = jsToTransaction(obj); + } catch (Exception e) { return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); } - byte[] from = jsToAddress((String)obj.get("from")); - Account acc = null; - for (Account ac : ethereum.getWallet().getAccountCollection()) { - if (Arrays.equals(ac.getAddress(), from)) { - acc = ac; - break; - } - } - if (acc == null) { - return new JSONRPC2Response(JSONRPC2Error.INTERNAL_ERROR, req.getID()); - } - - byte[] senderPrivKey = acc.getEcKey().getPrivKeyBytes(); - - // default - from ethereumj-studio - byte[] to = null; - if (obj.containsKey("to") && !((String)obj.get("to")).equals("")) { - to = jsToAddress((String) obj.get("to")); - } - - // default - from ethereumj-studio - BigInteger gasPrice = SZABO.value().multiply(BigInteger.TEN); - if (obj.containsKey("gasPrice") && !((String)obj.get("gasPrice")).equals("")) { - gasPrice = jsToBigInteger((String) obj.get("gasPrice")); - } - - // default - from cpp-ethereum - BigInteger gas = acc.getBalance().divide(gasPrice); - BigInteger gasBBLimit = new BigInteger(Long.toString(ethereum.getBlockchain().getBestBlock().getGasLimit() / 5)); - if (gasBBLimit.compareTo(gas) < 0) - gas = gasBBLimit; - if (obj.containsKey("gas") && !((String)obj.get("gas")).equals("")) { - gas = jsToBigInteger((String) obj.get("gas")); - } - - // default - from ethereumj-studio - BigInteger value = new BigInteger("1000"); - if (obj.containsKey("value") && !((String)obj.get("value")).equals("")) { - value = jsToBigInteger((String) obj.get("value")); - } - - // default - from ethereumj-studio - BigInteger nonce = ethereum.getRepository().getNonce(acc.getAddress()); - if (obj.containsKey("nonce") && !((String)obj.get("nonce")).equals("")) { - nonce = jsToBigInteger((String) obj.get("nonce")); - } - - // default - from ethereumj-studio - byte[] data = new byte[]{}; - if (obj.containsKey("data") && !((String)obj.get("data")).equals("")) { - data = jsToAddress((String) obj.get("data")); - } - - Transaction tx = ethereum.createTransaction(nonce, gasPrice, gas, to, value, data); - - tx.sign(senderPrivKey); - try { ethereum.submitTransaction(tx).get(CONFIG.transactionApproveTimeout(), TimeUnit.SECONDS); } catch (Exception e) { diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_submitWork.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_submitWork.java new file mode 100644 index 00000000..26de2cf8 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_submitWork.java @@ -0,0 +1,35 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.facade.Ethereum; + +import java.util.List; + +/* +TODO: right now -core not auto start mining so no way to get information about state +*/ +public class eth_submitWork extends JsonRpcServerMethod { + + public eth_submitWork (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 3) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] nonce = jsToAddress((String) params.get(0)); + byte[] powHash = jsToAddress((String) params.get(1)); + byte[] mixDigest = jsToAddress((String) params.get(2)); + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_uninstallFilter.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_uninstallFilter.java new file mode 100644 index 00000000..7e8db421 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/eth_uninstallFilter.java @@ -0,0 +1,31 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import net.minidev.json.JSONObject; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.filter.FilterBase; +import org.ethereum.android.jsonrpc.filter.FilterLog; +import org.ethereum.android.jsonrpc.filter.FilterManager; +import org.ethereum.facade.Ethereum; +import java.util.List; + +public class eth_uninstallFilter extends JsonRpcServerMethod { + + public eth_uninstallFilter (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + int id = jsToInt((String) params.get(0)); + JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().uninstallFilter(id), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_addToGroup.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_addToGroup.java new file mode 100644 index 00000000..86c49a8e --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_addToGroup.java @@ -0,0 +1,32 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +import java.util.List; + +/* +TODO: not present clear specification for this method, also cpp and go version not provide it. +*/ +public class shh_addToGroup extends JsonRpcServerMethod { + + public shh_addToGroup(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] identity = jsToAddress((String)params.get(0)); + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getFilterChanges.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getFilterChanges.java new file mode 100644 index 00000000..3bfeb761 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getFilterChanges.java @@ -0,0 +1,32 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.whisper.FilterManager; +import org.ethereum.facade.Ethereum; + +import java.util.List; + +/* +TODO: done it when shh will be ready in -core +*/ +public class shh_getFilterChanges extends JsonRpcServerMethod { + + public shh_getFilterChanges(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + int id = jsToInt((String)params.get(0)); + JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJS(id), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getMessages.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getMessages.java new file mode 100644 index 00000000..51a2dda3 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_getMessages.java @@ -0,0 +1,32 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.whisper.FilterManager; +import org.ethereum.facade.Ethereum; + +import java.util.List; + +/* +TODO: done it when shh will be ready in -core +*/ +public class shh_getMessages extends JsonRpcServerMethod { + + public shh_getMessages(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + int id = jsToInt((String)params.get(0)); + JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().toJSAll(id), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_hasIdentity.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_hasIdentity.java new file mode 100644 index 00000000..f1eede34 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_hasIdentity.java @@ -0,0 +1,32 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +import java.util.List; + +/* +TODO: done it when shh will be ready in -core +*/ +public class shh_hasIdentity extends JsonRpcServerMethod { + + public shh_hasIdentity(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + byte[] identity = jsToAddress((String)params.get(0)); + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newFilter.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newFilter.java new file mode 100644 index 00000000..54e2ff96 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newFilter.java @@ -0,0 +1,38 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; + +import net.minidev.json.JSONObject; + +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.whisper.Filter; +import org.ethereum.android.jsonrpc.whisper.FilterManager; +import org.ethereum.facade.Ethereum; + +import java.util.List; + +/* +TODO: done it when shh will be ready in -core +*/ +public class shh_newFilter extends JsonRpcServerMethod { + + public shh_newFilter(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + JSONObject obj = (JSONObject)params.get(0); + int id = FilterManager.getInstance().addFilter(new Filter(obj)); + String tmp = "0x" + Integer.toHexString(id); + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newGroup.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newGroup.java new file mode 100644 index 00000000..636c214e --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newGroup.java @@ -0,0 +1,23 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +/* +TODO: not present clear specification for this method, also cpp and go version not provide it. +*/ +public class shh_newGroup extends JsonRpcServerMethod { + + public shh_newGroup(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newIdentity.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newIdentity.java new file mode 100644 index 00000000..87c23e27 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_newIdentity.java @@ -0,0 +1,23 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; + +/* +TODO: done it when shh will be ready in -core +*/ +public class shh_newIdentity extends JsonRpcServerMethod { + + public shh_newIdentity(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_post.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_post.java new file mode 100644 index 00000000..927cb2be --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_post.java @@ -0,0 +1,60 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; + +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; + +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; +import org.spongycastle.util.encoders.Hex; + +import java.util.ArrayList; +import java.util.List; + +/* +TODO: done it when shh will be ready in -core +*/ +public class shh_post extends JsonRpcServerMethod { + + public shh_post (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + JSONObject obj = (JSONObject)params.get(0); + + byte[] from = null; + if (obj.containsKey("from")) + from = jsToAddress((String)obj.get("from")); + + byte[] to = null; + if (obj.containsKey("to")) + to = jsToAddress((String)obj.get("to")); + + ArrayList topics = new ArrayList<>(); + for (Object item : (JSONArray)obj.get("topics")) { + if (item instanceof String) { + topics.add(jsToAddress((String)item)); + } + } + + byte[] payload = jsToAddress((String)obj.get("payload")); + + int priority = jsToInt((String) obj.get("priority")); + + int ttl = jsToInt((String)obj.get("ttl")); + + //TODO: + + JSONRPC2Response res = new JSONRPC2Response(JSONRPC2Error.METHOD_NOT_FOUND, req.getID()); + return res; + } + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_uninstallFilter.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_uninstallFilter.java new file mode 100644 index 00000000..0dd232f5 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_uninstallFilter.java @@ -0,0 +1,32 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.android.jsonrpc.whisper.FilterManager; +import org.ethereum.facade.Ethereum; + +import java.util.List; + +/* +TODO: done it when shh will be ready in -core +*/ +public class shh_uninstallFilter extends JsonRpcServerMethod { + + public shh_uninstallFilter(Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + List params = req.getPositionalParams(); + if (params.size() != 1) { + return new JSONRPC2Response(JSONRPC2Error.INVALID_PARAMS, req.getID()); + } else { + int id = jsToInt((String)params.get(0)); + JSONRPC2Response res = new JSONRPC2Response(FilterManager.getInstance().uninstallFilter(id), req.getID()); + return res; + } + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_version.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_version.java new file mode 100644 index 00000000..12aba25f --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/method/shh_version.java @@ -0,0 +1,22 @@ +package org.ethereum.android.jsonrpc.method; + +import com.thetransactioncompany.jsonrpc2.*; +import com.thetransactioncompany.jsonrpc2.server.*; +import org.ethereum.android.jsonrpc.JsonRpcServerMethod; +import org.ethereum.facade.Ethereum; +import org.ethereum.net.shh.ShhHandler; + +public class shh_version extends JsonRpcServerMethod { + + public shh_version (Ethereum ethereum) { + super(ethereum); + } + + protected JSONRPC2Response worker(JSONRPC2Request req, MessageContext ctx) { + + String tmp = "" + ShhHandler.VERSION; + JSONRPC2Response res = new JSONRPC2Response(tmp, req.getID()); + return res; + + } +} \ No newline at end of file diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/Filter.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/Filter.java new file mode 100644 index 00000000..c23217c8 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/Filter.java @@ -0,0 +1,86 @@ +package org.ethereum.android.jsonrpc.whisper; + +import net.minidev.json.JSONArray; +import net.minidev.json.JSONObject; + +import org.ethereum.facade.Ethereum; +import org.ethereum.net.shh.ShhMessage; +import org.spongycastle.util.encoders.Hex; + +import java.util.ArrayList; + +/* +TODO: replace ShhMessage with real class when Roman finish Shh. +*/ +public class Filter { + protected int id; + protected ArrayList messages; + byte[] to = null; + boolean isWildcard = false; + ArrayList> or; + ArrayList and; + int sendID = 0; + + public Filter (JSONObject data) { + messages = new ArrayList(); + if (data.containsKey("to")) { + to = Hex.decode(((String)data.get("to")).substring(2)); + } + JSONArray topics = (JSONArray)data.get("topics"); + for (Object item : topics) { + if (item == null) { + isWildcard = true; + } + else if (item instanceof JSONArray) { + ArrayList tmp = new ArrayList(); + for (Object ori : (JSONArray)item) { + if (ori instanceof String) { + tmp.add(Hex.decode(((String)ori).substring(2))); + } + } + or.add(tmp); + } else if (item instanceof String) { + and.add(Hex.decode(((String)item).substring(2))); + } + } + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public void processEvent(Object data) { + //TODO: parse incomming data when we will know what comes. + } + + public JSONArray toJS() { + JSONArray res = new JSONArray(); + synchronized (messages) { + for (int i = sendID; i < messages.size(); i++) { + res.add(toJS(messages.get(i))); + } + sendID = messages.size(); + } + return res; + } + + public JSONArray toJSAll() { + JSONArray res = new JSONArray(); + synchronized (messages) { + for (int i = 0; i < messages.size(); i++) { + res.add(toJS(messages.get(i))); + } + sendID = messages.size(); + } + return res; + } + + private JSONObject toJS (ShhMessage data) { + JSONObject res = new JSONObject(); + return res; + } +} diff --git a/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/FilterManager.java b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/FilterManager.java new file mode 100644 index 00000000..ebc60443 --- /dev/null +++ b/ethereumj-core-android/src/main/java/org/ethereum/android/jsonrpc/whisper/FilterManager.java @@ -0,0 +1,80 @@ +package org.ethereum.android.jsonrpc.whisper; + +import net.minidev.json.JSONArray; + +import org.ethereum.facade.Ethereum; + +import java.util.Hashtable; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; + +/* +This class must receive notification from -core about new whisper message. Right now I not see the way todo that. +TODO: ask advice from Roman about how to send notification to this class. +*/ +public class FilterManager { + + protected static FilterManager instance = null; + + public static FilterManager getInstance() { + if (instance == null) + instance = new FilterManager(); + return instance; + } + + protected Hashtable filters; + protected int last_id = 0; + + private FilterManager() { + filters = new Hashtable(); + } + + public void processEvent(Object data) { + synchronized (filters) { + for (Map.Entry item : filters.entrySet()) { + item.getValue().processEvent(data); + } + } + } + + public int addFilter(Filter filter) { + filter.setId(++last_id); + filters.put(filter.getId(), filter); + return filter.getId(); + } + + public Filter getFilter(int id) { + if (filters.containsKey(id)) { + return filters.get(id); + } + return null; + } + + public boolean uninstallFilter(int id) { + synchronized (filters) { + if (!filters.containsKey(id)) + return false; + filters.remove(id); + } + return true; + } + + public JSONArray toJS(int id) { + synchronized (filters) { + if (!filters.containsKey(id)) + return null; + return filters.get(id).toJS(); + } + } + + public JSONArray toJSAll(int id) { + synchronized (filters) { + if (!filters.containsKey(id)) + return null; + return filters.get(id).toJSAll(); + } + } + +} \ No newline at end of file