Skip to content

Commit

Permalink
EIP-1283 implementation. #14
Browse files Browse the repository at this point in the history
  • Loading branch information
dcaoyuan committed Mar 31, 2019
1 parent e2bd777 commit dcf8a61
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 7 deletions.
8 changes: 8 additions & 0 deletions khipu-eth/src/main/scala/khipu/ledger/TrieStorage.scala
Expand Up @@ -25,11 +25,19 @@ final class TrieStorage private (

def underlying = underlyingTrie

private var originalValues = Map[UInt256, UInt256]()

def getOriginalValue(address: UInt256): Option[UInt256] =
originalValues.get(address) orElse underlyingTrie.get(address)

def load(address: UInt256): UInt256 = {
logs.get(address) match {
case None =>
underlyingTrie.get(address) match {
case Some(value) =>
if (!originalValues.contains(address)) {
originalValues += (address -> value)
}
logs += (address -> Original(value))
value
case None => UInt256.Zero
Expand Down
11 changes: 8 additions & 3 deletions khipu-eth/src/main/scala/khipu/vm/EvmConfig.scala
Expand Up @@ -49,7 +49,8 @@ object EvmConfig {
eip198 = false,
eip658 = false,
eip145 = false,
eip1052 = false
eip1052 = false,
eip1283 = false
)

val HomesteadConfig = EvmConfig(
Expand All @@ -67,7 +68,8 @@ object EvmConfig {
eip198 = false,
eip658 = false,
eip145 = false,
eip1052 = false
eip1052 = false,
eip1283 = false
)

val PostEIP150Config = HomesteadConfig.copy(
Expand Down Expand Up @@ -138,7 +140,8 @@ final case class EvmConfig(
eip198: Boolean,
eip658: Boolean,
eip145: Boolean,
eip1052: Boolean
eip1052: Boolean,
eip1283: Boolean
) {
import EvmConfig._

Expand Down Expand Up @@ -240,6 +243,7 @@ object FeeSchedule {
override val G_jumpdest = 1
override val G_sset = 20000
override val G_sreset = 5000
override val G_sreuse = 200
override val R_sclear = 15000
override val R_selfdestruct = 24000
override val G_selfdestruct = 0
Expand Down Expand Up @@ -300,6 +304,7 @@ trait FeeSchedule {
def G_jumpdest: Long
def G_sset: Long
def G_sreset: Long
def G_sreuse: Long
def R_sclear: Long
def R_selfdestruct: Long
def G_selfdestruct: Long
Expand Down
62 changes: 58 additions & 4 deletions khipu-eth/src/main/scala/khipu/vm/OpCode.scala
Expand Up @@ -771,7 +771,40 @@ case object SSTORE extends OpCode[(UInt256, UInt256)](0x55, 2, 0) {
} else {
val (key, value) = params
val oldValue = state.storage.load(key)
val refund = if (value.isZero && oldValue.nonZero) state.config.feeSchedule.R_sclear else 0
var refund = 0L
if (state.config.eip1283) {
val origValue = state.storage.getOriginalValue(key).getOrElse(UInt256.Zero)
if (oldValue == origValue) {
if (origValue.isZero) {
// no refund
} else {
if (value.isZero) {
refund += state.config.feeSchedule.R_sclear
}
}
} else { // oldValue != origValue
if (origValue.nonZero) {
if (value.isZero) {
refund -= state.config.feeSchedule.R_sclear
} else {
refund += state.config.feeSchedule.R_sclear
}
}

if (origValue == value) {
if (origValue.isZero) {
refund += (state.config.feeSchedule.G_sset - state.config.feeSchedule.R_sclear)
} else {
refund += (state.config.feeSchedule.G_sreset - state.config.feeSchedule.R_sclear)
}
}
}
} else {
if (oldValue.nonZero && value.isZero) {
refund += state.config.feeSchedule.R_sclear
}
}

val updatedStorage = state.storage.store(key, value)
val world = state.world.saveStorage(state.ownAddress, updatedStorage)

Expand All @@ -783,9 +816,30 @@ case object SSTORE extends OpCode[(UInt256, UInt256)](0x55, 2, 0) {
}

protected def varGas[W <: WorldState[W, S], S <: Storage[S]](state: ProgramState[W, S], params: (UInt256, UInt256)): Long = {
val (offset, value) = params
val oldValue = state.storage.load(offset)
if (oldValue.isZero && !value.isZero) state.config.feeSchedule.G_sset else state.config.feeSchedule.G_sreset
val (key, value) = params
val oldValue = state.storage.load(key)
if (state.config.eip1283) {
if (value == oldValue) {
state.config.feeSchedule.G_sreuse
} else {
val origValue = state.storage.getOriginalValue(key).getOrElse(UInt256.Zero)
if (oldValue == origValue) {
if (origValue.isZero) {
state.config.feeSchedule.G_sset
} else {
state.config.feeSchedule.G_sreset
}
} else {
state.config.feeSchedule.G_sreuse
}
}
} else {
if (oldValue.isZero && value.nonZero) {
state.config.feeSchedule.G_sset
} else {
state.config.feeSchedule.G_sreset
}
}
}
}

Expand Down
1 change: 1 addition & 0 deletions khipu-eth/src/main/scala/khipu/vm/Storage.scala
Expand Up @@ -8,4 +8,5 @@ import khipu.UInt256
trait Storage[S <: Storage[S]] {
def store(offset: UInt256, value: UInt256): S
def load(offset: UInt256): UInt256
def getOriginalValue(address: UInt256): Option[UInt256]
}

0 comments on commit dcf8a61

Please sign in to comment.