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
// 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

View File

@ -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: