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