Skip to content

Commit

Permalink
EIP-1052 implementation. #14
Browse files Browse the repository at this point in the history
  • Loading branch information
dcaoyuan committed Mar 31, 2019
1 parent c510bc3 commit e2bd777
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 10 deletions.
4 changes: 4 additions & 0 deletions khipu-eth/src/main/scala/khipu/ledger/BlockWorldState.scala
Expand Up @@ -273,6 +273,10 @@ final class BlockWorldState private (
this
}

def getCodeHash(address: Address): Option[UInt256] = {
getAccount(address).map(_.codeHash).map(UInt256(_))
}

private def addRaceCondition(modified: RaceCondition, address: Address) {
raceConditions += (modified -> (raceConditions.getOrElse(modified, Set()) + address))
}
Expand Down
23 changes: 16 additions & 7 deletions khipu-eth/src/main/scala/khipu/vm/EvmConfig.scala
Expand Up @@ -48,7 +48,8 @@ object EvmConfig {
eip212 = false,
eip198 = false,
eip658 = false,
eip145 = false
eip145 = false,
eip1052 = false
)

val HomesteadConfig = EvmConfig(
Expand All @@ -65,7 +66,8 @@ object EvmConfig {
eip212 = false,
eip198 = false,
eip658 = false,
eip145 = false
eip145 = false,
eip1052 = false
)

val PostEIP150Config = HomesteadConfig.copy(
Expand Down Expand Up @@ -116,7 +118,8 @@ object EvmConfig {

val ConstantinopleConfig = ByzantiumConfig.copy(
opCodes = OpCodes.ConstantinopleCodes,
eip145 = true
eip145 = true,
eip1052 = true
)
}

Expand All @@ -134,7 +137,8 @@ final case class EvmConfig(
eip212: Boolean, // replaced eip197
eip198: Boolean,
eip658: Boolean,
eip145: Boolean
eip145: Boolean,
eip1052: Boolean
) {
import EvmConfig._

Expand Down Expand Up @@ -259,7 +263,9 @@ object FeeSchedule {
override val G_sha3word = 6
override val G_copy = 3
override val G_blockhash = 20
override val G_extcode = 20
override val G_extcodesize = 20
override val G_extcodecopy = 20
override val G_extcodehash = 400
}

object HomesteadFeeSchedule extends HomesteadFeeSchedule
Expand All @@ -273,7 +279,8 @@ object FeeSchedule {
override val G_call = 700
override val G_balance = 400
override val G_selfdestruct = 5000
override val G_extcode = 700
override val G_extcodesize = 700
override val G_extcodecopy = 700
}

object PostEIP160FeeSchedule extends PostEIP160FeeSchedule
Expand Down Expand Up @@ -316,5 +323,7 @@ trait FeeSchedule {
def G_sha3word: Long
def G_copy: Long
def G_blockhash: Long
def G_extcode: Long
def G_extcodesize: Long
def G_extcodecopy: Long
def G_extcodehash: Long
}
22 changes: 19 additions & 3 deletions khipu-eth/src/main/scala/khipu/vm/OpCode.scala
Expand Up @@ -169,7 +169,8 @@ object OpCodes {
val ConstantinopleCodes: List[OpCode[_]] = ByzantiumOpCodes ++ List(
SHL,
SHR,
SAR
SAR,
EXTCODEHASH
)
}

Expand Down Expand Up @@ -564,7 +565,7 @@ case object CODECOPY extends OpCode[(UInt256, UInt256, UInt256)](0x39, 3, 0) {
}

case object EXTCODESIZE extends OpCode[UInt256](0x3b, 1, 1) with ConstGas[UInt256] {
protected def constGasFn(s: FeeSchedule) = s.G_extcode
protected def constGasFn(s: FeeSchedule) = s.G_extcodesize
protected def getParams[W <: WorldState[W, S], S <: Storage[S]](state: ProgramState[W, S]) = {
val List(addr) = state.stack.pop()
addr
Expand All @@ -579,7 +580,7 @@ case object EXTCODESIZE extends OpCode[UInt256](0x3b, 1, 1) with ConstGas[UInt25
}

case object EXTCODECOPY extends OpCode[(UInt256, UInt256, UInt256, UInt256)](0x3c, 4, 0) {
protected def constGasFn(s: FeeSchedule) = s.G_extcode
protected def constGasFn(s: FeeSchedule) = s.G_extcodecopy
protected def getParams[W <: WorldState[W, S], S <: Storage[S]](state: ProgramState[W, S]) = {
// do not need to check params bound, just use safe int value
val List(address, memOffset, codeOffset, size) = state.stack.pop(4)
Expand All @@ -601,6 +602,21 @@ case object EXTCODECOPY extends OpCode[(UInt256, UInt256, UInt256, UInt256)](0x3
}
}

case object EXTCODEHASH extends OpCode[UInt256](0x3f, 1, 1) with ConstGas[UInt256] {
protected def constGasFn(s: FeeSchedule) = s.G_extcodehash
protected def getParams[W <: WorldState[W, S], S <: Storage[S]](state: ProgramState[W, S]) = {
val List(addr) = state.stack.pop()
addr
}

protected def exec[W <: WorldState[W, S], S <: Storage[S]](state: ProgramState[W, S], params: UInt256): ProgramState[W, S] = {
val addr = params
val codeHash = state.world.getCodeHash(Address(addr)).getOrElse(UInt256.Zero)
state.stack.push(codeHash)
state.step()
}
}

case object RETURNDATASIZE extends OpCode[Unit](0x3d, 0, 1) with ConstGas[Unit] {
protected def constGasFn(s: FeeSchedule) = s.G_base
protected def getParams[W <: WorldState[W, S], S <: Storage[S]](state: ProgramState[W, S]) = ()
Expand Down
1 change: 1 addition & 0 deletions khipu-eth/src/main/scala/khipu/vm/WorldState.scala
Expand Up @@ -41,6 +41,7 @@ trait WorldState[W <: WorldState[W, S], S <: Storage[S]] { self: W =>
def getCode(address: Address): ByteString
def getStorage(address: Address): S
def getBlockHash(number: Long): Option[UInt256]
def getCodeHash(address: Address): Option[UInt256]

def saveCode(address: Address, code: ByteString): W
def saveStorage(address: Address, storage: S): W
Expand Down

0 comments on commit e2bd777

Please sign in to comment.