mirror of
https://github.com/forta-network/go-multicall.git
synced 2026-02-26 07:37:23 +00:00
fix chunking
This commit is contained in:
parent
83a1516841
commit
1436386c67
2 changed files with 84 additions and 10 deletions
40
caller.go
40
caller.go
|
|
@ -78,21 +78,41 @@ func (caller *Caller) Call(opts *bind.CallOpts, calls ...*Call) ([]*Call, error)
|
||||||
|
|
||||||
// CallChunked makes multiple multicalls by chunking given calls.
|
// CallChunked makes multiple multicalls by chunking given calls.
|
||||||
func (caller *Caller) CallChunked(opts *bind.CallOpts, chunkSize int, calls ...*Call) ([]*Call, error) {
|
func (caller *Caller) CallChunked(opts *bind.CallOpts, chunkSize int, calls ...*Call) ([]*Call, error) {
|
||||||
if chunkSize <= 0 || len(calls) < 2 {
|
|
||||||
return caller.Call(opts, calls...)
|
|
||||||
}
|
|
||||||
callCount := len(calls) / chunkSize
|
|
||||||
|
|
||||||
var allCalls []*Call
|
var allCalls []*Call
|
||||||
for i := 0; i < callCount; i++ {
|
for i, chunk := range chunkInputs(chunkSize, calls) {
|
||||||
start := i * chunkSize
|
chunk, err := caller.Call(opts, chunk...)
|
||||||
end := start + chunkSize
|
|
||||||
chunk, err := caller.Call(opts, calls[start:end]...)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return calls, fmt.Errorf("call chunk [%d] failed: %v", i, err)
|
return calls, fmt.Errorf("call chunk [%d] failed: %v", i, err)
|
||||||
}
|
}
|
||||||
allCalls = append(allCalls, chunk...)
|
allCalls = append(allCalls, chunk...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return allCalls, nil
|
return allCalls, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func chunkInputs[T any](chunkSize int, inputs []T) (chunks [][]T) {
|
||||||
|
if len(inputs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if chunkSize <= 0 || len(inputs) < 2 || chunkSize > len(inputs) {
|
||||||
|
return [][]T{inputs}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastChunkSize := len(inputs) % chunkSize
|
||||||
|
|
||||||
|
chunkCount := len(inputs) / chunkSize
|
||||||
|
|
||||||
|
for i := 0; i < chunkCount; i++ {
|
||||||
|
start := i * chunkSize
|
||||||
|
end := start + chunkSize
|
||||||
|
chunks = append(chunks, inputs[start:end])
|
||||||
|
}
|
||||||
|
|
||||||
|
if lastChunkSize > 0 {
|
||||||
|
start := chunkCount * chunkSize
|
||||||
|
end := start + lastChunkSize
|
||||||
|
chunks = append(chunks, inputs[start:end])
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -325,3 +325,57 @@ func TestDial(t *testing.T) {
|
||||||
r.NoError(err)
|
r.NoError(err)
|
||||||
r.NotNil(caller)
|
r.NotNil(caller)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestChunkInputs(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
chunkSize int
|
||||||
|
inputs []int
|
||||||
|
expected [][]int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "zero inputs large chunk size",
|
||||||
|
chunkSize: 12345,
|
||||||
|
inputs: []int{},
|
||||||
|
expected: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "single input large chunk size",
|
||||||
|
chunkSize: 12345,
|
||||||
|
inputs: []int{10},
|
||||||
|
expected: [][]int{{10}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "2 inputs chunk size 1",
|
||||||
|
chunkSize: 1,
|
||||||
|
inputs: []int{10, 20},
|
||||||
|
expected: [][]int{{10}, {20}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "2 inputs chunk size 2",
|
||||||
|
chunkSize: 2,
|
||||||
|
inputs: []int{10, 20},
|
||||||
|
expected: [][]int{{10, 20}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "5 inputs chunk size 3",
|
||||||
|
chunkSize: 3,
|
||||||
|
inputs: []int{10, 20, 30, 40, 50},
|
||||||
|
expected: [][]int{{10, 20, 30}, {40, 50}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "3 inputs chunk size 5",
|
||||||
|
chunkSize: 5,
|
||||||
|
inputs: []int{10, 20, 30},
|
||||||
|
expected: [][]int{{10, 20, 30}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.name, func(t *testing.T) {
|
||||||
|
r := require.New(t)
|
||||||
|
|
||||||
|
r.Equal(testCase.expected, chunkInputs(testCase.chunkSize, testCase.inputs))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue