From 90514081406630d69eb3c41763ab3e95627dcf7f Mon Sep 17 00:00:00 2001 From: Francesco4203 Date: Mon, 8 Jul 2024 17:55:51 +0700 Subject: [PATCH] core/vm: add RB Tree EVM benchmark --- core/vm/evm_benchmark_test.go | 112 ++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/core/vm/evm_benchmark_test.go b/core/vm/evm_benchmark_test.go index ee6cf3b09e..489994f64c 100644 --- a/core/vm/evm_benchmark_test.go +++ b/core/vm/evm_benchmark_test.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" ) @@ -330,3 +331,114 @@ func BenchmarkEvmMulticallErcTransfer(b *testing.B) { benchmarkEVM(b, &suite) } + +func BenchmarkEVMRedBlackTree(b *testing.B) { + // Create random array of numbers and options + // The "random" values are generated using a fixed seed for accurate comparison + n := 10000 + bound := 1000 + var numbers []*big.Int + var options []*big.Int + var args []interface{} + for i := 0; i < n; i++ { + rng := rand.New(rand.NewSource(int64(i))) + numbers = append(numbers, big.NewInt(int64(rng.Intn(bound))+1)) + options = append(options, big.NewInt(int64(rng.Intn(2)+1))) + } + args = append(args, numbers) + args = append(args, options) + + // Pack data for ABI + parsedABI, err := abi.JSON(strings.NewReader( + ` + [ + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "numbers", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "options", + "type": "uint256[]" + } + ], + "name": "process", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + `, + )) + if err != nil { + b.Fatalf("Failed to parse ABI: %v", err) + } + data, err := parsedABI.Pack("process", args...) + if err != nil { + b.Fatalf("Failed to pack data for ABI: %v", err) + } + + // Setup EVM to run contract + /* + pragma solidity ^0.8.18; + ... + // RBTree library - https://github.com/Vectorized/solady/blob/29d61c504425519c6deddc3e12c2e039ad43e8e3/test/RedBlackTree.t.sol#L4 + ... + contract OpcodeTest { + using RedBlackTreeLib for *; + RedBlackTreeLib.Tree tree; + + function process(uint256[] memory numbers, uint256[] memory options) external { + for (uint256 i = 0; i < numbers.length; i++) { + uint256 option = options[i]; + uint256 number = numbers[i]; + if (option == 1) { + if (!tree.exists(number)) { + tree.insert(number); + } + } else if (option == 2) { + if (tree.exists(number)) { + tree.remove(number); + } + } + } + } + } + */ + contractString := + "608060405234801561001057600080fd5b506004361061002b5760003560e01c80636e476ea014610030575b600080fd5b61004361003e366004610987565b610045565b005b60005b82518110156100e1576000828281518110610065576100656109f0565b602002602001015190506000848381518110610083576100836109f0565b60200260200101519050816001036100b4576100a06000826100e6565b6100af576100af6000826100ff565b6100d7565b816002036100d7576100c76000826100e6565b156100d7576100d760008261011c565b5050600101610048565b505050565b6000806100f38484610128565b15159695505050505050565b600061010b83836101b0565b905080156100e1576100e1816101de565b600061010b83836101e8565b600080808361013e5761013e63c94f18776101de565b846020526801dc27bb5462fdadcb600052604060002060201b9250601f600152825460801c5b80156101a857809250808417548060601c806101865750848217638000000017545b8681036101975784935050506101a8565b8611511c637fffffff169050610164565b509250925092565b6000806000806101c08686610128565b9250925092506101d4838383886000610215565b9695505050505050565b806000526004601cfd5b60008060006101f78585610128565b925050915061020c8260008360006001610215565b95945050505050565b6000610896565b8082175480851c637fffffff16603e82901c637fffffff168382175480871c637fffffff16801561025f578086178054637fffffff603e1b1916603e89901b1790555b8261026d57836000526102a5565b8583178054808a1c637fffffff16890361029557637fffffff8a1b1916858a1b1790556102a5565b637fffffff8b1b1916858b1b1790555b637fffffff603e1b19637fffffff808b1b19969096169190991b178816603e84811b919091178787175593871b199716921b91909117949094169190921b17911755565b600083156102fc575063bb33e6ac6104b4565b600160205160801c01637fffffff81111561031e5763ed732d0c9150506104b4565b8060801b60205283603e1b6001605d1b178184176001600160a01b03881161034d57818860601b179150610357565b8763800000008217555b558361036657806000526103ab565b83831780548060601c8061037e575063800000008217545b80891061039e5750673fffffff800000001916601f83901b1790556103ab565b50637fffffff1916821790555b93506001605d1b5b60005185146104a55782851754603e1c637fffffff16808417548281166103db5750506104a5565b603e81901c637fffffff1685811754601f637fffffff8216851402601f811882821c637fffffff16808a175480891661047e5786841c637fffffff168d0361042c57879c5061042c84848f8e61021c565b8a8d1754603e1c637fffffff169750878b1754965088198716888c175561045a603e88637fffffff911c1690565b8b811780548b17905595506104718385888e61021c565b50505050505050506103b3565b88198716888c175588198116828c17555050505084811782881755508097505050506103b3565b60005183178119815416815550505b949350505050565b6001605d1b5b60005183146105fc5782821754808216156104dd57506105fc565b603e81901c637fffffff1683811754909150601f637fffffff8216861402601f811882821c637fffffff1680871754808716156105425786198116828917558685178689175561052f8484888b61021c565b505085841754821c637fffffff16808717545b80831c637fffffff168881175482861c637fffffff16808b17548083178b1661057b5750505050861790871755509194506104c2915050565b808b166105c4578a198316848d17558a8517868d175561059d8789888f61021c565b8b8a1754881c637fffffff168c811754909650945084881c637fffffff169150818c175490505b898c175498508885188b168518868d17558a1989168a8d17558a198116828d17555050505050506105f78282868961021c565b505050505b9117805491199091169055565b8161061657505060005250565b178054637fffffff601f81831695909514159490940293841b19169190921b179055565b600060205160801c831115610654575063ccd52fbc610890565b82610664575063b113638a610890565b818317548390637fffffff601f82901c81169116808202156106a0578192505b84831754637fffffff168061069957506106a0565b9250610684565b505082811754637fffffff81168015601f0282901c637fffffff169050603e82901c637fffffff168186178054637fffffff603e1b1916603e83901b1790556106eb84838389610609565b50858314610765578486175461070d8785603e84901c637fffffff1689610609565b637fffffff811686178054637fffffff603e1b1916603e86901b179055601f81901c637fffffff1686178054637fffffff603e1b1916603e86901b17905582186bffffffffffffffffffffffff168218858417559194915b816001605d1b1661077a5761077a81866104bc565b505060205160801c808417548060601c60008161079f57505063800000008583171754805b8487175460601c6000816107bb57505063800000008786171754805b8184146108665784878a17558083146107da5782878a17638000000017555b603e85901c637fffffff16806107f35787600052610814565b8981178054637fffffff8082168a1415601f028b811b91901b199091161790555b50601f85901c637fffffff16801561083e57808a178054637fffffff603e1b1916603e8a901b1790555b50637fffffff8516801561086457808a178054637fffffff603e1b1916603e8a901b1790555b505b50506000848817558015610881576000848817638000000017555b5050506000190160801b602052505b92915050565b386000528554601052816108b7576108b0838587896102e9565b90506108c4565b6108c1848761063a565b90505b601051865595945050505050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126108f957600080fd5b813567ffffffffffffffff811115610913576109136108d2565b8060051b604051601f19603f830116810181811067ffffffffffffffff82111715610940576109406108d2565b60405291825260208185018101929081018684111561095e57600080fd5b6020860192505b8383101561097d578235815260209283019201610965565b5095945050505050565b6000806040838503121561099a57600080fd5b823567ffffffffffffffff8111156109b157600080fd5b6109bd858286016108e8565b925050602083013567ffffffffffffffff8111156109da57600080fd5b6109e6858286016108e8565b9150509250929050565b634e487b7160e01b600052603260045260246000fdfea264697066735822122060f7fd286cb5b1331bc5d1520a171917f649e24017f29882e087085a042e6a0c64736f6c634300081a0033" + statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) + if err != nil { + b.Fatal(err) + } + evm := NewEVM( + BlockContext{ + BlockNumber: common.Big0, + Transfer: func(_ StateDB, _, _ common.Address, _ *big.Int) {}, + PublishEvents: make(PublishEventsMap), + CurrentTransaction: types.NewTx(&types.LegacyTx{}), + }, + TxContext{}, + statedb, + ¶ms.ChainConfig{ + LondonBlock: common.Big0, + }, + Config{}, + ) + + testContract := common.Hex2Bytes(contractString) + testAddress := common.BigToAddress(big.NewInt(0x201)) + + statedb.SetCode(testAddress, testContract) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _, err = evm.Call(AccountRef(testAddress), testAddress, data, 100_000_000_000, big.NewInt(0)) + if err != nil { + b.Fatal(err) + } + } +}