Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/utils: report the correct invalid block number in block import #27213

Merged

Conversation

gballet
Copy link
Member

@gballet gballet commented May 3, 2023

When the block import fails, the error displays the number of the first block past the import batch, not the number of the failing block. This PR fixes this problem by identifying which blocks fails and reporting its number.

cmd/utils/cmd.go Outdated
Comment on lines 214 to 215
if failindex, err := chain.InsertChain(missing); err != nil {
return fmt.Errorf("invalid block %d: %v", blocks[failindex].NumberU64(), err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code can now panic on invalid array index, -1 or too large. If you just check that so we don't panic here, then it's fine by me

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just double-checked, it really can not be -1 (in the current state of the code) since there is no return between the moment the iterator is initalized with -1 and the moment the index is set to a >= 0 value. This is just FYI, not using an array index is the better, future-proof approach.

Copy link
Contributor

@holiman holiman May 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, here's a panic though:

func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
	// Sanity check that we have something meaningful to import
	if len(chain) == 0 {
		return 0, nil
	}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, incidentally, this should not return 0, but i or i-1:

	for i := 1; i < len(chain); i++ {
		block, prev := chain[i], chain[i-1]
		if block.NumberU64() != prev.NumberU64()+1 || block.ParentHash() != prev.Hash() {
			log.Error("Non contiguous block insert",
				"number", block.Number(),
				"hash", block.Hash(),
				"parent", block.ParentHash(),
				"prevnumber", prev.Number(),
				"prevhash", prev.Hash(),
			)
			return 0, fmt.Errorf("non contiguous insert: item %d is #%d [%x..], item %d is #%d [%x..] (parent [%x..])", i-1, prev.NumberU64(),
				prev.Hash().Bytes()[:4], i, block.NumberU64(), block.Hash().Bytes()[:4], block.ParentHash().Bytes()[:4])

Copy link
Contributor

@holiman holiman May 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, perhaps better to show both the index of the block in the sequence, and the block number ( if we have it), possibly aswell as the current "last good" (?).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, here's a panic though:

func (bc *BlockChain) InsertChain(chain types.Blocks) (int, error) {
	// Sanity check that we have something meaningful to import
	if len(chain) == 0 {
		return 0, nil
	}

thought so at first too, but the error would be nil, so it would not try to access that branch, and therefore not panic.

And, incidentally, this should not return 0, but i or i-1:

True, I'll fix that

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, incidentally, this should not return 0, but i or i-1:

So actually, it's subtle but returning 0 here is correct imo: since the code hasn't tried to insert any block, no individual single block is responsible for the failure, it's the sequence as a whole that is incorrect. But it's also possible to consider i to be incorrect, also it's harder to argue in the case i=1 because maybe the first block is the incorrect one. What do you think?

Also, perhaps better to show both the index of the block in the sequence, and the block number ( if we have it), possibly aswell as the current "last good" (?).

That is already done inside the error message that is returned.

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -211,8 +215,11 @@ func ImportChain(chain *core.BlockChain, fn string) error {
log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash())
continue
}
if _, err := chain.InsertChain(missing); err != nil {
return fmt.Errorf("invalid block %d: %v", n, err)
if failindex, err := chain.InsertChain(missing); err != nil {
Copy link
Member

@rjl493456442 rjl493456442 May 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can simplify it a bit.

diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index e1bafc53c3..37b6d222a5 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -211,8 +211,14 @@ func ImportChain(chain *core.BlockChain, fn string) error {
                        log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash())
                        continue
                }
-               if _, err := chain.InsertChain(missing); err != nil {
-                       return fmt.Errorf("invalid block %d: %v", n, err)
+               if failIndex, err := chain.InsertChain(missing); err != nil {
+                       var failNumber uint64
+                       if failIndex == -1 {
+                               failNumber = missing[0].NumberU64()
+                       } else {
+                               failNumber = missing[failIndex].NumberU64()
+                       }
+                       return fmt.Errorf("invalid block %d: %v", failNumber, err)
                }
        }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd change @rjl493456442 's condition-check into

+                       if failIndex > 0 && failIndex < len(missing) {
+                               failNumber = missing[failIndex].NumberU64()
+                       } else {
+                               failNumber = missing[0].NumberU64()
+                       }

Copy link

@mohammadfarari1360 mohammadfarari1360 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello dear

@rjl493456442
Copy link
Member

Good to go!

@holiman holiman added this to the 1.11.7 milestone May 9, 2023
@holiman holiman merged commit c62da24 into ethereum:master May 9, 2023
mohammadfarari1360 added a commit to mohammadfarari1360/go-ethereum that referenced this pull request May 25, 2023
shekhirin pushed a commit to shekhirin/go-ethereum that referenced this pull request Jun 6, 2023
…7213)

When block import fails, the error displays the number of the first block past the import batch, not the number of the failing block. This change fixes this problem by identifying which blocks fails and reporting its number.
devopsbo3 pushed a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
…7213)

When block import fails, the error displays the number of the first block past the import batch, not the number of the failing block. This change fixes this problem by identifying which blocks fails and reporting its number.
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants