Fix reconnect to newHeads (#178)

* Fix reconnect to newHeads
This commit is contained in:
KirillPamPam
2023-03-21 16:41:47 +04:00
committed by GitHub
parent 9d81bbae65
commit 74d666a0bd
7 changed files with 74 additions and 11 deletions

View File

@@ -77,4 +77,9 @@ class EthereumHeadMock implements Head {
void stop() {
}
@Override
void onNoHeadUpdates() {
}
}

View File

@@ -60,7 +60,7 @@ class AbstractHeadSpec extends Specification {
head.stop()
source.tryEmitComplete()
}
.expectComplete()
.thenCancel()
.verify(Duration.ofSeconds(1))
}
@@ -85,7 +85,7 @@ class AbstractHeadSpec extends Specification {
head.stop()
source.tryEmitComplete()
}
.expectComplete()
.thenCancel()
.verify(Duration.ofSeconds(1))
}
@@ -115,7 +115,7 @@ class AbstractHeadSpec extends Specification {
head.stop()
source.tryEmitComplete()
}
.expectComplete()
.thenCancel()
.verify(Duration.ofSeconds(1))
}

View File

@@ -25,8 +25,11 @@ import io.emeraldpay.etherjar.domain.TransactionId
import io.emeraldpay.etherjar.rpc.json.BlockJson
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import reactor.test.StepVerifier
import spock.lang.Specification
import java.time.Duration
import java.time.Instant
import java.time.temporal.ChronoUnit
@@ -71,4 +74,47 @@ class EthereumWsHeadSpec extends Specification {
headBlock
])
}
def "Restart ethereum ws head"() {
setup:
def block = new BlockJson<TransactionRefJson>()
block.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
block.number = 103
block.hash = BlockHash.from("0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200")
def secondBlock = new BlockJson<TransactionRefJson>()
secondBlock.timestamp = Instant.now().truncatedTo(ChronoUnit.SECONDS)
secondBlock.number = 105
secondBlock.hash = BlockHash.from("0x29229361dc5aa1ec66c323dc7a299e2b61a8c8dd2a3522d41255ec10eca25dd8")
def firstHeadBlock = block.with {
Global.objectMapper.writeValueAsBytes(it)
}
def secondHeadBlock = secondBlock.with {
Global.objectMapper.writeValueAsBytes(it)
}
def apiMock = TestingCommons.api()
apiMock.answerOnce("eth_getBlockByHash", ["0x3ec2ebf5d0ec474d0ac6bc50d2770d8409ad76e119968e7919f85d5ec8915200", false], null)
apiMock.answerOnce("eth_getBlockByHash", ["0x29229361dc5aa1ec66c323dc7a299e2b61a8c8dd2a3522d41255ec10eca25dd8", false], null)
apiMock.answerOnce("eth_blockNumber", [], Mono.empty())
apiMock.answerOnce("eth_blockNumber", [], Mono.empty())
def ws = Mock(WsSubscriptions) {
2 * subscribe("newHeads") >>> [Flux.fromIterable([firstHeadBlock]), Flux.fromIterable([secondHeadBlock])]
}
def head = new EthereumWsHead("fake", new AlwaysForkChoice(), BlockValidator.ALWAYS_VALID, apiMock, ws, true)
when:
def act = head.getFlux()
then:
StepVerifier.create(act)
.then { head.start() }
.expectNext(BlockContainer.from(block))
.then { head.onNoHeadUpdates() }
.expectNext(BlockContainer.from(secondBlock))
.thenCancel()
.verify(Duration.ofSeconds(1))
}
}