@@ -0,0 +1,39 @@
|
||||
package testing
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
|
||||
class BlocksHandler implements CallHandler {
|
||||
|
||||
ObjectMapper objectMapper
|
||||
|
||||
BlocksHandler(ObjectMapper objectMapper) {
|
||||
this.objectMapper = objectMapper
|
||||
}
|
||||
|
||||
@Override
|
||||
Result handle(String method, List<Object> params) {
|
||||
if (method == "eth_blockNumber") {
|
||||
return Result.ok("0x100001")
|
||||
}
|
||||
if (method == "eth_getBlockByNumber") {
|
||||
String blockId = params[0]
|
||||
println("get block $blockId")
|
||||
def result = getResource("block-${blockId}.json")
|
||||
return Result.ok(result)
|
||||
}
|
||||
if (method == "eth_getTransactionByHash") {
|
||||
String txId = params[0]
|
||||
def result = getResource("tx-${txId}.json")
|
||||
return Result.ok(result)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
Object getResource(String name) {
|
||||
String json = BlocksHandler.class.getResourceAsStream("/" + name)?.text
|
||||
if (json == null) {
|
||||
return null
|
||||
}
|
||||
return objectMapper.readValue(json, Map)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package testing
|
||||
|
||||
interface CallHandler {
|
||||
|
||||
Result handle(String method, List<Object> params)
|
||||
|
||||
static class Result {
|
||||
private Object result
|
||||
private Integer errorCode
|
||||
private String errorMessage
|
||||
|
||||
Result(Object result, Integer errorCode, String errorMessage) {
|
||||
this.result = result
|
||||
this.errorCode = errorCode
|
||||
this.errorMessage = errorMessage
|
||||
}
|
||||
|
||||
static Result ok(Object result) {
|
||||
return new Result(result, null, null)
|
||||
}
|
||||
|
||||
static Result error(int errorCode, String errorMessage) {
|
||||
return new Result(null, errorCode, errorMessage)
|
||||
}
|
||||
|
||||
boolean isResult() {
|
||||
return errorCode == null
|
||||
}
|
||||
|
||||
Object getResult() {
|
||||
return result
|
||||
}
|
||||
|
||||
int getErrorCode() {
|
||||
return errorCode
|
||||
}
|
||||
|
||||
String getErrorMessage() {
|
||||
return errorMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package testing
|
||||
|
||||
class CommonHandlers implements CallHandler {
|
||||
|
||||
|
||||
@Override
|
||||
Result handle(String method, List<Object> params) {
|
||||
if (method == "eth_syncing") {
|
||||
return Result.ok(false)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package testing
|
||||
|
||||
class InvalidCallHandler implements CallHandler {
|
||||
@Override
|
||||
Result handle(String method, List<Object> params) {
|
||||
return Result.error(-32000, "Call is not supported")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package testing
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import spark.Spark
|
||||
|
||||
class SimpleUpstream {
|
||||
|
||||
private int port = 18545
|
||||
private ObjectMapper objectMapper
|
||||
|
||||
private List<CallHandler> handlers = []
|
||||
|
||||
void prepare() {
|
||||
objectMapper = new ObjectMapper()
|
||||
|
||||
handlers << new TestcaseHandler()
|
||||
handlers << new CommonHandlers()
|
||||
handlers << new BlocksHandler(objectMapper)
|
||||
handlers << new InvalidCallHandler()
|
||||
}
|
||||
|
||||
void start() {
|
||||
println("Starting upstream on 0.0.0.0:$port")
|
||||
Spark.port(port)
|
||||
Spark.post("/") { req, resp ->
|
||||
println("request")
|
||||
try {
|
||||
Map json = objectMapper.readValue(req.body(), Map)
|
||||
def id = json["id"]
|
||||
String method = json["method"].toString()
|
||||
List<Object> params = json.containsKey("params") ? json["params"] as List<Object> : []
|
||||
|
||||
CallHandler.Result result = handlers.findResult { h ->
|
||||
return h.handle(method, params)
|
||||
}
|
||||
Map resultJson = [
|
||||
id : id,
|
||||
jsonrpc: "2.0"
|
||||
]
|
||||
if (result.isResult()) {
|
||||
resultJson["result"] = result.result
|
||||
} else {
|
||||
resultJson["error"] = [
|
||||
code : result.getErrorCode(),
|
||||
message: result.getErrorMessage()
|
||||
]
|
||||
}
|
||||
resp.status(200)
|
||||
resp.header("content-type", "application/json")
|
||||
return objectMapper.writeValueAsString(resultJson)
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
def server = new SimpleUpstream()
|
||||
server.prepare()
|
||||
server.start()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package testing
|
||||
|
||||
class TestcaseHandler implements CallHandler {
|
||||
|
||||
@Override
|
||||
Result handle(String method, List<Object> params) {
|
||||
// https://github.com/emeraldpay/dshackle/issues/35
|
||||
if (method == "eth_call"
|
||||
&& params[0].to?.toLowerCase() == "0x542156d51D10Db5acCB99f9Db7e7C91B74E80a2c".toLowerCase()) {
|
||||
return Result.error(-32015, "VM execution error.")
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"difficulty": "0xc6d2fa46fd6",
|
||||
"extraData": "0xd783010400844765746887676f312e352e31856c696e7578",
|
||||
"gasLimit": "0x2fefd8",
|
||||
"gasUsed": "0xa410",
|
||||
"hash": "0x9a834c53bbee9c2665a5a84789a1d1ad73750b2d77b50de44f457f411d02e52e",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"miner": "0x68795c4aa09d6f4ed3e5deddf8c2ad3049a601da",
|
||||
"mixHash": "0x72224fd0b7b32d0fea13f2953eba28d2512af43632725ed75583dd30e42dfc64",
|
||||
"nonce": "0xf1a453a44f9de627",
|
||||
"number": "0x100000",
|
||||
"parentHash": "0x2dcaf9a8a3fd329d925eb47c1f22022d4f2d562500e546d878bad4247d013858",
|
||||
"receiptsRoot": "0x178000485de197ed06a4ebada431864e5b564b43f994fb8888521f74b4b3257b",
|
||||
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"size": "0x303",
|
||||
"stateRoot": "0xeaddaa0b6b673ba3f8cb7235ca656340ccf703295cf5252cb04a4202c47252c2",
|
||||
"timestamp": "0x56cc7b73",
|
||||
"totalDifficulty": "0x6bab93cdf810b22a",
|
||||
"transactions": [
|
||||
"0x01c5a8461d06c2c195035c148af0f871c7679841d86ae5bb98676bb2d8e68dfa",
|
||||
"0xb4216e88df6ebfe666bbe43370d1ddfe8d9c1975d2b8375a522700f7f59c3ed0"
|
||||
],
|
||||
"transactionsRoot": "0x91d9b419b34a790cc2a7d59c6b95e57ccc5ec9bc1034ce9510dfb551d3049c93",
|
||||
"uncles": []
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"difficulty": "0xc6ba1fe7c49",
|
||||
"extraData": "0xd783010400844765746887676f312e352e31856c696e7578",
|
||||
"gasLimit": "0x2fefd8",
|
||||
"gasUsed": "0xa410",
|
||||
"hash": "0x18c68d9ba58772a4409d65d61891b25db03a105a7769ae08ef2cff697921b446",
|
||||
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"miner": "0x0c729be7c39543c3d549282a40395299d987cec2",
|
||||
"mixHash": "0xf8679fe0f04d5aad4844694cc8fb1a1b97482a5822658379c9bb8633f91daf97",
|
||||
"nonce": "0x347a267c0ec88618",
|
||||
"number": "0x100001",
|
||||
"parentHash": "0x9a834c53bbee9c2665a5a84789a1d1ad73750b2d77b50de44f457f411d02e52e",
|
||||
"receiptsRoot": "0x4f4ed1139baadbd4506d6b0c330335d2108715095fb93fd282bd69aa9edc09eb",
|
||||
"sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
|
||||
"size": "0x304",
|
||||
"stateRoot": "0xee13382462fcd5748a403ca131c38e871fa7206bca2b962f67b59e800741daa3",
|
||||
"timestamp": "0x56cc7b8c",
|
||||
"totalDifficulty": "0x6baba0399a0f2e73",
|
||||
"transactions": [
|
||||
"0x146b8f4b6300c73bb7476359b9f1c5ee3f686a86b2aa673552cf0f9de9a42e77",
|
||||
"0xe589a39acea3091b584b650158d08b159aa07e97b8e8cddb8f81cb606e13382e"
|
||||
],
|
||||
"transactionsRoot": "0xc90078e2af52aef81815cb2a71c22ebd781dd658dd953d9df57f7769a0b2fe51",
|
||||
"uncles": []
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"blockHash": "0x9a834c53bbee9c2665a5a84789a1d1ad73750b2d77b50de44f457f411d02e52e",
|
||||
"blockNumber": "0x100000",
|
||||
"from": "0x68795c4aa09d6f4ed3e5deddf8c2ad3049a601da",
|
||||
"gas": "0x15f90",
|
||||
"gasPrice": "0xba43b7400",
|
||||
"hash": "0x01c5a8461d06c2c195035c148af0f871c7679841d86ae5bb98676bb2d8e68dfa",
|
||||
"input": "0x",
|
||||
"nonce": "0x2f31",
|
||||
"r": "0x1d263f32de00456cbc3e4099c623a6ca48e3188f01dd16461687512f8c3bb7d6",
|
||||
"s": "0x62629f42a98f7c5fa60f8c3630cf67b5eb4772e0ff65a458d2116c15e22d6451",
|
||||
"to": "0xdae787ec66e65c60ad35203800b97b45fcb0f909",
|
||||
"transactionIndex": "0x0",
|
||||
"v": "0x1b",
|
||||
"value": "0x2b81097c919a9e000"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"blockHash": "0x18c68d9ba58772a4409d65d61891b25db03a105a7769ae08ef2cff697921b446",
|
||||
"blockNumber": "0x100001",
|
||||
"from": "0x2a65aca4d5fc5b5c859090a6c34d164135398226",
|
||||
"gas": "0x15f90",
|
||||
"gasPrice": "0xba43b7400",
|
||||
"hash": "0x146b8f4b6300c73bb7476359b9f1c5ee3f686a86b2aa673552cf0f9de9a42e77",
|
||||
"input": "0x",
|
||||
"nonce": "0x32c13",
|
||||
"r": "0xe6ca408c2e91163b46c6bb66054a000a25b6c1d8024460499a185ab2e4bb41a0",
|
||||
"s": "0x53bc43662fda46c2e7051fa704b75ec815e9102cca5400817011ffd99e77139d",
|
||||
"to": "0x7388ae5bc873163025fffe5956322f734f9b570d",
|
||||
"transactionIndex": "0x0",
|
||||
"v": "0x1b",
|
||||
"value": "0xe660f79cf5e4800"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"blockHash": "0x9a834c53bbee9c2665a5a84789a1d1ad73750b2d77b50de44f457f411d02e52e",
|
||||
"blockNumber": "0x100000",
|
||||
"from": "0x68795c4aa09d6f4ed3e5deddf8c2ad3049a601da",
|
||||
"gas": "0x15f90",
|
||||
"gasPrice": "0xba43b7400",
|
||||
"hash": "0xb4216e88df6ebfe666bbe43370d1ddfe8d9c1975d2b8375a522700f7f59c3ed0",
|
||||
"input": "0x",
|
||||
"nonce": "0x2f32",
|
||||
"r": "0xc25ceef654cd3bd734201fc08589970e0663431121bc47cc4a70335e072b09c0",
|
||||
"s": "0x1c67b037a59a8f5badde3a7eb586d7888dcf6dad64aabb080c4c0db593a91254",
|
||||
"to": "0x04a2a3ee9c9ea82e1f918ece209f8a7e6d7521e7",
|
||||
"transactionIndex": "0x1",
|
||||
"v": "0x1c",
|
||||
"value": "0x377fb2f2cbd73c00"
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"blockHash": "0x18c68d9ba58772a4409d65d61891b25db03a105a7769ae08ef2cff697921b446",
|
||||
"blockNumber": "0x100001",
|
||||
"from": "0x2a65aca4d5fc5b5c859090a6c34d164135398226",
|
||||
"gas": "0x15f90",
|
||||
"gasPrice": "0xba43b7400",
|
||||
"hash": "0xe589a39acea3091b584b650158d08b159aa07e97b8e8cddb8f81cb606e13382e",
|
||||
"input": "0x",
|
||||
"nonce": "0x32c14",
|
||||
"r": "0x77fe7cfb03258f2eed8ffbbdc19f73f4a6095a55a7e06f81ade02f3435f7e249",
|
||||
"s": "0x821ad733ceecfa7567e9c8ffb66e3f8bbc3b2b7b21bacadb2a065e57b2a6992",
|
||||
"to": "0x1c774e876a46f51e305add171ba3bb4589408273",
|
||||
"transactionIndex": "0x1",
|
||||
"v": "0x1b",
|
||||
"value": "0xe5ef66c73b5fc00"
|
||||
}
|
||||
Reference in New Issue
Block a user