Skip to content

Commit 4dd1b1c

Browse files
committed
address test coverage
Signed-off-by: Chengxuan Xing <[email protected]>
1 parent ce65daf commit 4dd1b1c

File tree

2 files changed

+53
-69
lines changed

2 files changed

+53
-69
lines changed

internal/ethereum/confirmation_reconciler.go

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (bl *blockListener) buildConfirmationList(ctx context.Context, existingConf
7979
// - The `lateList`. This is the most recent set of blocks that we are interesting in and we believe are accurate for the current state of the chain
8080

8181
earlyList := createEarlyList(existingConfirmations, txBlockInfo, reconcileResult)
82-
lateList, err := createLateList(ctx, txBlockInfo, targetConfirmationCount, reconcileResult, bl)
82+
lateList, err := createLateList(ctx, txBlockInfo, targetConfirmationCount, bl)
8383
if err != nil {
8484
return nil, err
8585
}
@@ -140,9 +140,6 @@ func newSplice(earlyList []*ffcapi.MinimalBlockInfo, lateList []*ffcapi.MinimalB
140140
earlyList: earlyList,
141141
lateList: lateList,
142142
}
143-
if len(s.earlyList) == 0 || len(s.lateList) == 0 {
144-
return s, false
145-
}
146143
detectedFork := false
147144
// if the early list is bigger than the gap between the transaction block number and the first block in the late list, then we have an overlap
148145
txBlockNumber := s.earlyList[0].BlockNumber.Uint64()
@@ -178,11 +175,6 @@ func (s *splice) isEarlyListEmpty() bool {
178175
}
179176

180177
func (s *splice) fillOneGap(ctx context.Context, blockListener *blockListener) error {
181-
if !s.hasGap() {
182-
// no gap to fill
183-
return nil
184-
}
185-
186178
// fill one slot in the gap between the late list and the early list
187179
// always fill from the end of the gap ( i.e. the block before the start of the late list) because
188180
// the late list is our best view of the current canonical chain so working backwards from there will increase the number of blocks that we have a high confidence in
@@ -191,9 +183,6 @@ func (s *splice) fillOneGap(ctx context.Context, blockListener *blockListener) e
191183
if err != nil {
192184
return err
193185
}
194-
if freshBlockInfo == nil {
195-
return i18n.NewError(ctx, msgs.MsgBlockNotAvailable)
196-
}
197186

198187
fetchedBlock := &ffcapi.MinimalBlockInfo{
199188
BlockNumber: fftypes.FFuint64(freshBlockInfo.Number.BigInt().Uint64()),
@@ -213,25 +202,12 @@ func (s *splice) fillOneGap(ctx context.Context, blockListener *blockListener) e
213202
}
214203

215204
func (s *splice) removeBrokenLink() {
216-
if s.hasGap() {
217-
// nothing to remove if there is a gap
218-
return
219-
}
220205
// remove the last block from the early list because it is not the parent of the first block in the late list and we have higher confidence in the late list
221206
s.earlyList = s.earlyList[:len(s.earlyList)-1]
222207

223208
}
224209

225210
func (s *splice) toSingleLinkedList() []*ffcapi.MinimalBlockInfo {
226-
if s.hasGap() {
227-
return nil
228-
}
229-
if len(s.earlyList) == 0 {
230-
return s.lateList
231-
}
232-
if len(s.lateList) == 0 {
233-
return s.earlyList
234-
}
235211
if s.earlyList[len(s.earlyList)-1].IsParentOf(s.lateList[0]) {
236212
return append(s.earlyList, s.lateList...)
237213
}
@@ -244,20 +220,20 @@ func (s *splice) toSingleLinkedList() []*ffcapi.MinimalBlockInfo {
244220
// any blocks that are not contiguous will be discarded
245221
func createEarlyList(existingConfirmations []*ffcapi.MinimalBlockInfo, txBlockInfo *ffcapi.MinimalBlockInfo, reconcileResult *ffcapi.ConfirmationUpdateResult) (earlyList []*ffcapi.MinimalBlockInfo) {
246222
if len(existingConfirmations) > 0 && !existingConfirmations[0].Equal(txBlockInfo) {
247-
// otherwise we discard the existing confirmations queue
223+
// otherwise we discard the existing confirmations list
248224
reconcileResult.NewFork = true
249225
} else {
250226
earlyList = existingConfirmations
251227
}
252228

253-
if len(existingConfirmations) == 0 {
229+
if len(earlyList) == 0 {
254230
// either because this is the first time we are reconciling this transaction or because we just discarded the existing confirmations queue
255231
earlyList = []*ffcapi.MinimalBlockInfo{txBlockInfo}
256232
}
257233
return earlyList
258234
}
259235

260-
func createLateList(ctx context.Context, txBlockInfo *ffcapi.MinimalBlockInfo, targetConfirmationCount uint64, reconcileResult *ffcapi.ConfirmationUpdateResult, blockListener *blockListener) (lateList []*ffcapi.MinimalBlockInfo, err error) {
236+
func createLateList(ctx context.Context, txBlockInfo *ffcapi.MinimalBlockInfo, targetConfirmationCount uint64, blockListener *blockListener) (lateList []*ffcapi.MinimalBlockInfo, err error) {
261237
lateList, err = blockListener.buildConfirmationQueueUsingInMemoryPartialChain(ctx, txBlockInfo, targetConfirmationCount)
262238
if err != nil {
263239
return nil, err
@@ -270,10 +246,6 @@ func createLateList(ctx context.Context, txBlockInfo *ffcapi.MinimalBlockInfo, t
270246
if err != nil {
271247
return nil, err
272248
}
273-
if targetBlockInfo == nil {
274-
return nil, i18n.NewError(ctx, msgs.MsgBlockNotAvailable)
275-
}
276-
277249
lateList = []*ffcapi.MinimalBlockInfo{
278250
{
279251
BlockNumber: fftypes.FFuint64(targetBlockInfo.Number.BigInt().Uint64()),
@@ -360,7 +332,7 @@ func (bl *blockListener) handleZeroTargetConfirmationCount(ctx context.Context,
360332
return nil, i18n.NewError(ctx, msgs.MsgInMemoryPartialChainNotCaughtUp, txBlockInfo.BlockNumber.Uint64(), txBlockInfo.BlockHash)
361333
}
362334

363-
func (bl *blockListener) handleTargetCountLessThanExistingConfirmationLength(ctx context.Context, existingConfirmations []*ffcapi.MinimalBlockInfo, txBlockInfo *ffcapi.MinimalBlockInfo, targetConfirmationCount uint64) (*ffcapi.ConfirmationUpdateResult, error) {
335+
func (bl *blockListener) handleTargetCountLessThanExistingConfirmationLength(_ context.Context, existingConfirmations []*ffcapi.MinimalBlockInfo, txBlockInfo *ffcapi.MinimalBlockInfo, targetConfirmationCount uint64) (*ffcapi.ConfirmationUpdateResult, error) {
364336
bl.mux.RLock()
365337
defer bl.mux.RUnlock()
366338
nextInMemoryBlock := bl.canonicalChain.Front()

internal/ethereum/confirmation_reconciler_test.go

Lines changed: 48 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,54 @@ func TestReconcileConfirmationsForTransaction_NewConfirmation(t *testing.T) {
229229
mRPC.AssertExpectations(t)
230230
}
231231

232+
func TestReconcileConfirmationsForTransaction_DifferentTxBlock(t *testing.T) {
233+
234+
_, c, mRPC, _ := newTestConnectorWithNoBlockerFilterDefaultMocks(t)
235+
bl := c.blockListener
236+
bl.canonicalChain = createTestChain(1976, 1978) // Single block at 50, tx is at 100
237+
238+
// Mock for TransactionReceipt call
239+
mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getTransactionReceipt",
240+
mock.MatchedBy(func(txHash string) bool {
241+
assert.Equal(t, "0x6197ef1a58a2a592bb447efb651f0db7945de21aa8048801b250bd7b7431f9b6", txHash)
242+
return true
243+
})).
244+
Return(nil).
245+
Run(func(args mock.Arguments) {
246+
err := json.Unmarshal([]byte(sampleJSONRPCReceipt), args[1])
247+
assert.NoError(t, err)
248+
})
249+
250+
mRPC.On("CallRPC", mock.Anything, mock.Anything, "eth_getBlockByNumber", mock.MatchedBy(func(bn *ethtypes.HexInteger) bool {
251+
return bn.BigInt().String() == "1977"
252+
}), false).Return(nil).Run(func(args mock.Arguments) {
253+
*args[1].(**blockInfoJSONRPC) = &blockInfoJSONRPC{
254+
Number: ethtypes.NewHexInteger64(1977),
255+
Hash: ethtypes.MustNewHexBytes0xPrefix(generateTestHash(1977)),
256+
ParentHash: ethtypes.MustNewHexBytes0xPrefix(generateTestHash(1976)),
257+
}
258+
})
259+
260+
// Execute the reconcileConfirmationsForTransaction function
261+
result, err := c.ReconcileConfirmationsForTransaction(context.Background(), "0x6197ef1a58a2a592bb447efb651f0db7945de21aa8048801b250bd7b7431f9b6", []*ffcapi.MinimalBlockInfo{
262+
{BlockNumber: fftypes.FFuint64(1979), BlockHash: generateTestHash(1979), ParentHash: generateTestHash(1978)},
263+
{BlockNumber: fftypes.FFuint64(1980), BlockHash: generateTestHash(1980), ParentHash: generateTestHash(1979)},
264+
}, 5)
265+
266+
// Assertions - expect the existing confirmation queue to be returned because the tx block doesn't match the same block number in the canonical chain
267+
assert.NoError(t, err)
268+
assert.NotNil(t, result)
269+
assert.True(t, result.NewFork)
270+
assert.False(t, result.Confirmed)
271+
assert.Equal(t, []*ffcapi.MinimalBlockInfo{
272+
{BlockNumber: fftypes.FFuint64(1977), BlockHash: generateTestHash(1977), ParentHash: generateTestHash(1976)},
273+
{BlockNumber: fftypes.FFuint64(1978), BlockHash: generateTestHash(1978), ParentHash: generateTestHash(1977)},
274+
}, result.Confirmations)
275+
assert.Equal(t, uint64(5), result.TargetConfirmationCount)
276+
277+
mRPC.AssertExpectations(t)
278+
}
279+
232280
func TestBuildConfirmationList_GapInExistingConfirmationsError(t *testing.T) {
233281
// Setup
234282
_, c, mRPC, _ := newTestConnectorWithNoBlockerFilterDefaultMocks(t)
@@ -281,7 +329,6 @@ func TestBuildConfirmationList_MismatchConfirmationBlockError(t *testing.T) {
281329
assert.Nil(t, confirmationUpdateResult)
282330
assert.Regexp(t, "FF23063", err.Error())
283331
}
284-
285332
func TestBuildConfirmationList_ExistingConfirmationLaterThanCurrentBlockError(t *testing.T) {
286333
// Setup
287334
_, c, mRPC, _ := newTestConnectorWithNoBlockerFilterDefaultMocks(t)
@@ -650,41 +697,6 @@ func TestBuildConfirmationList_ConnectionNodeMismatch(t *testing.T) {
650697
assert.Equal(t, txBlockNumber+5, uint64(confirmationUpdateResult.Confirmations[5].BlockNumber))
651698
}
652699

653-
func TestBuildConfirmationList_CorruptedExistingConfirmationAfterFirstConfirmation(t *testing.T) {
654-
// Setup
655-
bl, done := newBlockListenerWithTestChain(t, 100, 5, 100, 150, []uint64{})
656-
defer done()
657-
658-
ctx := context.Background()
659-
existingQueue := []*ffcapi.MinimalBlockInfo{
660-
{BlockHash: generateTestHash(100), BlockNumber: fftypes.FFuint64(100), ParentHash: generateTestHash(99)},
661-
{BlockHash: generateTestHash(101), BlockNumber: fftypes.FFuint64(101), ParentHash: generateTestHash(100)},
662-
{BlockHash: generateTestHash(102), BlockNumber: fftypes.FFuint64(102), ParentHash: "0xblockwrong"},
663-
}
664-
txBlockNumber := uint64(100)
665-
txBlockHash := generateTestHash(100)
666-
txBlockInfo := &ffcapi.MinimalBlockInfo{
667-
BlockNumber: fftypes.FFuint64(txBlockNumber),
668-
BlockHash: txBlockHash,
669-
ParentHash: generateTestHash(99),
670-
}
671-
targetConfirmationCount := uint64(5)
672-
673-
// Execute
674-
confirmationUpdateResult, err := bl.buildConfirmationList(ctx, existingQueue, txBlockInfo, targetConfirmationCount)
675-
assert.NoError(t, err)
676-
// Assert
677-
assert.True(t, confirmationUpdateResult.NewFork)
678-
assert.True(t, confirmationUpdateResult.Confirmed)
679-
assert.Len(t, confirmationUpdateResult.Confirmations, 6)
680-
assert.Equal(t, txBlockNumber, uint64(confirmationUpdateResult.Confirmations[0].BlockNumber))
681-
assert.Equal(t, txBlockNumber+1, uint64(confirmationUpdateResult.Confirmations[1].BlockNumber))
682-
assert.Equal(t, txBlockNumber+2, uint64(confirmationUpdateResult.Confirmations[2].BlockNumber))
683-
assert.Equal(t, txBlockNumber+3, uint64(confirmationUpdateResult.Confirmations[3].BlockNumber))
684-
assert.Equal(t, txBlockNumber+4, uint64(confirmationUpdateResult.Confirmations[4].BlockNumber))
685-
assert.Equal(t, txBlockNumber+5, uint64(confirmationUpdateResult.Confirmations[5].BlockNumber))
686-
}
687-
688700
func TestBuildConfirmationList_FailedToFetchBlockInfo(t *testing.T) {
689701
// Setup
690702
mRPC := &rpcbackendmocks.Backend{}

0 commit comments

Comments
 (0)