github.com/hyperledger/burrow@v0.34.5-0.20220512172541-77f09336001d/integration/rpctest/helpers.go (about)

     1  package rpctest
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/hyperledger/burrow/encoding"
     8  
     9  	"github.com/hyperledger/burrow/acm"
    10  	"github.com/hyperledger/burrow/crypto"
    11  	_ "github.com/hyperledger/burrow/encoding"
    12  	"github.com/hyperledger/burrow/execution/exec"
    13  	"github.com/hyperledger/burrow/execution/names"
    14  	"github.com/hyperledger/burrow/integration"
    15  	"github.com/hyperledger/burrow/rpc"
    16  	"github.com/hyperledger/burrow/rpc/rpcevents"
    17  	"github.com/hyperledger/burrow/rpc/rpcinfo/infoclient"
    18  	"github.com/hyperledger/burrow/rpc/rpcquery"
    19  	"github.com/hyperledger/burrow/rpc/rpctransact"
    20  	"github.com/hyperledger/burrow/txs"
    21  	"github.com/hyperledger/burrow/txs/payload"
    22  	"github.com/stretchr/testify/require"
    23  	"golang.org/x/crypto/sha3"
    24  )
    25  
    26  // Recursive call count for UpsieDownsie() function call from strange_loop.sol
    27  // Equals initial call, then depth from 17 -> 34, one for the bounce, then depth from 34 -> 23,
    28  // so... (I didn't say it had to make sense):
    29  const UpsieDownsieCallCount = 1 + (34 - 17) + 1 + (34 - 23)
    30  
    31  var PrivateAccounts = integration.MakePrivateAccounts("mysecret", 10) // make keys
    32  var GenesisDoc = integration.TestGenesisDoc(PrivateAccounts, 0)
    33  
    34  // Helpers
    35  func NewTransactClient(t testing.TB, listenAddress string) rpctransact.TransactClient {
    36  	conn, err := encoding.GRPCDial(listenAddress)
    37  	require.NoError(t, err)
    38  	return rpctransact.NewTransactClient(conn)
    39  }
    40  
    41  func NewExecutionEventsClient(t testing.TB, listenAddress string) rpcevents.ExecutionEventsClient {
    42  	conn, err := encoding.GRPCDial(listenAddress)
    43  	require.NoError(t, err)
    44  	return rpcevents.NewExecutionEventsClient(conn)
    45  }
    46  
    47  func NewQueryClient(t testing.TB, listenAddress string) rpcquery.QueryClient {
    48  	conn, err := encoding.GRPCDial(listenAddress)
    49  	require.NoError(t, err)
    50  	return rpcquery.NewQueryClient(conn)
    51  }
    52  
    53  type MetadataMap struct {
    54  	DeployedCode []byte
    55  	Abi          []byte
    56  }
    57  
    58  func CreateEVMContract(cli rpctransact.TransactClient, inputAddress crypto.Address, bytecode []byte, metamap []MetadataMap) (*exec.TxExecution, error) {
    59  	var meta []*payload.ContractMeta
    60  	if metamap != nil {
    61  		meta = make([]*payload.ContractMeta, len(metamap))
    62  		for i, m := range metamap {
    63  			hash := sha3.NewLegacyKeccak256()
    64  			hash.Write(m.DeployedCode)
    65  			meta[i] = &payload.ContractMeta{
    66  				CodeHash: hash.Sum(nil),
    67  				Meta:     string(m.Abi),
    68  			}
    69  		}
    70  	}
    71  
    72  	txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{
    73  		Input: &payload.TxInput{
    74  			Address: inputAddress,
    75  			Amount:  2,
    76  		},
    77  		Address:      nil,
    78  		Data:         bytecode,
    79  		Fee:          2,
    80  		GasLimit:     10000,
    81  		ContractMeta: meta,
    82  	})
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	return txe, nil
    87  }
    88  
    89  func CreateWASMContract(cli rpctransact.TransactClient, inputAddress crypto.Address, bytecode []byte, metamap []MetadataMap) (*exec.TxExecution, error) {
    90  	var meta []*payload.ContractMeta
    91  	if metamap != nil {
    92  		meta = make([]*payload.ContractMeta, len(metamap))
    93  		for i, m := range metamap {
    94  			hash := sha3.NewLegacyKeccak256()
    95  			hash.Write(m.DeployedCode)
    96  			meta[i] = &payload.ContractMeta{
    97  				CodeHash: hash.Sum(nil),
    98  				Meta:     string(m.Abi),
    99  			}
   100  		}
   101  	}
   102  
   103  	txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{
   104  		Input: &payload.TxInput{
   105  			Address: inputAddress,
   106  			Amount:  2,
   107  		},
   108  		Address:      nil,
   109  		WASM:         bytecode,
   110  		Fee:          2,
   111  		GasLimit:     10000,
   112  		ContractMeta: meta,
   113  	})
   114  	if err != nil {
   115  		return nil, err
   116  	}
   117  	return txe, nil
   118  }
   119  
   120  func CallContract(cli rpctransact.TransactClient, inputAddress, contractAddress crypto.Address, data []byte) (*exec.TxExecution, error) {
   121  	txe, err := cli.CallTxSync(context.Background(), &payload.CallTx{
   122  		Input: &payload.TxInput{
   123  			Address: inputAddress,
   124  			Amount:  2,
   125  		},
   126  		Address:  &contractAddress,
   127  		Data:     data,
   128  		Fee:      2,
   129  		GasLimit: 1000000,
   130  	})
   131  	if err != nil {
   132  		return nil, err
   133  	}
   134  	return txe, nil
   135  }
   136  
   137  func UpdateName(cli rpctransact.TransactClient, inputAddress crypto.Address, name, data string,
   138  	expiresIn uint64) (*exec.TxExecution, error) {
   139  
   140  	return cli.NameTxSync(context.Background(), &payload.NameTx{
   141  		Input: &payload.TxInput{
   142  			Address: inputAddress,
   143  			Amount:  names.NameCostForExpiryIn(name, data, expiresIn),
   144  		},
   145  		Name: name,
   146  		Data: data,
   147  	})
   148  }
   149  
   150  //-------------------------------------------------------------------------------
   151  // some default transaction functions
   152  
   153  func MakeDefaultCallTx(t *testing.T, client rpc.Client, addr *crypto.Address, code []byte, amt, gasLim,
   154  	fee uint64) *txs.Envelope {
   155  	sequence := GetSequence(t, client, PrivateAccounts[0].GetAddress())
   156  	tx := payload.NewCallTxWithSequence(PrivateAccounts[0].GetPublicKey(), addr, code, amt, gasLim, fee, sequence+1)
   157  	txEnv := txs.Enclose(GenesisDoc.GetChainID(), tx)
   158  	require.NoError(t, txEnv.Sign(PrivateAccounts[0]))
   159  	return txEnv
   160  }
   161  
   162  //-------------------------------------------------------------------------------
   163  // rpc call wrappers (fail on err)
   164  
   165  // get an account's sequence number
   166  func GetSequence(t *testing.T, client rpc.Client, addr crypto.Address) uint64 {
   167  	acc, err := infoclient.Account(client, addr)
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	if acc == nil {
   172  		return 0
   173  	}
   174  	return acc.Sequence
   175  }
   176  
   177  // get the account
   178  func GetAccount(t *testing.T, client rpc.Client, addr crypto.Address) *acm.Account {
   179  	ac, err := infoclient.Account(client, addr)
   180  	if err != nil {
   181  		t.Fatal(err)
   182  	}
   183  	return ac
   184  }
   185  
   186  // dump all storage for an account. currently unused
   187  func DumpStorage(t *testing.T, client rpc.Client, addr crypto.Address) *rpc.ResultDumpStorage {
   188  	resp, err := infoclient.DumpStorage(client, addr)
   189  	if err != nil {
   190  		t.Fatal(err)
   191  	}
   192  	return resp
   193  }
   194  
   195  func GetStorage(t *testing.T, client rpc.Client, addr crypto.Address, key []byte) []byte {
   196  	resp, err := infoclient.Storage(client, addr, key)
   197  	if err != nil {
   198  		t.Fatal(err)
   199  	}
   200  	return resp
   201  }
   202  
   203  func WaitNBlocks(ecli rpcevents.ExecutionEventsClient, n int) (rerr error) {
   204  	stream, err := ecli.Stream(context.Background(), &rpcevents.BlocksRequest{
   205  		BlockRange: rpcevents.NewBlockRange(rpcevents.LatestBound(), rpcevents.StreamBound()),
   206  	})
   207  	if err != nil {
   208  		return err
   209  	}
   210  	defer func() {
   211  		rerr = stream.CloseSend()
   212  	}()
   213  	var ev *exec.StreamEvent
   214  	for err == nil && n > 0 {
   215  		ev, err = stream.Recv()
   216  		if err == nil && ev.EndBlock != nil {
   217  			n--
   218  		}
   219  	}
   220  	if err != nil {
   221  		return err
   222  	}
   223  	return
   224  }