add test for overrides

This commit is contained in:
Jared Wasinger 2024-11-27 14:20:17 +07:00 committed by Felix Lange
parent 77158e5bf0
commit 1e8aca95e9
2 changed files with 132 additions and 18 deletions

View File

@ -49,7 +49,7 @@ func deployContract(backend bind.ContractBackend, auth *bind.TransactOpts, const
} }
// deployLibs iterates the set contracts (map of pattern to hex-encoded // 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. // 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) { 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) deploymentTxs = make(map[common.Address]*types.Transaction)
@ -72,9 +72,9 @@ func deployLibs(backend bind.ContractBackend, auth *bind.TransactOpts, contracts
return deploymentTxs, deployAddrs, nil return deploymentTxs, deployAddrs, nil
} }
// linkContract takes an unlinked contract deploy code (contract) a map of // linkContract takes an unlinked contract deployer hex-encoded code, a map of
// linked-and-deployed library dependencies, replaces references to library // already-deployed library dependencies, replaces references to deployed library
// deps in the contract code, and returns the contract deployment bytecode on // dependencies in the contract code, and returns the contract deployment bytecode on
// success. // success.
func linkContract(contract string, linkedLibs map[string]common.Address) (deployableContract string, err error) { func linkContract(contract string, linkedLibs map[string]common.Address) (deployableContract string, err error) {
reMatchSpecificPattern, err := regexp.Compile("__\\$([a-f0-9]+)\\$__") 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 // linkLibs iterates the set of dependencies that have yet to be
// linked/deployed (pending), replacing references to library dependencies // 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 // 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) { func linkLibs(pending *map[string]string, linked map[string]common.Address) (deployableDeps map[string]string) {
reMatchSpecificPattern, err := regexp.Compile("__\\$([a-f0-9]+)\\$__") reMatchSpecificPattern, err := regexp.Compile("__\\$([a-f0-9]+)\\$__")
if err != nil { if err != nil {
@ -160,7 +161,8 @@ type DeploymentResult struct {
} }
// LinkAndDeploy deploys a specified set of contracts and their dependent // 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) { func LinkAndDeploy(auth *bind.TransactOpts, backend bind.ContractBackend, deployParams DeploymentParams) (res *DeploymentResult, err error) {
libMetas := deployParams.Libraries libMetas := deployParams.Libraries
overrides := deployParams.Overrides 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 { for _, contractParams := range deployParams.Contracts {
linkedContract, err := linkContract(contractParams.Meta.Bin, deployed) linkedContract, err := linkContract(contractParams.Meta.Bin, deployed)
if err != nil { if err != nil {
return res, err return res, err
} }
// link and deploy the contracts
contractTx, contractAddr, err := deployContract(backend, auth, contractParams.Input, linkedContract) contractTx, contractAddr, err := deployContract(backend, auth, contractParams.Input, linkedContract)
if err != nil { if err != nil {
return res, err return res, err

View File

@ -19,6 +19,7 @@ package v2
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
@ -49,9 +50,7 @@ func JSON(reader io.Reader) (abi.ABI, error) {
return instance, nil return instance, nil
} }
// test that deploying a contract with library dependencies works, func testSetup() (*bind.TransactOpts, *backends.SimulatedBackend, error) {
// verifying by calling the deployed contract.
func TestDeployment(t *testing.T) {
testAddr := crypto.PubkeyToAddress(testKey.PublicKey) testAddr := crypto.PubkeyToAddress(testKey.PublicKey)
backend := simulated.NewBackend( backend := simulated.NewBackend(
types.GenesisAlloc{ types.GenesisAlloc{
@ -61,11 +60,10 @@ func TestDeployment(t *testing.T) {
ethConf.Genesis.Difficulty = big.NewInt(0) ethConf.Genesis.Difficulty = big.NewInt(0)
}, },
) )
defer backend.Close()
_, err := JSON(strings.NewReader(nested_libraries.C1MetaData.ABI)) _, err := JSON(strings.NewReader(nested_libraries.C1MetaData.ABI))
if err != nil { if err != nil {
panic(err) return nil, nil, err
} }
signer := types.LatestSigner(params.AllDevChainProtocolChanges) 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) { Signer: func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey) signature, err := crypto.Sign(signer.Hash(tx).Bytes(), testKey)
if err != nil { if err != nil {
t.Fatal(err) panic(fmt.Sprintf("error signing tx: %v", err))
return nil, err
} }
signedTx, err := tx.WithSignature(signer, signature) signedTx, err := tx.WithSignature(signer, signature)
if err != nil { if err != nil {
t.Fatal(err) panic(fmt.Sprintf("error creating tx with sig: %v", err))
return nil, err
} }
return signedTx, nil return signedTx, nil
}, },
@ -92,6 +92,18 @@ func TestDeployment(t *testing.T) {
Backend: backend, Backend: backend,
Client: backend.Client(), 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() ctrct, err := nested_libraries.NewC1()
if err != nil { if err != nil {
panic(err) panic(err)
@ -111,7 +123,7 @@ func TestDeployment(t *testing.T) {
Libraries: nested_libraries.C1LibraryDeps, Libraries: nested_libraries.C1LibraryDeps,
Overrides: nil, Overrides: nil,
} }
res, err := LinkAndDeploy(&opts, bindBackend, deploymentParams) res, err := LinkAndDeploy(opts, bindBackend, deploymentParams)
if err != nil { if err != nil {
t.Fatalf("err: %+v\n", err) 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)) t.Fatalf("deployment should have generated 5 addresses. got %d", len(res.Addrs))
} }
for _, tx := range res.Txs { for _, tx := range res.Txs {
_, err = bind.WaitDeployed(context.Background(), &bindBackend, tx) _, err = bind.WaitDeployed(context.Background(), bindBackend, tx)
if err != nil { if err != nil {
t.Fatalf("error deploying library: %+v", err) t.Fatalf("error deploying library: %+v", err)
} }
@ -140,7 +152,104 @@ func TestDeployment(t *testing.T) {
t.Fatalf("error getting abi object: %v", err) t.Fatalf("error getting abi object: %v", err)
} }
contractAddr := res.Addrs[nested_libraries.C1MetaData.Pattern] 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{ callOpts := &bind.CallOpts{
From: common.Address{}, From: common.Address{},
Context: context.Background(), Context: context.Background(),
@ -158,6 +267,9 @@ func TestDeployment(t *testing.T) {
} }
} }
/*
*
*/
/* /*
func TestDeploymentWithOverrides(t *testing.T) { func TestDeploymentWithOverrides(t *testing.T) {
// more deployment test case ideas: // more deployment test case ideas: