From 60542f674af2eda44289544d4ca63526f225421c Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Tue, 7 Nov 2023 16:17:10 +0700 Subject: [PATCH] precompiled: adjust the gas cost of consortium precompiled contract This commit adds the benchmarks and calculated gas cost from the benchmarks to validator sorting, pick validator set and verify double sign proof precompiled contracts. Ethereum aims for 30 mgas/s when setting gas cost for precompiled contracts, we aims for 60 mgas/s. Benchmark results: BenchmarkConsortiumValidatorSorting/validator-sort-Gas=4620-8 228014 54940 ns/op 4620 gas/op 84.09 mgas/s 35755 B/op 560 allocs/op BenchmarkConsortiumValidatorSorting/validator-sort-Gas=19560-8 60619 182986 ns/op 19560 gas/op 106.9 mgas/s 148101 B/op 2342 allocs/op BenchmarkConsortiumVerifyHeaders/verify-headers-Gas=24000-8 32920 354968 ns/op 24000 gas/op 67.61 mgas/s 97101 B/op 924 allocs/op BenchmarkConsortiumPickValidatorSet/pick-validator-set-Gas=7080-8 128181 86701 ns/op 7080 gas/op 81.65 mgas/s 50221 B/op 684 allocs/op BenchmarkConsortiumPickValidatorSet/pick-validator-set-Gas=29580-8 53889 244067 ns/op 29580 gas/op 121.2 mgas/s 179618 B/op 2597 allocs/op --- core/vm/consortium_precompiled_contracts.go | 85 ++++++--- .../consortium_precompiled_contracts_test.go | 169 +++++++++++++++++- core/vm/contracts_test.go | 3 + params/protocol_params.go | 4 +- 4 files changed, 231 insertions(+), 30 deletions(-) diff --git a/core/vm/consortium_precompiled_contracts.go b/core/vm/consortium_precompiled_contracts.go index 28f6cea120..56802958fe 100644 --- a/core/vm/consortium_precompiled_contracts.go +++ b/core/vm/consortium_precompiled_contracts.go @@ -89,16 +89,28 @@ type consortiumPickValidatorSet struct { evm *EVM } -func (c *consortiumPickValidatorSet) RequiredGas(_ []byte) uint64 { - return 0 +func (c *consortiumPickValidatorSet) RequiredGas(input []byte) uint64 { + // c.evm is nil in benchmark + if c.evm == nil || c.evm.chainRules.IsMiko { + // We approximate the number of validators by dividing the length of input by + // length of address (20). This is likely an overestimation because there are + // slices of weight, maxValidatorNumber and maxPrioritizedValidatorNumber in + // the input too. + return uint64((len(input) / common.AddressLength)) * params.ValidatorSortingBaseGas + } else { + return 0 + } } func (c *consortiumPickValidatorSet) Run(input []byte) ([]byte, error) { - if c.evm.ChainConfig().ConsortiumV2Contracts == nil { - return nil, errors.New("cannot find consortium v2 contracts") - } - if !c.evm.ChainConfig().ConsortiumV2Contracts.IsSystemContract(c.caller.Address()) { - return nil, errors.New("unauthorized sender") + // These 2 fields are nil in benchmark only + if c.caller != nil && c.evm != nil { + if c.evm.ChainConfig().ConsortiumV2Contracts == nil { + return nil, errors.New("cannot find consortium v2 contracts") + } + if !c.evm.ChainConfig().ConsortiumV2Contracts.IsSystemContract(c.caller.Address()) { + return nil, errors.New("unauthorized sender") + } } // get method, args from abi _, method, args, err := loadMethodAndArgs(consortiumPickValidatorSetAbi, input) @@ -216,16 +228,27 @@ type consortiumValidatorSorting struct { evm *EVM } -func (c *consortiumValidatorSorting) RequiredGas(_ []byte) uint64 { - return 0 +func (c *consortiumValidatorSorting) RequiredGas(input []byte) uint64 { + // c.evm is nil in benchmark + if c.evm == nil || c.evm.chainRules.IsMiko { + // We approximate the number of validators by dividing the length of input by + // length of address (20). This is likely an overestimation because there is + // a slice of weight in the input too. + return uint64((len(input) / common.AddressLength)) * params.ValidatorSortingBaseGas + } else { + return 0 + } } func (c *consortiumValidatorSorting) Run(input []byte) ([]byte, error) { - if c.evm.ChainConfig().ConsortiumV2Contracts == nil { - return nil, errors.New("cannot find consortium v2 contracts") - } - if !c.evm.ChainConfig().ConsortiumV2Contracts.IsSystemContract(c.caller.Address()) { - return nil, errors.New("unauthorized sender") + // These 2 fields are nil in benchmark only + if c.caller != nil && c.evm != nil { + if c.evm.ChainConfig().ConsortiumV2Contracts == nil { + return nil, errors.New("cannot find consortium v2 contracts") + } + if !c.evm.ChainConfig().ConsortiumV2Contracts.IsSystemContract(c.caller.Address()) { + return nil, errors.New("unauthorized sender") + } } // get method, args from abi _, method, args, err := loadMethodAndArgs(consortiumSortValidatorAbi, input) @@ -364,15 +387,23 @@ type consortiumVerifyHeaders struct { } func (c *consortiumVerifyHeaders) RequiredGas(_ []byte) uint64 { - return 0 + // c.evm is nil in benchmark + if c.evm == nil || c.evm.chainRules.IsMiko { + return params.VerifyFinalityHeadersProofGas + } else { + return 0 + } } func (c *consortiumVerifyHeaders) Run(input []byte) ([]byte, error) { - if c.evm.ChainConfig().ConsortiumV2Contracts == nil { - return nil, errors.New("cannot find consortium v2 contracts") - } - if !c.evm.ChainConfig().ConsortiumV2Contracts.IsSystemContract(c.caller.Address()) { - return nil, errors.New("unauthorized sender") + // These 2 fields are nil in benchmark only + if c.caller != nil && c.evm != nil { + if c.evm.ChainConfig().ConsortiumV2Contracts == nil { + return nil, errors.New("cannot find consortium v2 contracts") + } + if !c.evm.ChainConfig().ConsortiumV2Contracts.IsSystemContract(c.caller.Address()) { + return nil, errors.New("unauthorized sender") + } } // get method, args from abi smcAbi, method, args, err := loadMethodAndArgs(consortiumVerifyHeadersAbi, input) @@ -438,7 +469,8 @@ func (c *consortiumVerifyHeaders) getSigner(header types.BlockHeader) (common.Ad func (c *consortiumVerifyHeaders) verify(consensusAddr common.Address, header1, header2 types.BlockHeader) bool { var maxOffset *big.Int - if !c.evm.chainConfig.IsConsortiumV2(header1.Number) { + // c.evm s nil in benchmark, so we skip this check in benchmark + if c.evm != nil && !c.evm.chainConfig.IsConsortiumV2(header1.Number) { return false } if header1.ToHeader().ParentHash.Hex() != header2.ToHeader().ParentHash.Hex() { @@ -487,10 +519,13 @@ func (c *consortiumVerifyHeaders) verify(consensusAddr common.Address, header1, } } - currentBlock := c.evm.Context.BlockNumber - // What if current block < header1.Number? - if currentBlock.Cmp(header1.Number) > 0 && new(big.Int).Sub(currentBlock, header1.Number).Cmp(maxOffset) > 0 { - return false + // c.evm is nil in benchmark, so we skip this check in benchmark + if c.evm != nil { + currentBlock := c.evm.Context.BlockNumber + // What if current block < header1.Number? + if currentBlock.Cmp(header1.Number) > 0 && new(big.Int).Sub(currentBlock, header1.Number).Cmp(maxOffset) > 0 { + return false + } } return signer1.Hex() == signer2.Hex() && diff --git a/core/vm/consortium_precompiled_contracts_test.go b/core/vm/consortium_precompiled_contracts_test.go index a7106b2829..501edba1d1 100644 --- a/core/vm/consortium_precompiled_contracts_test.go +++ b/core/vm/consortium_precompiled_contracts_test.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" "math/big" + "math/rand" "strings" "testing" @@ -139,7 +140,7 @@ pragma solidity >=0.8.0 <0.9.0; let payloadStart := add(payload, 32) if iszero( staticcall( - 0, + gas(), _smc, payloadStart, payloadLength, @@ -158,7 +159,7 @@ pragma solidity >=0.8.0 <0.9.0; ``` */ const ( - wrapupCode = `6080604052604051806102a00160405280606473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250600090601561044d929190610523565b50604051806102a001604052806103e881526020016107d08152602001610bb88152602001610fa0815260200161138881526020016117708152602001611b588152602001611f40815260200161232881526020016127108152602001612af88152602001612ee081526020016132c881526020016136b08152602001613a988152602001613e80815260200161426881526020016146508152602001614a388152602001614e20815260200161520881525060019060156105109291906105ad565b5034801561051d57600080fd5b50610617565b82805482825590600052602060002090810192821561059c579160200282015b8281111561059b5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190610543565b5b5090506105a991906105fa565b5090565b8280548282559060005260206000209081019282156105e9579160200282015b828111156105e85782518255916020019190600101906105cd565b5b5090506105f691906105fa565b5090565b5b808211156106135760008160009055506001016105fb565b5090565b6105bc806106266000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806327167aec14610030575b600080fd5b61003861004e565b60405161004591906102de565b60405180910390f35b61005661014c565b600080600160405160240161006c9291906102fa565b6040516020818303038152906040527f788341af000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008151905060008080549050905060006020826101099190610430565b90506000604060208461011c9190610430565b61012691906103da565b90506000606690506020860182888783856000fa61014357600080fd5b836040893e8388f35b604051806102a00160405280601590602082028036833780820191505090505090565b600061017b838361019f565b60208301905092915050565b600061019383836102cf565b60208301905092915050565b6101a8816104b4565b82525050565b6101b781610365565b6101c181846103ad565b92506101cc82610331565b8060005b838110156101fd5781516101e4878261016f565b96506101ef83610386565b9250506001810190506101d0565b505050505050565b600061021082610370565b61021a81856103b8565b93506102258361033b565b8060005b8381101561025d5761023a82610553565b610244888261016f565b975061024f83610393565b925050600181019050610229565b5085935050505092915050565b60006102758261037b565b61027f81856103c9565b935061028a83610350565b8060005b838110156102c25761029f82610566565b6102a98882610187565b97506102b4836103a0565b92505060018101905061028e565b5085935050505092915050565b6102d8816104e6565b82525050565b60006102a0820190506102f460008301846101ae565b92915050565b600060408201905081810360008301526103148185610205565b90508181036020830152610328818461026a565b90509392505050565b6000819050919050565b60008190508160005260206000209050919050565b60008190508160005260206000209050919050565b600060159050919050565b600081549050919050565b600081549050919050565b6000602082019050919050565b6000600182019050919050565b6000600182019050919050565b600081905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006103e5826104e6565b91506103f0836104e6565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561042557610424610524565b5b828201905092915050565b600061043b826104e6565b9150610446836104e6565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561047f5761047e610524565b5b828202905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006104bf826104c6565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006105036104fe83610579565b61048a565b9050919050565b600061051d61051883610579565b6104aa565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061055f82546104f0565b9050919050565b6000610572825461050a565b9050919050565b60008160001c905091905056fea2646970667358221220bf18e78f84c245c19e8996d9afbcaa3ec60e02e413932b3848d7eed59feb161264736f6c63430008070033` + wrapupCode = "6080604052604051806102a00160405280606473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606c73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606d73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001606f73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607073ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001607873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815250600090601561044d929190610523565b50604051806102a001604052806103e881526020016107d08152602001610bb88152602001610fa0815260200161138881526020016117708152602001611b588152602001611f40815260200161232881526020016127108152602001612af88152602001612ee081526020016132c881526020016136b08152602001613a988152602001613e80815260200161426881526020016146508152602001614a388152602001614e20815260200161520881525060019060156105109291906105ad565b5034801561051d57600080fd5b50610617565b82805482825590600052602060002090810192821561059c579160200282015b8281111561059b5782518260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555091602001919060010190610543565b5b5090506105a991906105fa565b5090565b8280548282559060005260206000209081019282156105e9579160200282015b828111156105e85782518255916020019190600101906105cd565b5b5090506105f691906105fa565b5090565b5b808211156106135760008160009055506001016105fb565b5090565b61057f806106266000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806327167aec14610030575b600080fd5b61003861004e565b604051610045919061024a565b60405180910390f35b61005661014b565b600080600160405160240161006c92919061046d565b6040516020818303038152906040527f788341af000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050600081519050600080805490509050600060208261010991906104d3565b90506000604060208461011c91906104d3565b6101269190610515565b90506000606690506020860182888783855afa61014257600080fd5b836040893e8388f35b6040518060600160405280600390602082028036833780820191505090505090565b600060039050919050565b600081905092915050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101b88261018d565b9050919050565b6101c8816101ad565b82525050565b60006101da83836101bf565b60208301905092915050565b6000602082019050919050565b6101fc8161016d565b6102068184610178565b925061021182610183565b8060005b8381101561024257815161022987826101ce565b9650610234836101e6565b925050600181019050610215565b505050505050565b600060608201905061025f60008301846101f3565b92915050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b60008160001c9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102d66102d183610296565b6102a3565b9050919050565b60006102e982546102c3565b9050919050565b6000600182019050919050565b600061030882610265565b6103128185610270565b935061031d83610281565b8060005b8381101561035557610332826102dd565b61033c88826101ce565b9750610347836102f0565b925050600181019050610321565b5085935050505092915050565b600081549050919050565b600082825260208201905092915050565b60008190508160005260206000209050919050565b6000819050919050565b6103a681610393565b82525050565b60006103b8838361039d565b60208301905092915050565b6000819050919050565b60006103e16103dc83610296565b6103c4565b9050919050565b60006103f482546103ce565b9050919050565b6000600182019050919050565b600061041382610362565b61041d818561036d565b93506104288361037e565b8060005b838110156104605761043d826103e8565b61044788826103ac565b9750610452836103fb565b92505060018101905061042c565b5085935050505092915050565b6000604082019050818103600083015261048781856102fd565b9050818103602083015261049b8184610408565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006104de82610393565b91506104e983610393565b92508282026104f781610393565b9150828204841483151761050e5761050d6104a4565b5b5092915050565b600061052082610393565b915061052b83610393565b9250828201905080821115610543576105426104a4565b5b9291505056fea26469706673582212209c0a26634f0573266e0920a580ad0aa466f5f1be2bd12450465d114e981b1e7464736f6c63430008120033" wrapupAbi = `[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"sortValidators","outputs":[{"internalType":"address[21]","name":"_validators","type":"address[21]"}],"stateMutability":"view","type":"function"}]` ) @@ -324,7 +325,7 @@ contract VerifyHeaderTestContract { uint[1] memory _output; assembly { let payloadStart := add(payload, 32) - if iszero(staticcall(0, _smc, payloadStart, payloadLength, _output, 0x20)) { + if iszero(staticcall(gas(), _smc, payloadStart, payloadLength, _output, 0x20)) { revert(0, 0) } } @@ -337,7 +338,7 @@ contract VerifyHeaderTestContract { } */ const ( - verifyHeadersTestCode = "608060405234801561001057600080fd5b506105b0806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635ade66331461003b578063df4b6ee01461006b575b600080fd5b61005560048036038101906100509190610367565b61008b565b604051610062919061040d565b60405180910390f35b610073610177565b60405161008293929190610441565b60405180910390f35b6000808484846040516024016100a393929190610506565b6040516020818303038152906040527f7fc35677000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008151905060006067905061013661018d565b602084016020828583866000fa61014c57600080fd5b506000816000600181106101635761016261054b565b5b602002015114159450505050509392505050565b6000806000806000617080925092509250909192565b6040518060200160405280600190602082028036833780820191505090505090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101ee826101c3565b9050919050565b6101fe816101e3565b811461020957600080fd5b50565b60008135905061021b816101f5565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6102748261022b565b810181811067ffffffffffffffff821117156102935761029261023c565b5b80604052505050565b60006102a66101af565b90506102b2828261026b565b919050565b600067ffffffffffffffff8211156102d2576102d161023c565b5b6102db8261022b565b9050602081019050919050565b82818337600083830152505050565b600061030a610305846102b7565b61029c565b90508281526020810184848401111561032657610325610226565b5b6103318482856102e8565b509392505050565b600082601f83011261034e5761034d610221565b5b813561035e8482602086016102f7565b91505092915050565b6000806000606084860312156103805761037f6101b9565b5b600061038e8682870161020c565b935050602084013567ffffffffffffffff8111156103af576103ae6101be565b5b6103bb86828701610339565b925050604084013567ffffffffffffffff8111156103dc576103db6101be565b5b6103e886828701610339565b9150509250925092565b60008115159050919050565b610407816103f2565b82525050565b600060208201905061042260008301846103fe565b92915050565b6000819050919050565b61043b81610428565b82525050565b60006060820190506104566000830186610432565b6104636020830185610432565b6104706040830184610432565b949350505050565b610481816101e3565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156104c15780820151818401526020810190506104a6565b60008484015250505050565b60006104d882610487565b6104e28185610492565b93506104f28185602086016104a3565b6104fb8161022b565b840191505092915050565b600060608201905061051b6000830186610478565b818103602083015261052d81856104cd565b9050818103604083015261054181846104cd565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220580f08738139da315b1f79849f0483345f8978c632fa3122169e7bdb6ade283364736f6c63430008120033" + verifyHeadersTestCode = "608060405234801561001057600080fd5b506105af806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80635ade66331461003b578063df4b6ee01461006b575b600080fd5b61005560048036038101906100509190610366565b61008b565b604051610062919061040c565b60405180910390f35b610073610176565b60405161008293929190610440565b60405180910390f35b6000808484846040516024016100a393929190610505565b6040516020818303038152906040527f7fc35677000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060008151905060006067905061013661018c565b602084016020828583865afa61014b57600080fd5b506000816000600181106101625761016161054a565b5b602002015114159450505050509392505050565b6000806000806000617080925092509250909192565b6040518060200160405280600190602082028036833780820191505090505090565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101ed826101c2565b9050919050565b6101fd816101e2565b811461020857600080fd5b50565b60008135905061021a816101f4565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6102738261022a565b810181811067ffffffffffffffff821117156102925761029161023b565b5b80604052505050565b60006102a56101ae565b90506102b1828261026a565b919050565b600067ffffffffffffffff8211156102d1576102d061023b565b5b6102da8261022a565b9050602081019050919050565b82818337600083830152505050565b6000610309610304846102b6565b61029b565b90508281526020810184848401111561032557610324610225565b5b6103308482856102e7565b509392505050565b600082601f83011261034d5761034c610220565b5b813561035d8482602086016102f6565b91505092915050565b60008060006060848603121561037f5761037e6101b8565b5b600061038d8682870161020b565b935050602084013567ffffffffffffffff8111156103ae576103ad6101bd565b5b6103ba86828701610338565b925050604084013567ffffffffffffffff8111156103db576103da6101bd565b5b6103e786828701610338565b9150509250925092565b60008115159050919050565b610406816103f1565b82525050565b600060208201905061042160008301846103fd565b92915050565b6000819050919050565b61043a81610427565b82525050565b60006060820190506104556000830186610431565b6104626020830185610431565b61046f6040830184610431565b949350505050565b610480816101e2565b82525050565b600081519050919050565b600082825260208201905092915050565b60005b838110156104c05780820151818401526020810190506104a5565b60008484015250505050565b60006104d782610486565b6104e18185610491565b93506104f18185602086016104a2565b6104fa8161022a565b840191505092915050565b600060608201905061051a6000830186610477565b818103602083015261052c81856104cc565b9050818103604083015261054081846104cc565b9050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea2646970667358221220dc019b9821e90fec0a5c0be6a93228b7e4c926289e45ad5cce1f893e0dc3267f64736f6c63430008120033" verifyHeadersTestAbi = `[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"getDoubleSignSlashingConfigs","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"consensusAddr","type":"address"},{"internalType":"bytes","name":"header1","type":"bytes"},{"internalType":"bytes","name":"header2","type":"bytes"}],"name":"verify","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]` ) @@ -675,6 +676,66 @@ func TestConsortiumValidatorSorting_Run2(t *testing.T) { } } +func BenchmarkConsortiumValidatorSorting(b *testing.B) { + smcAbi, err := abi.JSON(strings.NewReader(consortiumSortValidatorAbi)) + if err != nil { + b.Fatal(err) + } + + var ( + addresses []common.Address + weights []*big.Int + ) + for i := 0; i < 22; i++ { + addresses = append(addresses, common.BytesToAddress([]byte{uint8(i)})) + weights = append(weights, big.NewInt(rand.Int63())) + } + + input, err := smcAbi.Pack(sortValidatorsMethod, addresses, weights) + if err != nil { + b.Fatal(err) + } + + c := &consortiumValidatorSorting{} + output, err := c.Run(input) + if err != nil { + b.Fatal(err) + } + + test := precompiledTest{ + Input: common.Bytes2Hex(input), + Expected: common.Bytes2Hex(output), + Name: "validator-sort", + } + + benchmarkPrecompiled("66", test, b) + + addresses = nil + weights = nil + for i := 0; i < 100; i++ { + addresses = append(addresses, common.BytesToAddress([]byte{uint8(i)})) + weights = append(weights, big.NewInt(rand.Int63())) + } + + input, err = smcAbi.Pack(sortValidatorsMethod, addresses, weights) + if err != nil { + b.Fatal(err) + } + + output, err = c.Run(input) + if err != nil { + b.Fatal(err) + } + + test = precompiledTest{ + Input: common.Bytes2Hex(input), + Expected: common.Bytes2Hex(output), + Name: "validator-sort", + } + + benchmarkPrecompiled("66", test, b) +} + // TestConsortiumVerifyHeaders_verify tests verify function func TestConsortiumVerifyHeaders_verify(t *testing.T) { header1, header2, err := prepareHeader(big1) @@ -866,6 +927,42 @@ func TestConsortiumVerifyHeaders_Run2(t *testing.T) { } } +func BenchmarkConsortiumVerifyHeaders(b *testing.B) { + smcAbi, err := abi.JSON(strings.NewReader(consortiumVerifyHeadersAbi)) + if err != nil { + b.Fatal(err) + } + header1, header2, err := prepareHeader(big1) + if err != nil { + b.Fatal(err) + } + encodedHeader1, err := types.FromHeader(header1, big1).Bytes(consortiumVerifyHeadersAbi, getHeader) + if err != nil { + b.Fatal(err) + } + encodedHeader2, err := types.FromHeader(header2, big1).Bytes(consortiumVerifyHeadersAbi, getHeader) + if err != nil { + b.Fatal(err) + } + input, err := smcAbi.Pack(verifyHeaders, header1.Coinbase, encodedHeader1, encodedHeader2) + if err != nil { + b.Fatal(err) + } + + output, err := smcAbi.Methods[verifyHeaders].Outputs.Pack(true) + if err != nil { + b.Fatal(err) + } + + test := precompiledTest{ + Input: common.Bytes2Hex(input), + Expected: common.Bytes2Hex(output), + Name: "verify-headers", + } + + benchmarkPrecompiled("67", test, b) +} + // TestArrangeValidatorCandidates arranges 21 candidates with 11 trusted nodes (ordering) func TestArrangeValidatorCandidates(t *testing.T) { scenarios := getTestScenarios() @@ -1609,6 +1706,70 @@ func TestConsortiumPickValidatorSet_Run5(t *testing.T) { } } +func BenchmarkConsortiumPickValidatorSet(b *testing.B) { + smcAbi, err := abi.JSON(strings.NewReader(consortiumPickValidatorSetAbi)) + if err != nil { + b.Fatal(err) + } + + var ( + addresses []common.Address + weights []*big.Int + trustedWeights []*big.Int + ) + for i := 0; i < 22; i++ { + addresses = append(addresses, common.BytesToAddress([]byte{uint8(i)})) + weights = append(weights, big.NewInt(rand.Int63())) + trustedWeights = append(trustedWeights, big0) + } + + input, err := smcAbi.Pack(pickValidatorSetMethod, addresses, weights, trustedWeights, big.NewInt(22), big0) + if err != nil { + b.Fatal(err) + } + + c := &consortiumPickValidatorSet{} + output, err := c.Run(input) + if err != nil { + b.Fatal(err) + } + + test := precompiledTest{ + Input: common.Bytes2Hex(input), + Expected: common.Bytes2Hex(output), + Name: "pick-validator-set", + } + + benchmarkPrecompiled("68", test, b) + + addresses = nil + weights = nil + trustedWeights = nil + for i := 0; i < 100; i++ { + addresses = append(addresses, common.BytesToAddress([]byte{uint8(i)})) + weights = append(weights, big.NewInt(rand.Int63())) + trustedWeights = append(trustedWeights, big0) + } + + input, err = smcAbi.Pack(pickValidatorSetMethod, addresses, weights, trustedWeights, big.NewInt(100), big0) + if err != nil { + b.Fatal(err) + } + + output, err = c.Run(input) + if err != nil { + b.Fatal(err) + } + + test = precompiledTest{ + Input: common.Bytes2Hex(input), + Expected: common.Bytes2Hex(output), + Name: "pick-validator-set", + } + + benchmarkPrecompiled("68", test, b) +} + func prepareHeader(chainId *big.Int) (*types.Header, *types.Header, error) { privateKey, err := crypto.GenerateKey() if err != nil { diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index c73fc27ccc..443a68209b 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -71,6 +71,9 @@ var allPrecompiles = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{17}): &bls12381MapG1{}, common.BytesToAddress([]byte{18}): &bls12381MapG2{}, common.BytesToAddress([]byte{101}): &consortiumLog{}, + common.BytesToAddress([]byte{102}): &consortiumValidatorSorting{}, + common.BytesToAddress([]byte{103}): &consortiumVerifyHeaders{test: true}, + common.BytesToAddress([]byte{104}): &consortiumPickValidatorSet{}, common.BytesToAddress([]byte{105}): &consortiumValidateFinalityProof{}, } diff --git a/params/protocol_params.go b/params/protocol_params.go index 3b318d1970..cdfc325c02 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -155,7 +155,9 @@ const ( Bls12381MapG1Gas uint64 = 5500 // Gas price for BLS12-381 mapping field element to G1 operation Bls12381MapG2Gas uint64 = 110000 // Gas price for BLS12-381 mapping field element to G2 operation - ValidateFinalityProofGas uint64 = 200000 // Gas for validating finality proof + ValidatorSortingBaseGas uint64 = 60 // Base gas for validator sorting and picking validator set + VerifyFinalityHeadersProofGas uint64 = EcrecoverGas*2 + 18000 // Gas for verifying finality headers proof + ValidateFinalityProofGas uint64 = 200000 // Gas for validating finality proof // The Refund Quotient is the cap on how much of the used gas can be refunded. Before EIP-3529, // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529