problem: invalid height matcher when block hash is specified
This commit is contained in:
@@ -73,34 +73,20 @@ class EthereumCallSelector(
|
|||||||
// for earliest it doesn't nothing, we expect to have 0 block
|
// for earliest it doesn't nothing, we expect to have 0 block
|
||||||
"earliest" -> 0L
|
"earliest" -> 0L
|
||||||
else -> if (tag.startsWith("0x")) {
|
else -> if (tag.startsWith("0x")) {
|
||||||
try {
|
return if (tag.length == 66) { //32-byte hash is represented as 0x + 64 characters
|
||||||
HexQuantity.from(tag).value.toLong()
|
blockByHash(tag, head)
|
||||||
} catch (t: Throwable) {
|
} else {
|
||||||
log.debug("Invalid tag: $tag. ${t.javaClass}: ${t.message}")
|
blockByHeight(tag)
|
||||||
null
|
|
||||||
}
|
}
|
||||||
} else if (tag.startsWith("{") && list[pos] is Map<*, *>) {
|
} else if (tag.startsWith("{") && list[pos] is Map<*, *>) {
|
||||||
// see https://eips.ethereum.org/EIPS/eip-1898
|
// see https://eips.ethereum.org/EIPS/eip-1898
|
||||||
val obj = list[pos] as Map<*, *>
|
val obj = list[pos] as Map<*, *>
|
||||||
when {
|
when {
|
||||||
obj.containsKey("blockNumber") -> {
|
obj.containsKey("blockNumber") -> {
|
||||||
try {
|
return blockByHeight(obj["blockNumber"].toString())
|
||||||
HexQuantity.from(obj["blockNumber"].toString()).value.toLong()
|
|
||||||
} catch (t: Throwable) {
|
|
||||||
log.warn("Invalid blockNumber: $tag")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
obj.containsKey("blockHash") -> {
|
obj.containsKey("blockHash") -> {
|
||||||
try {
|
return blockByHash(obj["blockHash"].toString(), head)
|
||||||
val blockId = BlockId.from(obj["blockHash"].toString())
|
|
||||||
return heightReader.read(blockId)
|
|
||||||
.switchIfEmpty(Mono.justOrEmpty(head.getCurrentHeight()))
|
|
||||||
.map { Selector.HeightMatcher(it) }
|
|
||||||
} catch (t: Throwable) {
|
|
||||||
log.warn("Invalid blockHash: $tag")
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
@@ -116,4 +102,25 @@ class EthereumCallSelector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun blockByHeight(blockNumber: String): Mono<Selector.Matcher> {
|
||||||
|
return try {
|
||||||
|
Mono.just(Selector.HeightMatcher(HexQuantity.from(blockNumber).value.longValueExact()))
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
log.warn("Invalid blockNumber: $blockNumber")
|
||||||
|
Mono.empty<Selector.Matcher>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun blockByHash(blockHash: String, head: Head): Mono<Selector.Matcher> {
|
||||||
|
return try {
|
||||||
|
val blockId = BlockId.from(blockHash)
|
||||||
|
heightReader.read(blockId)
|
||||||
|
.switchIfEmpty(Mono.justOrEmpty(head.getCurrentHeight()))
|
||||||
|
.map { Selector.HeightMatcher(it) }
|
||||||
|
} catch (t: Throwable) {
|
||||||
|
log.warn("Invalid blockHash: $blockHash")
|
||||||
|
Mono.empty<Selector.Matcher>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -73,6 +73,59 @@ class EthereumCallSelectorSpec extends Specification {
|
|||||||
act == new Selector.HeightMatcher(0x40)
|
act == new Selector.HeightMatcher(0x40)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def "Get height matcher for balance on block referred by hash"() {
|
||||||
|
setup:
|
||||||
|
def heights = Mock(Reader) {
|
||||||
|
1 * it.read(BlockId.from("0xc90f1c8c125a4d5b90742f16947bdb1d10516f173fd7fc51223d10499de2a812")) >> Mono.just(8606722L)
|
||||||
|
}
|
||||||
|
EthereumCallSelector callSelector = new EthereumCallSelector(heights)
|
||||||
|
def head = Mock(Head) {
|
||||||
|
_ * getCurrentHeight() >> 9128116
|
||||||
|
}
|
||||||
|
when:
|
||||||
|
def act = callSelector.getMatcher("eth_getBalance", '["0x0000", "0xc90f1c8c125a4d5b90742f16947bdb1d10516f173fd7fc51223d10499de2a812"]', head).block()
|
||||||
|
then:
|
||||||
|
act == new Selector.HeightMatcher(8606722)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "No matcher for invalid height"() {
|
||||||
|
setup:
|
||||||
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader))
|
||||||
|
def head = Mock(Head) {
|
||||||
|
_ * getCurrentHeight() >> 100
|
||||||
|
}
|
||||||
|
when:
|
||||||
|
// 0x10000000000000000 is too large to be a block
|
||||||
|
def act = callSelector.getMatcher("eth_getBalance", '["0x0000", "0x10000000000000000"]', head).block()
|
||||||
|
then:
|
||||||
|
act == null
|
||||||
|
}
|
||||||
|
|
||||||
|
def "No matcher for negative height"() {
|
||||||
|
setup:
|
||||||
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader))
|
||||||
|
def head = Mock(Head) {
|
||||||
|
_ * getCurrentHeight() >> 100
|
||||||
|
}
|
||||||
|
when:
|
||||||
|
def act = callSelector.getMatcher("eth_getBalance", '["0x0000", "-0x100"]', head).block()
|
||||||
|
then:
|
||||||
|
act == null
|
||||||
|
}
|
||||||
|
|
||||||
|
def "No matcher for negative long"() {
|
||||||
|
setup:
|
||||||
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader))
|
||||||
|
def head = Mock(Head) {
|
||||||
|
_ * getCurrentHeight() >> 100
|
||||||
|
}
|
||||||
|
when:
|
||||||
|
// 0x8000000000000000 becomes -9223372036854775808 in converted to long as is, i.e. high bit is set
|
||||||
|
def act = callSelector.getMatcher("eth_getBalance", '["0x0000", "0x8000000000000000"]', head).block()
|
||||||
|
then:
|
||||||
|
act == null
|
||||||
|
}
|
||||||
|
|
||||||
def "No matcher for pending balance"() {
|
def "No matcher for pending balance"() {
|
||||||
setup:
|
setup:
|
||||||
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader))
|
EthereumCallSelector callSelector = new EthereumCallSelector(Stub(Reader))
|
||||||
|
|||||||
Reference in New Issue
Block a user