计算成本
由于 Kaia 的目标是保持 1 秒的区块时间,因此必须对事务的执行时间进行管理。 以下是实现这一目标的三种方法:
- 限制交易的气体限值
- 限制事务的执行时间
- 限制交易的计算成本
限制交易的气体上限并不是一个可行的解决方案,因为气体的概念代表了区块链平台中各种资源(如计算、存储、网络带宽等)当前的交换价值。 它不适合作为衡量事务执行时间的指标。
限制交易的执行时间也不可行,因为区块链平台上不同节点的执行时间可能不同。 例如,我们将事务的执行时间限制为 100 毫秒。 如果一个节点在 90 毫秒内执行了一个事务,而另一个节点在 110 毫秒内执行了该事务,则这两个节点无法达成共识。 因此,这种解决方案并不合适。
最后一种方法是限制交易的计算成本。 我们根据每个 EVM 操作码的实际执行时间对其计算成本进行建模,并限制一个事务的计算成本总和 。 通过这种方法,我们可以排除其他因素,只计算归一化的执行时间单位,节点也能达成共识。
因此,我们为 Kaia 选择了第三种方案。 计算成本上限为 100,000,000 美元,但随着 CPU 计算性能的提高,坎昆 EVM 硬分叉后上限已提高到 150,000,000 美元。 该限制值由平台决定,因此开发人员应了解交易的计算成本。 Kaia 提供 kaia_estimateComputationCost 来计算事务的计算成本。 用法与 kaia_estimateGas 几乎相同。
与硬叉相关的计算成本变更可在本页底部找到。 转到 Hardfork Changes。
计算成本限额
在执行事务时,一系列操作码或预编译合约按顺序执行。 为了限制事务的执行时间,我们根据实际执行时间为操作码和预编译合约建立了一个确定性的执行时间计算模型。
根据这一模型,运算代码和预编译合同的预定计算成本值会被添加到总计算成本中。 如果总值超过计算成本限制,事务执行将中止,并返回 ComputationCostLimitReached(0x0a) 错误。
在设置计算成本限制值时,如果 --opcode-computation-cost-limit
标志值设置为非零值,我们会将其设置为限制值。 如果为零,则限制值将设置为为每个特定硬分叉定义的默认计算成本限制。
作为例外,call/estimateGas/estimateComputationCost 的限制始终设置为无限,不受标志或硬分叉值的影响。 但是,由于其他限制(如油箱盖),执行仍有可能中止。
操作码的计算成本
下表显示了 EVM 运算代码的计算成本。 计算成本是根据实验确定的。
操作码 | 计算成本 |
---|---|
STOP | 0 |
ADD | 150 |
MUL | 200 |
SUB | 219 |
DIV | 404 |
SDIV | 360 |
MOD | 320 |
SMOD | 560 |
ADDMOD | 360 |
MULMOD | 700 |
EXP | 720 |
SIGNEXTEND | 481 |
LT | 201 |
GT | 264 |
SLT | 176 |
SGT | 222 |
EQ | 220 |
ISZERO | 165 |
AND | 288 |
OR | 160 |
XOR | 454 |
NOT | 364 |
BYTE | 589 |
SHL | 478 |
SHR | 498 |
SAR | 834 |
SHA3 | 560 |
ADDRESS | 284 |
BALANCE | 1407 |
ORIGIN | 210 |
CALLER | 188 |
CALLVALUE | 149 |
CALLDATALOAD | 596 |
CALLDATASIZE | 194 |
CALLDATACOPY | 100 |
CODESIZE | 145 |
CODECOPY | 898 |
GASPRICE | 131 |
EXTCODESIZE | 1481 |
EXTCODECOPY | 1000 |
RETURNDATASIZE | 10 |
RETURNDATACOPY | 40 |
EXTCODEHASH | 1000 |
BLOCKHASH | 500 |
COINBASE | 189 |
TIMESTAMP | 265 |
NUMBER | 202 |
PREVRANDAO | 1498 |
GASLIMIT | 166 |
CHAINID | 120 |
SELFBALANCE | 374 |
POP | 140 |
MLOAD | 376 |
MSTORE | 288 |
MSTORE8 | 230 |
SLOAD | 2550 |
SSTORE | 2510 |
JUMP | 253 |
JUMPI | 176 |
PC | 147 |
MSIZE | 137 |
GAS | 230 |
JUMPDEST | 10 |
PUSH0 | 80 |
PUSH1 | 120 |
PUSH2 | 120 |
PUSH3 | 120 |
PUSH4 | 120 |
PUSH5 | 120 |
PUSH6 | 120 |
PUSH7 | 120 |
PUSH8 | 120 |
PUSH9 | 120 |
PUSH10 | 120 |
PUSH11 | 120 |
PUSH12 | 120 |
PUSH13 | 120 |
PUSH14 | 120 |
PUSH15 | 120 |
PUSH16 | 120 |
PUSH17 | 120 |
PUSH18 | 120 |
PUSH19 | 120 |
PUSH20 | 120 |
PUSH21 | 120 |
PUSH22 | 120 |
PUSH23 | 120 |
PUSH24 | 120 |
PUSH25 | 120 |
PUSH26 | 120 |
PUSH27 | 120 |
PUSH28 | 120 |
PUSH29 | 120 |
PUSH30 | 120 |
PUSH31 | 120 |
PUSH32 | 120 |
DUP1 | 190 |
DUP2 | 190 |
DUP3 | 176 |
DUP4 | 142 |
DUP5 | 177 |
DUP6 | 165 |
DUP7 | 147 |
DUP8 | 157 |
DUP9 | 138 |
DUP10 | 174 |
DUP11 | 141 |
DUP12 | 144 |
DUP13 | 157 |
DUP14 | 143 |
DUP15 | 237 |
DUP16 | 149 |
SWAP1 | 141 |
SWAP2 | 156 |
SWAP3 | 145 |
SWAP4 | 135 |
SWAP5 | 115 |
SWAP6 | 146 |
SWAP7 | 199 |
SWAP8 | 130 |
SWAP9 | 160 |
SWAP10 | 134 |
SWAP11 | 147 |
SWAP12 | 128 |
SWAP13 | 121 |
SWAP14 | 114 |
SWAP15 | 197 |
SWAP16 | 128 |
LOG0 | 100 |
LOG1 | 500 |
LOG2 | 500 |
LOG3 | 500 |
LOG4 | 500 |
PUSH | 0 |
DUP | 0 |
SWAP | 0 |
CREATE | 2094 |
CALL | 5000 |
CALLCODE | 4000 |
RETURN | 0 |
DELEGATECALL | 696 |
CREATE2 | 10000 |
STATICCALL | 10000 |
REVERT | 0 |
SELFDESTRUCT | 0 |
BASEFEE | 198 |
BLOBBASEFEE | 120 |
BLOBHASH | 165 |
TSTORE | 280 |
TLOAD | 220 |
MCOPY | 250 |
Precompiled contracts computation cost table
Input
is a byte array input of a precompiled contract.
Address | Precompiled contracts | Computation Cost |
---|---|---|
0x01 | ecrecover | 113,150 |
0x02 | sha256hash | numOfWords(input) / 32 * 100 + 1,000 |
0x03 | ripemd160hash | numOfWords(input) / 32 * 10 + 100 |
0x04 | dataCopy | 0 |
0x05 | bigModExp | 查看代码 此处 |
0x06 | bn256Add | 8,000 |
0x07 | bn256ScalarMul | 100,000 |
0x08 | bn256Pairing | numOfPairings(input) * 1,000,000 + 2,000,000 |
0x09 | blake2f | bigEndian(getRounds(input[0:4])) * 10 + 10,000 |
0x0A | kzg | 2,200,000 |
0x3FD | vmLog | 10 |
0x3FE | feePayer | 10 |
0x3FF | validateSender | numOfSigs(input) * 180,000 + 10,000 |
Hardfork Changes
Hardfork | New items | Changes | ||
---|---|---|---|---|
Cancun EVM | BLOBBASEFEE (0x49) BLOBHASH (0x50) TSTORE (0x5c) opcode TLOAD (0x5d) MCOPY (0x5e) kzg (0x0a) precompiled contract | 提高计算成本限制 从 100,000,000 提高到 150,000,000 降低某些操作码的计算成本 由于 CPU 性能提高 -Sdiv (0x05):739 -> 360 -Mod (0x06):812 -> 320 -Addmod (0x08):1410 -> 360 -Mulmod (0x09):1760 -> 700 -Exp (0x0A):5000 -> 720 -Sha3 (0x20): 2465 -> 560 -Mstore8 (0x53):5142 -> 230 -Log1, Log2, Log3, Log4 (0xA1-0xA4):1000 -> 500 由于数据库大小增加,某些操作码的计算成本会增加 -SLOAD (0x54):835 -> 2550 -SSTORE (0x55):1548 -> 2510 | ||
Shanghai EVM | PUSH0 (0x5f) opcode | |||
Kore | modExp (0x05) 预编译合同 使用新的气体计算逻辑。 计算成本也受到 影响。 更加准确。 | |||
London EVM | BaseFee (0x48) opcode | |||
Istanbul EVM | CHAINID (0x46) opcode SELFBALANCE (0x47) opcode blake2f (0x09) precompiled contract | 降低过高操作码的计算成本 - ADDMOD (0x08):3349 -> 1410 - MULMOD (0x09):4757 -> 1760 - XOR (0x18):657 -> 454 - NOT (0x19):1289 -> 364 - SHL (0x1B): 1603 -> 478 - SHR (0x1C):1815 -> 834 |