-
Notifications
You must be signed in to change notification settings - Fork 154
/
iterator.go
99 lines (79 loc) · 1.95 KB
/
iterator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package starknet
import (
"errors"
"fmt"
"github.com/NethermindEth/juno/blockchain"
"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/db"
)
type iterator struct {
bcReader blockchain.Reader
blockNumber uint64
step uint64
limit uint64
forward bool
reachedEnd bool
}
func newIteratorByNumber(bcReader blockchain.Reader, blockNumber, limit, step uint64, forward bool) (*iterator, error) {
if step == 0 {
return nil, fmt.Errorf("step is zero")
}
if limit == 0 {
return nil, fmt.Errorf("limit is zero")
}
return &iterator{
bcReader: bcReader,
blockNumber: blockNumber,
limit: limit,
step: step,
forward: forward,
reachedEnd: false,
}, nil
}
func newIteratorByHash(bcReader blockchain.Reader, blockHash *felt.Felt, limit, step uint64, forward bool) (*iterator, error) {
if blockHash == nil {
return nil, fmt.Errorf("block hash is nil")
}
block, err := bcReader.BlockByHash(blockHash)
if err != nil {
return nil, err
}
return newIteratorByNumber(bcReader, block.Number, limit, step, forward)
}
func (it *iterator) Valid() bool {
if it.limit == 0 || it.reachedEnd {
return false
}
return true
}
func (it *iterator) Next() bool {
if !it.Valid() {
return false
}
if it.forward {
it.blockNumber += it.step
} else {
it.blockNumber -= it.step
}
// assumption that it.Valid checks for zero limit i.e. no overflow is possible here
it.limit--
return it.Valid()
}
func (it *iterator) BlockNumber() uint64 {
return it.blockNumber
}
func (it *iterator) Block() (*core.Block, error) {
block, err := it.bcReader.BlockByNumber(it.blockNumber)
if errors.Is(err, db.ErrKeyNotFound) {
it.reachedEnd = true
}
return block, err
}
func (it *iterator) Header() (*core.Header, error) {
header, err := it.bcReader.BlockHeaderByNumber(it.blockNumber)
if errors.Is(err, db.ErrKeyNotFound) {
it.reachedEnd = true
}
return header, err
}