2024-11-26 06:14:19 -06:00
|
|
|
// Copyright 2024 The go-ethereum Authors
|
|
|
|
// This file is part of the go-ethereum library.
|
|
|
|
//
|
|
|
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
2024-11-04 07:50:47 -06:00
|
|
|
package v2
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
2024-12-13 06:44:01 -06:00
|
|
|
"io"
|
|
|
|
"math/big"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2024-11-26 04:18:20 -06:00
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
2024-11-04 07:50:47 -06:00
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
2024-12-03 03:04:05 -06:00
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/v2/internal/events"
|
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/v2/internal/nested_libraries"
|
2024-12-12 02:20:16 -06:00
|
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/v2/internal/solc_errors"
|
2024-12-02 07:27:05 -06:00
|
|
|
"github.com/ethereum/go-ethereum/cmd/utils"
|
2024-11-04 07:50:47 -06:00
|
|
|
"github.com/ethereum/go-ethereum/common"
|
2024-12-02 07:27:05 -06:00
|
|
|
"github.com/ethereum/go-ethereum/common/compiler"
|
2024-11-04 07:50:47 -06:00
|
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
2024-11-26 04:18:20 -06:00
|
|
|
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
2024-12-12 09:06:39 -06:00
|
|
|
"github.com/ethereum/go-ethereum/ethclient"
|
2024-11-04 07:50:47 -06:00
|
|
|
"github.com/ethereum/go-ethereum/ethclient/simulated"
|
2024-11-26 04:18:20 -06:00
|
|
|
"github.com/ethereum/go-ethereum/node"
|
2024-11-04 07:50:47 -06:00
|
|
|
"github.com/ethereum/go-ethereum/params"
|
|
|
|
)
|
|
|
|
|
|
|
|
var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
|
|
|
|
|
|
|
|
// JSON returns a parsed ABI interface and error if it failed.
|
|
|
|
func JSON(reader io.Reader) (abi.ABI, error) {
|
|
|
|
dec := json.NewDecoder(reader)
|
|
|
|
|
|
|
|
var instance abi.ABI
|
|
|
|
if err := dec.Decode(&instance); err != nil {
|
|
|
|
return abi.ABI{}, err
|
|
|
|
}
|
|
|
|
return instance, nil
|
|
|
|
}
|
|
|
|
|
2024-11-27 01:20:17 -06:00
|
|
|
func testSetup() (*bind.TransactOpts, *backends.SimulatedBackend, error) {
|
2024-11-24 06:35:16 -06:00
|
|
|
testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
|
|
|
|
backend := simulated.NewBackend(
|
|
|
|
types.GenesisAlloc{
|
|
|
|
testAddr: {Balance: big.NewInt(10000000000000000)},
|
|
|
|
},
|
|
|
|
func(nodeConf *node.Config, ethConf *ethconfig.Config) {
|
|
|
|
ethConf.Genesis.Difficulty = big.NewInt(0)
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
signer := types.LatestSigner(params.AllDevChainProtocolChanges)
|
2024-11-27 08:17:13 -06:00
|
|
|
opts := &bind.TransactOpts{
|
2024-11-24 06:35:16 -06:00
|
|
|
From: testAddr,
|
|
|
|
Nonce: nil,
|
|
|
|
Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
|
|
|
|
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
|
|
|
|
if err != nil {
|
2024-11-27 01:20:17 -06:00
|
|
|
return nil, err
|
2024-11-24 06:35:16 -06:00
|
|
|
}
|
|
|
|
signedTx, err := tx.WithSignature(signer, signature)
|
|
|
|
if err != nil {
|
2024-11-27 01:20:17 -06:00
|
|
|
return nil, err
|
2024-11-24 06:35:16 -06:00
|
|
|
}
|
|
|
|
return signedTx, nil
|
|
|
|
},
|
|
|
|
Context: context.Background(),
|
|
|
|
}
|
|
|
|
// we should just be able to use the backend directly, instead of using
|
|
|
|
// this deprecated interface. However, the simulated backend no longer
|
|
|
|
// implements backends.SimulatedBackend...
|
|
|
|
bindBackend := backends.SimulatedBackend{
|
|
|
|
Backend: backend,
|
|
|
|
Client: backend.Client(),
|
|
|
|
}
|
2024-11-27 08:17:13 -06:00
|
|
|
return opts, &bindBackend, nil
|
|
|
|
}
|
|
|
|
|
2024-12-05 04:32:24 -06:00
|
|
|
func makeTestDeployer(auth *bind.TransactOpts, backend bind.ContractBackend) func(input, deployer []byte) (common.Address, *types.Transaction, error) {
|
|
|
|
return func(input, deployer []byte) (common.Address, *types.Transaction, error) {
|
|
|
|
addr, tx, _, err := bind.DeployContractRaw(auth, deployer, backend, input)
|
|
|
|
return addr, tx, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-11-27 01:20:17 -06:00
|
|
|
// test that deploying a contract with library dependencies works,
|
2024-12-02 01:43:32 -06:00
|
|
|
// verifying by calling method on the deployed contract.
|
2024-11-27 08:17:13 -06:00
|
|
|
func TestDeploymentLibraries(t *testing.T) {
|
2024-11-27 01:20:17 -06:00
|
|
|
opts, bindBackend, err := testSetup()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err setting up test: %v", err)
|
|
|
|
}
|
|
|
|
defer bindBackend.Backend.Close()
|
|
|
|
|
2024-11-26 02:54:18 -06:00
|
|
|
ctrct, err := nested_libraries.NewC1()
|
2024-11-25 01:30:29 -06:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2024-11-26 02:54:18 -06:00
|
|
|
|
|
|
|
constructorInput, err := ctrct.PackConstructor(big.NewInt(42), big.NewInt(1))
|
2024-11-25 01:30:29 -06:00
|
|
|
if err != nil {
|
2024-11-26 06:31:58 -06:00
|
|
|
t.Fatalf("failed to pack constructor: %v", err)
|
2024-11-25 01:30:29 -06:00
|
|
|
}
|
2024-12-15 04:35:25 -06:00
|
|
|
deploymentParams := bind.DeploymentParams{
|
2024-12-09 23:23:23 -06:00
|
|
|
Contracts: append(nested_libraries.C1LibraryDeps, nested_libraries.C1MetaData),
|
|
|
|
Inputs: map[string][]byte{nested_libraries.C1MetaData.Pattern: constructorInput},
|
2024-11-26 02:54:18 -06:00
|
|
|
Overrides: nil,
|
|
|
|
}
|
2024-12-05 04:32:24 -06:00
|
|
|
|
2024-12-15 04:35:25 -06:00
|
|
|
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(opts, bindBackend))
|
2024-11-24 06:35:16 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %+v\n", err)
|
|
|
|
}
|
2024-11-24 09:32:11 -06:00
|
|
|
bindBackend.Commit()
|
2024-11-26 02:54:18 -06:00
|
|
|
|
2024-11-26 04:18:20 -06:00
|
|
|
if len(res.Addrs) != 5 {
|
|
|
|
t.Fatalf("deployment should have generated 5 addresses. got %d", len(res.Addrs))
|
|
|
|
}
|
2024-11-26 02:54:18 -06:00
|
|
|
for _, tx := range res.Txs {
|
2024-11-27 01:20:17 -06:00
|
|
|
_, err = bind.WaitDeployed(context.Background(), bindBackend, tx)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error deploying library: %+v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c, err := nested_libraries.NewC1()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err is %v", err)
|
|
|
|
}
|
|
|
|
doInput, err := c.PackDo(big.NewInt(1))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("pack function input err: %v\n", doInput)
|
|
|
|
}
|
|
|
|
|
|
|
|
contractAddr := res.Addrs[nested_libraries.C1MetaData.Pattern]
|
|
|
|
callOpts := &bind.CallOpts{
|
|
|
|
From: common.Address{},
|
|
|
|
Context: context.Background(),
|
|
|
|
}
|
2024-12-03 00:49:24 -06:00
|
|
|
|
|
|
|
ctrctInstance := &ContractInstance{
|
|
|
|
Address: contractAddr,
|
|
|
|
Backend: bindBackend,
|
2024-11-27 01:20:17 -06:00
|
|
|
}
|
2024-12-03 00:49:24 -06:00
|
|
|
internalCallCount, err := Call[big.Int](ctrctInstance, callOpts, doInput, ctrct.UnpackDo)
|
2024-11-27 01:20:17 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err unpacking result: %v", err)
|
|
|
|
}
|
|
|
|
if internalCallCount.Uint64() != 6 {
|
|
|
|
t.Fatalf("expected internal call count of 6. got %d.", internalCallCount.Uint64())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-12-02 01:43:32 -06:00
|
|
|
// Same as TestDeployment. However, stagger the deployments with overrides:
|
|
|
|
// first deploy the library deps and then the contract.
|
2024-11-27 01:20:17 -06:00
|
|
|
func TestDeploymentWithOverrides(t *testing.T) {
|
|
|
|
opts, bindBackend, err := testSetup()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err setting up test: %v", err)
|
|
|
|
}
|
|
|
|
defer bindBackend.Backend.Close()
|
|
|
|
|
|
|
|
// deploy some library deps
|
2024-12-15 04:35:25 -06:00
|
|
|
deploymentParams := bind.DeploymentParams{
|
2024-12-09 23:23:23 -06:00
|
|
|
Contracts: nested_libraries.C1LibraryDeps,
|
2024-11-27 01:20:17 -06:00
|
|
|
}
|
|
|
|
|
2024-12-15 04:35:25 -06:00
|
|
|
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(opts, bindBackend))
|
2024-11-27 01:20:17 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %+v\n", err)
|
|
|
|
}
|
|
|
|
bindBackend.Commit()
|
|
|
|
|
|
|
|
if len(res.Addrs) != 4 {
|
|
|
|
t.Fatalf("deployment should have generated 4 addresses. got %d", len(res.Addrs))
|
|
|
|
}
|
|
|
|
for _, tx := range res.Txs {
|
|
|
|
_, err = bind.WaitDeployed(context.Background(), bindBackend, tx)
|
2024-11-24 06:35:16 -06:00
|
|
|
if err != nil {
|
2024-11-26 02:54:18 -06:00
|
|
|
t.Fatalf("error deploying library: %+v", err)
|
2024-11-24 06:35:16 -06:00
|
|
|
}
|
|
|
|
}
|
2024-11-27 01:20:17 -06:00
|
|
|
|
|
|
|
ctrct, err := nested_libraries.NewC1()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
constructorInput, err := ctrct.PackConstructor(big.NewInt(42), big.NewInt(1))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("failed to pack constructor: %v", err)
|
|
|
|
}
|
|
|
|
overrides := res.Addrs
|
|
|
|
// deploy the contract
|
2024-12-15 04:35:25 -06:00
|
|
|
deploymentParams = bind.DeploymentParams{
|
2024-12-09 23:23:23 -06:00
|
|
|
Contracts: []*bind.MetaData{nested_libraries.C1MetaData},
|
|
|
|
Inputs: map[string][]byte{nested_libraries.C1MetaData.Pattern: constructorInput},
|
2024-11-27 01:20:17 -06:00
|
|
|
Overrides: overrides,
|
|
|
|
}
|
2024-12-15 04:35:25 -06:00
|
|
|
res, err = bind.LinkAndDeploy(deploymentParams, makeTestDeployer(opts, bindBackend))
|
2024-11-27 01:20:17 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %+v\n", err)
|
|
|
|
}
|
|
|
|
bindBackend.Commit()
|
|
|
|
|
|
|
|
if len(res.Addrs) != 1 {
|
|
|
|
t.Fatalf("deployment should have generated 1 address. got %d", len(res.Addrs))
|
|
|
|
}
|
|
|
|
for _, tx := range res.Txs {
|
|
|
|
_, err = bind.WaitDeployed(context.Background(), bindBackend, tx)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error deploying library: %+v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// call the deployed contract and make sure it returns the correct result
|
2024-11-26 02:54:18 -06:00
|
|
|
c, err := nested_libraries.NewC1()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err is %v", err)
|
|
|
|
}
|
|
|
|
doInput, err := c.PackDo(big.NewInt(1))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("pack function input err: %v\n", doInput)
|
|
|
|
}
|
|
|
|
|
|
|
|
cABI, err := nested_libraries.C1MetaData.GetAbi()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error getting abi object: %v", err)
|
|
|
|
}
|
|
|
|
contractAddr := res.Addrs[nested_libraries.C1MetaData.Pattern]
|
2024-12-02 01:43:32 -06:00
|
|
|
boundContract := bind.NewBoundContract(contractAddr, *cABI, bindBackend, bindBackend, bindBackend)
|
2024-11-26 02:54:18 -06:00
|
|
|
callOpts := &bind.CallOpts{
|
|
|
|
From: common.Address{},
|
|
|
|
Context: context.Background(),
|
|
|
|
}
|
2024-12-02 01:43:32 -06:00
|
|
|
callRes, err := boundContract.CallRaw(callOpts, doInput)
|
2024-11-26 02:54:18 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err calling contract: %v", err)
|
|
|
|
}
|
2024-11-26 04:18:20 -06:00
|
|
|
internalCallCount, err := c.UnpackDo(callRes)
|
2024-11-26 02:54:18 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err unpacking result: %v", err)
|
|
|
|
}
|
2024-11-26 04:18:20 -06:00
|
|
|
if internalCallCount.Uint64() != 6 {
|
|
|
|
t.Fatalf("expected internal call count of 6. got %d.", internalCallCount.Uint64())
|
|
|
|
}
|
2024-11-26 02:54:18 -06:00
|
|
|
}
|
2024-12-12 02:20:16 -06:00
|
|
|
|
2024-11-26 02:54:18 -06:00
|
|
|
func TestEvents(t *testing.T) {
|
|
|
|
// test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.)
|
2024-11-27 08:17:13 -06:00
|
|
|
txAuth, backend, err := testSetup()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error setting up testing env: %v", err)
|
|
|
|
}
|
|
|
|
|
2024-12-15 04:35:25 -06:00
|
|
|
deploymentParams := bind.DeploymentParams{
|
2024-12-09 23:23:23 -06:00
|
|
|
Contracts: []*bind.MetaData{events.CMetaData},
|
2024-11-27 08:17:13 -06:00
|
|
|
}
|
|
|
|
|
2024-12-15 04:35:25 -06:00
|
|
|
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(txAuth, backend))
|
2024-11-27 08:17:13 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error deploying contract for testing: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
backend.Commit()
|
|
|
|
if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[events.CMetaData.Pattern]); err != nil {
|
|
|
|
t.Fatalf("WaitDeployed failed %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
ctrct, err := events.NewC()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error instantiating contract instance: %v", err)
|
|
|
|
}
|
|
|
|
|
2024-12-16 01:08:46 -06:00
|
|
|
ctrctABI, _ := events.CMetaData.GetAbi()
|
|
|
|
ctrctInstance := ContractInstance{
|
2024-12-03 00:25:46 -06:00
|
|
|
res.Addrs[events.CMetaData.Pattern],
|
|
|
|
backend,
|
2024-12-16 01:08:46 -06:00
|
|
|
*ctrctABI,
|
2024-12-03 00:25:46 -06:00
|
|
|
}
|
2024-11-27 08:17:13 -06:00
|
|
|
|
2024-12-03 00:25:46 -06:00
|
|
|
newCBasic1Ch := make(chan *events.CBasic1)
|
|
|
|
newCBasic2Ch := make(chan *events.CBasic2)
|
2024-11-27 08:17:13 -06:00
|
|
|
watchOpts := &bind.WatchOpts{
|
|
|
|
Start: nil,
|
|
|
|
Context: context.Background(),
|
|
|
|
}
|
2024-12-16 01:08:46 -06:00
|
|
|
sub1, err := WatchEvents(&ctrctInstance, watchOpts, events.CBasic1EventName, ctrct.UnpackBasic1Event, newCBasic1Ch)
|
2024-12-13 06:44:01 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("WatchEvents returned error: %v", err)
|
|
|
|
}
|
2024-12-16 01:08:46 -06:00
|
|
|
sub2, err := WatchEvents(&ctrctInstance, watchOpts, events.CBasic2EventName, ctrct.UnpackBasic2Event, newCBasic2Ch)
|
2024-12-13 06:44:01 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("WatchEvents returned error: %v", err)
|
|
|
|
}
|
2024-11-27 08:17:13 -06:00
|
|
|
defer sub1.Unsubscribe()
|
2024-12-02 01:43:32 -06:00
|
|
|
defer sub2.Unsubscribe()
|
|
|
|
|
2024-12-03 00:25:46 -06:00
|
|
|
packedInput, _ := ctrct.PackEmitMulti()
|
2024-12-16 01:08:46 -06:00
|
|
|
tx, err := Transact(&ctrctInstance, txAuth, packedInput)
|
2024-11-27 08:17:13 -06:00
|
|
|
if err != nil {
|
2024-12-03 00:25:46 -06:00
|
|
|
t.Fatalf("failed to send transaction: %v", err)
|
2024-11-27 08:17:13 -06:00
|
|
|
}
|
|
|
|
backend.Commit()
|
|
|
|
if _, err := bind.WaitMined(context.Background(), backend, tx); err != nil {
|
|
|
|
t.Fatalf("error waiting for tx to be mined: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
timeout := time.NewTimer(2 * time.Second)
|
|
|
|
e1Count := 0
|
|
|
|
e2Count := 0
|
|
|
|
for {
|
|
|
|
select {
|
2024-12-13 06:44:01 -06:00
|
|
|
case <-newCBasic1Ch:
|
2024-11-27 08:17:13 -06:00
|
|
|
e1Count++
|
2024-12-13 06:44:01 -06:00
|
|
|
case <-newCBasic2Ch:
|
2024-11-27 08:17:13 -06:00
|
|
|
e2Count++
|
2024-12-13 06:44:01 -06:00
|
|
|
case <-timeout.C:
|
2024-12-03 00:25:46 -06:00
|
|
|
goto done
|
|
|
|
}
|
|
|
|
if e1Count == 2 && e2Count == 1 {
|
|
|
|
break
|
2024-11-27 08:17:13 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
done:
|
|
|
|
if e1Count != 2 {
|
|
|
|
t.Fatalf("expected event type 1 count to be 2. got %d", e1Count)
|
|
|
|
}
|
|
|
|
if e2Count != 1 {
|
|
|
|
t.Fatalf("expected event type 2 count to be 1. got %d", e2Count)
|
|
|
|
}
|
|
|
|
|
2024-12-01 23:57:09 -06:00
|
|
|
// now, test that we can filter those same logs after they were included in the chain
|
2024-11-27 10:10:15 -06:00
|
|
|
|
|
|
|
filterOpts := &bind.FilterOpts{
|
|
|
|
Start: 0,
|
|
|
|
Context: context.Background(),
|
|
|
|
}
|
2024-12-16 01:08:46 -06:00
|
|
|
it, err := FilterEvents[events.CBasic1](&ctrctInstance, filterOpts, events.CBasic1EventName, ctrct.UnpackBasic1Event)
|
2024-11-27 10:10:15 -06:00
|
|
|
if err != nil {
|
2024-12-03 00:25:46 -06:00
|
|
|
t.Fatalf("error filtering logs %v\n", err)
|
2024-11-27 10:10:15 -06:00
|
|
|
}
|
2024-12-16 01:08:46 -06:00
|
|
|
it2, err := FilterEvents[events.CBasic2](&ctrctInstance, filterOpts, events.CBasic2EventName, ctrct.UnpackBasic2Event)
|
2024-11-27 10:10:15 -06:00
|
|
|
if err != nil {
|
2024-12-03 00:25:46 -06:00
|
|
|
t.Fatalf("error filtering logs %v\n", err)
|
2024-11-27 10:10:15 -06:00
|
|
|
}
|
|
|
|
e1Count = 0
|
|
|
|
e2Count = 0
|
2024-12-03 00:25:46 -06:00
|
|
|
for it.Next() {
|
|
|
|
e1Count++
|
|
|
|
}
|
|
|
|
for it2.Next() {
|
|
|
|
e2Count++
|
2024-11-27 08:17:13 -06:00
|
|
|
}
|
2024-12-02 01:43:32 -06:00
|
|
|
if e1Count != 2 {
|
2024-12-03 00:25:46 -06:00
|
|
|
t.Fatalf("expected e1Count of 2 from filter call. got %d", e1Count)
|
2024-11-27 08:17:13 -06:00
|
|
|
}
|
|
|
|
if e2Count != 1 {
|
2024-12-03 00:25:46 -06:00
|
|
|
t.Fatalf("expected e2Count of 1 from filter call. got %d", e1Count)
|
2024-11-27 08:17:13 -06:00
|
|
|
}
|
2024-11-20 05:57:03 -06:00
|
|
|
}
|
2024-12-02 07:27:05 -06:00
|
|
|
|
2024-12-12 02:20:16 -06:00
|
|
|
func TestErrors(t *testing.T) {
|
|
|
|
// test watch/filter logs method on a contract that emits various kinds of events (struct-containing, etc.)
|
|
|
|
txAuth, backend, err := testSetup()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error setting up testing env: %v", err)
|
|
|
|
}
|
|
|
|
|
2024-12-15 04:35:25 -06:00
|
|
|
deploymentParams := bind.DeploymentParams{
|
2024-12-12 02:20:16 -06:00
|
|
|
Contracts: []*bind.MetaData{solc_errors.CMetaData},
|
|
|
|
}
|
|
|
|
|
2024-12-15 04:35:25 -06:00
|
|
|
res, err := bind.LinkAndDeploy(deploymentParams, makeTestDeployer(txAuth, backend))
|
2024-12-12 02:20:16 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error deploying contract for testing: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
backend.Commit()
|
|
|
|
if _, err := bind.WaitDeployed(context.Background(), backend, res.Txs[solc_errors.CMetaData.Pattern]); err != nil {
|
|
|
|
t.Fatalf("WaitDeployed failed %v", err)
|
|
|
|
}
|
|
|
|
|
2024-12-12 09:06:39 -06:00
|
|
|
ctrct, _ := solc_errors.NewC()
|
|
|
|
|
2024-12-12 02:20:16 -06:00
|
|
|
var packedInput []byte
|
|
|
|
opts := &bind.CallOpts{
|
|
|
|
From: res.Addrs[solc_errors.CMetaData.Pattern],
|
|
|
|
}
|
2024-12-12 09:06:39 -06:00
|
|
|
packedInput, _ = ctrct.PackFoo()
|
|
|
|
|
2024-12-16 01:08:46 -06:00
|
|
|
ctrctABI, _ := solc_errors.CMetaData.GetAbi()
|
|
|
|
instance := ContractInstance{res.Addrs[solc_errors.CMetaData.Pattern], backend, *ctrctABI}
|
2024-12-12 09:06:39 -06:00
|
|
|
_, err = Call[struct{}](&instance, opts, packedInput, func(packed []byte) (*struct{}, error) { return nil, nil })
|
2024-12-12 02:20:16 -06:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected call to fail")
|
|
|
|
}
|
2024-12-12 09:06:39 -06:00
|
|
|
raw, hasRevertErrorData := ethclient.RevertErrorData(err)
|
|
|
|
if !hasRevertErrorData {
|
|
|
|
t.Fatalf("expected call error to contain revert error data.")
|
|
|
|
}
|
|
|
|
unpackedErr := ctrct.UnpackError(raw)
|
|
|
|
if unpackedErr == nil {
|
|
|
|
t.Fatalf("expected to unpack error")
|
|
|
|
}
|
|
|
|
// TODO: check anything about the error?
|
2024-12-12 02:20:16 -06:00
|
|
|
}
|
|
|
|
|
2024-12-12 09:06:39 -06:00
|
|
|
// TODO: this test will pass if the code is changed but not compiled to a combined-abi.json.
|
|
|
|
// Not really possible to test this without including solc in the path when running CI.
|
2024-12-02 07:27:05 -06:00
|
|
|
func TestBindingGeneration(t *testing.T) {
|
2024-12-03 03:04:05 -06:00
|
|
|
matches, _ := filepath.Glob("internal/*")
|
2024-12-02 07:27:05 -06:00
|
|
|
var dirs []string
|
|
|
|
for _, match := range matches {
|
|
|
|
f, _ := os.Stat(match)
|
|
|
|
if f.IsDir() {
|
|
|
|
dirs = append(dirs, f.Name())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, dir := range dirs {
|
|
|
|
var (
|
|
|
|
abis []string
|
|
|
|
bins []string
|
|
|
|
types []string
|
|
|
|
sigs []map[string]string
|
|
|
|
libs = make(map[string]string)
|
|
|
|
)
|
2024-12-03 03:04:05 -06:00
|
|
|
basePath := filepath.Join("internal", dir)
|
2024-12-02 07:27:05 -06:00
|
|
|
combinedJsonPath := filepath.Join(basePath, "combined-abi.json")
|
|
|
|
abiBytes, err := os.ReadFile(combinedJsonPath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error trying to read file %s: %v", combinedJsonPath, err)
|
|
|
|
}
|
|
|
|
contracts, err := compiler.ParseCombinedJSON(abiBytes, "", "", "", "")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Failed to read contract information from json output: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, contract := range contracts {
|
|
|
|
// fully qualified name is of the form <solFilePath>:<type>
|
|
|
|
nameParts := strings.Split(name, ":")
|
|
|
|
typeName := nameParts[len(nameParts)-1]
|
|
|
|
abi, err := json.Marshal(contract.Info.AbiDefinition) // Flatten the compiler parse
|
|
|
|
if err != nil {
|
|
|
|
utils.Fatalf("Failed to parse ABIs from compiler output: %v", err)
|
|
|
|
}
|
|
|
|
abis = append(abis, string(abi))
|
|
|
|
bins = append(bins, contract.Code)
|
|
|
|
sigs = append(sigs, contract.Hashes)
|
|
|
|
types = append(types, typeName)
|
|
|
|
|
|
|
|
// Derive the library placeholder which is a 34 character prefix of the
|
|
|
|
// hex encoding of the keccak256 hash of the fully qualified library name.
|
|
|
|
// Note that the fully qualified library name is the path of its source
|
|
|
|
// file and the library name separated by ":".
|
|
|
|
libPattern := crypto.Keccak256Hash([]byte(name)).String()[2:36] // the first 2 chars are 0x
|
|
|
|
libs[libPattern] = typeName
|
|
|
|
}
|
|
|
|
code, err := bind.BindV2(types, abis, bins, sigs, dir, libs, make(map[string]string))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error creating bindings for package %s: %v", dir, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
existingBindings, err := os.ReadFile(filepath.Join(basePath, "bindings.go"))
|
2024-12-13 06:44:01 -06:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("ReadFile returned error: %v", err)
|
|
|
|
}
|
2024-12-02 07:27:05 -06:00
|
|
|
if code != string(existingBindings) {
|
|
|
|
t.Fatalf("code mismatch for %s", dir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|