constantinople's skeletal implementation
This commit is contained in:
parent
b45e9d5493
commit
213fb3b971
|
@ -48,7 +48,9 @@ type
|
||||||
GasSha3, # Paid for each SHA3 operation.
|
GasSha3, # Paid for each SHA3 operation.
|
||||||
GasSha3Word, # Paid for each word (rounded up) for input data to a SHA3 operation.
|
GasSha3Word, # Paid for each word (rounded up) for input data to a SHA3 operation.
|
||||||
GasCopy, # Partial payment for COPY operations, multiplied by words copied, rounded up.
|
GasCopy, # Partial payment for COPY operations, multiplied by words copied, rounded up.
|
||||||
GasBlockhash # Payment for BLOCKHASH operation.
|
GasBlockhash, # Payment for BLOCKHASH operation.
|
||||||
|
GasArithmetic, # Payment for bitwise Shl and Shr operators
|
||||||
|
GasExtCodeHash # Payment for contract's code hashing
|
||||||
|
|
||||||
GasFeeSchedule = array[GasFeeKind, GasInt]
|
GasFeeSchedule = array[GasFeeKind, GasInt]
|
||||||
|
|
||||||
|
@ -400,6 +402,9 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
|
||||||
Xor: fixed GasVeryLow,
|
Xor: fixed GasVeryLow,
|
||||||
Not: fixed GasVeryLow,
|
Not: fixed GasVeryLow,
|
||||||
Byte: fixed GasVeryLow,
|
Byte: fixed GasVeryLow,
|
||||||
|
Shl: fixed GasArithmetic,
|
||||||
|
Shr: fixed GasArithmetic,
|
||||||
|
Sar: fixed GasVeryLow,
|
||||||
|
|
||||||
# 20s: SHA3
|
# 20s: SHA3
|
||||||
Sha3: memExpansion `prefix gasSha3`,
|
Sha3: memExpansion `prefix gasSha3`,
|
||||||
|
@ -420,6 +425,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
|
||||||
ExtCodeCopy: memExpansion `prefix gasExtCodeCopy`,
|
ExtCodeCopy: memExpansion `prefix gasExtCodeCopy`,
|
||||||
ReturnDataSize: fixed GasBase,
|
ReturnDataSize: fixed GasBase,
|
||||||
ReturnDataCopy: memExpansion `prefix gasCopy`,
|
ReturnDataCopy: memExpansion `prefix gasCopy`,
|
||||||
|
ExtCodeHash: fixed GasExtCodeHash,
|
||||||
|
|
||||||
# 40s: Block Information
|
# 40s: Block Information
|
||||||
Blockhash: fixed GasBlockhash,
|
Blockhash: fixed GasBlockhash,
|
||||||
|
@ -526,6 +532,7 @@ template gasCosts(fork: Fork, prefix, ResultGasCostsName: untyped) =
|
||||||
CallCode: complex `prefix gasCall`,
|
CallCode: complex `prefix gasCall`,
|
||||||
Return: memExpansion `prefix gasHalt`,
|
Return: memExpansion `prefix gasHalt`,
|
||||||
DelegateCall: complex `prefix gasCall`,
|
DelegateCall: complex `prefix gasCall`,
|
||||||
|
Create2: complex `prefix gasCall`,
|
||||||
StaticCall: complex `prefix gasCall`,
|
StaticCall: complex `prefix gasCall`,
|
||||||
Revert: memExpansion `prefix gasHalt`,
|
Revert: memExpansion `prefix gasHalt`,
|
||||||
Invalid: fixed GasZero,
|
Invalid: fixed GasZero,
|
||||||
|
@ -570,7 +577,9 @@ const
|
||||||
GasSha3: 30,
|
GasSha3: 30,
|
||||||
GasSha3Word: 6,
|
GasSha3Word: 6,
|
||||||
GasCopy: 3,
|
GasCopy: 3,
|
||||||
GasBlockhash: 20
|
GasBlockhash: 20,
|
||||||
|
GasArithmetic: 35,
|
||||||
|
GasExtCodeHash: 400
|
||||||
]
|
]
|
||||||
|
|
||||||
# Create the schedule for each forks
|
# Create the schedule for each forks
|
||||||
|
@ -605,7 +614,8 @@ const
|
||||||
FkDao: HomesteadGasFees,
|
FkDao: HomesteadGasFees,
|
||||||
FkTangerine: TangerineGasFees,
|
FkTangerine: TangerineGasFees,
|
||||||
FkSpurious: SpuriousGasFees,
|
FkSpurious: SpuriousGasFees,
|
||||||
FkByzantium: SpuriousGasFees, # not supported yet
|
FkByzantium: SpuriousGasFees,
|
||||||
|
FkConstantinople: SpuriousGasFees
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,9 @@ fill_enum_holes:
|
||||||
Xor = 0x18, # Bitwise XOR operation.
|
Xor = 0x18, # Bitwise XOR operation.
|
||||||
Not = 0x19, # Bitwise NOT operation.
|
Not = 0x19, # Bitwise NOT operation.
|
||||||
Byte = 0x1A, # Retrieve single byte from word.
|
Byte = 0x1A, # Retrieve single byte from word.
|
||||||
|
Shl = 0x1B, # Shift left
|
||||||
|
Shr = 0x1C, # Logical shift right
|
||||||
|
Sar = 0x1D, # Arithmetic shift right
|
||||||
|
|
||||||
# 20s: SHA3
|
# 20s: SHA3
|
||||||
Sha3 = 0x20, # Compute Keccak-256 hash.
|
Sha3 = 0x20, # Compute Keccak-256 hash.
|
||||||
|
@ -66,6 +69,7 @@ fill_enum_holes:
|
||||||
ExtCodeCopy = 0x3c, # Copy an account's code to memory.
|
ExtCodeCopy = 0x3c, # Copy an account's code to memory.
|
||||||
ReturnDataSize = 0x3d, # Get size of output data from the previous call from the current environment.
|
ReturnDataSize = 0x3d, # Get size of output data from the previous call from the current environment.
|
||||||
ReturnDataCopy = 0x3e, # Copy output data from the previous call to memory.
|
ReturnDataCopy = 0x3e, # Copy output data from the previous call to memory.
|
||||||
|
ExtCodeHash = 0x3f, # Returns the keccak256 hash of a contract’s code
|
||||||
|
|
||||||
# 40s: Block Information
|
# 40s: Block Information
|
||||||
Blockhash = 0x40, # Get the hash of one of the 256 most recent complete blocks.
|
Blockhash = 0x40, # Get the hash of one of the 256 most recent complete blocks.
|
||||||
|
@ -172,6 +176,7 @@ fill_enum_holes:
|
||||||
CallCode = 0xf2, # Message-call into this account with an alternative account's code.
|
CallCode = 0xf2, # Message-call into this account with an alternative account's code.
|
||||||
Return = 0xf3, # Halt execution returning output data.
|
Return = 0xf3, # Halt execution returning output data.
|
||||||
DelegateCall = 0xf4, # Message-call into this account with an alternative account's code, but persisting the current values for sender and value.
|
DelegateCall = 0xf4, # Message-call into this account with an alternative account's code, but persisting the current values for sender and value.
|
||||||
|
Create2 = 0xf5, # Behaves identically to CREATE, except using keccak256( 0xff ++ address ++ salt ++ keccak256(init_code))[12:]
|
||||||
StaticCall = 0xfa, # Static message-call into an account.
|
StaticCall = 0xfa, # Static message-call into an account.
|
||||||
Revert = 0xfd, # Halt execution reverting state changes but returning data and remaining gas.
|
Revert = 0xfd, # Halt execution reverting state changes but returning data and remaining gas.
|
||||||
Invalid = 0xfe, # Designated invalid instruction.
|
Invalid = 0xfe, # Designated invalid instruction.
|
||||||
|
|
|
@ -881,3 +881,24 @@ op selfDestructEip161, inline = false:
|
||||||
let gasCost = computation.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
let gasCost = computation.gasCosts[SelfDestruct].c_handler(0.u256, gasParams).gasCost
|
||||||
computation.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP161")
|
computation.gasMeter.consumeGas(gasCost, reason = "SELFDESTRUCT EIP161")
|
||||||
selfDestructImpl(computation, beneficiary)
|
selfDestructImpl(computation, beneficiary)
|
||||||
|
|
||||||
|
# Constantinople's new opcodes
|
||||||
|
op shlOp, inline = true, num, shift:
|
||||||
|
# TODO: implementation
|
||||||
|
discard
|
||||||
|
|
||||||
|
op shrOp, inline = true, num, shift:
|
||||||
|
# TODO: implementation
|
||||||
|
discard
|
||||||
|
|
||||||
|
op sarOp, inline = true, num, shift:
|
||||||
|
# TODO: implementation
|
||||||
|
discard
|
||||||
|
|
||||||
|
op extCodeHash, inline = true, address:
|
||||||
|
# TODO: implementation
|
||||||
|
discard
|
||||||
|
|
||||||
|
op create2, inline = false:
|
||||||
|
# TODO: implementation
|
||||||
|
discard
|
||||||
|
|
|
@ -15,17 +15,19 @@ type
|
||||||
FkDao,
|
FkDao,
|
||||||
FkTangerine,
|
FkTangerine,
|
||||||
FkSpurious,
|
FkSpurious,
|
||||||
FkByzantium
|
FkByzantium,
|
||||||
|
FkConstantinople
|
||||||
|
|
||||||
const
|
const
|
||||||
forkBlocks*: array[Fork, Uint256] = [
|
forkBlocks*: array[Fork, Uint256] = [
|
||||||
FkFrontier: 1.u256, # 30/07/2015 19:26:28
|
FkFrontier: 1.u256, # 30/07/2015 19:26:28
|
||||||
FkThawing: 200_000.u256, # 08/09/2015 01:33:09
|
FkThawing: 200_000.u256, # 08/09/2015 01:33:09
|
||||||
FkHomestead: 1_150_000.u256, # 14/03/2016 20:49:53
|
FkHomestead: 1_150_000.u256, # 14/03/2016 20:49:53
|
||||||
FkDao: 1_920_000.u256, # 20/07/2016 17:20:40
|
FkDao: 1_920_000.u256, # 20/07/2016 17:20:40
|
||||||
FkTangerine: 2_463_000.u256, # 18/10/2016 17:19:31
|
FkTangerine: 2_463_000.u256, # 18/10/2016 17:19:31
|
||||||
FkSpurious: 2_675_000.u256, # 22/11/2016 18:15:44
|
FkSpurious: 2_675_000.u256, # 22/11/2016 18:15:44
|
||||||
FkByzantium: 4_370_000.u256 # 16/10/2017 09:22:11
|
FkByzantium: 4_370_000.u256, # 16/10/2017 09:22:11
|
||||||
|
FkConstantinople: 7_280_000.u256 # 28/02/2019 07:52:04
|
||||||
]
|
]
|
||||||
|
|
||||||
proc toFork*(blockNumber: UInt256): Fork =
|
proc toFork*(blockNumber: UInt256): Fork =
|
||||||
|
@ -44,8 +46,8 @@ proc toFork*(blockNumber: UInt256): Fork =
|
||||||
elif blockNumber < forkBlocks[FkTangerine]: FkDao
|
elif blockNumber < forkBlocks[FkTangerine]: FkDao
|
||||||
elif blockNumber < forkBlocks[FkSpurious]: FkTangerine
|
elif blockNumber < forkBlocks[FkSpurious]: FkTangerine
|
||||||
elif blockNumber < forkBlocks[FkByzantium]: FkSpurious
|
elif blockNumber < forkBlocks[FkByzantium]: FkSpurious
|
||||||
else:
|
elif blockNumber < forkBlocks[FkConstantinople]: FkByzantium
|
||||||
FkByzantium # Update for constantinople when announced
|
else: FkConstantinople
|
||||||
|
|
||||||
proc `$`*(fork: Fork): string =
|
proc `$`*(fork: Fork): string =
|
||||||
case fork
|
case fork
|
||||||
|
@ -56,4 +58,5 @@ proc `$`*(fork: Fork): string =
|
||||||
of FkTangerine: result = "Tangerine Whistle"
|
of FkTangerine: result = "Tangerine Whistle"
|
||||||
of FkSpurious: result = "Spurious Dragon"
|
of FkSpurious: result = "Spurious Dragon"
|
||||||
of FkByzantium: result = "Byzantium"
|
of FkByzantium: result = "Byzantium"
|
||||||
|
of FkConstantinople: result = "Constantinople"
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,16 @@ proc genByzantiumJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compil
|
||||||
|
|
||||||
let ByzantiumOpDispatch {.compileTime.}: array[Op, NimNode] = genByzantiumJumpTable(SpuriousOpDispatch)
|
let ByzantiumOpDispatch {.compileTime.}: array[Op, NimNode] = genByzantiumJumpTable(SpuriousOpDispatch)
|
||||||
|
|
||||||
|
proc genConstantinopleJumpTable(ops: array[Op, NimNode]): array[Op, NimNode] {.compileTime.} =
|
||||||
|
result = ops
|
||||||
|
result[Shl] = newIdentNode "shlOp"
|
||||||
|
result[Shr] = newIdentNode "shrOp"
|
||||||
|
result[Sar] = newIdentNode "sarOp"
|
||||||
|
result[ExtCodeHash] = newIdentNode "extCodeHash"
|
||||||
|
result[Create2] = newIdentNode "create2"
|
||||||
|
|
||||||
|
let ConstantinopleOpDispatch {.compileTime.}: array[Op, NimNode] = genConstantinopleJumpTable(ByzantiumOpDispatch)
|
||||||
|
|
||||||
proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNode =
|
proc opTableToCaseStmt(opTable: array[Op, NimNode], computation: NimNode): NimNode =
|
||||||
|
|
||||||
let instr = quote do: `computation`.instr
|
let instr = quote do: `computation`.instr
|
||||||
|
@ -275,6 +285,9 @@ macro genSpuriousDispatch(computation: BaseComputation): untyped =
|
||||||
macro genByzantiumDispatch(computation: BaseComputation): untyped =
|
macro genByzantiumDispatch(computation: BaseComputation): untyped =
|
||||||
result = opTableToCaseStmt(ByzantiumOpDispatch, computation)
|
result = opTableToCaseStmt(ByzantiumOpDispatch, computation)
|
||||||
|
|
||||||
|
macro genConstantinopleDispatch(computation: BaseComputation): untyped =
|
||||||
|
result = opTableToCaseStmt(ConstantinopleOpDispatch, computation)
|
||||||
|
|
||||||
proc frontierVM(computation: BaseComputation) =
|
proc frontierVM(computation: BaseComputation) =
|
||||||
genFrontierDispatch(computation)
|
genFrontierDispatch(computation)
|
||||||
|
|
||||||
|
@ -290,6 +303,9 @@ proc spuriousVM(computation: BaseComputation) {.gcsafe.} =
|
||||||
proc byzantiumVM(computation: BaseComputation) {.gcsafe.} =
|
proc byzantiumVM(computation: BaseComputation) {.gcsafe.} =
|
||||||
genByzantiumDispatch(computation)
|
genByzantiumDispatch(computation)
|
||||||
|
|
||||||
|
proc constantinopleVM(computation: BaseComputation) {.gcsafe.} =
|
||||||
|
genConstantinopleDispatch(computation)
|
||||||
|
|
||||||
proc selectVM(computation: BaseComputation, fork: Fork) {.gcsafe.} =
|
proc selectVM(computation: BaseComputation, fork: Fork) {.gcsafe.} =
|
||||||
# TODO: Optimise getting fork and updating opCodeExec only when necessary
|
# TODO: Optimise getting fork and updating opCodeExec only when necessary
|
||||||
case fork
|
case fork
|
||||||
|
@ -303,6 +319,8 @@ proc selectVM(computation: BaseComputation, fork: Fork) {.gcsafe.} =
|
||||||
computation.spuriousVM()
|
computation.spuriousVM()
|
||||||
of FKByzantium:
|
of FKByzantium:
|
||||||
computation.byzantiumVM()
|
computation.byzantiumVM()
|
||||||
|
else:
|
||||||
|
computation.constantinopleVM()
|
||||||
|
|
||||||
proc executeOpcodes(computation: BaseComputation) =
|
proc executeOpcodes(computation: BaseComputation) =
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -21,6 +21,7 @@ const
|
||||||
FkTangerine: "EIP150",
|
FkTangerine: "EIP150",
|
||||||
FkSpurious: "EIP158",
|
FkSpurious: "EIP158",
|
||||||
FkByzantium: "Byzantium",
|
FkByzantium: "Byzantium",
|
||||||
|
FkConstantinople: "ConstantinopleFix"
|
||||||
}.toTable
|
}.toTable
|
||||||
|
|
||||||
supportedForks* = {FkFrontier, FkHomestead, FkTangerine, FkSpurious, FkByzantium}
|
supportedForks* = {FkFrontier, FkHomestead, FkTangerine, FkSpurious, FkByzantium}
|
||||||
|
|
Loading…
Reference in New Issue