Revert "Sync upstream 7.12.2022"
This commit is contained in:
8
testing/trial/README.adoc
Normal file
8
testing/trial/README.adoc
Normal file
@@ -0,0 +1,8 @@
|
||||
= Actual Tests
|
||||
|
||||
Expects running _Simple Upstream_ and _Testing Dshackle_.
|
||||
|
||||
.Run from current directory
|
||||
----
|
||||
./gradlew check
|
||||
----
|
||||
35
testing/trial/build.gradle
Normal file
35
testing/trial/build.gradle
Normal file
@@ -0,0 +1,35 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'groovy'
|
||||
id 'idea'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven { url "https://maven.emrld.io" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.apache.httpcomponents:httpclient:4.5.12"
|
||||
implementation "org.codehaus.groovy:groovy:3.0.4"
|
||||
implementation "com.fasterxml.jackson.core:jackson-core:2.9.8"
|
||||
implementation "com.fasterxml.jackson.core:jackson-databind:2.9.8"
|
||||
implementation "io.grpc:grpc-netty:1.46.0"
|
||||
implementation "org.bouncycastle:bcprov-jdk15on:1.61"
|
||||
implementation("io.emeraldpay:emerald-api:0.12-alpha.1") {
|
||||
exclude group: 'com.salesforce.servicelibs', module: 'reactor-grpc'
|
||||
}
|
||||
|
||||
testImplementation "org.spockframework:spock-core:2.0-M3-groovy-3.0"
|
||||
}
|
||||
|
||||
|
||||
test {
|
||||
systemProperty "trialMode", project.getProperty("dshackleTrialMode")
|
||||
systemProperty "signatureKey", project.getProperty("signatureKey")
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events "PASSED", "FAILED"
|
||||
}
|
||||
}
|
||||
1
testing/trial/settings.gradle
Normal file
1
testing/trial/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
rootProject.name = 'dshackle-testing-trial'
|
||||
@@ -0,0 +1,6 @@
|
||||
package io.emeraldpay.dshackle.testing.trial
|
||||
|
||||
interface Client {
|
||||
Map<String, Object> execute(String method, List<Object> params)
|
||||
Map<String, Object> execute(Object id, String method, List<Object> params)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.emeraldpay.dshackle.testing.trial
|
||||
|
||||
class Debugger {
|
||||
|
||||
public static enabled = true
|
||||
|
||||
static void showOut(String json) {
|
||||
if (!enabled) {
|
||||
return
|
||||
}
|
||||
println(">> $json")
|
||||
}
|
||||
|
||||
static void showIn(String json) {
|
||||
if (!enabled) {
|
||||
return
|
||||
}
|
||||
println("<< $json")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package io.emeraldpay.dshackle.testing.trial
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.google.common.primitives.Bytes
|
||||
import com.google.protobuf.ByteString
|
||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||
import io.emeraldpay.api.proto.Common
|
||||
import io.emeraldpay.api.proto.ReactorBlockchainGrpc
|
||||
import io.emeraldpay.grpc.Chain
|
||||
import io.grpc.ManagedChannel
|
||||
import io.grpc.netty.NettyChannelBuilder
|
||||
|
||||
class ProtoClient implements Client {
|
||||
private int sequence = 0;
|
||||
private ObjectMapper objectMapper;
|
||||
private ReactorBlockchainGrpc.ReactorBlockchainStub stub
|
||||
private Chain chain
|
||||
|
||||
ProtoClient(ManagedChannel channel, Chain chain) {
|
||||
this.stub = ReactorBlockchainGrpc.newReactorStub(channel)
|
||||
this.objectMapper = new ObjectMapper()
|
||||
this.chain= chain
|
||||
}
|
||||
|
||||
static ProtoClient create(String host, int port, Chain chain) {
|
||||
def channel = NettyChannelBuilder.forAddress(host, port)
|
||||
.maxInboundMessageSize(Integer.MAX_VALUE)
|
||||
.usePlaintext()
|
||||
new ProtoClient(channel.build(), chain)
|
||||
}
|
||||
|
||||
static ProtoClient basic() {
|
||||
create("localhost", 12448, Chain.ETHEREUM)
|
||||
}
|
||||
|
||||
BlockchainOuterClass.NativeCallReplyItem executeNative(String method, List<Object> params, Long nonce) {
|
||||
def req = BlockchainOuterClass.NativeCallRequest
|
||||
.newBuilder()
|
||||
.setChain(Common.ChainRef.CHAIN_ETHEREUM)
|
||||
.addItems(BlockchainOuterClass.NativeCallItem
|
||||
.newBuilder()
|
||||
.setId(0)
|
||||
.setNonce(nonce)
|
||||
.setMethod(method)
|
||||
.setPayload(ByteString.copyFrom(objectMapper.writeValueAsBytes(params)))
|
||||
.build()
|
||||
).build()
|
||||
stub.nativeCall(req)
|
||||
.single()
|
||||
.block()
|
||||
}
|
||||
|
||||
Map<String, Object> execute(String method, List<Object> params) {
|
||||
return execute(sequence++, method, params)
|
||||
}
|
||||
Map<String, Object> execute(Object id, String method, List<Object> params) {
|
||||
def result = executeNative(method, params, 0L)
|
||||
if (result.errorMessage != "") {
|
||||
return [error: result.errorMessage]
|
||||
} else {
|
||||
return objectMapper.readerFor(Map).readValue(Bytes.concat("{\"result\": ".bytes, result.payload.toByteArray(), "}".bytes))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package io.emeraldpay.dshackle.testing.trial
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import org.apache.commons.codec.binary.Hex
|
||||
import org.apache.http.HttpHeaders
|
||||
import org.apache.http.client.HttpClient
|
||||
import org.apache.http.client.methods.CloseableHttpResponse
|
||||
import org.apache.http.client.methods.HttpPost
|
||||
import org.apache.http.entity.ContentType
|
||||
import org.apache.http.entity.StringEntity
|
||||
import org.apache.http.impl.client.CloseableHttpClient
|
||||
import org.apache.http.impl.client.HttpClientBuilder
|
||||
import org.apache.http.impl.client.HttpClients
|
||||
|
||||
class ProxyClient implements Client {
|
||||
|
||||
private int sequence = 0;
|
||||
|
||||
private String url
|
||||
private ObjectMapper objectMapper
|
||||
|
||||
ProxyClient(String url) {
|
||||
this.url = url
|
||||
this.objectMapper = new ObjectMapper()
|
||||
}
|
||||
|
||||
static ProxyClient ethereumMock() {
|
||||
return forPrefix(18080, "eth")
|
||||
}
|
||||
|
||||
static ProxyClient ethereumReal() {
|
||||
return forPrefix(18081, "eth")
|
||||
}
|
||||
|
||||
static ProxyClient ethereumRinkeby() {
|
||||
return forPrefix(18081, "rinkeby")
|
||||
}
|
||||
|
||||
static ProxyClient forPrefix(String prefix) {
|
||||
return forPrefix(18080, prefix)
|
||||
}
|
||||
|
||||
static ProxyClient forPrefix(int port, String prefix) {
|
||||
return new ProxyClient("http://127.0.0.1:$port/$prefix")
|
||||
}
|
||||
|
||||
static ProxyClient forOriginal(int port) {
|
||||
return new ProxyClient("http://127.0.0.1:$port")
|
||||
}
|
||||
|
||||
Map<String, Object> execute(String method, List<Object> params) {
|
||||
return execute(sequence++, method, params)
|
||||
}
|
||||
|
||||
Map<String, Object> execute(Object id, String method, List<Object> params) {
|
||||
Map jsonData = [
|
||||
id : id,
|
||||
jsonrpc: "2.0",
|
||||
method : method,
|
||||
params : params
|
||||
]
|
||||
String reqJson = objectMapper.writeValueAsString(jsonData)
|
||||
Debugger.showOut(reqJson)
|
||||
CloseableHttpClient httpClient = null
|
||||
try {
|
||||
httpClient = HttpClients.createDefault()
|
||||
def request = new HttpPost(url)
|
||||
request.setEntity(new StringEntity(reqJson, ContentType.APPLICATION_JSON))
|
||||
CloseableHttpResponse response = httpClient.execute(request)
|
||||
if (response.getStatusLine().statusCode != 200) {
|
||||
throw new IllegalStateException("Non-ok status: " + response.getStatusLine().statusCode)
|
||||
}
|
||||
String respJson = response.entity.content.text
|
||||
Debugger.showIn(respJson)
|
||||
return objectMapper.readerFor(Map).readValue(respJson)
|
||||
} finally {
|
||||
httpClient?.close()
|
||||
}
|
||||
|
||||
return [error: "NOT EXECUTED"]
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package io.emeraldpay.dshackle.testing.trial.basicproxy
|
||||
|
||||
import io.emeraldpay.dshackle.testing.trial.ProxyClient
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
|
||||
@IgnoreIf({ System.getProperty('trialMode') != 'basic' })
|
||||
class DispatchSpec extends Specification {
|
||||
|
||||
def client = ProxyClient.forPrefix("eth")
|
||||
|
||||
def "multiple calls routed roughly equal to upstreams"() {
|
||||
when:
|
||||
def calls1before = ProxyClient.forOriginal(18545).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
def calls2before = ProxyClient.forOriginal(18546).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
|
||||
100.times {
|
||||
client.execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000001", data: "0x00000000" + Integer.toString(it, 16)]])
|
||||
}
|
||||
|
||||
def calls1after = ProxyClient.forOriginal(18545).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
def calls2after = ProxyClient.forOriginal(18546).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
|
||||
def calls1 = onlyNew(calls1before, calls1after)
|
||||
def calls2 = onlyNew(calls2before, calls2after)
|
||||
|
||||
then:
|
||||
calls1.size() >= 48
|
||||
calls2.size() >= 48
|
||||
calls1.size() + calls2.size() == 100
|
||||
}
|
||||
|
||||
def "multiple calls routed roughly equal to upstreams - for latest block"() {
|
||||
when:
|
||||
def calls1before = ProxyClient.forOriginal(18545).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
def calls2before = ProxyClient.forOriginal(18546).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
|
||||
100.times {
|
||||
client.execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000001", data: "0x00000000" + Integer.toString(it, 16)], "0x100001"])
|
||||
}
|
||||
|
||||
def calls1after = ProxyClient.forOriginal(18545).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
def calls2after = ProxyClient.forOriginal(18546).execute("eth_call", [[to: "0x0123456789abcdef0123456789abcdef00000002"]]).result as List
|
||||
|
||||
def calls1 = onlyNew(calls1before, calls1after)
|
||||
def calls2 = onlyNew(calls2before, calls2after)
|
||||
|
||||
then:
|
||||
calls1.size() >= 48
|
||||
calls2.size() >= 48
|
||||
calls1.size() + calls2.size() == 100
|
||||
}
|
||||
|
||||
private List onlyNew(List before, List after) {
|
||||
return after.findAll { a ->
|
||||
!before.any { b ->
|
||||
b.id == a.id
|
||||
}
|
||||
}.findAll {
|
||||
(it.json as String).contains("0x0123456789abcdef0123456789abcdef00000001")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package io.emeraldpay.dshackle.testing.trial.basicproxy
|
||||
|
||||
import io.emeraldpay.dshackle.testing.trial.ProxyClient
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
|
||||
@IgnoreIf({ System.getProperty('trialMode') != 'basic' })
|
||||
class GivesErrorSpec extends Specification {
|
||||
|
||||
def client = ProxyClient.forPrefix("eth")
|
||||
|
||||
def "Gives error message"() {
|
||||
// issue #42
|
||||
when:
|
||||
def act = client.execute("eth_call", [[to: "0x542156d51D10Db5acCB99f9Db7e7C91B74E80a2c"]])
|
||||
then:
|
||||
act.result == null
|
||||
act.error != null
|
||||
with(act.error) {
|
||||
code == -32015
|
||||
message == "VM execution error."
|
||||
}
|
||||
}
|
||||
|
||||
def "Gives error data"() {
|
||||
// issue #42
|
||||
when:
|
||||
def act = client.execute("eth_call", [[to: "0x8ee2a5aca4f88cb8c757b8593d0734855dcc0eba"]])
|
||||
then:
|
||||
act.result == null
|
||||
act.error != null
|
||||
with(act.error) {
|
||||
code == -32015
|
||||
message == "VM execution error."
|
||||
data == "revert: SafeMath: division by zero"
|
||||
}
|
||||
}
|
||||
|
||||
def "Dispatch error from upstream when block is specified"() {
|
||||
// issue #67
|
||||
when:
|
||||
def call = [
|
||||
to : "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
from: "0xEF65ffB384c99a00403EAa22115323a555700D79",
|
||||
data: "0xa9059cbb0000000000000000000000003f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be000000000000000000000000000000000000000000000000000000004856fb60"
|
||||
]
|
||||
def act = client.execute("eth_call", [call, "0x100000"])
|
||||
then:
|
||||
act.result == null
|
||||
act.error != null
|
||||
with(act.error) {
|
||||
code == -32000
|
||||
message == "invalid opcode: opcode 0xfe not defined"
|
||||
}
|
||||
}
|
||||
|
||||
def "Dispatch error from upstream when custome method is used"() {
|
||||
// issue #67
|
||||
when:
|
||||
def call = [
|
||||
to : "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
||||
from: "0xEF65ffB384c99a00403EAa22115323a555700D79",
|
||||
data: "0xa9059cbb0000000000000000000000003f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be000000000000000000000000000000000000000000000000000000004856fb60"
|
||||
]
|
||||
def act = client.execute("test_foo", [call, "0x100000"])
|
||||
then:
|
||||
act.result == null
|
||||
act.error != null
|
||||
with(act.error) {
|
||||
code == -32000
|
||||
message == "invalid opcode: opcode 0xfe not defined"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package io.emeraldpay.dshackle.testing.trial.basicproxy
|
||||
|
||||
import io.emeraldpay.dshackle.testing.trial.ProxyClient
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
|
||||
@IgnoreIf({ System.getProperty('trialMode') != 'basic' })
|
||||
class HardcodedCallsSpec extends Specification {
|
||||
|
||||
def client = ProxyClient.forPrefix("eth")
|
||||
|
||||
def "get syncing"() {
|
||||
when:
|
||||
def act = client.execute("eth_syncing", [])
|
||||
then:
|
||||
act.result == false
|
||||
act.error == null
|
||||
}
|
||||
|
||||
def "get network version"() {
|
||||
when:
|
||||
def act = client.execute("net_version", [])
|
||||
then:
|
||||
act.result == "1"
|
||||
act.error == null
|
||||
}
|
||||
|
||||
def "get peer count"() {
|
||||
when:
|
||||
def act = client.execute("net_peerCount", [])
|
||||
then:
|
||||
act.result == "0x2a"
|
||||
act.error == null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.emeraldpay.dshackle.testing.trial.basicproxy
|
||||
|
||||
import io.emeraldpay.dshackle.testing.trial.ProxyClient
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
|
||||
@IgnoreIf({ System.getProperty('trialMode') != 'basic' })
|
||||
class MetamaskCallSpec extends Specification {
|
||||
|
||||
def client = ProxyClient.forPrefix("eth")
|
||||
|
||||
def "use long id"() {
|
||||
when:
|
||||
def act = client.execute(1057264140543346, "net_version", [])
|
||||
then:
|
||||
act.id == 1057264140543346
|
||||
act.result != null
|
||||
act.error == null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package io.emeraldpay.dshackle.testing.trial.basicproxy
|
||||
|
||||
import com.google.common.primitives.Bytes
|
||||
import com.google.common.primitives.Longs
|
||||
import io.emeraldpay.dshackle.testing.trial.ProtoClient
|
||||
import io.emeraldpay.dshackle.testing.trial.ProxyClient
|
||||
import org.apache.commons.codec.binary.Hex
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Shared
|
||||
import spock.lang.Specification
|
||||
import java.security.KeyFactory
|
||||
import org.bouncycastle.util.io.pem.PemReader
|
||||
|
||||
import java.security.MessageDigest
|
||||
import java.security.Signature
|
||||
import java.security.spec.PKCS8EncodedKeySpec
|
||||
import java.security.spec.X509EncodedKeySpec
|
||||
|
||||
@IgnoreIf({ System.getProperty('trialMode') != 'basic' })
|
||||
class StandardCallsSpec extends Specification {
|
||||
|
||||
@Shared client_proto = ProtoClient.basic()
|
||||
@Shared client_proxy = ProxyClient.forPrefix("eth")
|
||||
|
||||
@Shared clients = [client_proto, client_proxy]
|
||||
|
||||
def "get height"() {
|
||||
when:
|
||||
def act = client.execute("eth_blockNumber", [])
|
||||
then:
|
||||
act.result == "0x100001"
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "get block"() {
|
||||
when:
|
||||
def act = client.execute("eth_getBlockByNumber", ["0x100001", false])
|
||||
then:
|
||||
act.result != null
|
||||
with(act.result) {
|
||||
number == "0x100001"
|
||||
hash == "0x18c68d9ba58772a4409d65d61891b25db03a105a7769ae08ef2cff697921b446"
|
||||
transactions == [
|
||||
"0x146b8f4b6300c73bb7476359b9f1c5ee3f686a86b2aa673552cf0f9de9a42e77",
|
||||
"0xe589a39acea3091b584b650158d08b159aa07e97b8e8cddb8f81cb606e13382e"
|
||||
]
|
||||
}
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "get non-existing block"() {
|
||||
when:
|
||||
def act = client.execute("eth_getBlockByNumber", ["0x200001", false])
|
||||
then:
|
||||
act.result == null
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "get tx"() {
|
||||
when:
|
||||
def act = client.execute("eth_getTransactionByHash", ["0x01c5a8461d06c2c195035c148af0f871c7679841d86ae5bb98676bb2d8e68dfa"])
|
||||
then:
|
||||
act.result != null
|
||||
with(act.result) {
|
||||
blockHash == "0x9a834c53bbee9c2665a5a84789a1d1ad73750b2d77b50de44f457f411d02e52e"
|
||||
}
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "get non-existing tx"() {
|
||||
when:
|
||||
def act = client.execute("eth_getTransactionByHash", ["0x000000461d06c2c195035c148af0f871c7679841d86ae5bb98676bb2d8e68dfa"])
|
||||
then:
|
||||
act.result == null
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "get block with txes"() {
|
||||
when:
|
||||
def act = client.execute("eth_getBlockByNumber", ["0x100001", true])
|
||||
then:
|
||||
act.result != null
|
||||
with(act.result) {
|
||||
number == "0x100001"
|
||||
hash == "0x18c68d9ba58772a4409d65d61891b25db03a105a7769ae08ef2cff697921b446"
|
||||
transactions.size() == 2
|
||||
transactions[0] instanceof Map
|
||||
transactions[1] instanceof Map
|
||||
with(transactions.find { it.hash == "0x146b8f4b6300c73bb7476359b9f1c5ee3f686a86b2aa673552cf0f9de9a42e77" }) {
|
||||
from == "0x2a65aca4d5fc5b5c859090a6c34d164135398226"
|
||||
}
|
||||
}
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "returns original block json"() {
|
||||
when:
|
||||
def act = client.execute("eth_getBlockByNumber", ["0x100001", false])
|
||||
then:
|
||||
act.result != null
|
||||
with(act.result) {
|
||||
testFoo == "bar"
|
||||
}
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "returns original block json with tx"() {
|
||||
when:
|
||||
def act = client.execute("eth_getBlockByNumber", ["0x100001", true])
|
||||
then:
|
||||
act.result != null
|
||||
with(act.result) {
|
||||
testFoo == "bar"
|
||||
}
|
||||
act.error == null
|
||||
where:
|
||||
client << clients
|
||||
}
|
||||
|
||||
def "check response signature with nonce"() {
|
||||
when:
|
||||
def act = client_proto.executeNative("eth_blockNumber", [], 10)
|
||||
def keyFactory = KeyFactory.getInstance("EC")
|
||||
def key = new File(System.getProperty('signatureKey'))
|
||||
def reader = new PemReader(key.newReader())
|
||||
def keySpec = new X509EncodedKeySpec(reader.readPemObject().getContent())
|
||||
def pubKey = keyFactory.generatePublic(keySpec)
|
||||
def sig = Signature.getInstance("SHA256withECDSA")
|
||||
sig.initVerify(pubKey)
|
||||
def sep = "/".bytes
|
||||
def digest = MessageDigest.getInstance("SHA-256")
|
||||
def messageHash = digest.digest(act.payload.toByteArray())
|
||||
def sigmessage = Bytes.concat("DSHACKLESIG".bytes,
|
||||
sep,
|
||||
10L.toString().bytes,
|
||||
sep,
|
||||
act.signature.upstreamId.bytes,
|
||||
sep,
|
||||
Hex.encodeHexString(messageHash).bytes)
|
||||
sig.update(sigmessage)
|
||||
then:
|
||||
(new String(act.payload.toByteArray())) == "\"0x100001\""
|
||||
sig.verify(act.signature.signature.toByteArray())
|
||||
}
|
||||
|
||||
def "check response signature without nonce"() {
|
||||
when:
|
||||
def act = client_proto.executeNative("eth_blockNumber", [], 0L)
|
||||
then:
|
||||
act.signature.signature.isEmpty()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package io.emeraldpay.dshackle.testing.trial.mainnet
|
||||
|
||||
import io.emeraldpay.dshackle.testing.trial.Debugger
|
||||
import io.emeraldpay.dshackle.testing.trial.ProxyClient
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
import spock.lang.Timeout
|
||||
|
||||
@IgnoreIf({ System.getProperty('trialMode') != 'real' })
|
||||
class GetBlockSpec extends Specification {
|
||||
|
||||
def client = ProxyClient.ethereumReal()
|
||||
|
||||
def setup() {
|
||||
Debugger.enabled = false
|
||||
}
|
||||
|
||||
def cleanup() {
|
||||
Debugger.enabled = true
|
||||
}
|
||||
|
||||
@Timeout(15)
|
||||
def "Correct order for transactions on #height"() {
|
||||
expect:
|
||||
def results = [
|
||||
(client.execute("eth_getBlockByNumber", ["0x" + Integer.toString(height, 16), false]).result["transactions"] as List<String>),
|
||||
(client.execute("eth_getBlockByNumber", ["0x" + Integer.toString(height, 16), true]).result["transactions"] as List<Map<String, Object>>)
|
||||
.collect { it.hash }
|
||||
]
|
||||
|
||||
println(results[0])
|
||||
println(results[1])
|
||||
|
||||
results[0] == results[1]
|
||||
|
||||
where:
|
||||
height << (10_000_000..10_000_500)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.emeraldpay.dshackle.testing.trial.rinkeby
|
||||
|
||||
import io.emeraldpay.dshackle.testing.trial.ProxyClient
|
||||
import spock.lang.IgnoreIf
|
||||
import spock.lang.Specification
|
||||
|
||||
@IgnoreIf({ System.getProperty('trialMode') != 'rinkeby' })
|
||||
class CallContractSpec extends Specification {
|
||||
|
||||
def client = ProxyClient.ethereumRinkeby()
|
||||
|
||||
def "get block"() {
|
||||
when:
|
||||
def act = client.execute(65, "eth_call",
|
||||
[
|
||||
[
|
||||
"to" : "0xB8Ba177465b3d696180742c6ba58C408175CB6Dd",
|
||||
"data": "0x70a08231000000000000000000000000da3f87aa38d07f1fc836873a3b34ec23088ef78a"
|
||||
],
|
||||
"0xc90f1c8c125a4d5b90742f16947bdb1d10516f173fd7fc51223d10499de2a812"
|
||||
]
|
||||
)
|
||||
then:
|
||||
act.id == 65
|
||||
act.result != null
|
||||
act.result == "0x000000000000000000000000000000000000000000000000000000003af9a800"
|
||||
act.error == null
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user