-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
jsonrpc: Implement debug_getBadBlocks (#11888)
#8171 - reference of rpc api query params/return value is taken from geth [here](https://github.com/ethereum/go-ethereum/blob/b4d99e39176f89bb0ffbb32635e9cf17b5fd7367/eth/api_debug.go#L107) - difference is that geth returns ALL bad blocks, this PR returns 100.
- Loading branch information
1 parent
5d99935
commit 53b973d
Showing
9 changed files
with
381 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package utils | ||
|
||
import ( | ||
"container/heap" | ||
|
||
"github.com/erigontech/erigon-lib/common" | ||
) | ||
|
||
// blockMaxHeap stores a (limited-length) priority queue of blocks. | ||
// the queue will maintain a fixed length of blocks, discarding the lowest block num when limit is exceeded. | ||
// Effectively the heap stores the maximum `limit` blocks (by block_num) among all blocks pushed. | ||
// -1 means unlimited length | ||
type blockMaxHeap struct { | ||
heap []*BlockId | ||
limit int | ||
} | ||
|
||
type BlockId struct { | ||
Number uint64 | ||
Hash common.Hash | ||
} | ||
|
||
type ExtendedHeap interface { | ||
heap.Interface | ||
SortedValues() []*BlockId | ||
} | ||
|
||
func NewBlockMaxHeap(limit int) ExtendedHeap { | ||
return &blockMaxHeap{limit: limit} | ||
} | ||
|
||
func (h *blockMaxHeap) Len() int { | ||
return len(h.heap) | ||
} | ||
|
||
func (h *blockMaxHeap) Less(i, j int) bool { | ||
return h.heap[i].Number < h.heap[j].Number | ||
} | ||
|
||
func (h *blockMaxHeap) Swap(i, j int) { | ||
h.heap[i], h.heap[j] = h.heap[j], h.heap[i] | ||
} | ||
|
||
func (h *blockMaxHeap) Push(x any) { | ||
if h.limit == 0 { | ||
return | ||
} | ||
len := len(h.heap) | ||
if h.limit != -1 && len >= h.limit && len > 0 { | ||
if h.heap[0].Number < x.(*BlockId).Number { | ||
_ = heap.Pop(h) | ||
} else { | ||
// discard | ||
return | ||
} | ||
} | ||
h.heap = append(h.heap, x.(*BlockId)) | ||
} | ||
|
||
func (h *blockMaxHeap) Pop() any { | ||
n := len(h.heap) | ||
x := h.heap[n-1] | ||
h.heap = h.heap[0 : n-1] | ||
return x | ||
} | ||
|
||
func (h *blockMaxHeap) copy() *blockMaxHeap { | ||
newHeap := NewBlockMaxHeap(h.limit) | ||
for _, b := range h.heap { | ||
heap.Push(newHeap, b) | ||
} | ||
return newHeap.(*blockMaxHeap) | ||
} | ||
|
||
func (h *blockMaxHeap) SortedValues() []*BlockId { | ||
// copy | ||
copyHeap := h.copy() | ||
res := make([]*BlockId, len(copyHeap.heap)) | ||
for copyHeap.Len() > 0 { | ||
res[copyHeap.Len()-1] = heap.Pop(copyHeap).(*BlockId) | ||
} | ||
|
||
return res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package utils_test | ||
|
||
import ( | ||
"container/heap" | ||
"testing" | ||
|
||
"github.com/erigontech/erigon-lib/common" | ||
"github.com/erigontech/erigon/core/rawdb/utils" | ||
) | ||
|
||
func TestPush(t *testing.T) { | ||
h := utils.NewBlockMaxHeap(-1) | ||
heap.Push(h, newB(1, []byte{})) | ||
if h.Len() != 1 { | ||
t.Fatal("expected 1") | ||
} | ||
|
||
heap.Push(h, newB(2, []byte{})) | ||
if h.Len() != 2 { | ||
t.Fatal("expected 2") | ||
} | ||
} | ||
|
||
func TestPop(t *testing.T) { | ||
h := utils.NewBlockMaxHeap(-1) | ||
heap.Push(h, newB(4, []byte{0x01})) | ||
heap.Push(h, newB(99, []byte{0x02})) | ||
heap.Push(h, newB(3, []byte{0x03})) | ||
|
||
x := heap.Pop(h).(*utils.BlockId) | ||
if x.Number != 3 || lastByte(x) != 0x03 { | ||
t.Fatal("unexpected") | ||
} | ||
|
||
x = heap.Pop(h).(*utils.BlockId) | ||
if x.Number != 4 || lastByte(x) != 0x01 { | ||
t.Fatal("unexpected") | ||
} | ||
|
||
x = h.Pop().(*utils.BlockId) | ||
if x.Number != 99 || lastByte(x) != 0x02 { | ||
t.Fatal("unexpected") | ||
} | ||
} | ||
|
||
func TestPopWithLimits(t *testing.T) { | ||
h := utils.NewBlockMaxHeap(2) | ||
heap.Push(h, newB(4, []byte{0x01})) | ||
heap.Push(h, newB(2, []byte{0x04})) | ||
heap.Push(h, newB(99, []byte{0x02})) | ||
heap.Push(h, newB(3, []byte{0x03})) | ||
|
||
if h.Len() != 2 { | ||
t.Fatal("expected 2 got ", h.Len()) | ||
} | ||
x := heap.Pop(h).(*utils.BlockId) | ||
if x.Number != 4 || lastByte(x) != 0x01 { | ||
t.Fatal("unexpected") | ||
} | ||
|
||
x = heap.Pop(h).(*utils.BlockId) | ||
if x.Number != 99 || lastByte(x) != 0x02 { | ||
t.Fatal("unexpected") | ||
} | ||
} | ||
|
||
func TestPopWithEmptyHeap(t *testing.T) { | ||
h := utils.NewBlockMaxHeap(0) | ||
heap.Push(h, newB(4, []byte{0x01})) | ||
if h.Len() != 0 { | ||
t.Fatal("expected 0") | ||
} | ||
} | ||
|
||
func newB(id uint64, hash []byte) *utils.BlockId { | ||
return &utils.BlockId{Number: id, Hash: common.BytesToHash(hash)} | ||
} | ||
|
||
func lastByte(b *utils.BlockId) byte { | ||
by := b.Hash.Bytes() | ||
return by[len(by)-1] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.