@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user