avoid re-writing code (#2490)
Avoids pointless rocksdb writes that cause write compaction / amplification, specially in the case where code is shared between multiple accounts
This commit is contained in:
parent
6cf57d9912
commit
0e36a17e5b
|
@ -347,12 +347,16 @@ proc persistMode(acc: AccountRef): PersistMode =
|
||||||
result = Remove
|
result = Remove
|
||||||
|
|
||||||
proc persistCode(acc: AccountRef, ac: AccountsLedgerRef) =
|
proc persistCode(acc: AccountRef, ac: AccountsLedgerRef) =
|
||||||
if acc.code.len != 0:
|
if acc.code.len != 0 and not acc.code.persisted:
|
||||||
let rc = ac.kvt.put(
|
let rc = ac.kvt.put(
|
||||||
contractHashKey(acc.statement.codeHash).toOpenArray, acc.code.bytes())
|
contractHashKey(acc.statement.codeHash).toOpenArray, acc.code.bytes())
|
||||||
if rc.isErr:
|
if rc.isErr:
|
||||||
warn logTxt "persistCode()",
|
warn logTxt "persistCode()",
|
||||||
codeHash=acc.statement.codeHash, error=($$rc.error)
|
codeHash=acc.statement.codeHash, error=($$rc.error)
|
||||||
|
else:
|
||||||
|
# If the ledger changes rolled back entirely from the database, the ledger
|
||||||
|
# code cache must also be cleared!
|
||||||
|
acc.code.persisted = true
|
||||||
|
|
||||||
proc persistStorage(acc: AccountRef, ac: AccountsLedgerRef) =
|
proc persistStorage(acc: AccountRef, ac: AccountsLedgerRef) =
|
||||||
const info = "persistStorage(): "
|
const info = "persistStorage(): "
|
||||||
|
@ -452,7 +456,7 @@ proc getCode*(ac: AccountsLedgerRef, address: EthAddress): CodeBytesRef =
|
||||||
warn logTxt "getCode()", codeHash=acc.statement.codeHash, error=($$rc.error)
|
warn logTxt "getCode()", codeHash=acc.statement.codeHash, error=($$rc.error)
|
||||||
CodeBytesRef()
|
CodeBytesRef()
|
||||||
else:
|
else:
|
||||||
let newCode = CodeBytesRef.init(move(rc.value))
|
let newCode = CodeBytesRef.init(move(rc.value), persisted = true)
|
||||||
ac.code.lruAppend(acc.statement.codeHash, newCode, codeLruSize)
|
ac.code.lruAppend(acc.statement.codeHash, newCode, codeLruSize)
|
||||||
else:
|
else:
|
||||||
CodeBytesRef()
|
CodeBytesRef()
|
||||||
|
|
|
@ -16,16 +16,21 @@ type CodeBytesRef* = ref object
|
||||||
bytes: seq[byte]
|
bytes: seq[byte]
|
||||||
invalidPositions: seq[byte] # bit seq of invalid jump positions
|
invalidPositions: seq[byte] # bit seq of invalid jump positions
|
||||||
processed: int
|
processed: int
|
||||||
|
persisted*: bool ## This code stream has been persisted to the database
|
||||||
|
|
||||||
template bitpos(pos: int): (int, byte) =
|
template bitpos(pos: int): (int, byte) =
|
||||||
(pos shr 3, 1'u8 shl (pos and 0x07))
|
(pos shr 3, 1'u8 shl (pos and 0x07))
|
||||||
|
|
||||||
func init*(T: type CodeBytesRef, bytes: sink seq[byte]): CodeBytesRef =
|
func init*(
|
||||||
|
T: type CodeBytesRef, bytes: sink seq[byte], persisted = false
|
||||||
|
): CodeBytesRef =
|
||||||
let ip = newSeq[byte]((bytes.len + 7) div 8)
|
let ip = newSeq[byte]((bytes.len + 7) div 8)
|
||||||
CodeBytesRef(bytes: move(bytes), invalidPositions: ip)
|
CodeBytesRef(bytes: move(bytes), invalidPositions: ip, persisted: persisted)
|
||||||
|
|
||||||
func init*(T: type CodeBytesRef, bytes: openArray[byte]): CodeBytesRef =
|
func init*(
|
||||||
CodeBytesRef.init(@bytes)
|
T: type CodeBytesRef, bytes: openArray[byte], persisted = false
|
||||||
|
): CodeBytesRef =
|
||||||
|
CodeBytesRef.init(@bytes, persisted = persisted)
|
||||||
|
|
||||||
func init*(T: type CodeBytesRef, bytes: openArray[char]): CodeBytesRef =
|
func init*(T: type CodeBytesRef, bytes: openArray[char]): CodeBytesRef =
|
||||||
CodeBytesRef.init(bytes.toOpenArrayByte(0, bytes.high()))
|
CodeBytesRef.init(bytes.toOpenArrayByte(0, bytes.high()))
|
||||||
|
|
Loading…
Reference in New Issue