From 1e8aca95e93b496f931f0dae534b19eb683b9a72 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Wed, 27 Nov 2024 14:20:17 +0700 Subject: [PATCH] add test for overrides --- accounts/abi/bind/v2/lib.go | 18 +++-- accounts/abi/bind/v2/lib_test.go | 132 ++++++++++++++++++++++++++++--- 2 files changed, 132 insertions(+), 18 deletions(-) diff --git a/accounts/abi/bind/v2/lib.go b/accounts/abi/bind/v2/lib.go index e160bc2e08..0895d446c8 100644 --- a/accounts/abi/bind/v2/lib.go +++ b/accounts/abi/bind/v2/lib.go @@ -49,7 +49,7 @@ func deployContract(backend bind.ContractBackend, auth *bind.TransactOpts, const } // deployLibs iterates the set contracts (map of pattern to hex-encoded -// contract deploy code). each value in contracts is deployed, and the +// contract deployer code). Each contract is deployed, and the // resulting addresses/deployment-txs are returned on success. func deployLibs(backend bind.ContractBackend, auth *bind.TransactOpts, contracts map[string]string) (deploymentTxs map[common.Address]*types.Transaction, deployAddrs map[string]common.Address, err error) { deploymentTxs = make(map[common.Address]*types.Transaction) @@ -72,9 +72,9 @@ func deployLibs(backend bind.ContractBackend, auth *bind.TransactOpts, contracts return deploymentTxs, deployAddrs, nil } -// linkContract takes an unlinked contract deploy code (contract) a map of -// linked-and-deployed library dependencies, replaces references to library -// deps in the contract code, and returns the contract deployment bytecode on +// linkContract takes an unlinked contract deployer hex-encoded code, a map of +// already-deployed library dependencies, replaces references to deployed library +// dependencies in the contract code, and returns the contract deployment bytecode on // success. func linkContract(contract string, linkedLibs map[string]common.Address) (deployableContract string, err error) { reMatchSpecificPattern, err := regexp.Compile("__\\$([a-f0-9]+)\\$__") @@ -92,10 +92,11 @@ func linkContract(contract string, linkedLibs map[string]common.Address) (deploy // linkLibs iterates the set of dependencies that have yet to be // linked/deployed (pending), replacing references to library dependencies -// if those dependencies are fully linked/deployed (in 'linked'). +// (i.e. mutating pending) if those dependencies are fully linked/deployed +// (in 'linked'). // // contracts that have become fully linked in the current invocation are -// returned in the resulting map. +// returned. func linkLibs(pending *map[string]string, linked map[string]common.Address) (deployableDeps map[string]string) { reMatchSpecificPattern, err := regexp.Compile("__\\$([a-f0-9]+)\\$__") if err != nil { @@ -160,7 +161,8 @@ type DeploymentResult struct { } // LinkAndDeploy deploys a specified set of contracts and their dependent -// libraries. +// libraries. If an error occurs, only contracts which were successfully +// deployed are returned in the result. func LinkAndDeploy(auth *bind.TransactOpts, backend bind.ContractBackend, deployParams DeploymentParams) (res *DeploymentResult, err error) { libMetas := deployParams.Libraries overrides := deployParams.Overrides @@ -202,12 +204,12 @@ func LinkAndDeploy(auth *bind.TransactOpts, backend bind.ContractBackend, deploy } } + // link and deploy contracts for _, contractParams := range deployParams.Contracts { linkedContract, err := linkContract(contractParams.Meta.Bin, deployed) if err != nil { return res, err } - // link and deploy the contracts contractTx, contractAddr, err := deployContract(backend, auth, contractParams.Input, linkedContract) if err != nil { return res, err diff --git a/accounts/abi/bind/v2/lib_test.go b/accounts/abi/bind/v2/lib_test.go index 612a38f97a..84fb4b28b7 100644 --- a/accounts/abi/bind/v2/lib_test.go +++ b/accounts/abi/bind/v2/lib_test.go @@ -19,6 +19,7 @@ package v2 import ( "context" "encoding/json" + "fmt" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" @@ -49,9 +50,7 @@ func JSON(reader io.Reader) (abi.ABI, error) { return instance, nil } -// test that deploying a contract with library dependencies works, -// verifying by calling the deployed contract. -func TestDeployment(t *testing.T) { +func testSetup() (*bind.TransactOpts, *backends.SimulatedBackend, error) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) backend := simulated.NewBackend( types.GenesisAlloc{ @@ -61,11 +60,10 @@ func TestDeployment(t *testing.T) { ethConf.Genesis.Difficulty = big.NewInt(0) }, ) - defer backend.Close() _, err := JSON(strings.NewReader(nested_libraries.C1MetaData.ABI)) if err != nil { - panic(err) + return nil, nil, err } signer := types.LatestSigner(params.AllDevChainProtocolChanges) @@ -75,11 +73,13 @@ func TestDeployment(t *testing.T) { Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) { signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey) if err != nil { - t.Fatal(err) + panic(fmt.Sprintf("error signing tx: %v", err)) + return nil, err } signedTx, err := tx.WithSignature(signer, signature) if err != nil { - t.Fatal(err) + panic(fmt.Sprintf("error creating tx with sig: %v", err)) + return nil, err } return signedTx, nil }, @@ -92,6 +92,18 @@ func TestDeployment(t *testing.T) { Backend: backend, Client: backend.Client(), } + return &opts, &bindBackend, nil +} + +// test that deploying a contract with library dependencies works, +// verifying by calling the deployed contract. +func TestDeployment(t *testing.T) { + opts, bindBackend, err := testSetup() + if err != nil { + t.Fatalf("err setting up test: %v", err) + } + defer bindBackend.Backend.Close() + ctrct, err := nested_libraries.NewC1() if err != nil { panic(err) @@ -111,7 +123,7 @@ func TestDeployment(t *testing.T) { Libraries: nested_libraries.C1LibraryDeps, Overrides: nil, } - res, err := LinkAndDeploy(&opts, bindBackend, deploymentParams) + res, err := LinkAndDeploy(opts, bindBackend, deploymentParams) if err != nil { t.Fatalf("err: %+v\n", err) } @@ -121,7 +133,7 @@ func TestDeployment(t *testing.T) { t.Fatalf("deployment should have generated 5 addresses. got %d", len(res.Addrs)) } for _, tx := range res.Txs { - _, err = bind.WaitDeployed(context.Background(), &bindBackend, tx) + _, err = bind.WaitDeployed(context.Background(), bindBackend, tx) if err != nil { t.Fatalf("error deploying library: %+v", err) } @@ -140,7 +152,104 @@ func TestDeployment(t *testing.T) { t.Fatalf("error getting abi object: %v", err) } contractAddr := res.Addrs[nested_libraries.C1MetaData.Pattern] - boundC := bind.NewBoundContract(contractAddr, *cABI, &bindBackend, &bindBackend, &bindBackend) + boundC := bind.NewBoundContract(contractAddr, *cABI, bindBackend, bindBackend, bindBackend) + callOpts := &bind.CallOpts{ + From: common.Address{}, + Context: context.Background(), + } + callRes, err := boundC.CallRaw(callOpts, doInput) + if err != nil { + t.Fatalf("err calling contract: %v", err) + } + internalCallCount, err := c.UnpackDo(callRes) + 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()) + } +} + +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 + deploymentParams := DeploymentParams{ + Libraries: nested_libraries.C1LibraryDeps, + } + + res, err := LinkAndDeploy(opts, bindBackend, deploymentParams) + 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) + if err != nil { + t.Fatalf("error deploying library: %+v", err) + } + } + + 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 + deploymentParams = DeploymentParams{ + Contracts: []ContractDeployParams{ + { + Meta: nested_libraries.C1MetaData, + Input: constructorInput, + }, + }, + Libraries: nil, + Overrides: overrides, + } + res, err = LinkAndDeploy(opts, bindBackend, deploymentParams) + 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 + 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] + boundC := bind.NewBoundContract(contractAddr, *cABI, bindBackend, bindBackend, bindBackend) callOpts := &bind.CallOpts{ From: common.Address{}, Context: context.Background(), @@ -158,6 +267,9 @@ func TestDeployment(t *testing.T) { } } +/* + * + */ /* func TestDeploymentWithOverrides(t *testing.T) { // more deployment test case ideas: