-
Notifications
You must be signed in to change notification settings - Fork 0
/
index_iter.go
66 lines (53 loc) · 1.5 KB
/
index_iter.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
package ethutils
import (
"context"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/lmittmann/w3/module/eth"
"github.com/lmittmann/w3/w3types"
)
type BatchIterator struct {
provider *Provider
index common.Address
entryCount *big.Int
currentIndex int64
batchSize int64
}
const defaultBatchSize = 500
func (p *Provider) NewBatchIterator(ctx context.Context, index common.Address) (*BatchIterator, error) {
var entryCount *big.Int
if err := p.Client.CallCtx(
ctx,
eth.CallFunc(index, entryCountFunc).Returns(&entryCount),
); err != nil {
return nil, err
}
return &BatchIterator{
provider: p,
index: index,
entryCount: entryCount,
currentIndex: 0,
batchSize: defaultBatchSize,
}, nil
}
func (iter *BatchIterator) Next(ctx context.Context) ([]common.Address, error) {
if iter.currentIndex >= iter.entryCount.Int64() {
return nil, nil
}
endIndex := iter.currentIndex + iter.batchSize
if endIndex > iter.entryCount.Int64() {
endIndex = iter.entryCount.Int64()
}
batchSize := endIndex - iter.currentIndex
calls := make([]w3types.RPCCaller, batchSize)
tokenAddresses := make([]common.Address, batchSize)
for i := int64(0); i < batchSize; i++ {
index := iter.currentIndex + i
calls[i] = eth.CallFunc(iter.index, entrySig, new(big.Int).SetInt64(index)).Returns(&tokenAddresses[i])
}
if err := iter.provider.Client.CallCtx(ctx, calls...); err != nil {
return nil, err
}
iter.currentIndex = endIndex
return tokenAddresses, nil
}