From 4c1475f2e7c38f7bde3190145da69a8efcaec80e Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Fri, 12 May 2023 15:45:01 +0200 Subject: [PATCH 1/7] Benchmark test - comparing diff eth clients --- benchmark/README.md | 17 ++ benchmark/benchmark_test.go | 10 + benchmark/common/contract_codes.go | 81 ++++++++ benchmark/common/executors.go | 61 ++++++ benchmark/common/helper.go | 99 +++++++++ benchmark/root_child_send_tx.go | 196 ++++++++++++++++++ command/benchmark/benchmark.go | 121 +++++++++++ command/root/root.go | 2 + consensus/polybft/checkpoint_manager_test.go | 10 + consensus/polybft/stake_manager_test.go | 11 + .../state_sync_relayer_test.go | 11 + e2e-polybft/framework/test-bridge.go | 8 +- e2e-polybft/framework/test-cluster.go | 84 ++++---- e2e-polybft/framework/test-server.go | 14 +- txrelayer/txrelayer.go | 17 +- 15 files changed, 684 insertions(+), 58 deletions(-) create mode 100644 benchmark/README.md create mode 100644 benchmark/benchmark_test.go create mode 100644 benchmark/common/contract_codes.go create mode 100644 benchmark/common/executors.go create mode 100644 benchmark/common/helper.go create mode 100644 benchmark/root_child_send_tx.go create mode 100644 command/benchmark/benchmark.go diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 0000000000..5f678336e9 --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,17 @@ +# Benchmark tests +The benchmark folder contains benchmark tests for the smart contracts. + +## Common directory +In the common directory, you'll find: +- the contract_code.go file that contains byte codes for the contracts used in the tests, +- helpers.go that has helper functions needed in tests like deploying contracts and similar, +- executors.go that holds executors which execute the test cases. For example, there is an executor that submits multiple transactions in parallel and measures the execution time. + +## Tests +All test scenarios are executed in benchmark_test.go. Decoupling test scenarios from execution enables the usage of different scenarios in the benchmark command, which is written for the purpose of executing the benchmark test on a test environment. The command can be run with in a following way: +polygon-edge benchmark-test --childJSONRPC="http://127.0.0.1:12001" --rootJSONRPC="http://127.0.0.1:8545" --privateKey="aa75e9a7d427efc732f8e4f1a5b7646adcc61fd5bae40f80d13c8419c9f43d6d" + +## Testing tx send on root and child chains +The RootChildSendTx function executes test cases that measure transaction execution on both the root and child chains. To do this, it first calls RootChildSendTxSetUp to set up the testing environment, which may include starting the cluster, deploying contracts, and building the test cases. After building the test cases, RootChildSendTx returns them along with a cleanup function that should be called after the test cases have been executed. + +The test cases are executed by the TxTestCasesExecutor. The RootJSONRPC, ChildJSONRPC, and PrivateKey flags are used to configure the testing environment. If all of these flags are set, then the local cluster will not be started and the provided addresses will be used as the endpoints to the root and child chains. If any of these flags is not set, the local cluster will be started automatically. If the private key is specified, it will be used as the transaction sender. Otherwise, the local cluster will generate a sender key. If the cluster is not run locally, then the sender must have enough funds for sending transactions. \ No newline at end of file diff --git a/benchmark/benchmark_test.go b/benchmark/benchmark_test.go new file mode 100644 index 0000000000..8e94b3ee64 --- /dev/null +++ b/benchmark/benchmark_test.go @@ -0,0 +1,10 @@ +package benchmark + +import ( + "testing" +) + +func Benchmark_RunTests(b *testing.B) { + // benchmark tests + RootChildSendTx(b) +} diff --git a/benchmark/common/contract_codes.go b/benchmark/common/contract_codes.go new file mode 100644 index 0000000000..6cac4cfaf3 --- /dev/null +++ b/benchmark/common/contract_codes.go @@ -0,0 +1,81 @@ +//nolint:lll +package common + +// pragma solidity ^0.5.16; + +// contract SingleCallContract { +// uint256[] private val; + +// function addValue(uint256 value) public { +// val.push(value); +// } + +// function getValue() public view returns (uint256[] memory) { +// return val; +// } + +// function compute(uint256 x, uint256 y) public pure returns (uint256) { +// uint256 result = x + y; +// for (uint256 i = 0; i < 10; i++) { +// result = result * 2; +// } +// return result; +// } +// } +const SingleContByteCode = `608060405234801561001057600080fd5b50610210806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806320965255146100465780635b9af12b146100a55780637a85644b146100d3575b600080fd5b61004e61011f565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610091578082015181840152602081019050610076565b505050509050019250505060405180910390f35b6100d1600480360360208110156100bb57600080fd5b8101908080359060200190929190505050610177565b005b610109600480360360408110156100e957600080fd5b8101908080359060200190929190803590602001909291905050506101a6565b6040518082815260200191505060405180910390f35b6060600080548060200260200160405190810160405280929190818152602001828054801561016d57602002820191906000526020600020905b815481526020019060010190808311610159575b5050505050905090565b600081908060018154018082558091505090600182039060005260206000200160009091929091909150555050565b600080828401905060008090505b600a8110156101d05760028202915080806001019150506101b4565b50809150509291505056fea265627a7a72315820ec23cf989c20e0d41d7819001da6dfe6cc129988f15cd8a7b79595a2e61a93d264736f6c63430005100032` + +//MULTI CONTRACTS CALL: A->B->C + +// pragma solidity ^0.5.16; +// interface IContractB { +// function fnB() external returns (uint256); +// } +// contract ContractA { +// address contractAddr; +// +// function setContractAddr(address _contract) public { +// contractAddr = _contract; +// } + +// function fnA() public returns (uint256) { +// uint256 valB = IContractB(contractAddr).fnB(); +// return valB; +// } +// } +const MultiContAByteCode = `608060405234801561001057600080fd5b506101c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063286d2e3a1461003b57806368685ad31461007f575b600080fd5b61007d6004803603602081101561005157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061009d565b005b6100876100e0565b6040518082815260200191505060405180910390f35b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636cde00cd6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561014c57600080fd5b505af1158015610160573d6000803e3d6000fd5b505050506040513d602081101561017657600080fd5b81019080805190602001909291905050509050809150509056fea265627a7a7231582082d7a079b4ea6bcf371ef0665da89a56bd53bdc82ae90daa9dd21b61fc6c115864736f6c63430005100032` + +// pragma solidity ^0.5.16; +// interface IContractC { +// function fnC1() external returns (uint256); +// } +// contract ContractB { +// uint256 public valB; +// address contractAddr; + +// function setContractAddr(address _contract) public { +// contractAddr = _contract; +// } + +// function fnB() external returns (uint256) { +// uint256 valC = IContractC(contractAddr).fnC1(); +// valB += valC; +// return valC; +// } + +// } +const MultiContBByteCode = `608060405234801561001057600080fd5b50610205806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063286d2e3a146100465780636cde00cd1461008a578063735b7e6f146100a8575b600080fd5b6100886004803603602081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100c6565b005b61009261010a565b6040518082815260200191505060405180910390f35b6100b06101ca565b6040518082815260200191505060405180910390f35b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349ec07186040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561017757600080fd5b505af115801561018b573d6000803e3d6000fd5b505050506040513d60208110156101a157600080fd5b810190808051906020019092919050505090508060008082825401925050819055508091505090565b6000548156fea265627a7a7231582082a5dbbf184a5c59907837a73f0ea2083719218b0bd60ef31a3ef2b209aad00764736f6c63430005100032` + +// pragma solidity ^0.5.16; +// contract ContractC { +// uint256 public valC; +// function fnC1() external returns (uint256) { +// uint256 valC2 = fnC2(); +// valC++; +// return valC2; +// } + +// function fnC2() public view returns (uint256) { +// return uint256(keccak256(abi.encode(block.timestamp, block.difficulty))) % 100; +// } +// } +const MultiContCByteCode = `608060405234801561001057600080fd5b50610143806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80631990ceb9146100465780633b3cf4e31461006457806349ec071814610082575b600080fd5b61004e6100a0565b6040518082815260200191505060405180910390f35b61006c6100e3565b6040518082815260200191505060405180910390f35b61008a6100e9565b6040518082815260200191505060405180910390f35b60006064424460405160200180838152602001828152602001925050506040516020818303038152906040528051906020012060001c816100dd57fe5b06905090565b60005481565b6000806100f46100a0565b90506000808154809291906001019190505550809150509056fea265627a7a72315820834484e13fa60ebe10a9d7102df12bafa8db4d9cdad5a38d2af6d360adc7ff4064736f6c63430005100032` diff --git a/benchmark/common/executors.go b/benchmark/common/executors.go new file mode 100644 index 0000000000..c3dd1ce4c8 --- /dev/null +++ b/benchmark/common/executors.go @@ -0,0 +1,61 @@ +package common + +import ( + "sync" + "testing" + + "github.com/0xPolygon/polygon-edge/txrelayer" + "github.com/0xPolygon/polygon-edge/types" + "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo" +) + +// TxTestCase represents a test case data to be run with txTestCasesExecutor +type TxTestCase struct { + Name string + Relayer txrelayer.TxRelayer + ContractAddr ethgo.Address + Input [][]byte + Sender ethgo.Key + TxNumber int +} + +// TxTestCasesExecutor executes transactions from testInput and waits in separate +// go routins for each tx receipt +func TxTestCasesExecutor(b *testing.B, testInput TxTestCase) { + b.Helper() + b.Run(testInput.Name, func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + var wg sync.WaitGroup + + // submit all tx 'repeatCall' times + for i := 0; i < testInput.TxNumber; i++ { + // call contract for the all inputs + for j := 0; j < len(testInput.Input); j++ { + // the tx is submitted to the blockchain without waiting for the receipt, + // since we want to have multiple tx in one block + txHash, err := testInput.Relayer.SumbitTransaction( + ðgo.Transaction{ + To: &testInput.ContractAddr, + Input: testInput.Input[j], + }, testInput.Sender) + require.NoError(b, err) + require.NotEqual(b, ethgo.ZeroHash, txHash) + + wg.Add(1) + + // wait for receipt of submitted tx in a separate routine, and continue with the next tx + func(hash ethgo.Hash) { + defer wg.Done() + + receipt, err := testInput.Relayer.WaitForReceipt(hash) + require.NoError(b, err) + require.Equal(b, uint64(types.ReceiptSuccess), receipt.Status) + }(txHash) + } + } + + wg.Wait() + }) +} diff --git a/benchmark/common/helper.go b/benchmark/common/helper.go new file mode 100644 index 0000000000..1e9c5073ed --- /dev/null +++ b/benchmark/common/helper.go @@ -0,0 +1,99 @@ +package common + +import ( + "encoding/hex" + "testing" + + "github.com/0xPolygon/polygon-edge/txrelayer" + "github.com/0xPolygon/polygon-edge/types" + "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/abi" + "github.com/umbracle/ethgo/wallet" +) + +// DeployContractOnRootAndChild deploys contract code on both root and child chain +func DeployContractOnRootAndChild( + b *testing.B, + childTxRelayer txrelayer.TxRelayer, + rootTxRelayer txrelayer.TxRelayer, + sender ethgo.Key, + byteCodeString string) (ethgo.Address, ethgo.Address) { + b.Helper() + + // bytecode from string + byteCode, err := hex.DecodeString(byteCodeString) + require.NoError(b, err) + + // deploy contract on the child chain + contractChildAddr := DeployContract(b, childTxRelayer, sender, byteCode) + + // deploy contract on the root chain + contractRootAddr := DeployContract(b, rootTxRelayer, sender, byteCode) + + return contractChildAddr, contractRootAddr +} + +// DeployContract deploys contract code for the given relayer +func DeployContract(b *testing.B, txRelayer txrelayer.TxRelayer, sender ethgo.Key, byteCode []byte) ethgo.Address { + b.Helper() + + txn := ðgo.Transaction{ + To: nil, // contract deployment + Input: byteCode, + } + + receipt, err := txRelayer.SendTransaction(txn, sender) + require.NoError(b, err) + require.Equal(b, uint64(types.ReceiptSuccess), receipt.Status) + require.NotEqual(b, ethgo.ZeroAddress, receipt.ContractAddress) + + return receipt.ContractAddress +} + +// GetTxInput returns input for sending tx, given the abi encoded method and call parameters +func GetTxInput(b *testing.B, method *abi.Method, args interface{}) []byte { + b.Helper() + + var input []byte + + var err error + + if args != nil { + input, err = method.Encode(args) + } else { + input = method.ID() + } + + require.NoError(b, err) + + return input +} + +// SetContractDependencyAddress calls setContract function on caller contract, to set address of the callee contract +func SetContractDependencyAddress(b *testing.B, txRelayer txrelayer.TxRelayer, callerContractAddr ethgo.Address, + calleeContractAddr ethgo.Address, setContractAbiMethod *abi.Method, sender ethgo.Key) { + b.Helper() + + input := GetTxInput(b, setContractAbiMethod, []interface{}{calleeContractAddr}) + receipt, err := txRelayer.SendTransaction( + ðgo.Transaction{ + To: &callerContractAddr, + Input: input, + }, sender) + require.NoError(b, err) + require.Equal(b, uint64(types.ReceiptSuccess), receipt.Status) +} + +// GetPrivateKey initializes a private key from provided raw private key +func GetPrivateKey(b *testing.B, privateKeyRaw string) ethgo.Key { + b.Helper() + + dec, err := hex.DecodeString(privateKeyRaw) + require.NoError(b, err) + + privateKey, err := wallet.NewWalletFromPrivKey(dec) + require.NoError(b, err) + + return privateKey +} diff --git a/benchmark/root_child_send_tx.go b/benchmark/root_child_send_tx.go new file mode 100644 index 0000000000..bb829096df --- /dev/null +++ b/benchmark/root_child_send_tx.go @@ -0,0 +1,196 @@ +package benchmark + +import ( + "flag" + "math/big" + "testing" + + "github.com/0xPolygon/polygon-edge/benchmark/common" + "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" + "github.com/0xPolygon/polygon-edge/txrelayer" + "github.com/0xPolygon/polygon-edge/types" + "github.com/stretchr/testify/require" + "github.com/umbracle/ethgo" + "github.com/umbracle/ethgo/abi" + "github.com/umbracle/ethgo/wallet" +) + +var ( + singleContCalcFunc = abi.MustNewMethod("function compute(uint256 x, uint256 y) public returns (uint256)") + singleContGetFunc = abi.MustNewMethod("function getValue() public returns (uint256[] memory)") + singleContSetFunc = abi.MustNewMethod("function addValue(uint256 value) public") + multiContSetAddrFunc = abi.MustNewMethod("function setContractAddr(address _contract) public") + multiContFnA = abi.MustNewMethod("function fnA() public returns (uint256)") + RootJSONRPC = flag.String("rootJSONRPC", "", "JSONRPC address of the root node") + ChildJSONRPC = flag.String("childJSONRPC", "", "JSONRPC address of the child node") + PrivateKey = flag.String("privateKey", "", "private key that will be used to send tx") +) + +// RootChildSendTx deploys single and multi contracts to the root and child chain, execute tx from the +// test cases and measure its execution +func RootChildSendTx(b *testing.B) { + b.Helper() + // set up environment, get test cases and clean up fn + testCases, cleanUpFn := RootChildSendTxSetUp(b) + defer cleanUpFn() + + // Loop over the test cases and measure the execution time of the transactions + for _, testInput := range testCases { + common.TxTestCasesExecutor(b, testInput) + } +} + +// RootChildSendTxSetUp sets environment for execution of sentTx test cases on both root and child chains and +// returns test cases and clean up fn +func RootChildSendTxSetUp(b *testing.B) ([]common.TxTestCase, func()) { + b.Helper() + // check if test is called with the root and child node addresses and private key set. + // if that is the case use that json rpc addresses, otherwise run the cluster + rootNodeAddr := *RootJSONRPC + childNodeAddr := *ChildJSONRPC + privateKeyRaw := *PrivateKey + startCluster := rootNodeAddr == "" || childNodeAddr == "" || privateKeyRaw == "" + + var sender ethgo.Key + // if the privateKey flag is set then recover the key, otherwise recover the key + if privateKeyRaw != "" { + sender = common.GetPrivateKey(b, privateKeyRaw) + } else { + var err error + sender, err = wallet.GenerateKey() + require.NoError(b, err) + } + + senderEthAddr := sender.Address() + + // start the cluster if needed + cleanUpFn := func() {} + + if startCluster { + b.Log("Starting the cluster...") + cluster := framework.NewTestCluster(b, 5, + framework.WithPremine(types.Address(senderEthAddr)), + framework.WithEpochSize(5)) + + cleanUpFn = func() { cluster.Stop() } + + cluster.WaitForReady(b) + rootNodeAddr = cluster.Bridge.JSONRPCAddr() + childNodeAddr = cluster.Servers[0].JSONRPCAddr() + } + + //create tx relayers + rootTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(rootNodeAddr)) + require.NoError(b, err) + + childTxRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(childNodeAddr)) + require.NoError(b, err) + + if startCluster { + // fund sender on root chain to be able to deploy contracts and execute transactions + txn := ðgo.Transaction{To: &senderEthAddr, Value: ethgo.Ether(1)} + receipt, err := rootTxRelayer.SendTransactionLocal(txn) + require.NoError(b, err) + require.Equal(b, uint64(types.ReceiptSuccess), receipt.Status) + } + + // deploy contracts + singleContChildAddr, singleContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, common.SingleContByteCode) + multiAContChildAddr, multiAContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, common.MultiContAByteCode) + multiBContChildAddr, multiBContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, common.MultiContBByteCode) + multiCContChildAddr, multiCContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, common.MultiContCByteCode) + + // set callee contract addresses for multi call contracts (A->B->C) + // set B contract address in A contract + common.SetContractDependencyAddress(b, childTxRelayer, multiAContChildAddr, multiBContChildAddr, + multiContSetAddrFunc, sender) + common.SetContractDependencyAddress(b, rootTxRelayer, multiAContRootAddr, multiBContRootAddr, + multiContSetAddrFunc, sender) + // set C contract address in B contract + common.SetContractDependencyAddress(b, childTxRelayer, multiBContChildAddr, multiCContChildAddr, + multiContSetAddrFunc, sender) + common.SetContractDependencyAddress(b, rootTxRelayer, multiBContRootAddr, multiCContRootAddr, + multiContSetAddrFunc, sender) + + // create inputs for contract calls + singleContInputs := map[string][]byte{ + "calc": common.GetTxInput(b, singleContCalcFunc, []interface{}{big.NewInt(50), big.NewInt(150)}), + "set": common.GetTxInput(b, singleContSetFunc, []interface{}{big.NewInt(10)}), + "get": common.GetTxInput(b, singleContGetFunc, nil), + } + multiContInput := common.GetTxInput(b, multiContFnA, nil) + + // test cases + testCases := []common.TxTestCase{ + { + Name: "[Child chain] setter 5tx", + Relayer: childTxRelayer, + ContractAddr: singleContChildAddr, + Input: [][]byte{singleContInputs["set"]}, + Sender: sender, + TxNumber: 5, + }, + { + Name: "[Root chain] setter 5tx", + Relayer: rootTxRelayer, + ContractAddr: singleContRootAddr, + Input: [][]byte{singleContInputs["set"]}, + Sender: sender, + TxNumber: 5, + }, + { + Name: "[Child chain] getter 5tx", + Relayer: childTxRelayer, + ContractAddr: singleContChildAddr, + Input: [][]byte{singleContInputs["get"]}, + Sender: sender, + TxNumber: 5, + }, + { + Name: "[Root chain] getter 5tx", + Relayer: rootTxRelayer, + ContractAddr: singleContRootAddr, + Input: [][]byte{singleContInputs["get"]}, + Sender: sender, + TxNumber: 5, + }, + { + Name: "[Child chain] set,get,calculate 15tx", + Relayer: childTxRelayer, + ContractAddr: singleContChildAddr, + Input: [][]byte{singleContInputs["get"], singleContInputs["set"], singleContInputs["calc"]}, + Sender: sender, + TxNumber: 5, + }, + { + Name: "[Root chain] set,get,calculate 15tx", + Relayer: rootTxRelayer, + ContractAddr: singleContRootAddr, + Input: [][]byte{singleContInputs["get"], singleContInputs["set"], singleContInputs["calc"]}, + Sender: sender, + TxNumber: 5, + }, + { + Name: "[Child chain] multi contract call 5tx", + Relayer: childTxRelayer, + ContractAddr: multiAContChildAddr, + Input: [][]byte{multiContInput}, + Sender: sender, + TxNumber: 5, + }, + { + Name: "[Root chain] multi contract call 5tx", + Relayer: rootTxRelayer, + ContractAddr: multiAContRootAddr, + Input: [][]byte{multiContInput}, + Sender: sender, + TxNumber: 5, + }, + } + + return testCases, cleanUpFn +} diff --git a/command/benchmark/benchmark.go b/command/benchmark/benchmark.go new file mode 100644 index 0000000000..e52612c197 --- /dev/null +++ b/command/benchmark/benchmark.go @@ -0,0 +1,121 @@ +package benchmark + +import ( + "bytes" + "fmt" + "testing" + + "github.com/0xPolygon/polygon-edge/benchmark" + "github.com/0xPolygon/polygon-edge/benchmark/common" + "github.com/0xPolygon/polygon-edge/command" + "github.com/spf13/cobra" +) + +const ( + rootJSONRPCFlag = "rootJSONRPC" + childJSONRPCFlag = "childJSONRPC" + privateKeyFlag = "privateKey" +) + +type benchmarkParams struct { + rootJSONRPC string + childJSONRPC string + privateKey string +} + +type benchmarkResult struct { + name string + result string +} + +var ( + params *benchmarkParams = &benchmarkParams{} +) + +func GetCommand() *cobra.Command { + benchmarkCmd := &cobra.Command{ + Use: "benchmark-test", + Short: "Run benchmark tests", + Example: getCmdExample(), + Run: runCommand, + } + + setFlags(benchmarkCmd) + + return benchmarkCmd +} + +func runCommand(cmd *cobra.Command, _ []string) { + outputter := command.InitializeOutputter(cmd) + defer outputter.WriteOutput() + + // set up the testing environment + testing.Init() + + // set testing params + benchmark.RootJSONRPC = ¶ms.rootJSONRPC + benchmark.ChildJSONRPC = ¶ms.childJSONRPC + benchmark.PrivateKey = ¶ms.privateKey + + // set up environment, get test cases and clean up fn + testCases, cleanUpFn := benchmark.RootChildSendTxSetUp(&testing.B{}) + defer cleanUpFn() + + // Loop over the test cases and call the benchmark test + for _, testInput := range testCases { + sendTxResult := testing.Benchmark(func(b *testing.B) { + b.Helper() + common.TxTestCasesExecutor(b, testInput) + }) + benchmarkResult := &benchmarkResult{ + name: testInput.Name, + result: fmt.Sprintf("%s %s", sendTxResult.String(), sendTxResult.MemString()), + } + outputter.SetCommandResult(benchmarkResult) + outputter.WriteOutput() + } +} + +func setFlags(cmd *cobra.Command) { + cmd.Flags().StringVar( + ¶ms.rootJSONRPC, + rootJSONRPCFlag, + "", + "JSONRPC address of the root node", + ) + cmd.Flags().StringVar( + ¶ms.childJSONRPC, + childJSONRPCFlag, + "", + "JSONRPC address of the child node", + ) + cmd.Flags().StringVar( + ¶ms.privateKey, + privateKeyFlag, + "", + "private key that will be used to send tx (it is expected that this address has enough funds)", + ) + + _ = cmd.MarkFlagRequired(rootJSONRPCFlag) + _ = cmd.MarkFlagRequired(childJSONRPCFlag) + _ = cmd.MarkFlagRequired(privateKeyFlag) +} + +func (p *benchmarkParams) validateFlags() error { + // add addresses and key validation + return nil +} + +func (br *benchmarkResult) GetOutput() string { + var buffer bytes.Buffer + + buffer.WriteString(fmt.Sprintf("\n%s: %s\n", br.result, br.name)) + + return buffer.String() +} + +func getCmdExample() string { + return fmt.Sprintf("%s %s %s %s %s", "polygon-edge", "benchmark-test", + "--childJSONRPC=\"http://127.0.0.1:12001\"", "--rootJSONRPC=\"http://127.0.0.1:8545\"", + "--privateKey=\"aa75e9a7d427efc732f8e4f1a5b7646adcc61fd5bae40f80d13c8419c9f43d6d\"") +} diff --git a/command/root/root.go b/command/root/root.go index 05805f9b11..75d15953ff 100644 --- a/command/root/root.go +++ b/command/root/root.go @@ -7,6 +7,7 @@ import ( "github.com/spf13/cobra" "github.com/0xPolygon/polygon-edge/command/backup" + "github.com/0xPolygon/polygon-edge/command/benchmark" "github.com/0xPolygon/polygon-edge/command/bridge" "github.com/0xPolygon/polygon-edge/command/genesis" "github.com/0xPolygon/polygon-edge/command/helper" @@ -63,6 +64,7 @@ func (rc *RootCommand) registerSubCommands() { polybft.GetCommand(), bridge.GetCommand(), regenesis.GetCommand(), + benchmark.GetCommand(), ) } diff --git a/consensus/polybft/checkpoint_manager_test.go b/consensus/polybft/checkpoint_manager_test.go index fa177b4ab3..165c760adf 100644 --- a/consensus/polybft/checkpoint_manager_test.go +++ b/consensus/polybft/checkpoint_manager_test.go @@ -507,6 +507,16 @@ func (d *dummyTxRelayer) SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Re return args.Get(0).(*ethgo.Receipt), args.Error(1) //nolint:forcetypeassert } +// SumbitTransaction signs given transaction by provided key and sends it to the blockchain without waiting for the receipt +func (d *dummyTxRelayer) SumbitTransaction(txn *ethgo.Transaction, key ethgo.Key) (ethgo.Hash, error) { + return ethgo.ZeroHash, errors.New("SumbitTransaction is not implemented") +} + +// WaitForReceipt waits for tx receipt (this is only for testing purposes) +func (d *dummyTxRelayer) WaitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { + return nil, errors.New("WaitForReceipt is not implemented") +} + func (d *dummyTxRelayer) Client() *jsonrpc.Client { return nil } diff --git a/consensus/polybft/stake_manager_test.go b/consensus/polybft/stake_manager_test.go index 540ad586da..92103f9cb2 100644 --- a/consensus/polybft/stake_manager_test.go +++ b/consensus/polybft/stake_manager_test.go @@ -1,6 +1,7 @@ package polybft import ( + "errors" "math/big" "testing" @@ -512,3 +513,13 @@ func (d *dummyStakeTxRelayer) SendTransactionLocal(txn *ethgo.Transaction) (*eth func (d *dummyStakeTxRelayer) Client() *jsonrpc.Client { return nil } + +// SumbitTransaction signs given transaction by provided key and sends it to the blockchain without waiting for the receipt +func (d *dummyStakeTxRelayer) SumbitTransaction(txn *ethgo.Transaction, key ethgo.Key) (ethgo.Hash, error) { + return ethgo.ZeroHash, errors.New("SumbitTransaction is not implemented") +} + +// WaitForReceipt waits for tx receipt (this is only for testing purposes) +func (d *dummyStakeTxRelayer) WaitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { + return nil, errors.New("WaitForReceipt is not implemented") +} diff --git a/consensus/polybft/statesyncrelayer/state_sync_relayer_test.go b/consensus/polybft/statesyncrelayer/state_sync_relayer_test.go index e523bb0b40..8bebc93c32 100644 --- a/consensus/polybft/statesyncrelayer/state_sync_relayer_test.go +++ b/consensus/polybft/statesyncrelayer/state_sync_relayer_test.go @@ -1,6 +1,7 @@ package statesyncrelayer import ( + "errors" "math/big" "testing" @@ -43,6 +44,16 @@ func (t *txRelayerMock) Client() *jsonrpc.Client { return nil } +// SumbitTransaction signs given transaction by provided key and sends it to the blockchain without waiting for the receipt +func (t *txRelayerMock) SumbitTransaction(txn *ethgo.Transaction, key ethgo.Key) (ethgo.Hash, error) { + return ethgo.ZeroHash, errors.New("SumbitTransaction is not implemented") +} + +// WaitForReceipt waits for tx receipt (this is only for testing purposes) +func (t *txRelayerMock) WaitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { + return nil, errors.New("WaitForReceipt is not implemented") +} + func Test_executeStateSync(t *testing.T) { t.Parallel() diff --git a/e2e-polybft/framework/test-bridge.go b/e2e-polybft/framework/test-bridge.go index b7475a5644..0f2712c747 100644 --- a/e2e-polybft/framework/test-bridge.go +++ b/e2e-polybft/framework/test-bridge.go @@ -23,16 +23,16 @@ import ( ) type TestBridge struct { - t *testing.T + t testing.TB clusterConfig *TestClusterConfig node *node } -func NewTestBridge(t *testing.T, clusterConfig *TestClusterConfig) (*TestBridge, error) { - t.Helper() +func NewTestBridge(tb testing.TB, clusterConfig *TestClusterConfig) (*TestBridge, error) { + tb.Helper() bridge := &TestBridge{ - t: t, + t: tb, clusterConfig: clusterConfig, } diff --git a/e2e-polybft/framework/test-cluster.go b/e2e-polybft/framework/test-cluster.go index f2c594b5e5..b915cf9e4d 100644 --- a/e2e-polybft/framework/test-cluster.go +++ b/e2e-polybft/framework/test-cluster.go @@ -70,7 +70,7 @@ func resolveBinary() string { } type TestClusterConfig struct { - t *testing.T + t testing.TB Name string Premine []string // address[:amount] @@ -372,13 +372,13 @@ func NewPropertyTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOp return NewTestCluster(t, validatorsCount, opts...) } -func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *TestCluster { - t.Helper() +func NewTestCluster(tb testing.TB, validatorsCount int, opts ...ClusterOption) *TestCluster { + tb.Helper() var err error config := &TestClusterConfig{ - t: t, + t: tb, WithLogs: isTrueEnv(envLogsEnabled), WithStdout: isTrueEnv(envStdoutEnabled), Binary: resolveBinary(), @@ -404,11 +404,11 @@ func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *T testType = "integration" } - t.Skip(fmt.Sprintf("%s tests are disabled.", testType)) + tb.Skip(fmt.Sprintf("%s tests are disabled.", testType)) } config.TmpDir, err = os.MkdirTemp("/tmp", "e2e-polybft-") - require.NoError(t, err) + require.NoError(tb, err) cluster := &TestCluster{ Servers: []*TestServer{}, @@ -425,7 +425,7 @@ func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *T // run init accounts for validators addresses, err := cluster.InitSecrets(cluster.Config.ValidatorPrefix, int(cluster.Config.ValidatorSetSize)) - require.NoError(t, err) + require.NoError(tb, err) if cluster.Config.SecretsCallback != nil { cluster.Config.SecretsCallback(addresses, cluster.Config) @@ -436,7 +436,7 @@ func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *T // we don't call secrets callback on non-validators, // since we have nothing to premine nor stake for non validators _, err = cluster.InitSecrets(nonValidatorPrefix, config.NonValidatorCount) - require.NoError(t, err) + require.NoError(tb, err) } genesisPath := path.Join(config.TmpDir, "genesis.json") @@ -482,7 +482,7 @@ func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *T validators, err := genesis.ReadValidatorsByPrefix( cluster.Config.TmpDir, cluster.Config.ValidatorPrefix) - require.NoError(t, err) + require.NoError(tb, err) if cluster.Config.BootnodeCount > 0 { bootNodesCnt := cluster.Config.BootnodeCount @@ -562,60 +562,60 @@ func NewTestCluster(t *testing.T, validatorsCount int, opts ...ClusterOption) *T // run genesis command with all the arguments err = cluster.cmdRun(args...) - require.NoError(t, err) + require.NoError(tb, err) } if !cluster.Config.WithoutBridge { // start bridge - cluster.Bridge, err = NewTestBridge(t, cluster.Config) - require.NoError(t, err) + cluster.Bridge, err = NewTestBridge(tb, cluster.Config) + require.NoError(tb, err) // deploy rootchain contracts err := cluster.Bridge.deployRootchainContracts(genesisPath) - require.NoError(t, err) + require.NoError(tb, err) polybftConfig, chainID, err := polybft.LoadPolyBFTConfig(genesisPath) - require.NoError(t, err) + require.NoError(tb, err) // fund validators on the rootchain err = cluster.Bridge.fundRootchainValidators(polybftConfig) - require.NoError(t, err) + require.NoError(tb, err) // whitelist genesis validators on the rootchain err = cluster.Bridge.whitelistValidators(addresses, polybftConfig) - require.NoError(t, err) + require.NoError(tb, err) // register genesis validators on the rootchain err = cluster.Bridge.registerGenesisValidators(polybftConfig) - require.NoError(t, err) + require.NoError(tb, err) // do initial staking for genesis validators on the rootchain err = cluster.Bridge.initialStakingOfGenesisValidators(polybftConfig, chainID) - require.NoError(t, err) + require.NoError(tb, err) // finalize genesis validators on the rootchain err = cluster.Bridge.finalizeGenesis(genesisPath, polybftConfig) - require.NoError(t, err) + require.NoError(tb, err) } for i := 1; i <= int(cluster.Config.ValidatorSetSize); i++ { dir := cluster.Config.ValidatorPrefix + strconv.Itoa(i) - cluster.InitTestServer(t, dir, cluster.Bridge.JSONRPCAddr(), + cluster.InitTestServer(tb, dir, cluster.Bridge.JSONRPCAddr(), true, !cluster.Config.WithoutBridge && i == 1 /* relayer */) } for i := 1; i <= cluster.Config.NonValidatorCount; i++ { dir := nonValidatorPrefix + strconv.Itoa(i) - cluster.InitTestServer(t, dir, cluster.Bridge.JSONRPCAddr(), + cluster.InitTestServer(tb, dir, cluster.Bridge.JSONRPCAddr(), false, false /* relayer */) } return cluster } -func (c *TestCluster) InitTestServer(t *testing.T, +func (c *TestCluster) InitTestServer(tb testing.TB, dataDir string, bridgeJSONRPC string, isValidator bool, relayer bool) { - t.Helper() + tb.Helper() logLevel := os.Getenv(envLogLevel) @@ -623,11 +623,11 @@ func (c *TestCluster) InitTestServer(t *testing.T, if c.Config.InitialTrieDB != "" { err := CopyDir(c.Config.InitialTrieDB, filepath.Join(dataDir, "trie")) if err != nil { - t.Fatal(err) + tb.Fatal(err) } } - srv := NewTestServer(t, c.Config, bridgeJSONRPC, func(config *TestServerConfig) { + srv := NewTestServer(tb, c.Config, bridgeJSONRPC, func(config *TestServerConfig) { config.DataDir = dataDir config.Seal = isValidator config.Chain = c.Config.Dir("genesis.json") @@ -706,10 +706,10 @@ func (c *TestCluster) WaitUntil(timeout, pollFrequency time.Duration, handler fu } } -func (c *TestCluster) WaitForReady(t *testing.T) { - t.Helper() +func (c *TestCluster) WaitForReady(tb testing.TB) { + tb.Helper() - require.NoError(t, c.WaitForBlock(1, time.Minute)) + require.NoError(tb, c.WaitForBlock(1, time.Minute)) } func (c *TestCluster) WaitForBlock(n uint64, timeout time.Duration) error { @@ -819,11 +819,11 @@ func (c *TestCluster) InitSecrets(prefix string, count int) ([]types.Address, er return result, nil } -func (c *TestCluster) ExistsCode(t *testing.T, addr ethgo.Address) bool { - t.Helper() +func (c *TestCluster) ExistsCode(tb testing.TB, addr ethgo.Address) bool { + tb.Helper() client, err := jsonrpc.NewClient(c.Servers[0].JSONRPCAddr()) - require.NoError(t, err) + require.NoError(tb, err) code, err := client.Eth().GetCode(addr, ethgo.Latest) if err != nil { @@ -861,10 +861,10 @@ func (c *TestCluster) Call(t *testing.T, to types.Address, method *abi.Method, return output } -func (c *TestCluster) Deploy(t *testing.T, sender ethgo.Key, bytecode []byte) *TestTxn { - t.Helper() +func (c *TestCluster) Deploy(tb testing.TB, sender ethgo.Key, bytecode []byte) *TestTxn { + tb.Helper() - return c.SendTxn(t, sender, ðgo.Transaction{Input: bytecode}) + return c.SendTxn(tb, sender, ðgo.Transaction{Input: bytecode}) } func (c *TestCluster) Transfer(t *testing.T, sender ethgo.Key, target types.Address, value *big.Int) *TestTxn { @@ -884,8 +884,8 @@ func (c *TestCluster) MethodTxn(t *testing.T, sender ethgo.Key, target types.Add } // SendTxn sends a transaction -func (c *TestCluster) SendTxn(t *testing.T, sender ethgo.Key, txn *ethgo.Transaction) *TestTxn { - t.Helper() +func (c *TestCluster) SendTxn(tb testing.TB, sender ethgo.Key, txn *ethgo.Transaction) *TestTxn { + tb.Helper() // since we might use get nonce to query the latest nonce and that value is only // updated if the transaction is on the pool, it is recommended to lock the whole @@ -895,12 +895,12 @@ func (c *TestCluster) SendTxn(t *testing.T, sender ethgo.Key, txn *ethgo.Transac defer c.sendTxnLock.Unlock() client, err := jsonrpc.NewClient(c.Servers[0].JSONRPCAddr()) - require.NoError(t, err) + require.NoError(tb, err) // initialize transaction values if not set if txn.Nonce == 0 { nonce, err := client.Eth().GetNonce(sender.Address(), ethgo.Latest) - require.NoError(t, err) + require.NoError(tb, err) txn.Nonce = nonce } @@ -914,17 +914,17 @@ func (c *TestCluster) SendTxn(t *testing.T, sender ethgo.Key, txn *ethgo.Transac } chainID, err := client.Eth().ChainID() - require.NoError(t, err) + require.NoError(tb, err) signer := wallet.NewEIP155Signer(chainID.Uint64()) signedTxn, err := signer.SignTx(txn, sender) - require.NoError(t, err) + require.NoError(tb, err) txnRaw, err := signedTxn.MarshalRLPTo(nil) - require.NoError(t, err) + require.NoError(tb, err) hash, err := client.Eth().SendRawTransaction(txnRaw) - require.NoError(t, err) + require.NoError(tb, err) tTxn := &TestTxn{ client: client.Eth(), diff --git a/e2e-polybft/framework/test-server.go b/e2e-polybft/framework/test-server.go index 8dc94ab994..603cf6668e 100644 --- a/e2e-polybft/framework/test-server.go +++ b/e2e-polybft/framework/test-server.go @@ -48,7 +48,7 @@ func getOpenPortForServer() int64 { } type TestServer struct { - t *testing.T + t testing.TB address types.Address clusterConfig *TestClusterConfig @@ -99,9 +99,9 @@ func (t *TestServer) TxnPoolOperator() txpoolProto.TxnPoolOperatorClient { return txpoolProto.NewTxnPoolOperatorClient(conn) } -func NewTestServer(t *testing.T, clusterConfig *TestClusterConfig, +func NewTestServer(tb testing.TB, clusterConfig *TestClusterConfig, bridgeJSONRPC string, callback TestServerConfigCallback) *TestServer { - t.Helper() + tb.Helper() config := &TestServerConfig{ Name: uuid.New().String(), @@ -117,19 +117,19 @@ func NewTestServer(t *testing.T, clusterConfig *TestClusterConfig, if config.DataDir == "" { dataDir, err := ioutil.TempDir("/tmp", "edge-e2e-") - require.NoError(t, err) + require.NoError(tb, err) config.DataDir = dataDir } secretsManager, err := polybftsecrets.GetSecretsManager(config.DataDir, "", true) - require.NoError(t, err) + require.NoError(tb, err) key, err := wallet.GetEcdsaFromSecret(secretsManager) - require.NoError(t, err) + require.NoError(tb, err) srv := &TestServer{ - t: t, + t: tb, clusterConfig: clusterConfig, address: types.Address(key.Address()), config: config, diff --git a/txrelayer/txrelayer.go b/txrelayer/txrelayer.go index 95e0671da0..a6411b3498 100644 --- a/txrelayer/txrelayer.go +++ b/txrelayer/txrelayer.go @@ -30,6 +30,11 @@ type TxRelayer interface { // SendTransactionLocal sends non-signed transaction // (this function is meant only for testing purposes and is about to be removed at some point) SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Receipt, error) + // Waits for tx receipt to be written to the blockchain + WaitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) + // SumbitTransaction signs given transaction by provided key and sends it to the blockchain + // without waiting for the receipt + SumbitTransaction(txn *ethgo.Transaction, key ethgo.Key) (ethgo.Hash, error) // Client returns jsonrpc client Client() *jsonrpc.Client } @@ -78,12 +83,12 @@ func (t *TxRelayerImpl) Call(from ethgo.Address, to ethgo.Address, input []byte) // SendTransaction signs given transaction by provided key and sends it to the blockchain func (t *TxRelayerImpl) SendTransaction(txn *ethgo.Transaction, key ethgo.Key) (*ethgo.Receipt, error) { - txnHash, err := t.sendTransactionLocked(txn, key) + txnHash, err := t.SumbitTransaction(txn, key) if err != nil { return nil, err } - return t.waitForReceipt(txnHash) + return t.WaitForReceipt(txnHash) } // Client returns jsonrpc client @@ -91,7 +96,9 @@ func (t *TxRelayerImpl) Client() *jsonrpc.Client { return t.client } -func (t *TxRelayerImpl) sendTransactionLocked(txn *ethgo.Transaction, key ethgo.Key) (ethgo.Hash, error) { +// SumbitTransaction signs given transaction by provided key and sends it to the blockchain +// without waiting for the receipt +func (t *TxRelayerImpl) SumbitTransaction(txn *ethgo.Transaction, key ethgo.Key) (ethgo.Hash, error) { t.lock.Lock() defer t.lock.Unlock() @@ -149,10 +156,10 @@ func (t *TxRelayerImpl) SendTransactionLocal(txn *ethgo.Transaction) (*ethgo.Rec return nil, err } - return t.waitForReceipt(txnHash) + return t.WaitForReceipt(txnHash) } -func (t *TxRelayerImpl) waitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { +func (t *TxRelayerImpl) WaitForReceipt(hash ethgo.Hash) (*ethgo.Receipt, error) { count := uint(0) for { From 726fbea72df3f9ebcee777b0174cf49a72dfe4b9 Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Tue, 16 May 2023 12:40:17 +0200 Subject: [PATCH 2/7] cr fix - file reorganization --- benchmark/README.md | 17 ------- benchmark/benchmark_test.go | 2 +- benchmark/{common => }/contract_codes.go | 10 ++--- benchmark/{common => }/executors.go | 2 +- benchmark/{common => }/helper.go | 35 ++++++++------- benchmark/root_child_send_tx.go | 57 ++++++++++++++---------- command/benchmark/benchmark.go | 8 +--- 7 files changed, 59 insertions(+), 72 deletions(-) delete mode 100644 benchmark/README.md rename benchmark/{common => }/contract_codes.go (95%) rename benchmark/{common => }/executors.go (98%) rename benchmark/{common => }/helper.go (69%) diff --git a/benchmark/README.md b/benchmark/README.md deleted file mode 100644 index 5f678336e9..0000000000 --- a/benchmark/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Benchmark tests -The benchmark folder contains benchmark tests for the smart contracts. - -## Common directory -In the common directory, you'll find: -- the contract_code.go file that contains byte codes for the contracts used in the tests, -- helpers.go that has helper functions needed in tests like deploying contracts and similar, -- executors.go that holds executors which execute the test cases. For example, there is an executor that submits multiple transactions in parallel and measures the execution time. - -## Tests -All test scenarios are executed in benchmark_test.go. Decoupling test scenarios from execution enables the usage of different scenarios in the benchmark command, which is written for the purpose of executing the benchmark test on a test environment. The command can be run with in a following way: -polygon-edge benchmark-test --childJSONRPC="http://127.0.0.1:12001" --rootJSONRPC="http://127.0.0.1:8545" --privateKey="aa75e9a7d427efc732f8e4f1a5b7646adcc61fd5bae40f80d13c8419c9f43d6d" - -## Testing tx send on root and child chains -The RootChildSendTx function executes test cases that measure transaction execution on both the root and child chains. To do this, it first calls RootChildSendTxSetUp to set up the testing environment, which may include starting the cluster, deploying contracts, and building the test cases. After building the test cases, RootChildSendTx returns them along with a cleanup function that should be called after the test cases have been executed. - -The test cases are executed by the TxTestCasesExecutor. The RootJSONRPC, ChildJSONRPC, and PrivateKey flags are used to configure the testing environment. If all of these flags are set, then the local cluster will not be started and the provided addresses will be used as the endpoints to the root and child chains. If any of these flags is not set, the local cluster will be started automatically. If the private key is specified, it will be used as the transaction sender. Otherwise, the local cluster will generate a sender key. If the cluster is not run locally, then the sender must have enough funds for sending transactions. \ No newline at end of file diff --git a/benchmark/benchmark_test.go b/benchmark/benchmark_test.go index 8e94b3ee64..725bafafac 100644 --- a/benchmark/benchmark_test.go +++ b/benchmark/benchmark_test.go @@ -6,5 +6,5 @@ import ( func Benchmark_RunTests(b *testing.B) { // benchmark tests - RootChildSendTx(b) + rootChildSendTx(b) } diff --git a/benchmark/common/contract_codes.go b/benchmark/contract_codes.go similarity index 95% rename from benchmark/common/contract_codes.go rename to benchmark/contract_codes.go index 6cac4cfaf3..8a567032a6 100644 --- a/benchmark/common/contract_codes.go +++ b/benchmark/contract_codes.go @@ -1,5 +1,5 @@ //nolint:lll -package common +package benchmark // pragma solidity ^0.5.16; @@ -22,7 +22,7 @@ package common // return result; // } // } -const SingleContByteCode = `608060405234801561001057600080fd5b50610210806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806320965255146100465780635b9af12b146100a55780637a85644b146100d3575b600080fd5b61004e61011f565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610091578082015181840152602081019050610076565b505050509050019250505060405180910390f35b6100d1600480360360208110156100bb57600080fd5b8101908080359060200190929190505050610177565b005b610109600480360360408110156100e957600080fd5b8101908080359060200190929190803590602001909291905050506101a6565b6040518082815260200191505060405180910390f35b6060600080548060200260200160405190810160405280929190818152602001828054801561016d57602002820191906000526020600020905b815481526020019060010190808311610159575b5050505050905090565b600081908060018154018082558091505090600182039060005260206000200160009091929091909150555050565b600080828401905060008090505b600a8110156101d05760028202915080806001019150506101b4565b50809150509291505056fea265627a7a72315820ec23cf989c20e0d41d7819001da6dfe6cc129988f15cd8a7b79595a2e61a93d264736f6c63430005100032` +const singleContByteCode = `608060405234801561001057600080fd5b50610210806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806320965255146100465780635b9af12b146100a55780637a85644b146100d3575b600080fd5b61004e61011f565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610091578082015181840152602081019050610076565b505050509050019250505060405180910390f35b6100d1600480360360208110156100bb57600080fd5b8101908080359060200190929190505050610177565b005b610109600480360360408110156100e957600080fd5b8101908080359060200190929190803590602001909291905050506101a6565b6040518082815260200191505060405180910390f35b6060600080548060200260200160405190810160405280929190818152602001828054801561016d57602002820191906000526020600020905b815481526020019060010190808311610159575b5050505050905090565b600081908060018154018082558091505090600182039060005260206000200160009091929091909150555050565b600080828401905060008090505b600a8110156101d05760028202915080806001019150506101b4565b50809150509291505056fea265627a7a72315820ec23cf989c20e0d41d7819001da6dfe6cc129988f15cd8a7b79595a2e61a93d264736f6c63430005100032` //MULTI CONTRACTS CALL: A->B->C @@ -42,7 +42,7 @@ const SingleContByteCode = `608060405234801561001057600080fd5b506102108061002060 // return valB; // } // } -const MultiContAByteCode = `608060405234801561001057600080fd5b506101c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063286d2e3a1461003b57806368685ad31461007f575b600080fd5b61007d6004803603602081101561005157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061009d565b005b6100876100e0565b6040518082815260200191505060405180910390f35b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636cde00cd6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561014c57600080fd5b505af1158015610160573d6000803e3d6000fd5b505050506040513d602081101561017657600080fd5b81019080805190602001909291905050509050809150509056fea265627a7a7231582082d7a079b4ea6bcf371ef0665da89a56bd53bdc82ae90daa9dd21b61fc6c115864736f6c63430005100032` +const multiContAByteCode = `608060405234801561001057600080fd5b506101c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063286d2e3a1461003b57806368685ad31461007f575b600080fd5b61007d6004803603602081101561005157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061009d565b005b6100876100e0565b6040518082815260200191505060405180910390f35b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636cde00cd6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561014c57600080fd5b505af1158015610160573d6000803e3d6000fd5b505050506040513d602081101561017657600080fd5b81019080805190602001909291905050509050809150509056fea265627a7a7231582082d7a079b4ea6bcf371ef0665da89a56bd53bdc82ae90daa9dd21b61fc6c115864736f6c63430005100032` // pragma solidity ^0.5.16; // interface IContractC { @@ -63,7 +63,7 @@ const MultiContAByteCode = `608060405234801561001057600080fd5b506101c58061002060 // } // } -const MultiContBByteCode = `608060405234801561001057600080fd5b50610205806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063286d2e3a146100465780636cde00cd1461008a578063735b7e6f146100a8575b600080fd5b6100886004803603602081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100c6565b005b61009261010a565b6040518082815260200191505060405180910390f35b6100b06101ca565b6040518082815260200191505060405180910390f35b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349ec07186040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561017757600080fd5b505af115801561018b573d6000803e3d6000fd5b505050506040513d60208110156101a157600080fd5b810190808051906020019092919050505090508060008082825401925050819055508091505090565b6000548156fea265627a7a7231582082a5dbbf184a5c59907837a73f0ea2083719218b0bd60ef31a3ef2b209aad00764736f6c63430005100032` +const multiContBByteCode = `608060405234801561001057600080fd5b50610205806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063286d2e3a146100465780636cde00cd1461008a578063735b7e6f146100a8575b600080fd5b6100886004803603602081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100c6565b005b61009261010a565b6040518082815260200191505060405180910390f35b6100b06101ca565b6040518082815260200191505060405180910390f35b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349ec07186040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561017757600080fd5b505af115801561018b573d6000803e3d6000fd5b505050506040513d60208110156101a157600080fd5b810190808051906020019092919050505090508060008082825401925050819055508091505090565b6000548156fea265627a7a7231582082a5dbbf184a5c59907837a73f0ea2083719218b0bd60ef31a3ef2b209aad00764736f6c63430005100032` // pragma solidity ^0.5.16; // contract ContractC { @@ -78,4 +78,4 @@ const MultiContBByteCode = `608060405234801561001057600080fd5b506102058061002060 // return uint256(keccak256(abi.encode(block.timestamp, block.difficulty))) % 100; // } // } -const MultiContCByteCode = `608060405234801561001057600080fd5b50610143806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80631990ceb9146100465780633b3cf4e31461006457806349ec071814610082575b600080fd5b61004e6100a0565b6040518082815260200191505060405180910390f35b61006c6100e3565b6040518082815260200191505060405180910390f35b61008a6100e9565b6040518082815260200191505060405180910390f35b60006064424460405160200180838152602001828152602001925050506040516020818303038152906040528051906020012060001c816100dd57fe5b06905090565b60005481565b6000806100f46100a0565b90506000808154809291906001019190505550809150509056fea265627a7a72315820834484e13fa60ebe10a9d7102df12bafa8db4d9cdad5a38d2af6d360adc7ff4064736f6c63430005100032` +const multiContCByteCode = `608060405234801561001057600080fd5b50610143806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80631990ceb9146100465780633b3cf4e31461006457806349ec071814610082575b600080fd5b61004e6100a0565b6040518082815260200191505060405180910390f35b61006c6100e3565b6040518082815260200191505060405180910390f35b61008a6100e9565b6040518082815260200191505060405180910390f35b60006064424460405160200180838152602001828152602001925050506040516020818303038152906040528051906020012060001c816100dd57fe5b06905090565b60005481565b6000806100f46100a0565b90506000808154809291906001019190505550809150509056fea265627a7a72315820834484e13fa60ebe10a9d7102df12bafa8db4d9cdad5a38d2af6d360adc7ff4064736f6c63430005100032` diff --git a/benchmark/common/executors.go b/benchmark/executors.go similarity index 98% rename from benchmark/common/executors.go rename to benchmark/executors.go index c3dd1ce4c8..0fd55888c0 100644 --- a/benchmark/common/executors.go +++ b/benchmark/executors.go @@ -1,4 +1,4 @@ -package common +package benchmark import ( "sync" diff --git a/benchmark/common/helper.go b/benchmark/helper.go similarity index 69% rename from benchmark/common/helper.go rename to benchmark/helper.go index 1e9c5073ed..8fb8948895 100644 --- a/benchmark/common/helper.go +++ b/benchmark/helper.go @@ -1,4 +1,4 @@ -package common +package benchmark import ( "encoding/hex" @@ -12,8 +12,8 @@ import ( "github.com/umbracle/ethgo/wallet" ) -// DeployContractOnRootAndChild deploys contract code on both root and child chain -func DeployContractOnRootAndChild( +// deployContractOnRootAndChild deploys contract code on both root and child chain +func deployContractOnRootAndChild( b *testing.B, childTxRelayer txrelayer.TxRelayer, rootTxRelayer txrelayer.TxRelayer, @@ -26,16 +26,16 @@ func DeployContractOnRootAndChild( require.NoError(b, err) // deploy contract on the child chain - contractChildAddr := DeployContract(b, childTxRelayer, sender, byteCode) + contractChildAddr := deployContract(b, childTxRelayer, sender, byteCode) // deploy contract on the root chain - contractRootAddr := DeployContract(b, rootTxRelayer, sender, byteCode) + contractRootAddr := deployContract(b, rootTxRelayer, sender, byteCode) return contractChildAddr, contractRootAddr } -// DeployContract deploys contract code for the given relayer -func DeployContract(b *testing.B, txRelayer txrelayer.TxRelayer, sender ethgo.Key, byteCode []byte) ethgo.Address { +// deployContract deploys contract code for the given relayer +func deployContract(b *testing.B, txRelayer txrelayer.TxRelayer, sender ethgo.Key, byteCode []byte) ethgo.Address { b.Helper() txn := ðgo.Transaction{ @@ -51,13 +51,14 @@ func DeployContract(b *testing.B, txRelayer txrelayer.TxRelayer, sender ethgo.Ke return receipt.ContractAddress } -// GetTxInput returns input for sending tx, given the abi encoded method and call parameters -func GetTxInput(b *testing.B, method *abi.Method, args interface{}) []byte { +// getTxInput returns input for sending tx, given the abi encoded method and call parameters +func getTxInput(b *testing.B, method *abi.Method, args interface{}) []byte { b.Helper() - var input []byte - - var err error + var ( + input []byte + err error + ) if args != nil { input, err = method.Encode(args) @@ -70,12 +71,12 @@ func GetTxInput(b *testing.B, method *abi.Method, args interface{}) []byte { return input } -// SetContractDependencyAddress calls setContract function on caller contract, to set address of the callee contract -func SetContractDependencyAddress(b *testing.B, txRelayer txrelayer.TxRelayer, callerContractAddr ethgo.Address, +// setContractDependencyAddress calls setContract function on caller contract, to set address of the callee contract +func setContractDependencyAddress(b *testing.B, txRelayer txrelayer.TxRelayer, callerContractAddr ethgo.Address, calleeContractAddr ethgo.Address, setContractAbiMethod *abi.Method, sender ethgo.Key) { b.Helper() - input := GetTxInput(b, setContractAbiMethod, []interface{}{calleeContractAddr}) + input := getTxInput(b, setContractAbiMethod, []interface{}{calleeContractAddr}) receipt, err := txRelayer.SendTransaction( ðgo.Transaction{ To: &callerContractAddr, @@ -85,8 +86,8 @@ func SetContractDependencyAddress(b *testing.B, txRelayer txrelayer.TxRelayer, c require.Equal(b, uint64(types.ReceiptSuccess), receipt.Status) } -// GetPrivateKey initializes a private key from provided raw private key -func GetPrivateKey(b *testing.B, privateKeyRaw string) ethgo.Key { +// getPrivateKey initializes a private key from provided raw private key +func getPrivateKey(b *testing.B, privateKeyRaw string) ethgo.Key { b.Helper() dec, err := hex.DecodeString(privateKeyRaw) diff --git a/benchmark/root_child_send_tx.go b/benchmark/root_child_send_tx.go index bb829096df..3e8fca7a21 100644 --- a/benchmark/root_child_send_tx.go +++ b/benchmark/root_child_send_tx.go @@ -5,7 +5,6 @@ import ( "math/big" "testing" - "github.com/0xPolygon/polygon-edge/benchmark/common" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -26,9 +25,19 @@ var ( PrivateKey = flag.String("privateKey", "", "private key that will be used to send tx") ) -// RootChildSendTx deploys single and multi contracts to the root and child chain, execute tx from the -// test cases and measure its execution -func RootChildSendTx(b *testing.B) { +// The rootChildSendTx function executes test cases that measure transaction execution on both the root and child chains +// To do this, it first calls RootChildSendTxSetUp to set up the testing environment, +// which may include starting the cluster, deploying contracts, and building the test cases. +// After building the test cases, rootChildSendTx returns them along with a cleanup function that should be called +// after the test cases have been executed. The test cases are executed by the TxTestCasesExecutor. +// The rootJSONRPC, childJSONRPC, and privateKey flags are used to configure the testing environment. +// If all of these flags are set, then the local cluster will not be started and the provided addresses +// will be used as the endpoints to the root and child chains. +// If any of these flags is not set, the local cluster will be started automatically. +// If the private key is specified, it will be used as the transaction sender. +// Otherwise, the local cluster will generate a sender key. +// If the cluster is not run locally, then the sender must have enough funds for sending transactions. +func rootChildSendTx(b *testing.B) { b.Helper() // set up environment, get test cases and clean up fn testCases, cleanUpFn := RootChildSendTxSetUp(b) @@ -36,13 +45,13 @@ func RootChildSendTx(b *testing.B) { // Loop over the test cases and measure the execution time of the transactions for _, testInput := range testCases { - common.TxTestCasesExecutor(b, testInput) + TxTestCasesExecutor(b, testInput) } } // RootChildSendTxSetUp sets environment for execution of sentTx test cases on both root and child chains and // returns test cases and clean up fn -func RootChildSendTxSetUp(b *testing.B) ([]common.TxTestCase, func()) { +func RootChildSendTxSetUp(b *testing.B) ([]TxTestCase, func()) { b.Helper() // check if test is called with the root and child node addresses and private key set. // if that is the case use that json rpc addresses, otherwise run the cluster @@ -54,7 +63,7 @@ func RootChildSendTxSetUp(b *testing.B) ([]common.TxTestCase, func()) { var sender ethgo.Key // if the privateKey flag is set then recover the key, otherwise recover the key if privateKeyRaw != "" { - sender = common.GetPrivateKey(b, privateKeyRaw) + sender = getPrivateKey(b, privateKeyRaw) } else { var err error sender, err = wallet.GenerateKey() @@ -95,37 +104,37 @@ func RootChildSendTxSetUp(b *testing.B) ([]common.TxTestCase, func()) { } // deploy contracts - singleContChildAddr, singleContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, common.SingleContByteCode) - multiAContChildAddr, multiAContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, common.MultiContAByteCode) - multiBContChildAddr, multiBContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, common.MultiContBByteCode) - multiCContChildAddr, multiCContRootAddr := common.DeployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, common.MultiContCByteCode) + singleContChildAddr, singleContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, singleContByteCode) + multiAContChildAddr, multiAContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, multiContAByteCode) + multiBContChildAddr, multiBContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, multiContBByteCode) + multiCContChildAddr, multiCContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, + sender, multiContCByteCode) // set callee contract addresses for multi call contracts (A->B->C) // set B contract address in A contract - common.SetContractDependencyAddress(b, childTxRelayer, multiAContChildAddr, multiBContChildAddr, + setContractDependencyAddress(b, childTxRelayer, multiAContChildAddr, multiBContChildAddr, multiContSetAddrFunc, sender) - common.SetContractDependencyAddress(b, rootTxRelayer, multiAContRootAddr, multiBContRootAddr, + setContractDependencyAddress(b, rootTxRelayer, multiAContRootAddr, multiBContRootAddr, multiContSetAddrFunc, sender) // set C contract address in B contract - common.SetContractDependencyAddress(b, childTxRelayer, multiBContChildAddr, multiCContChildAddr, + setContractDependencyAddress(b, childTxRelayer, multiBContChildAddr, multiCContChildAddr, multiContSetAddrFunc, sender) - common.SetContractDependencyAddress(b, rootTxRelayer, multiBContRootAddr, multiCContRootAddr, + setContractDependencyAddress(b, rootTxRelayer, multiBContRootAddr, multiCContRootAddr, multiContSetAddrFunc, sender) // create inputs for contract calls singleContInputs := map[string][]byte{ - "calc": common.GetTxInput(b, singleContCalcFunc, []interface{}{big.NewInt(50), big.NewInt(150)}), - "set": common.GetTxInput(b, singleContSetFunc, []interface{}{big.NewInt(10)}), - "get": common.GetTxInput(b, singleContGetFunc, nil), + "calc": getTxInput(b, singleContCalcFunc, []interface{}{big.NewInt(50), big.NewInt(150)}), + "set": getTxInput(b, singleContSetFunc, []interface{}{big.NewInt(10)}), + "get": getTxInput(b, singleContGetFunc, nil), } - multiContInput := common.GetTxInput(b, multiContFnA, nil) + multiContInput := getTxInput(b, multiContFnA, nil) // test cases - testCases := []common.TxTestCase{ + testCases := []TxTestCase{ { Name: "[Child chain] setter 5tx", Relayer: childTxRelayer, diff --git a/command/benchmark/benchmark.go b/command/benchmark/benchmark.go index e52612c197..6240af2bb1 100644 --- a/command/benchmark/benchmark.go +++ b/command/benchmark/benchmark.go @@ -6,7 +6,6 @@ import ( "testing" "github.com/0xPolygon/polygon-edge/benchmark" - "github.com/0xPolygon/polygon-edge/benchmark/common" "github.com/0xPolygon/polygon-edge/command" "github.com/spf13/cobra" ) @@ -65,7 +64,7 @@ func runCommand(cmd *cobra.Command, _ []string) { for _, testInput := range testCases { sendTxResult := testing.Benchmark(func(b *testing.B) { b.Helper() - common.TxTestCasesExecutor(b, testInput) + benchmark.TxTestCasesExecutor(b, testInput) }) benchmarkResult := &benchmarkResult{ name: testInput.Name, @@ -101,11 +100,6 @@ func setFlags(cmd *cobra.Command) { _ = cmd.MarkFlagRequired(privateKeyFlag) } -func (p *benchmarkParams) validateFlags() error { - // add addresses and key validation - return nil -} - func (br *benchmarkResult) GetOutput() string { var buffer bytes.Buffer From 6e075ab922f3e1e3e3ccc3334b2404c26a0af4b7 Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Tue, 16 May 2023 18:34:25 +0200 Subject: [PATCH 3/7] cr fix - introduce startCluster flag --- benchmark/root_child_send_tx.go | 12 +++++++----- command/benchmark/benchmark.go | 26 +++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/benchmark/root_child_send_tx.go b/benchmark/root_child_send_tx.go index 3e8fca7a21..d9de979972 100644 --- a/benchmark/root_child_send_tx.go +++ b/benchmark/root_child_send_tx.go @@ -23,6 +23,7 @@ var ( RootJSONRPC = flag.String("rootJSONRPC", "", "JSONRPC address of the root node") ChildJSONRPC = flag.String("childJSONRPC", "", "JSONRPC address of the child node") PrivateKey = flag.String("privateKey", "", "private key that will be used to send tx") + StartCluster = flag.Bool("startCluster", true, "starts the cluster if sets to true") ) // The rootChildSendTx function executes test cases that measure transaction execution on both the root and child chains @@ -30,13 +31,13 @@ var ( // which may include starting the cluster, deploying contracts, and building the test cases. // After building the test cases, rootChildSendTx returns them along with a cleanup function that should be called // after the test cases have been executed. The test cases are executed by the TxTestCasesExecutor. -// The rootJSONRPC, childJSONRPC, and privateKey flags are used to configure the testing environment. -// If all of these flags are set, then the local cluster will not be started and the provided addresses +// The rootJSONRPC, childJSONRPC, privateKey and startCluster flags are used to configure the testing environment. +// If startCluster is false, then the local cluster will not be started and the provided addresses // will be used as the endpoints to the root and child chains. -// If any of these flags is not set, the local cluster will be started automatically. +// If startCluster is set to true, the local cluster will be started automatically. // If the private key is specified, it will be used as the transaction sender. // Otherwise, the local cluster will generate a sender key. -// If the cluster is not run locally, then the sender must have enough funds for sending transactions. +// If startCluster is set to false, then the sender must have enough funds for sending transactions. func rootChildSendTx(b *testing.B) { b.Helper() // set up environment, get test cases and clean up fn @@ -58,7 +59,8 @@ func RootChildSendTxSetUp(b *testing.B) ([]TxTestCase, func()) { rootNodeAddr := *RootJSONRPC childNodeAddr := *ChildJSONRPC privateKeyRaw := *PrivateKey - startCluster := rootNodeAddr == "" || childNodeAddr == "" || privateKeyRaw == "" + startCluster := *StartCluster + require.True(b, startCluster || rootNodeAddr != "" && childNodeAddr != "" && privateKeyRaw != "") var sender ethgo.Key // if the privateKey flag is set then recover the key, otherwise recover the key diff --git a/command/benchmark/benchmark.go b/command/benchmark/benchmark.go index 6240af2bb1..0f806bf997 100644 --- a/command/benchmark/benchmark.go +++ b/command/benchmark/benchmark.go @@ -2,6 +2,7 @@ package benchmark import ( "bytes" + "errors" "fmt" "testing" @@ -14,12 +15,14 @@ const ( rootJSONRPCFlag = "rootJSONRPC" childJSONRPCFlag = "childJSONRPC" privateKeyFlag = "privateKey" + startClusterFlag = "startCluster" ) type benchmarkParams struct { rootJSONRPC string childJSONRPC string privateKey string + startCluster bool } type benchmarkResult struct { @@ -36,6 +39,7 @@ func GetCommand() *cobra.Command { Use: "benchmark-test", Short: "Run benchmark tests", Example: getCmdExample(), + PreRunE: preRunCommand, Run: runCommand, } @@ -55,6 +59,7 @@ func runCommand(cmd *cobra.Command, _ []string) { benchmark.RootJSONRPC = ¶ms.rootJSONRPC benchmark.ChildJSONRPC = ¶ms.childJSONRPC benchmark.PrivateKey = ¶ms.privateKey + benchmark.StartCluster = ¶ms.startCluster // set up environment, get test cases and clean up fn testCases, cleanUpFn := benchmark.RootChildSendTxSetUp(&testing.B{}) @@ -94,10 +99,15 @@ func setFlags(cmd *cobra.Command) { "", "private key that will be used to send tx (it is expected that this address has enough funds)", ) + cmd.Flags().BoolVar( + ¶ms.startCluster, + startClusterFlag, + false, + "startCluster tells if the local cluster should be started", + ) - _ = cmd.MarkFlagRequired(rootJSONRPCFlag) - _ = cmd.MarkFlagRequired(childJSONRPCFlag) - _ = cmd.MarkFlagRequired(privateKeyFlag) + cmd.MarkFlagsMutuallyExclusive(startClusterFlag, rootJSONRPCFlag) + cmd.MarkFlagsMutuallyExclusive(startClusterFlag, childJSONRPCFlag) } func (br *benchmarkResult) GetOutput() string { @@ -113,3 +123,13 @@ func getCmdExample() string { "--childJSONRPC=\"http://127.0.0.1:12001\"", "--rootJSONRPC=\"http://127.0.0.1:8545\"", "--privateKey=\"aa75e9a7d427efc732f8e4f1a5b7646adcc61fd5bae40f80d13c8419c9f43d6d\"") } + +func preRunCommand(_ *cobra.Command, _ []string) error { + if !params.startCluster { + if params.rootJSONRPC == "" || params.childJSONRPC == "" || params.privateKey == "" { + return errors.New("if startCluster is not set then rootJSONRPC, childJSONRPC and privateKey must be set") + } + } + + return nil +} From 99efd02febfbca7286cd7e470e43ef3777880722 Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Wed, 17 May 2023 11:01:27 +0200 Subject: [PATCH 4/7] cr fix - move contract codes to contractsapi --- benchmark/contract_codes.go | 81 ------------------- benchmark/helper.go | 6 +- benchmark/root_child_send_tx.go | 9 ++- consensus/polybft/contractsapi/init.go | 24 ++++++ .../test-contracts/ITestBenchmarkB.json | 24 ++++++ .../test-contracts/ITestBenchmarkC.json | 24 ++++++ .../test-contracts/TestBenchmarkA.json | 37 +++++++++ .../test-contracts/TestBenchmarkA.sol | 18 +++++ .../test-contracts/TestBenchmarkB.json | 50 ++++++++++++ .../test-contracts/TestBenchmarkB.sol | 20 +++++ .../test-contracts/TestBenchmarkC.json | 50 ++++++++++++ .../test-contracts/TestBenchmarkC.sol | 15 ++++ .../test-contracts/TestBenchmarkSingle.json | 61 ++++++++++++++ .../test-contracts/TestBenchmarkSingle.sol | 22 +++++ 14 files changed, 351 insertions(+), 90 deletions(-) delete mode 100644 benchmark/contract_codes.go create mode 100644 consensus/polybft/contractsapi/test-contracts/ITestBenchmarkB.json create mode 100644 consensus/polybft/contractsapi/test-contracts/ITestBenchmarkC.json create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.json create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.sol create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.json create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.sol create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.json create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.sol create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.json create mode 100644 consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.sol diff --git a/benchmark/contract_codes.go b/benchmark/contract_codes.go deleted file mode 100644 index 8a567032a6..0000000000 --- a/benchmark/contract_codes.go +++ /dev/null @@ -1,81 +0,0 @@ -//nolint:lll -package benchmark - -// pragma solidity ^0.5.16; - -// contract SingleCallContract { -// uint256[] private val; - -// function addValue(uint256 value) public { -// val.push(value); -// } - -// function getValue() public view returns (uint256[] memory) { -// return val; -// } - -// function compute(uint256 x, uint256 y) public pure returns (uint256) { -// uint256 result = x + y; -// for (uint256 i = 0; i < 10; i++) { -// result = result * 2; -// } -// return result; -// } -// } -const singleContByteCode = `608060405234801561001057600080fd5b50610210806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806320965255146100465780635b9af12b146100a55780637a85644b146100d3575b600080fd5b61004e61011f565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610091578082015181840152602081019050610076565b505050509050019250505060405180910390f35b6100d1600480360360208110156100bb57600080fd5b8101908080359060200190929190505050610177565b005b610109600480360360408110156100e957600080fd5b8101908080359060200190929190803590602001909291905050506101a6565b6040518082815260200191505060405180910390f35b6060600080548060200260200160405190810160405280929190818152602001828054801561016d57602002820191906000526020600020905b815481526020019060010190808311610159575b5050505050905090565b600081908060018154018082558091505090600182039060005260206000200160009091929091909150555050565b600080828401905060008090505b600a8110156101d05760028202915080806001019150506101b4565b50809150509291505056fea265627a7a72315820ec23cf989c20e0d41d7819001da6dfe6cc129988f15cd8a7b79595a2e61a93d264736f6c63430005100032` - -//MULTI CONTRACTS CALL: A->B->C - -// pragma solidity ^0.5.16; -// interface IContractB { -// function fnB() external returns (uint256); -// } -// contract ContractA { -// address contractAddr; -// -// function setContractAddr(address _contract) public { -// contractAddr = _contract; -// } - -// function fnA() public returns (uint256) { -// uint256 valB = IContractB(contractAddr).fnB(); -// return valB; -// } -// } -const multiContAByteCode = `608060405234801561001057600080fd5b506101c5806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063286d2e3a1461003b57806368685ad31461007f575b600080fd5b61007d6004803603602081101561005157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061009d565b005b6100876100e0565b6040518082815260200191505060405180910390f35b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636cde00cd6040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561014c57600080fd5b505af1158015610160573d6000803e3d6000fd5b505050506040513d602081101561017657600080fd5b81019080805190602001909291905050509050809150509056fea265627a7a7231582082d7a079b4ea6bcf371ef0665da89a56bd53bdc82ae90daa9dd21b61fc6c115864736f6c63430005100032` - -// pragma solidity ^0.5.16; -// interface IContractC { -// function fnC1() external returns (uint256); -// } -// contract ContractB { -// uint256 public valB; -// address contractAddr; - -// function setContractAddr(address _contract) public { -// contractAddr = _contract; -// } - -// function fnB() external returns (uint256) { -// uint256 valC = IContractC(contractAddr).fnC1(); -// valB += valC; -// return valC; -// } - -// } -const multiContBByteCode = `608060405234801561001057600080fd5b50610205806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063286d2e3a146100465780636cde00cd1461008a578063735b7e6f146100a8575b600080fd5b6100886004803603602081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506100c6565b005b61009261010a565b6040518082815260200191505060405180910390f35b6100b06101ca565b6040518082815260200191505060405180910390f35b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166349ec07186040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561017757600080fd5b505af115801561018b573d6000803e3d6000fd5b505050506040513d60208110156101a157600080fd5b810190808051906020019092919050505090508060008082825401925050819055508091505090565b6000548156fea265627a7a7231582082a5dbbf184a5c59907837a73f0ea2083719218b0bd60ef31a3ef2b209aad00764736f6c63430005100032` - -// pragma solidity ^0.5.16; -// contract ContractC { -// uint256 public valC; -// function fnC1() external returns (uint256) { -// uint256 valC2 = fnC2(); -// valC++; -// return valC2; -// } - -// function fnC2() public view returns (uint256) { -// return uint256(keccak256(abi.encode(block.timestamp, block.difficulty))) % 100; -// } -// } -const multiContCByteCode = `608060405234801561001057600080fd5b50610143806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80631990ceb9146100465780633b3cf4e31461006457806349ec071814610082575b600080fd5b61004e6100a0565b6040518082815260200191505060405180910390f35b61006c6100e3565b6040518082815260200191505060405180910390f35b61008a6100e9565b6040518082815260200191505060405180910390f35b60006064424460405160200180838152602001828152602001925050506040516020818303038152906040528051906020012060001c816100dd57fe5b06905090565b60005481565b6000806100f46100a0565b90506000808154809291906001019190505550809150509056fea265627a7a72315820834484e13fa60ebe10a9d7102df12bafa8db4d9cdad5a38d2af6d360adc7ff4064736f6c63430005100032` diff --git a/benchmark/helper.go b/benchmark/helper.go index 8fb8948895..00ed724a64 100644 --- a/benchmark/helper.go +++ b/benchmark/helper.go @@ -18,13 +18,9 @@ func deployContractOnRootAndChild( childTxRelayer txrelayer.TxRelayer, rootTxRelayer txrelayer.TxRelayer, sender ethgo.Key, - byteCodeString string) (ethgo.Address, ethgo.Address) { + byteCode []byte) (ethgo.Address, ethgo.Address) { b.Helper() - // bytecode from string - byteCode, err := hex.DecodeString(byteCodeString) - require.NoError(b, err) - // deploy contract on the child chain contractChildAddr := deployContract(b, childTxRelayer, sender, byteCode) diff --git a/benchmark/root_child_send_tx.go b/benchmark/root_child_send_tx.go index d9de979972..adbc4fcfc8 100644 --- a/benchmark/root_child_send_tx.go +++ b/benchmark/root_child_send_tx.go @@ -5,6 +5,7 @@ import ( "math/big" "testing" + "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" @@ -107,13 +108,13 @@ func RootChildSendTxSetUp(b *testing.B) ([]TxTestCase, func()) { // deploy contracts singleContChildAddr, singleContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, singleContByteCode) + sender, contractsapi.TestBenchmarkSingle.Bytecode) multiAContChildAddr, multiAContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, multiContAByteCode) + sender, contractsapi.TestBenchmarkA.Bytecode) multiBContChildAddr, multiBContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, multiContBByteCode) + sender, contractsapi.TestBenchmarkB.Bytecode) multiCContChildAddr, multiCContRootAddr := deployContractOnRootAndChild(b, childTxRelayer, rootTxRelayer, - sender, multiContCByteCode) + sender, contractsapi.TestBenchmarkC.Bytecode) // set callee contract addresses for multi call contracts (A->B->C) // set B contract address in A contract diff --git a/consensus/polybft/contractsapi/init.go b/consensus/polybft/contractsapi/init.go index 7ec7a977bb..fb2e967076 100644 --- a/consensus/polybft/contractsapi/init.go +++ b/consensus/polybft/contractsapi/init.go @@ -52,6 +52,10 @@ var ( RootERC20 *artifact.Artifact TestSimple *artifact.Artifact TestRewardToken *artifact.Artifact + TestBenchmarkA *artifact.Artifact + TestBenchmarkB *artifact.Artifact + TestBenchmarkC *artifact.Artifact + TestBenchmarkSingle *artifact.Artifact ) func init() { @@ -202,6 +206,26 @@ func init() { log.Fatal(err) } + TestBenchmarkA, err = artifact.DecodeArtifact(readTestContractContent("TestBenchmarkA.json")) + if err != nil { + log.Fatal(err) + } + + TestBenchmarkB, err = artifact.DecodeArtifact(readTestContractContent("TestBenchmarkB.json")) + if err != nil { + log.Fatal(err) + } + + TestBenchmarkC, err = artifact.DecodeArtifact(readTestContractContent("TestBenchmarkC.json")) + if err != nil { + log.Fatal(err) + } + + TestBenchmarkSingle, err = artifact.DecodeArtifact(readTestContractContent("TestBenchmarkSingle.json")) + if err != nil { + log.Fatal(err) + } + CustomSupernetManager, err = artifact.DecodeArtifact([]byte(CustomSupernetManagerArtifact)) if err != nil { log.Fatal(err) diff --git a/consensus/polybft/contractsapi/test-contracts/ITestBenchmarkB.json b/consensus/polybft/contractsapi/test-contracts/ITestBenchmarkB.json new file mode 100644 index 0000000000..1c8f393171 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/ITestBenchmarkB.json @@ -0,0 +1,24 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ITestBenchmarkB", + "sourceName": "contracts/test/TestBenchmarkA.sol", + "abi": [ + { + "inputs": [], + "name": "fnB", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/ITestBenchmarkC.json b/consensus/polybft/contractsapi/test-contracts/ITestBenchmarkC.json new file mode 100644 index 0000000000..9ec29ff956 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/ITestBenchmarkC.json @@ -0,0 +1,24 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ITestBenchmarkC", + "sourceName": "contracts/test/TestBenchmarkB.sol", + "abi": [ + { + "inputs": [], + "name": "fnC1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x", + "deployedBytecode": "0x", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.json b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.json new file mode 100644 index 0000000000..3207437512 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.json @@ -0,0 +1,37 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TestBenchmarkA", + "sourceName": "contracts/test/TestBenchmarkA.sol", + "abi": [ + { + "inputs": [], + "name": "fnA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "setContractAddr", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5061017b806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063286d2e3a1461003b57806368685ad31461006d575b600080fd5b61006b6100493660046100fc565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b005b610075610087565b60405190815260200160405180910390f35b6000805460408051636cde00cd60e01b8152905183926001600160a01b031691636cde00cd916004808301926020929190829003018187875af11580156100d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f6919061012c565b92915050565b60006020828403121561010e57600080fd5b81356001600160a01b038116811461012557600080fd5b9392505050565b60006020828403121561013e57600080fd5b505191905056fea2646970667358221220a8ce85649b9a1ab453ecb852ac36c64f7be380547a5cf2faf83ffdbb59b6424464736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063286d2e3a1461003b57806368685ad31461006d575b600080fd5b61006b6100493660046100fc565b600080546001600160a01b0319166001600160a01b0392909216919091179055565b005b610075610087565b60405190815260200160405180910390f35b6000805460408051636cde00cd60e01b8152905183926001600160a01b031691636cde00cd916004808301926020929190829003018187875af11580156100d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f6919061012c565b92915050565b60006020828403121561010e57600080fd5b81356001600160a01b038116811461012557600080fd5b9392505050565b60006020828403121561013e57600080fd5b505191905056fea2646970667358221220a8ce85649b9a1ab453ecb852ac36c64f7be380547a5cf2faf83ffdbb59b6424464736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.sol b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.sol new file mode 100644 index 0000000000..aade227025 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkA.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +interface ITestBenchmarkB { + function fnB() external returns (uint256); +} +contract TestBenchmarkA { + address contractAddr; + + function setContractAddr(address _contract) public { + contractAddr = _contract; + } + + function fnA() public returns (uint256) { + uint256 valB = ITestBenchmarkB(contractAddr).fnB(); + return valB; + } + } \ No newline at end of file diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.json b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.json new file mode 100644 index 0000000000..a5c9e28157 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.json @@ -0,0 +1,50 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TestBenchmarkB", + "sourceName": "contracts/test/TestBenchmarkB.sol", + "abi": [ + { + "inputs": [], + "name": "fnB", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_contract", + "type": "address" + } + ], + "name": "setContractAddr", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "valB", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b506101db806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063286d2e3a146100465780636cde00cd14610078578063735b7e6f14610092575b600080fd5b610076610054366004610135565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b005b61008061009b565b60405190815260200160405180910390f35b61008060005481565b600080600160009054906101000a90046001600160a01b03166001600160a01b03166349ec07186040518163ffffffff1660e01b81526004016020604051808303816000875af11580156100f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101179190610165565b90508060008082825461012a919061017e565b909155509092915050565b60006020828403121561014757600080fd5b81356001600160a01b038116811461015e57600080fd5b9392505050565b60006020828403121561017757600080fd5b5051919050565b8082018082111561019f57634e487b7160e01b600052601160045260246000fd5b9291505056fea26469706673582212209f01d2971a8238a2a1c208a8dde49ecc84579475e54782314375cb36d1bf60ea64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c8063286d2e3a146100465780636cde00cd14610078578063735b7e6f14610092575b600080fd5b610076610054366004610135565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b005b61008061009b565b60405190815260200160405180910390f35b61008060005481565b600080600160009054906101000a90046001600160a01b03166001600160a01b03166349ec07186040518163ffffffff1660e01b81526004016020604051808303816000875af11580156100f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101179190610165565b90508060008082825461012a919061017e565b909155509092915050565b60006020828403121561014757600080fd5b81356001600160a01b038116811461015e57600080fd5b9392505050565b60006020828403121561017757600080fd5b5051919050565b8082018082111561019f57634e487b7160e01b600052601160045260246000fd5b9291505056fea26469706673582212209f01d2971a8238a2a1c208a8dde49ecc84579475e54782314375cb36d1bf60ea64736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.sol b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.sol new file mode 100644 index 0000000000..d4b033f43c --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkB.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +interface ITestBenchmarkC { + function fnC1() external returns (uint256); +} +contract TestBenchmarkB { + uint256 public valB; + address contractAddr; + + function setContractAddr(address _contract) public { + contractAddr = _contract; + } + + function fnB() external returns (uint256) { + uint256 valC = ITestBenchmarkC(contractAddr).fnC1(); + valB += valC; + return valC; + } +} \ No newline at end of file diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.json b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.json new file mode 100644 index 0000000000..8830848643 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.json @@ -0,0 +1,50 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TestBenchmarkC", + "sourceName": "contracts/test/TestBenchmarkC.sol", + "abi": [ + { + "inputs": [], + "name": "fnC1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "fnC2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "valC", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5061015f806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80631990ceb9146100465780633b3cf4e31461006057806349ec071814610069575b600080fd5b61004e610071565b60405190815260200160405180910390f35b61004e60005481565b61004e6100b9565b600060644244604051602001610091929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c6100b491906100e0565b905090565b6000806100c4610071565b60008054919250806100d583610102565b909155509092915050565b6000826100fd57634e487b7160e01b600052601260045260246000fd5b500690565b60006001820161012257634e487b7160e01b600052601160045260246000fd5b506001019056fea264697066735822122092ffbbf005793faaa839fdfd4e894697301342a305e3e8734927815308198d7964736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c80631990ceb9146100465780633b3cf4e31461006057806349ec071814610069575b600080fd5b61004e610071565b60405190815260200160405180910390f35b61004e60005481565b61004e6100b9565b600060644244604051602001610091929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c6100b491906100e0565b905090565b6000806100c4610071565b60008054919250806100d583610102565b909155509092915050565b6000826100fd57634e487b7160e01b600052601260045260246000fd5b500690565b60006001820161012257634e487b7160e01b600052601160045260246000fd5b506001019056fea264697066735822122092ffbbf005793faaa839fdfd4e894697301342a305e3e8734927815308198d7964736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.sol b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.sol new file mode 100644 index 0000000000..0203ed2de9 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkC.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +contract TestBenchmarkC { + uint256 public valC; + function fnC1() external returns (uint256) { + uint256 valC2 = fnC2(); + valC++; + return valC2; + } + + function fnC2() public view returns (uint256) { + return uint256(keccak256(abi.encode(block.timestamp, block.difficulty))) % 100; + } +} \ No newline at end of file diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.json b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.json new file mode 100644 index 0000000000..ba764ff24f --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.json @@ -0,0 +1,61 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "TestBenchmarkSingle", + "sourceName": "contracts/test/TestBenchmarkSingle.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "addValue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "name": "compute", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getValue", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50610271806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806320965255146100465780635b9af12b146100645780637a85644b146100a6575b600080fd5b61004e6100c7565b60405161005b9190610163565b60405180910390f35b6100a46100723660046101a7565b600080546001810182559080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5630155565b005b6100b96100b43660046101c0565b61011f565b60405190815260200161005b565b6060600080548060200260200160405190810160405280929190818152602001828054801561011557602002820191906000526020600020905b815481526020019060010190808311610101575b5050505050905090565b60008061012c83856101f8565b905060005b600a8110156101595761014582600261020b565b91508061015181610222565b915050610131565b5090505b92915050565b6020808252825182820181905260009190848201906040850190845b8181101561019b5783518352928401929184019160010161017f565b50909695505050505050565b6000602082840312156101b957600080fd5b5035919050565b600080604083850312156101d357600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b8082018082111561015d5761015d6101e2565b808202811582820484141761015d5761015d6101e2565b600060018201610234576102346101e2565b506001019056fea2646970667358221220c572f74159ad307792361021be5daa28297e481a4cac587b5b311e5679e9d9da64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806320965255146100465780635b9af12b146100645780637a85644b146100a6575b600080fd5b61004e6100c7565b60405161005b9190610163565b60405180910390f35b6100a46100723660046101a7565b600080546001810182559080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5630155565b005b6100b96100b43660046101c0565b61011f565b60405190815260200161005b565b6060600080548060200260200160405190810160405280929190818152602001828054801561011557602002820191906000526020600020905b815481526020019060010190808311610101575b5050505050905090565b60008061012c83856101f8565b905060005b600a8110156101595761014582600261020b565b91508061015181610222565b915050610131565b5090505b92915050565b6020808252825182820181905260009190848201906040850190845b8181101561019b5783518352928401929184019160010161017f565b50909695505050505050565b6000602082840312156101b957600080fd5b5035919050565b600080604083850312156101d357600080fd5b50508035926020909101359150565b634e487b7160e01b600052601160045260246000fd5b8082018082111561015d5761015d6101e2565b808202811582820484141761015d5761015d6101e2565b600060018201610234576102346101e2565b506001019056fea2646970667358221220c572f74159ad307792361021be5daa28297e481a4cac587b5b311e5679e9d9da64736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.sol b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.sol new file mode 100644 index 0000000000..432f7990e6 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/TestBenchmarkSingle.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +contract TestBenchmarkSingle { + uint256[] private val; + + function addValue(uint256 value) public { + val.push(value); + } + + function getValue() public view returns (uint256[] memory) { + return val; + } + + function compute(uint256 x, uint256 y) public pure returns (uint256) { + uint256 result = x + y; + for (uint256 i = 0; i < 10; i++) { + result = result * 2; + } + return result; + } + } \ No newline at end of file From 38bc3ceaa04c502d3e965a22feac658b271e40d9 Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Wed, 17 May 2023 11:27:33 +0200 Subject: [PATCH 5/7] cr fix - remove flags from test --- benchmark/root_child_send_tx.go | 36 +++++++++++++-------------------- command/benchmark/benchmark.go | 14 ++++++------- 2 files changed, 21 insertions(+), 29 deletions(-) diff --git a/benchmark/root_child_send_tx.go b/benchmark/root_child_send_tx.go index adbc4fcfc8..ab1fc848a5 100644 --- a/benchmark/root_child_send_tx.go +++ b/benchmark/root_child_send_tx.go @@ -1,7 +1,6 @@ package benchmark import ( - "flag" "math/big" "testing" @@ -21,10 +20,6 @@ var ( singleContSetFunc = abi.MustNewMethod("function addValue(uint256 value) public") multiContSetAddrFunc = abi.MustNewMethod("function setContractAddr(address _contract) public") multiContFnA = abi.MustNewMethod("function fnA() public returns (uint256)") - RootJSONRPC = flag.String("rootJSONRPC", "", "JSONRPC address of the root node") - ChildJSONRPC = flag.String("childJSONRPC", "", "JSONRPC address of the child node") - PrivateKey = flag.String("privateKey", "", "private key that will be used to send tx") - StartCluster = flag.Bool("startCluster", true, "starts the cluster if sets to true") ) // The rootChildSendTx function executes test cases that measure transaction execution on both the root and child chains @@ -32,17 +27,10 @@ var ( // which may include starting the cluster, deploying contracts, and building the test cases. // After building the test cases, rootChildSendTx returns them along with a cleanup function that should be called // after the test cases have been executed. The test cases are executed by the TxTestCasesExecutor. -// The rootJSONRPC, childJSONRPC, privateKey and startCluster flags are used to configure the testing environment. -// If startCluster is false, then the local cluster will not be started and the provided addresses -// will be used as the endpoints to the root and child chains. -// If startCluster is set to true, the local cluster will be started automatically. -// If the private key is specified, it will be used as the transaction sender. -// Otherwise, the local cluster will generate a sender key. -// If startCluster is set to false, then the sender must have enough funds for sending transactions. func rootChildSendTx(b *testing.B) { b.Helper() // set up environment, get test cases and clean up fn - testCases, cleanUpFn := RootChildSendTxSetUp(b) + testCases, cleanUpFn := RootChildSendTxSetUp(b, "", "", "", true) defer cleanUpFn() // Loop over the test cases and measure the execution time of the transactions @@ -52,21 +40,25 @@ func rootChildSendTx(b *testing.B) { } // RootChildSendTxSetUp sets environment for execution of sentTx test cases on both root and child chains and -// returns test cases and clean up fn -func RootChildSendTxSetUp(b *testing.B) ([]TxTestCase, func()) { +// returns test cases and clean up fn. +// The rootJSONRPC, childJSONRPC, privateKey and startCluster params are used to configure the testing environment. +// If startCluster is false, then the local cluster will not be started and the provided addresses +// will be used as the endpoints to the root and child chains. +// If startCluster is set to true, the local cluster will be started automatically. +// If the private key is specified, it will be used as the transaction sender. +// Otherwise, the local cluster will generate a sender key. +// If startCluster is set to false, then the sender must have enough funds for sending transactions. +func RootChildSendTxSetUp(b *testing.B, rootNodeAddr, childNodeAddr, + privateKey string, startCluster bool) ([]TxTestCase, func()) { b.Helper() // check if test is called with the root and child node addresses and private key set. // if that is the case use that json rpc addresses, otherwise run the cluster - rootNodeAddr := *RootJSONRPC - childNodeAddr := *ChildJSONRPC - privateKeyRaw := *PrivateKey - startCluster := *StartCluster - require.True(b, startCluster || rootNodeAddr != "" && childNodeAddr != "" && privateKeyRaw != "") + require.True(b, startCluster || rootNodeAddr != "" && childNodeAddr != "" && privateKey != "") var sender ethgo.Key // if the privateKey flag is set then recover the key, otherwise recover the key - if privateKeyRaw != "" { - sender = getPrivateKey(b, privateKeyRaw) + if privateKey != "" { + sender = getPrivateKey(b, privateKey) } else { var err error sender, err = wallet.GenerateKey() diff --git a/command/benchmark/benchmark.go b/command/benchmark/benchmark.go index 0f806bf997..7bdfd1c508 100644 --- a/command/benchmark/benchmark.go +++ b/command/benchmark/benchmark.go @@ -55,14 +55,14 @@ func runCommand(cmd *cobra.Command, _ []string) { // set up the testing environment testing.Init() - // set testing params - benchmark.RootJSONRPC = ¶ms.rootJSONRPC - benchmark.ChildJSONRPC = ¶ms.childJSONRPC - benchmark.PrivateKey = ¶ms.privateKey - benchmark.StartCluster = ¶ms.startCluster - // set up environment, get test cases and clean up fn - testCases, cleanUpFn := benchmark.RootChildSendTxSetUp(&testing.B{}) + testCases, cleanUpFn := benchmark.RootChildSendTxSetUp( + &testing.B{}, + params.rootJSONRPC, + params.childJSONRPC, + params.privateKey, + params.startCluster, + ) defer cleanUpFn() // Loop over the test cases and call the benchmark test From 70b0df9318c68e34ea6b09931859089dbd7a4100 Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Mon, 29 May 2023 15:40:46 +0200 Subject: [PATCH 6/7] add transition benchmark test --- benchmark/benchmark_test.go | 10 -- benchmark/executors.go | 61 -------- benchmark/helper.go | 96 ++++++++++++ benchmark/root_child_benchmark_test.go | 21 +++ benchmark/root_child_send_tx.go | 110 ++++++++++---- benchmark/transition_benchmark_test.go | 112 ++++++++++++++ consensus/polybft/contractsapi/init.go | 6 + .../test-contracts/SampleContract.json | 138 ++++++++++++++++++ .../test-contracts/SampleContract.sol | 40 +++++ 9 files changed, 493 insertions(+), 101 deletions(-) delete mode 100644 benchmark/benchmark_test.go delete mode 100644 benchmark/executors.go create mode 100644 benchmark/root_child_benchmark_test.go create mode 100644 benchmark/transition_benchmark_test.go create mode 100644 consensus/polybft/contractsapi/test-contracts/SampleContract.json create mode 100644 consensus/polybft/contractsapi/test-contracts/SampleContract.sol diff --git a/benchmark/benchmark_test.go b/benchmark/benchmark_test.go deleted file mode 100644 index 725bafafac..0000000000 --- a/benchmark/benchmark_test.go +++ /dev/null @@ -1,10 +0,0 @@ -package benchmark - -import ( - "testing" -) - -func Benchmark_RunTests(b *testing.B) { - // benchmark tests - rootChildSendTx(b) -} diff --git a/benchmark/executors.go b/benchmark/executors.go deleted file mode 100644 index 0fd55888c0..0000000000 --- a/benchmark/executors.go +++ /dev/null @@ -1,61 +0,0 @@ -package benchmark - -import ( - "sync" - "testing" - - "github.com/0xPolygon/polygon-edge/txrelayer" - "github.com/0xPolygon/polygon-edge/types" - "github.com/stretchr/testify/require" - "github.com/umbracle/ethgo" -) - -// TxTestCase represents a test case data to be run with txTestCasesExecutor -type TxTestCase struct { - Name string - Relayer txrelayer.TxRelayer - ContractAddr ethgo.Address - Input [][]byte - Sender ethgo.Key - TxNumber int -} - -// TxTestCasesExecutor executes transactions from testInput and waits in separate -// go routins for each tx receipt -func TxTestCasesExecutor(b *testing.B, testInput TxTestCase) { - b.Helper() - b.Run(testInput.Name, func(b *testing.B) { - b.ReportAllocs() - b.ResetTimer() - var wg sync.WaitGroup - - // submit all tx 'repeatCall' times - for i := 0; i < testInput.TxNumber; i++ { - // call contract for the all inputs - for j := 0; j < len(testInput.Input); j++ { - // the tx is submitted to the blockchain without waiting for the receipt, - // since we want to have multiple tx in one block - txHash, err := testInput.Relayer.SumbitTransaction( - ðgo.Transaction{ - To: &testInput.ContractAddr, - Input: testInput.Input[j], - }, testInput.Sender) - require.NoError(b, err) - require.NotEqual(b, ethgo.ZeroHash, txHash) - - wg.Add(1) - - // wait for receipt of submitted tx in a separate routine, and continue with the next tx - func(hash ethgo.Hash) { - defer wg.Done() - - receipt, err := testInput.Relayer.WaitForReceipt(hash) - require.NoError(b, err) - require.Equal(b, uint64(types.ReceiptSuccess), receipt.Status) - }(txHash) - } - } - - wg.Wait() - }) -} diff --git a/benchmark/helper.go b/benchmark/helper.go index 00ed724a64..9656316de2 100644 --- a/benchmark/helper.go +++ b/benchmark/helper.go @@ -2,16 +2,34 @@ package benchmark import ( "encoding/hex" + "math/big" + "os" + "path/filepath" "testing" + "github.com/0xPolygon/polygon-edge/chain" + "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" + "github.com/0xPolygon/polygon-edge/state" + itrie "github.com/0xPolygon/polygon-edge/state/immutable-trie" + "github.com/0xPolygon/polygon-edge/state/runtime" "github.com/0xPolygon/polygon-edge/txrelayer" "github.com/0xPolygon/polygon-edge/types" + "github.com/hashicorp/go-hclog" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" "github.com/umbracle/ethgo/abi" "github.com/umbracle/ethgo/wallet" ) +var ( + singleContCalcFunc = contractsapi.TestBenchmarkSingle.Abi.Methods["compute"] + singleContGetFunc = contractsapi.TestBenchmarkSingle.Abi.Methods["getValue"] + singleContSetFunc = contractsapi.TestBenchmarkSingle.Abi.Methods["addValue"] + multiContSetAAddrFunc = contractsapi.TestBenchmarkA.Abi.Methods["setContractAddr"] + multiContSetBAddrFunc = contractsapi.TestBenchmarkA.Abi.Methods["setContractAddr"] + multiContFnA = contractsapi.TestBenchmarkA.Abi.Methods["fnA"] +) + // deployContractOnRootAndChild deploys contract code on both root and child chain func deployContractOnRootAndChild( b *testing.B, @@ -94,3 +112,81 @@ func getPrivateKey(b *testing.B, privateKeyRaw string) ethgo.Key { return privateKey } + +func transitionDeployContract(b *testing.B, transition *state.Transition, byteCode []byte, + sender types.Address) types.Address { + b.Helper() + + deployResult := transition.Create2(sender, byteCode, big.NewInt(0), 1e9) + require.NoError(b, deployResult.Err) + + return deployResult.Address +} + +func transitionCallContract(b *testing.B, transition *state.Transition, contractAddress types.Address, + sender types.Address, input []byte) *runtime.ExecutionResult { + b.Helper() + + result := transition.Call2(sender, contractAddress, input, big.NewInt(0), 1e9) + require.NoError(b, result.Err) + + return result +} + +func newTestTransition(b *testing.B, alloc map[types.Address]*chain.GenesisAccount, disk bool) *state.Transition { + b.Helper() + + var st *itrie.State + + if disk { + testDir := createTestTempDirectory(b) + stateStorage, err := itrie.NewLevelDBStorage(filepath.Join(testDir, "trie"), hclog.NewNullLogger()) + require.NoError(b, err) + + st = itrie.NewState(stateStorage) + } else { + st = itrie.NewState(itrie.NewMemoryStorage()) + } + + ex := state.NewExecutor(&chain.Params{ + Forks: chain.AllForksEnabled, + BurnContract: map[uint64]string{ + 0: types.ZeroAddress.String(), + }, + }, st, hclog.NewNullLogger()) + + rootHash, err := ex.WriteGenesis(alloc, types.Hash{}) + require.NoError(b, err) + + ex.GetHash = func(h *types.Header) state.GetHashByNumber { + return func(i uint64) types.Hash { + return rootHash + } + } + + transition, err := ex.BeginTxn( + rootHash, + &types.Header{}, + types.ZeroAddress, + ) + require.NoError(b, err) + + return transition +} + +func createTestTempDirectory(b *testing.B) string { + b.Helper() + + path, err := os.MkdirTemp("", "temp") + if err != nil { + b.Logf("failed to create temp directory, err=%+v", err) + + b.FailNow() + } + + b.Cleanup(func() { + os.RemoveAll(path) + }) + + return path +} diff --git a/benchmark/root_child_benchmark_test.go b/benchmark/root_child_benchmark_test.go new file mode 100644 index 0000000000..3c6d21b57c --- /dev/null +++ b/benchmark/root_child_benchmark_test.go @@ -0,0 +1,21 @@ +package benchmark + +import ( + "testing" +) + +// The rootChildSendTx function executes test cases that measure transaction execution on both the root and child chains +// To do this, it first calls RootChildSendTxSetUp to set up the testing environment, +// which may include starting the cluster, deploying contracts, and building the test cases. +// After building the test cases, rootChildSendTx returns them along with a cleanup function that should be called +// after the test cases have been executed. The test cases are executed by the TxTestCasesExecutor. +func Benchmark_RootChildSendTx(b *testing.B) { + // set up environment, get test cases and clean up fn + testCases, cleanUpFn := RootChildSendTxSetUp(b, "", "", "", true) + defer cleanUpFn() + + // Loop over the test cases and measure the execution time of the transactions + for _, testInput := range testCases { + TxTestCasesExecutor(b, testInput) + } +} diff --git a/benchmark/root_child_send_tx.go b/benchmark/root_child_send_tx.go index ab1fc848a5..50669ddfb9 100644 --- a/benchmark/root_child_send_tx.go +++ b/benchmark/root_child_send_tx.go @@ -2,7 +2,9 @@ package benchmark import ( "math/big" + "sync" "testing" + "time" "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" "github.com/0xPolygon/polygon-edge/e2e-polybft/framework" @@ -10,35 +12,9 @@ import ( "github.com/0xPolygon/polygon-edge/types" "github.com/stretchr/testify/require" "github.com/umbracle/ethgo" - "github.com/umbracle/ethgo/abi" "github.com/umbracle/ethgo/wallet" ) -var ( - singleContCalcFunc = abi.MustNewMethod("function compute(uint256 x, uint256 y) public returns (uint256)") - singleContGetFunc = abi.MustNewMethod("function getValue() public returns (uint256[] memory)") - singleContSetFunc = abi.MustNewMethod("function addValue(uint256 value) public") - multiContSetAddrFunc = abi.MustNewMethod("function setContractAddr(address _contract) public") - multiContFnA = abi.MustNewMethod("function fnA() public returns (uint256)") -) - -// The rootChildSendTx function executes test cases that measure transaction execution on both the root and child chains -// To do this, it first calls RootChildSendTxSetUp to set up the testing environment, -// which may include starting the cluster, deploying contracts, and building the test cases. -// After building the test cases, rootChildSendTx returns them along with a cleanup function that should be called -// after the test cases have been executed. The test cases are executed by the TxTestCasesExecutor. -func rootChildSendTx(b *testing.B) { - b.Helper() - // set up environment, get test cases and clean up fn - testCases, cleanUpFn := RootChildSendTxSetUp(b, "", "", "", true) - defer cleanUpFn() - - // Loop over the test cases and measure the execution time of the transactions - for _, testInput := range testCases { - TxTestCasesExecutor(b, testInput) - } -} - // RootChildSendTxSetUp sets environment for execution of sentTx test cases on both root and child chains and // returns test cases and clean up fn. // The rootJSONRPC, childJSONRPC, privateKey and startCluster params are used to configure the testing environment. @@ -111,14 +87,14 @@ func RootChildSendTxSetUp(b *testing.B, rootNodeAddr, childNodeAddr, // set callee contract addresses for multi call contracts (A->B->C) // set B contract address in A contract setContractDependencyAddress(b, childTxRelayer, multiAContChildAddr, multiBContChildAddr, - multiContSetAddrFunc, sender) + multiContSetAAddrFunc, sender) setContractDependencyAddress(b, rootTxRelayer, multiAContRootAddr, multiBContRootAddr, - multiContSetAddrFunc, sender) + multiContSetAAddrFunc, sender) // set C contract address in B contract setContractDependencyAddress(b, childTxRelayer, multiBContChildAddr, multiCContChildAddr, - multiContSetAddrFunc, sender) + multiContSetBAddrFunc, sender) setContractDependencyAddress(b, rootTxRelayer, multiBContRootAddr, multiCContRootAddr, - multiContSetAddrFunc, sender) + multiContSetBAddrFunc, sender) // create inputs for contract calls singleContInputs := map[string][]byte{ @@ -198,3 +174,77 @@ func RootChildSendTxSetUp(b *testing.B, rootNodeAddr, childNodeAddr, return testCases, cleanUpFn } + +// TxTestCase represents a test case data to be run with txTestCasesExecutor +type TxTestCase struct { + Name string + Relayer txrelayer.TxRelayer + ContractAddr ethgo.Address + Input [][]byte + Sender ethgo.Key + TxNumber int +} + +// TxTestCasesExecutor executes transactions from testInput and waits in separate +// go routins for each tx receipt +func TxTestCasesExecutor(b *testing.B, testInput TxTestCase) { + b.Helper() + b.Run(testInput.Name, func(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + var wg sync.WaitGroup + + // submit all tx 'repeatCall' times + for i := 0; i < testInput.TxNumber; i++ { + // call contract for the all inputs + for j := 0; j < len(testInput.Input); j++ { + nonce, err := testInput.Relayer.Client().Eth().GetNonce(testInput.Sender.Address(), ethgo.Pending) + require.NoError(b, err) + + // the tx is submitted to the blockchain without waiting for the receipt, + // since we want to have multiple tx in one block + txHash, err := testInput.Relayer.SumbitTransaction( + ðgo.Transaction{ + To: &testInput.ContractAddr, + Input: testInput.Input[j], + }, testInput.Sender) + require.NoError(b, err) + require.NotEqual(b, ethgo.ZeroHash, txHash) + + wg.Add(1) + + // wait for receipt of submitted tx in a separate routine, and continue with the next tx + go func(hash ethgo.Hash) { + defer wg.Done() + + receipt, err := testInput.Relayer.WaitForReceipt(hash) + require.NoError(b, err) + require.Equal(b, uint64(types.ReceiptSuccess), receipt.Status) + }(txHash) + + // wait for tx to be added in mem pool so that we can create tx with the next nonce + waitForNextNonce(b, nonce, testInput.Sender.Address(), testInput.Relayer) + } + } + + wg.Wait() + }) +} + +func waitForNextNonce(b *testing.B, nonce uint64, address ethgo.Address, txRelayer txrelayer.TxRelayer) { + b.Helper() + + startTime := time.Now().UTC() + + for { + newNonce, err := txRelayer.Client().Eth().GetNonce(address, ethgo.Pending) + require.NoError(b, err) + + if newNonce > nonce { + return + } + + elapsedTime := time.Since(startTime) + require.True(b, elapsedTime <= 5*time.Second, "tx not added to the mem poolin 2s") + } +} diff --git a/benchmark/transition_benchmark_test.go b/benchmark/transition_benchmark_test.go new file mode 100644 index 0000000000..c96b603ade --- /dev/null +++ b/benchmark/transition_benchmark_test.go @@ -0,0 +1,112 @@ +package benchmark + +import ( + "math/big" + "testing" + + "github.com/0xPolygon/polygon-edge/chain" + "github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi" + "github.com/0xPolygon/polygon-edge/types" + "github.com/umbracle/ethgo" +) + +func Benchmark_TransitionMultiContractMemDb(b *testing.B) { + multiContractTest(b, false) +} + +func Benchmark_TransitionMultiContractLevelDb(b *testing.B) { + multiContractTest(b, true) +} + +func multiContractTest(b *testing.B, disk bool) { + b.Helper() + + senderAddr := types.Address{1} // account that sends transactions + + alloc := map[types.Address]*chain.GenesisAccount{ + senderAddr: {Balance: ethgo.Ether(100)}, // give some ethers to sender + } + + transition := newTestTransition(b, alloc, disk) + + // deploy contracts + singleContractAddr := transitionDeployContract(b, transition, contractsapi.TestBenchmarkSingle.Bytecode, senderAddr) + contractAAddr := transitionDeployContract(b, transition, contractsapi.TestBenchmarkA.Bytecode, senderAddr) + contractBAddr := transitionDeployContract(b, transition, contractsapi.TestBenchmarkB.Bytecode, senderAddr) + contractCAddr := transitionDeployContract(b, transition, contractsapi.TestBenchmarkC.Bytecode, senderAddr) + + //set multi contracts dependency address + input := getTxInput(b, multiContSetAAddrFunc, []interface{}{contractBAddr}) + transitionCallContract(b, transition, contractAAddr, senderAddr, input) + input = getTxInput(b, multiContSetBAddrFunc, []interface{}{contractCAddr}) + transitionCallContract(b, transition, contractBAddr, senderAddr, input) + + testCases := []struct { + contractAddr types.Address + input []byte + }{ + { + contractAddr: singleContractAddr, + input: getTxInput(b, singleContSetFunc, []interface{}{big.NewInt(10)}), + }, + { + contractAddr: singleContractAddr, + input: getTxInput(b, singleContGetFunc, nil), + }, + { + contractAddr: singleContractAddr, + input: getTxInput(b, singleContCalcFunc, []interface{}{big.NewInt(50), big.NewInt(150)}), + }, + { + contractAddr: contractAAddr, + input: getTxInput(b, multiContFnA, nil), + }, + } + + b.ReportAllocs() + b.ResetTimer() + // execute transactions + for i := 0; i < b.N; i++ { + for j := 0; j < 400; j++ { + for _, tc := range testCases { + transitionCallContract(b, transition, tc.contractAddr, senderAddr, tc.input) + } + } + } +} + +func Benchmark_SampleContractMemDb(b *testing.B) { + sampleContractTest(b, false) +} + +func Benchmark_SampleContractLevelDb(b *testing.B) { + sampleContractTest(b, true) +} + +func sampleContractTest(b *testing.B, disk bool) { + b.Helper() + + senderAddr := types.Address{1} // account that sends transactions + alloc := map[types.Address]*chain.GenesisAccount{ + senderAddr: {Balance: ethgo.Ether(100)}, // give some ethers to sender + } + transition := newTestTransition(b, alloc, disk) + code := contractsapi.SampleContract.Bytecode + cpurchase := getTxInput(b, contractsapi.SampleContract.Abi.Methods["confirmPurchase"], nil) + creceived := getTxInput(b, contractsapi.SampleContract.Abi.Methods["confirmReceived"], nil) + refund := getTxInput(b, contractsapi.SampleContract.Abi.Methods["refund"], nil) + + // deploy contracts + contractAddr := transitionDeployContract(b, transition, code, senderAddr) + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + for j := 0; j < 400; j++ { + transitionCallContract(b, transition, contractAddr, senderAddr, cpurchase) + transitionCallContract(b, transition, contractAddr, senderAddr, creceived) + transitionCallContract(b, transition, contractAddr, senderAddr, refund) + } + } +} diff --git a/consensus/polybft/contractsapi/init.go b/consensus/polybft/contractsapi/init.go index fb2e967076..f2066edd5c 100644 --- a/consensus/polybft/contractsapi/init.go +++ b/consensus/polybft/contractsapi/init.go @@ -56,6 +56,7 @@ var ( TestBenchmarkB *artifact.Artifact TestBenchmarkC *artifact.Artifact TestBenchmarkSingle *artifact.Artifact + SampleContract *artifact.Artifact ) func init() { @@ -221,6 +222,11 @@ func init() { log.Fatal(err) } + SampleContract, err = artifact.DecodeArtifact(readTestContractContent("SampleContract.json")) + if err != nil { + log.Fatal(err) + } + TestBenchmarkSingle, err = artifact.DecodeArtifact(readTestContractContent("TestBenchmarkSingle.json")) if err != nil { log.Fatal(err) diff --git a/consensus/polybft/contractsapi/test-contracts/SampleContract.json b/consensus/polybft/contractsapi/test-contracts/SampleContract.json new file mode 100644 index 0000000000..31d3fbbd84 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/SampleContract.json @@ -0,0 +1,138 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "SampleContract", + "sourceName": "contracts/test/SampleContract.sol", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [], + "name": "Aborted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "ItemReceived", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "PurchaseConfirmed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "Refunded", + "type": "event" + }, + { + "inputs": [], + "name": "abort", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "buyer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "confirmPurchase", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "confirmReceived", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "refund", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "seller", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "state", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "value", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a01b0319168155600155600280546001600160a81b0319169055610223806100436000396000f3fe608060405234801561001057600080fd5b50600436106100785760003560e01c806308551a531461007d57806335a063b4146100ad5780633fa4f245146100b7578063590e1ae3146100ce5780637150d8ae146100e657806373fac6f0146100f9578063c19d93fb14610101578063d696069714610127575b600080fd5b600054610090906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100b561012f565b005b6100c060015481565b6040519081526020016100a4565b6100d661015a565b60405190151581526020016100a4565b600254610090906001600160a01b031681565b6100d661018b565b60025461011590600160a01b900460ff1681565b60405160ff90911681526020016100a4565b6100d66101bc565b6040517f72c874aeff0b183a56e2b79c71b46e1aed4dee5e09862134b8821ba2fddbf8bf90600090a1565b6040516000907f8616bbbbad963e4e65b1366f1d75dfb63f9e9704bbbf91fb01bec70849906cf7908290a150600190565b6040516000907fe89152acd703c9d8c7d28829d443260b411454d45394e7995815140c8cbcbcf7908290a150600190565b6040516000907fd5d55c8a68912e9a110618df8d5e2e83b8d83211c57a8ddd1203df92885dc881908290a15060019056fea264697066735822122020dbaeea5fb377656e27e4776ca67b90b97234194ed45764407db48ad4a5e8cb64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100785760003560e01c806308551a531461007d57806335a063b4146100ad5780633fa4f245146100b7578063590e1ae3146100ce5780637150d8ae146100e657806373fac6f0146100f9578063c19d93fb14610101578063d696069714610127575b600080fd5b600054610090906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100b561012f565b005b6100c060015481565b6040519081526020016100a4565b6100d661015a565b60405190151581526020016100a4565b600254610090906001600160a01b031681565b6100d661018b565b60025461011590600160a01b900460ff1681565b60405160ff90911681526020016100a4565b6100d66101bc565b6040517f72c874aeff0b183a56e2b79c71b46e1aed4dee5e09862134b8821ba2fddbf8bf90600090a1565b6040516000907f8616bbbbad963e4e65b1366f1d75dfb63f9e9704bbbf91fb01bec70849906cf7908290a150600190565b6040516000907fe89152acd703c9d8c7d28829d443260b411454d45394e7995815140c8cbcbcf7908290a150600190565b6040516000907fd5d55c8a68912e9a110618df8d5e2e83b8d83211c57a8ddd1203df92885dc881908290a15060019056fea264697066735822122020dbaeea5fb377656e27e4776ca67b90b97234194ed45764407db48ad4a5e8cb64736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/SampleContract.sol b/consensus/polybft/contractsapi/test-contracts/SampleContract.sol new file mode 100644 index 0000000000..1c8a510dbf --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/SampleContract.sol @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.19; + +contract SampleContract { + address public seller; + uint256 public value; + address public buyer; + uint8 public state; + + event Aborted(); + event PurchaseConfirmed(); + event ItemReceived(); + event Refunded(); + + constructor() public { + seller = address(0); + value = 0; + buyer = address(0); + state = 0; + } + + function abort() external { + emit Aborted(); + } + + function confirmPurchase() external returns (bool) { + emit PurchaseConfirmed(); + return true; + } + + function confirmReceived() external returns (bool) { + emit ItemReceived(); + return true; + } + + function refund() external returns (bool) { + emit Refunded(); + return true; + } +} From 8164f552a3c4b1bc6f036c2f7fbe7f553a5b33ce Mon Sep 17 00:00:00 2001 From: stana-ethernal Date: Tue, 30 May 2023 21:48:23 +0200 Subject: [PATCH 7/7] large data test --- benchmark/helper.go | 24 +-- benchmark/transition_benchmark_test.go | 16 +- consensus/polybft/contractsapi/init.go | 4 +- .../test-contracts/BigDataContract.json | 49 +++++++ .../test-contracts/BigDataContract.sol | 13 ++ .../test-contracts/SampleContract.json | 138 ------------------ .../test-contracts/SampleContract.sol | 40 ----- 7 files changed, 75 insertions(+), 209 deletions(-) create mode 100644 consensus/polybft/contractsapi/test-contracts/BigDataContract.json create mode 100644 consensus/polybft/contractsapi/test-contracts/BigDataContract.sol delete mode 100644 consensus/polybft/contractsapi/test-contracts/SampleContract.json delete mode 100644 consensus/polybft/contractsapi/test-contracts/SampleContract.sol diff --git a/benchmark/helper.go b/benchmark/helper.go index 9656316de2..a3bce08e1e 100644 --- a/benchmark/helper.go +++ b/benchmark/helper.go @@ -2,8 +2,8 @@ package benchmark import ( "encoding/hex" + "math" "math/big" - "os" "path/filepath" "testing" @@ -127,7 +127,7 @@ func transitionCallContract(b *testing.B, transition *state.Transition, contract sender types.Address, input []byte) *runtime.ExecutionResult { b.Helper() - result := transition.Call2(sender, contractAddress, input, big.NewInt(0), 1e9) + result := transition.Call2(sender, contractAddress, input, big.NewInt(0), math.MaxUint64) require.NoError(b, result.Err) return result @@ -139,8 +139,7 @@ func newTestTransition(b *testing.B, alloc map[types.Address]*chain.GenesisAccou var st *itrie.State if disk { - testDir := createTestTempDirectory(b) - stateStorage, err := itrie.NewLevelDBStorage(filepath.Join(testDir, "trie"), hclog.NewNullLogger()) + stateStorage, err := itrie.NewLevelDBStorage(filepath.Join(b.TempDir(), "trie"), hclog.NewNullLogger()) require.NoError(b, err) st = itrie.NewState(stateStorage) @@ -173,20 +172,3 @@ func newTestTransition(b *testing.B, alloc map[types.Address]*chain.GenesisAccou return transition } - -func createTestTempDirectory(b *testing.B) string { - b.Helper() - - path, err := os.MkdirTemp("", "temp") - if err != nil { - b.Logf("failed to create temp directory, err=%+v", err) - - b.FailNow() - } - - b.Cleanup(func() { - os.RemoveAll(path) - }) - - return path -} diff --git a/benchmark/transition_benchmark_test.go b/benchmark/transition_benchmark_test.go index c96b603ade..66ad8fbb70 100644 --- a/benchmark/transition_benchmark_test.go +++ b/benchmark/transition_benchmark_test.go @@ -2,6 +2,7 @@ package benchmark import ( "math/big" + "strings" "testing" "github.com/0xPolygon/polygon-edge/chain" @@ -91,10 +92,9 @@ func sampleContractTest(b *testing.B, disk bool) { senderAddr: {Balance: ethgo.Ether(100)}, // give some ethers to sender } transition := newTestTransition(b, alloc, disk) - code := contractsapi.SampleContract.Bytecode - cpurchase := getTxInput(b, contractsapi.SampleContract.Abi.Methods["confirmPurchase"], nil) - creceived := getTxInput(b, contractsapi.SampleContract.Abi.Methods["confirmReceived"], nil) - refund := getTxInput(b, contractsapi.SampleContract.Abi.Methods["refund"], nil) + code := contractsapi.BigDataContract.Bytecode + newData := strings.Repeat("A", 100000) + input := getTxInput(b, contractsapi.BigDataContract.Abi.Methods["writeData"], []interface{}{[]byte(newData)}) // deploy contracts contractAddr := transitionDeployContract(b, transition, code, senderAddr) @@ -103,10 +103,10 @@ func sampleContractTest(b *testing.B, disk bool) { b.ResetTimer() for i := 0; i < b.N; i++ { - for j := 0; j < 400; j++ { - transitionCallContract(b, transition, contractAddr, senderAddr, cpurchase) - transitionCallContract(b, transition, contractAddr, senderAddr, creceived) - transitionCallContract(b, transition, contractAddr, senderAddr, refund) + for j := 0; j < 100; j++ { + transitionCallContract(b, transition, contractAddr, senderAddr, input) } } + b.StopTimer() + transition.Commit() } diff --git a/consensus/polybft/contractsapi/init.go b/consensus/polybft/contractsapi/init.go index f2066edd5c..f033034f74 100644 --- a/consensus/polybft/contractsapi/init.go +++ b/consensus/polybft/contractsapi/init.go @@ -56,7 +56,7 @@ var ( TestBenchmarkB *artifact.Artifact TestBenchmarkC *artifact.Artifact TestBenchmarkSingle *artifact.Artifact - SampleContract *artifact.Artifact + BigDataContract *artifact.Artifact ) func init() { @@ -222,7 +222,7 @@ func init() { log.Fatal(err) } - SampleContract, err = artifact.DecodeArtifact(readTestContractContent("SampleContract.json")) + BigDataContract, err = artifact.DecodeArtifact(readTestContractContent("BigDataContract.json")) if err != nil { log.Fatal(err) } diff --git a/consensus/polybft/contractsapi/test-contracts/BigDataContract.json b/consensus/polybft/contractsapi/test-contracts/BigDataContract.json new file mode 100644 index 0000000000..7cf62a1312 --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/BigDataContract.json @@ -0,0 +1,49 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "BigDataContract", + "sourceName": "contracts/test/BigDataContract.sol", + "abi": [ + { + "anonymous": false, + "inputs": [], + "name": "Written", + "type": "event" + }, + { + "inputs": [], + "name": "data", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "newData", + "type": "bytes" + } + ], + "name": "writeData", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5061050d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806373d4a13a1461003b578063f275d3ec14610059575b600080fd5b61004361006c565b604051610050919061020d565b60405180910390f35b610043610067366004610256565b6100fa565b6000805461007990610307565b80601f01602080910402602001604051908101604052809291908181526020018280546100a590610307565b80156100f25780601f106100c7576101008083540402835291602001916100f2565b820191906000526020600020905b8154815290600101906020018083116100d557829003601f168201915b505050505081565b6060600082604051602001610110929190610341565b6040516020818303038152906040526000908161012d9190610417565b506040517f6cf6fd6d80b7dfd898e622a3e48e8ab90bf067accc098070fd9ae2dba15f493f90600090a16000805461016490610307565b80601f016020809104026020016040519081016040528092919081815260200182805461019090610307565b80156101dd5780601f106101b2576101008083540402835291602001916101dd565b820191906000526020600020905b8154815290600101906020018083116101c057829003601f168201915b50505050509050919050565b60005b838110156102045781810151838201526020016101ec565b50506000910152565b602081526000825180602084015261022c8160408501602087016101e9565b601f01601f19169190910160400192915050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561026857600080fd5b813567ffffffffffffffff8082111561028057600080fd5b818401915084601f83011261029457600080fd5b8135818111156102a6576102a6610240565b604051601f8201601f19908116603f011681019083821181831017156102ce576102ce610240565b816040528281528760208487010111156102e757600080fd5b826020860160208301376000928101602001929092525095945050505050565b600181811c9082168061031b57607f821691505b60208210810361033b57634e487b7160e01b600052602260045260246000fd5b50919050565b600080845461034f81610307565b60018281168015610367576001811461037c576103ab565b60ff19841687528215158302870194506103ab565b8860005260208060002060005b858110156103a25781548a820152908401908201610389565b50505082870194505b5050505083516103bf8183602088016101e9565b01949350505050565b601f82111561041257600081815260208120601f850160051c810160208610156103ef5750805b601f850160051c820191505b8181101561040e578281556001016103fb565b5050505b505050565b815167ffffffffffffffff81111561043157610431610240565b6104458161043f8454610307565b846103c8565b602080601f83116001811461047a57600084156104625750858301515b600019600386901b1c1916600185901b17855561040e565b600085815260208120601f198616915b828110156104a95788860151825594840194600190910190840161048a565b50858210156104c75787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220066615155ab5f27a9cd866f718c66bfaed325ec934c74727b8b79240e844fc5b64736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806373d4a13a1461003b578063f275d3ec14610059575b600080fd5b61004361006c565b604051610050919061020d565b60405180910390f35b610043610067366004610256565b6100fa565b6000805461007990610307565b80601f01602080910402602001604051908101604052809291908181526020018280546100a590610307565b80156100f25780601f106100c7576101008083540402835291602001916100f2565b820191906000526020600020905b8154815290600101906020018083116100d557829003601f168201915b505050505081565b6060600082604051602001610110929190610341565b6040516020818303038152906040526000908161012d9190610417565b506040517f6cf6fd6d80b7dfd898e622a3e48e8ab90bf067accc098070fd9ae2dba15f493f90600090a16000805461016490610307565b80601f016020809104026020016040519081016040528092919081815260200182805461019090610307565b80156101dd5780601f106101b2576101008083540402835291602001916101dd565b820191906000526020600020905b8154815290600101906020018083116101c057829003601f168201915b50505050509050919050565b60005b838110156102045781810151838201526020016101ec565b50506000910152565b602081526000825180602084015261022c8160408501602087016101e9565b601f01601f19169190910160400192915050565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561026857600080fd5b813567ffffffffffffffff8082111561028057600080fd5b818401915084601f83011261029457600080fd5b8135818111156102a6576102a6610240565b604051601f8201601f19908116603f011681019083821181831017156102ce576102ce610240565b816040528281528760208487010111156102e757600080fd5b826020860160208301376000928101602001929092525095945050505050565b600181811c9082168061031b57607f821691505b60208210810361033b57634e487b7160e01b600052602260045260246000fd5b50919050565b600080845461034f81610307565b60018281168015610367576001811461037c576103ab565b60ff19841687528215158302870194506103ab565b8860005260208060002060005b858110156103a25781548a820152908401908201610389565b50505082870194505b5050505083516103bf8183602088016101e9565b01949350505050565b601f82111561041257600081815260208120601f850160051c810160208610156103ef5750805b601f850160051c820191505b8181101561040e578281556001016103fb565b5050505b505050565b815167ffffffffffffffff81111561043157610431610240565b6104458161043f8454610307565b846103c8565b602080601f83116001811461047a57600084156104625750858301515b600019600386901b1c1916600185901b17855561040e565b600085815260208120601f198616915b828110156104a95788860151825594840194600190910190840161048a565b50858210156104c75787850151600019600388901b60f8161c191681555b5050505050600190811b0190555056fea2646970667358221220066615155ab5f27a9cd866f718c66bfaed325ec934c74727b8b79240e844fc5b64736f6c63430008110033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/consensus/polybft/contractsapi/test-contracts/BigDataContract.sol b/consensus/polybft/contractsapi/test-contracts/BigDataContract.sol new file mode 100644 index 0000000000..e3a91a2a0a --- /dev/null +++ b/consensus/polybft/contractsapi/test-contracts/BigDataContract.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.17; + +contract BigDataContract { + bytes public data; + event Written(); + + function writeData(bytes memory newData) external returns (bytes memory) { + data = abi.encodePacked(data, newData); + emit Written(); + return data; + } +} diff --git a/consensus/polybft/contractsapi/test-contracts/SampleContract.json b/consensus/polybft/contractsapi/test-contracts/SampleContract.json deleted file mode 100644 index 31d3fbbd84..0000000000 --- a/consensus/polybft/contractsapi/test-contracts/SampleContract.json +++ /dev/null @@ -1,138 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "SampleContract", - "sourceName": "contracts/test/SampleContract.sol", - "abi": [ - { - "inputs": [], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [], - "name": "Aborted", - "type": "event" - }, - { - "anonymous": false, - "inputs": [], - "name": "ItemReceived", - "type": "event" - }, - { - "anonymous": false, - "inputs": [], - "name": "PurchaseConfirmed", - "type": "event" - }, - { - "anonymous": false, - "inputs": [], - "name": "Refunded", - "type": "event" - }, - { - "inputs": [], - "name": "abort", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "buyer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "confirmPurchase", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "confirmReceived", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "refund", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "seller", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "state", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "value", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - } - ], - "bytecode": "0x608060405234801561001057600080fd5b50600080546001600160a01b0319168155600155600280546001600160a81b0319169055610223806100436000396000f3fe608060405234801561001057600080fd5b50600436106100785760003560e01c806308551a531461007d57806335a063b4146100ad5780633fa4f245146100b7578063590e1ae3146100ce5780637150d8ae146100e657806373fac6f0146100f9578063c19d93fb14610101578063d696069714610127575b600080fd5b600054610090906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100b561012f565b005b6100c060015481565b6040519081526020016100a4565b6100d661015a565b60405190151581526020016100a4565b600254610090906001600160a01b031681565b6100d661018b565b60025461011590600160a01b900460ff1681565b60405160ff90911681526020016100a4565b6100d66101bc565b6040517f72c874aeff0b183a56e2b79c71b46e1aed4dee5e09862134b8821ba2fddbf8bf90600090a1565b6040516000907f8616bbbbad963e4e65b1366f1d75dfb63f9e9704bbbf91fb01bec70849906cf7908290a150600190565b6040516000907fe89152acd703c9d8c7d28829d443260b411454d45394e7995815140c8cbcbcf7908290a150600190565b6040516000907fd5d55c8a68912e9a110618df8d5e2e83b8d83211c57a8ddd1203df92885dc881908290a15060019056fea264697066735822122020dbaeea5fb377656e27e4776ca67b90b97234194ed45764407db48ad4a5e8cb64736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100785760003560e01c806308551a531461007d57806335a063b4146100ad5780633fa4f245146100b7578063590e1ae3146100ce5780637150d8ae146100e657806373fac6f0146100f9578063c19d93fb14610101578063d696069714610127575b600080fd5b600054610090906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100b561012f565b005b6100c060015481565b6040519081526020016100a4565b6100d661015a565b60405190151581526020016100a4565b600254610090906001600160a01b031681565b6100d661018b565b60025461011590600160a01b900460ff1681565b60405160ff90911681526020016100a4565b6100d66101bc565b6040517f72c874aeff0b183a56e2b79c71b46e1aed4dee5e09862134b8821ba2fddbf8bf90600090a1565b6040516000907f8616bbbbad963e4e65b1366f1d75dfb63f9e9704bbbf91fb01bec70849906cf7908290a150600190565b6040516000907fe89152acd703c9d8c7d28829d443260b411454d45394e7995815140c8cbcbcf7908290a150600190565b6040516000907fd5d55c8a68912e9a110618df8d5e2e83b8d83211c57a8ddd1203df92885dc881908290a15060019056fea264697066735822122020dbaeea5fb377656e27e4776ca67b90b97234194ed45764407db48ad4a5e8cb64736f6c63430008130033", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/consensus/polybft/contractsapi/test-contracts/SampleContract.sol b/consensus/polybft/contractsapi/test-contracts/SampleContract.sol deleted file mode 100644 index 1c8a510dbf..0000000000 --- a/consensus/polybft/contractsapi/test-contracts/SampleContract.sol +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.19; - -contract SampleContract { - address public seller; - uint256 public value; - address public buyer; - uint8 public state; - - event Aborted(); - event PurchaseConfirmed(); - event ItemReceived(); - event Refunded(); - - constructor() public { - seller = address(0); - value = 0; - buyer = address(0); - state = 0; - } - - function abort() external { - emit Aborted(); - } - - function confirmPurchase() external returns (bool) { - emit PurchaseConfirmed(); - return true; - } - - function confirmReceived() external returns (bool) { - emit ItemReceived(); - return true; - } - - function refund() external returns (bool) { - emit Refunded(); - return true; - } -}