Skip to content

Commit 3494cf9

Browse files
committed
multicall: batch call test
1 parent 79f4a92 commit 3494cf9

2 files changed

Lines changed: 158 additions & 2 deletions

File tree

ethrpc/multicall.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func (p *Provider) Multicall(ctx context.Context, calls []multicall.Call, option
6060
options[0].SkipMulticallLookup = true
6161
}
6262
if !found {
63-
return p.multicallFallback(ctx, calls, options...)
63+
return p.BatchCall(ctx, calls, options...)
6464
}
6565
}
6666

@@ -130,7 +130,7 @@ func (p *Provider) Multicall(ctx context.Context, calls []multicall.Call, option
130130
return results, options[0], nil
131131
}
132132

133-
func (p *Provider) multicallFallback(ctx context.Context, calls []multicall.Call, options ...MulticallOptions) ([]multicall.Multicall3Result, MulticallOptions, error) {
133+
func (p *Provider) BatchCall(ctx context.Context, calls []multicall.Call, options ...MulticallOptions) ([]multicall.Multicall3Result, MulticallOptions, error) {
134134
if len(options) == 0 {
135135
options = append(options, MulticallOptions{})
136136
}

ethrpc/multicall_test.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,129 @@ func TestMulticall(t *testing.T) {
139139
fmt.Println("last block:", lastBlockHash)
140140
}
141141

142+
func TestBatchCall(t *testing.T) {
143+
ctx := context.Background()
144+
145+
provider, err := ethrpc.NewProvider("https://nodes.sequence.app/mainnet")
146+
assert.NoError(t, err)
147+
148+
height, err := provider.BlockNumber(ctx)
149+
assert.NoError(t, err)
150+
151+
var (
152+
baseFee *big.Int
153+
blockHash common.Hash
154+
blockNumber *big.Int
155+
chainID *big.Int
156+
coinbase common.Address
157+
blockDifficulty *big.Int
158+
blockGasLimit *big.Int
159+
blockTimestamp *big.Int
160+
balance *big.Int
161+
lastBlockHash common.Hash
162+
)
163+
164+
results, options, err := provider.BatchCall(ctx, []multicall.Call{
165+
{
166+
Multicall3Call3Value: multicall.Multicall3Call3Value{
167+
Target: multicallAddress,
168+
CallData: multicall.BaseFee(),
169+
AllowFailure: true,
170+
},
171+
Outputs: []multicall.Output{{Type: uint256(), Output: &baseFee}},
172+
},
173+
{
174+
Multicall3Call3Value: multicall.Multicall3Call3Value{
175+
Target: multicallAddress,
176+
CallData: multicall.BlockHash(big.NewInt(int64(height) - 100)),
177+
AllowFailure: true,
178+
},
179+
Outputs: []multicall.Output{{Type: bytes32(), Output: &blockHash}},
180+
},
181+
{
182+
Multicall3Call3Value: multicall.Multicall3Call3Value{
183+
Target: multicallAddress,
184+
CallData: multicall.BlockNumber(),
185+
AllowFailure: true,
186+
},
187+
Outputs: []multicall.Output{{Type: uint256(), Output: &blockNumber}},
188+
},
189+
{
190+
Multicall3Call3Value: multicall.Multicall3Call3Value{
191+
Target: multicallAddress,
192+
CallData: multicall.ChainID(),
193+
AllowFailure: true,
194+
},
195+
Outputs: []multicall.Output{{Type: uint256(), Output: &chainID}},
196+
},
197+
{
198+
Multicall3Call3Value: multicall.Multicall3Call3Value{
199+
Target: multicallAddress,
200+
CallData: multicall.BlockCoinbase(),
201+
AllowFailure: true,
202+
},
203+
Outputs: []multicall.Output{{Type: address(), Output: &coinbase}},
204+
},
205+
{
206+
Multicall3Call3Value: multicall.Multicall3Call3Value{
207+
Target: multicallAddress,
208+
CallData: multicall.BlockDifficulty(),
209+
AllowFailure: true,
210+
},
211+
Outputs: []multicall.Output{{Type: uint256(), Output: &blockDifficulty}},
212+
},
213+
{
214+
Multicall3Call3Value: multicall.Multicall3Call3Value{
215+
Target: multicallAddress,
216+
CallData: multicall.BlockGasLimit(),
217+
AllowFailure: true,
218+
},
219+
Outputs: []multicall.Output{{Type: uint256(), Output: &blockGasLimit}},
220+
},
221+
{
222+
Multicall3Call3Value: multicall.Multicall3Call3Value{
223+
Target: multicallAddress,
224+
CallData: multicall.BlockTimestamp(),
225+
AllowFailure: true,
226+
},
227+
Outputs: []multicall.Output{{Type: uint256(), Output: &blockTimestamp}},
228+
},
229+
{
230+
Multicall3Call3Value: multicall.Multicall3Call3Value{
231+
Target: multicallAddress,
232+
CallData: multicall.Balance(common.HexToAddress("0xc06145782F31030dB1C40B203bE6B0fD53410B6d")),
233+
AllowFailure: true,
234+
},
235+
Outputs: []multicall.Output{{Type: uint256(), Output: &balance}},
236+
},
237+
{
238+
Multicall3Call3Value: multicall.Multicall3Call3Value{
239+
Target: multicallAddress,
240+
CallData: multicall.LastBlockHash(),
241+
AllowFailure: true,
242+
},
243+
Outputs: []multicall.Output{{Type: bytes32(), Output: &lastBlockHash}},
244+
},
245+
})
246+
assert.NoError(t, err)
247+
for _, result := range results {
248+
assert.True(t, result.Success)
249+
}
250+
251+
spew.Dump(options)
252+
253+
fmt.Println("base fee:", baseFee)
254+
fmt.Printf("block %v: %v\n", height-100, blockHash)
255+
fmt.Println("block number:", blockNumber)
256+
fmt.Println("chain id:", chainID)
257+
fmt.Println("block coinbase:", coinbase)
258+
fmt.Println("block difficulty:", blockDifficulty)
259+
fmt.Println("block gas limit:", blockGasLimit)
260+
fmt.Println("block timestamp:", blockTimestamp)
261+
fmt.Println("balance:", balance)
262+
fmt.Println("last block:", lastBlockHash)
263+
}
264+
142265
func TestMulticallBig(t *testing.T) {
143266
const N = 1023
144267

@@ -172,6 +295,39 @@ func TestMulticallBig(t *testing.T) {
172295
fmt.Println("balance:", balance)
173296
}
174297

298+
func TestBatchCallBig(t *testing.T) {
299+
const N = 40
300+
301+
ctx := context.Background()
302+
303+
provider, err := ethrpc.NewProvider("https://nodes.sequence.app/mainnet")
304+
assert.NoError(t, err)
305+
306+
var balance *big.Int
307+
308+
calls := make([]multicall.Call, 0, N)
309+
for range N {
310+
calls = append(calls, multicall.Call{
311+
Multicall3Call3Value: multicall.Multicall3Call3Value{
312+
Target: multicallAddress,
313+
CallData: multicall.Balance(common.HexToAddress("0xc06145782F31030dB1C40B203bE6B0fD53410B6d")),
314+
AllowFailure: true,
315+
},
316+
Outputs: []multicall.Output{{Type: uint256(), Output: &balance}},
317+
})
318+
}
319+
320+
results, options, err := provider.BatchCall(ctx, calls)
321+
assert.NoError(t, err)
322+
for _, result := range results {
323+
assert.True(t, result.Success)
324+
}
325+
326+
spew.Dump(options)
327+
328+
fmt.Println("balance:", balance)
329+
}
330+
175331
func address() abi.Argument {
176332
type_, _ := abi.NewType("address", "", nil)
177333
return abi.Argument{Type: type_}

0 commit comments

Comments
 (0)