Skip to content
This repository was archived by the owner on Nov 25, 2025. It is now read-only.

Commit 826f074

Browse files
author
Darioush Jalali
authored
fix passing options to Call (needed for native asset historical correctness) (#700)
1 parent 98f84c5 commit 826f074

File tree

2 files changed

+113
-2
lines changed

2 files changed

+113
-2
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// (c) 2024, Ava Labs, Inc. All rights reserved.
2+
// See the file LICENSE for licensing terms.
3+
4+
package bind_test
5+
6+
import (
7+
"bytes"
8+
"math/big"
9+
"testing"
10+
11+
"github.com/ava-labs/coreth/accounts/abi"
12+
"github.com/ava-labs/coreth/accounts/abi/bind"
13+
"github.com/ava-labs/coreth/accounts/abi/bind/backends"
14+
"github.com/ava-labs/coreth/core/types"
15+
"github.com/ava-labs/coreth/eth/ethconfig"
16+
"github.com/ava-labs/coreth/ethclient/simulated"
17+
"github.com/ava-labs/coreth/node"
18+
"github.com/ava-labs/coreth/params"
19+
"github.com/ava-labs/libevm/common"
20+
"github.com/ava-labs/libevm/crypto"
21+
)
22+
23+
// TestGetSenderNativeAssetCall checks that the NativeAssetCall proxies the
24+
// caller address This behavior is disabled on the network and is only to test
25+
// previous behavior. Note the test uses ApricotPhase2Config.
26+
func TestGetSenderNativeAssetCall(t *testing.T) {
27+
// pragma solidity >=0.8.0 <0.9.0;
28+
// contract GetSenderNativeAssetCall {
29+
// address _sender;
30+
// function getSender() public view returns (address){
31+
// return _sender;
32+
// }
33+
// function setSender() public {
34+
// _sender = msg.sender;
35+
// }
36+
// }
37+
rawABI := `[
38+
{
39+
"inputs": [],
40+
"name": "getSender",
41+
"outputs": [ { "internalType": "address", "name": "", "type": "address" } ],
42+
"stateMutability": "view",
43+
"type": "function"
44+
},
45+
{
46+
"inputs": [],
47+
"name": "setSender",
48+
"outputs": [],
49+
"stateMutability": "nonpayable",
50+
"type": "function"
51+
}
52+
]`
53+
bytecode := common.FromHex(`6080604052348015600f57600080fd5b506101608061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806350c36a521461003b5780635e01eb5a14610045575b600080fd5b610043610063565b005b61004d6100a5565b60405161005a919061010f565b60405180910390f35b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100f9826100ce565b9050919050565b610109816100ee565b82525050565b60006020820190506101246000830184610100565b9291505056fea26469706673582212209023ce54f38e749b58f44e8da750354578080ce16df95037b7305ed7e480c36d64736f6c634300081b0033`)
54+
setSenderMethodName := "setSender"
55+
getSenderMethodName := "getSender"
56+
57+
parsedABI, err := abi.JSON(bytes.NewReader([]byte(rawABI)))
58+
if err != nil {
59+
t.Fatalf("Failed to parse ABI: %v", err)
60+
}
61+
62+
// Generate a new random account and a funded simulator
63+
key, _ := crypto.GenerateKey()
64+
auth, _ := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337))
65+
alloc := types.GenesisAlloc{auth.From: {Balance: big.NewInt(1000000000000000000)}}
66+
atApricotPhase2 := func(nodeConf *node.Config, ethConf *ethconfig.Config) {
67+
chainConfig := *params.TestApricotPhase2Config
68+
chainConfig.ChainID = big.NewInt(1337)
69+
ethConf.Genesis.Config = &chainConfig
70+
}
71+
b := simulated.NewBackend(alloc, simulated.WithBlockGasLimit(10000000), atApricotPhase2)
72+
sim := &backends.SimulatedBackend{
73+
Backend: b,
74+
Client: b.Client(),
75+
}
76+
defer sim.Close()
77+
78+
// Deploy the get/setSender contract
79+
_, _, interactor, err := bind.DeployContract(auth, parsedABI, bytecode, sim)
80+
if err != nil {
81+
t.Fatalf("Failed to deploy interactor contract: %v", err)
82+
}
83+
sim.Commit(false)
84+
85+
// Setting NativeAssetCall in the transact opts will proxy the call through
86+
// the NativeAssetCall precompile
87+
opts := &bind.TransactOpts{
88+
From: auth.From,
89+
Signer: auth.Signer,
90+
NativeAssetCall: &bind.NativeAssetCallOpts{
91+
AssetAmount: big.NewInt(0),
92+
},
93+
}
94+
if _, err := interactor.Transact(opts, setSenderMethodName); err != nil {
95+
t.Fatalf("Failed to set sender: %v", err)
96+
}
97+
sim.Commit(true)
98+
99+
var results []interface{}
100+
if err := interactor.Call(nil, &results, getSenderMethodName); err != nil {
101+
t.Fatalf("Failed to get sender: %v", err)
102+
}
103+
if len(results) != 1 {
104+
t.Fatalf("Expected one result, got %d", len(results))
105+
}
106+
if addr, ok := results[0].(common.Address); !ok {
107+
t.Fatalf("Expected address, got %T", results[0])
108+
} else if addr != auth.From {
109+
t.Fatalf("Address mismatch: have '%v'", addr)
110+
}
111+
}

params/hooks_libevm.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ func (a accessableState) GetSnowContext() *snow.Context {
163163
return GetExtra(a.env.ChainConfig()).SnowCtx
164164
}
165165

166-
func (a accessableState) Call(addr common.Address, input []byte, gas uint64, value *uint256.Int, _ ...vm.CallOption) (ret []byte, gasRemaining uint64, _ error) {
167-
return a.env.Call(addr, input, gas, value)
166+
func (a accessableState) Call(addr common.Address, input []byte, gas uint64, value *uint256.Int, opts ...vm.CallOption) (ret []byte, gasRemaining uint64, _ error) {
167+
return a.env.Call(addr, input, gas, value, opts...)
168168
}
169169

170170
type precompileBlockContext struct {

0 commit comments

Comments
 (0)