Skip to content

Commit

Permalink
add test to verify the setting, monitoring and serving of contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
BedrockSquirrel committed Nov 16, 2023
1 parent 1263801 commit dc63568
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 2 deletions.
2 changes: 1 addition & 1 deletion go/ethadapter/mgmtcontractlib/mgmt_contract_ABI.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const (
InitializeSecretMethod = "InitializeNetworkSecret" //#nosec
GetHostAddressesMethod = "GetHostAddresses"
GetImportantContractKeysMethod = "GetImportantContractKeys"
SetImportantContractsMethod = "SetImportantContractAddresses"
SetImportantContractsMethod = "SetImportantContractAddress"
GetImportantAddressMethod = "importantContractAddresses"
)

Expand Down
10 changes: 10 additions & 0 deletions go/ethadapter/mgmtcontractlib/mgmt_contract_lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type MgmtContractLib interface {
GetHostAddressesMsg() (ethereum.CallMsg, error)
DecodeHostAddressesResponse(callResponse []byte) ([]string, error)

SetImportantContractMsg(key string, address gethcommon.Address) (ethereum.CallMsg, error)

GetImportantContractKeysMsg() (ethereum.CallMsg, error)
DecodeImportantContractKeysResponse(callResponse []byte) ([]string, error)

Expand Down Expand Up @@ -248,6 +250,14 @@ func (c *contractLibImpl) DecodeContractNamesResponse(callResponse []byte) ([]st
return contractNames, nil
}

func (c *contractLibImpl) SetImportantContractMsg(key string, address gethcommon.Address) (ethereum.CallMsg, error) {
data, err := c.contractABI.Pack(SetImportantContractsMethod, key, address)
if err != nil {
return ethereum.CallMsg{}, fmt.Errorf("could not pack the call data. Cause: %w", err)
}
return ethereum.CallMsg{To: c.addr, Data: data}, nil
}

func (c *contractLibImpl) GetImportantContractKeysMsg() (ethereum.CallMsg, error) {
data, err := c.contractABI.Pack(GetImportantContractKeysMethod)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions integration/ethereummock/mgmt_contract_lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ func (m *mockContractLib) DecodeImportantContractKeysResponse([]byte) ([]string,
return []string{""}, nil
}

func (m *mockContractLib) SetImportantContractMsg(string, gethcommon.Address) (ethereum.CallMsg, error) {
return ethereum.CallMsg{}, nil
}

func (m *mockContractLib) GetImportantAddressCallMsg(string) (ethereum.CallMsg, error) {
return ethereum.CallMsg{}, nil
}
Expand Down
110 changes: 110 additions & 0 deletions integration/networktest/actions/l1/important_contracts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package l1

import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/obscuronet/go-obscuro/go/common/retry"
"github.com/obscuronet/go-obscuro/go/ethadapter/mgmtcontractlib"
"github.com/obscuronet/go-obscuro/go/obsclient"
"github.com/obscuronet/go-obscuro/integration/common/testlog"
"github.com/obscuronet/go-obscuro/integration/networktest"
"github.com/pkg/errors"
"time"
)

type setImportantContract struct {
contractKey string
contractAddress common.Address
}

func SetImportantContract(contractKey string, contractAddress common.Address) networktest.Action {
return &setImportantContract{
contractKey: contractKey,
contractAddress: contractAddress,
}
}

func (s *setImportantContract) Run(ctx context.Context, network networktest.NetworkConnector) (context.Context, error) {
obsClient, err := obsclient.Dial(network.ValidatorRPCAddress(0))
if err != nil {
return ctx, errors.Wrap(err, "failed to dial obsClient")
}

networkCfg, err := obsClient.GetConfig()
if err != nil {
return ctx, errors.Wrap(err, "failed to get network config")
}

l1Client, err := network.GetL1Client()
if err != nil {
return ctx, errors.Wrap(err, "failed to get L1 client")
}

mgmtContract := mgmtcontractlib.NewMgmtContractLib(&networkCfg.ManagementContractAddress, testlog.Logger())

msg, err := mgmtContract.SetImportantContractMsg(s.contractKey, s.contractAddress)
if err != nil {
return ctx, errors.Wrap(err, "failed to create SetImportantContractMsg")
}

txData := &types.LegacyTx{
To: &networkCfg.ManagementContractAddress,
Data: msg.Data,
}
mcOwner, err := network.GetMCOwnerWallet()
if err != nil {
return ctx, errors.Wrap(err, "failed to get MC owner wallet")
}
// !! Important note !!
// The ownerOnly check in the contract doesn't like the gas estimate in here, to test you may need to hardcode a
// the gas value when the estimate errors
tx, err := l1Client.PrepareTransactionToSend(txData, networkCfg.ManagementContractAddress, mcOwner.GetNonceAndIncrement())
if err != nil {
return ctx, errors.Wrap(err, "failed to prepare tx")
}
signedTx, err := mcOwner.SignTransaction(tx)
if err != nil {
return ctx, errors.Wrap(err, "failed to sign tx")
}
err = l1Client.SendTransaction(signedTx)
if err != nil {
return nil, errors.Wrap(err, "failed to send tx")
}

// wait for tx to be mined
return ctx, retry.Do(func() error {
receipt, err := l1Client.TransactionReceipt(signedTx.Hash())
if err != nil {
return err
}
if receipt.Status != types.ReceiptStatusSuccessful {
return retry.FailFast(errors.New("tx failed"))
}
return nil
}, retry.NewTimeoutStrategy(15*time.Second, 1*time.Second))
}

func (s *setImportantContract) Verify(ctx context.Context, network networktest.NetworkConnector) error {
cli, err := obsclient.Dial(network.ValidatorRPCAddress(0))
if err != nil {
return errors.Wrap(err, "failed to dial obsClient")
}
networkCfg, err := cli.GetConfig()
fmt.Println("networkCfg: ", networkCfg)
if err != nil {
return errors.Wrap(err, "failed to get network config")
}

if networkCfg.ImportantContracts == nil || len(networkCfg.ImportantContracts) == 0 {
return errors.New("no important contracts set")
}
if len(networkCfg.ImportantContracts) > 1 {
return errors.New("more than one important contract set")
}
if addr, ok := networkCfg.ImportantContracts[s.contractKey]; !ok || addr != s.contractAddress {
return errors.New("important contract not set")
}
return nil
}
6 changes: 6 additions & 0 deletions integration/networktest/env/testnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"github.com/obscuronet/go-obscuro/go/wallet"
"math/big"
"net/http"
"time"
Expand Down Expand Up @@ -124,3 +126,7 @@ func (t *testnetConnector) AllocateFaucetFundsWithWallet(ctx context.Context, ac
}
return nil
}

func (t *testnetConnector) GetMCOwnerWallet() (wallet.Wallet, error) {
return nil, errors.New("testnet connector environments cannot access the MC owner wallet")
}
6 changes: 5 additions & 1 deletion integration/networktest/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package networktest

import (
"context"
"github.com/obscuronet/go-obscuro/go/wallet"

"github.com/obscuronet/go-obscuro/go/ethadapter"

Expand All @@ -10,7 +11,9 @@ import (

// NetworkConnector represents the network being tested against, e.g. testnet, dev-testnet, dev-sim
//
// It provides network details (standard contract addresses) and easy client setup for sim users
// # It provides network details (standard contract addresses) and easy client setup for sim users
//
// Note: some of these methods may not be available for some networks (e.g. MC Owner wallet for live testnets)
type NetworkConnector interface {
ChainID() int64
// AllocateFaucetFunds uses the networks default faucet mechanism for allocating funds to a test account
Expand All @@ -21,6 +24,7 @@ type NetworkConnector interface {
GetSequencerNode() NodeOperator
GetValidatorNode(idx int) NodeOperator
GetL1Client() (ethadapter.EthClient, error)
GetMCOwnerWallet() (wallet.Wallet, error) // wallet that owns the management contract (network admin)
}

// Action is any step in a test, they will typically be either minimally small steps in the test or they will be containers
Expand Down
22 changes: 22 additions & 0 deletions integration/networktest/tests/bridge/important_contracts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package bridge

import (
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/obscuronet/go-obscuro/integration/networktest"
"github.com/obscuronet/go-obscuro/integration/networktest/actions"
"github.com/obscuronet/go-obscuro/integration/networktest/actions/l1"
"github.com/obscuronet/go-obscuro/integration/networktest/env"
"testing"
)

func TestImportantContractsLookup(t *testing.T) {
networktest.TestOnlyRunsInIDE(t)
networktest.Run(
"important-contracts-lookup",
t,
env.LocalDevNetwork(),
actions.Series(
l1.SetImportantContract("L1TestContract", gethcommon.HexToAddress("0x64")),
),
)
}
4 changes: 4 additions & 0 deletions integration/simulation/devnetwork/dev_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ type InMemDevNetwork struct {
faucetLock sync.Mutex
}

func (s *InMemDevNetwork) GetMCOwnerWallet() (wallet.Wallet, error) {
return s.networkWallets.MCOwnerWallet, nil
}

func (s *InMemDevNetwork) ChainID() int64 {
return integration.ObscuroChainID
}
Expand Down

0 comments on commit dc63568

Please sign in to comment.