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:
Jacek Sieka 2024-07-15 15:02:23 +02:00 committed by GitHub
parent 6cf57d9912
commit 0e36a17e5b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 6 deletions

View File

@ -347,12 +347,16 @@ proc persistMode(acc: AccountRef): PersistMode =
result = Remove
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(
contractHashKey(acc.statement.codeHash).toOpenArray, acc.code.bytes())
if rc.isErr:
warn logTxt "persistCode()",
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) =
const info = "persistStorage(): "
@ -452,7 +456,7 @@ proc getCode*(ac: AccountsLedgerRef, address: EthAddress): CodeBytesRef =
warn logTxt "getCode()", codeHash=acc.statement.codeHash, error=($$rc.error)
CodeBytesRef()
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)
else:
CodeBytesRef()

View File

@ -16,16 +16,21 @@ type CodeBytesRef* = ref object
bytes: seq[byte]
invalidPositions: seq[byte] # bit seq of invalid jump positions
processed: int
persisted*: bool ## This code stream has been persisted to the database
template bitpos(pos: int): (int, byte) =
(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)
CodeBytesRef(bytes: move(bytes), invalidPositions: ip)
CodeBytesRef(bytes: move(bytes), invalidPositions: ip, persisted: persisted)
func init*(T: type CodeBytesRef, bytes: openArray[byte]): CodeBytesRef =
CodeBytesRef.init(@bytes)
func init*(
T: type CodeBytesRef, bytes: openArray[byte], persisted = false
): CodeBytesRef =
CodeBytesRef.init(@bytes, persisted = persisted)
func init*(T: type CodeBytesRef, bytes: openArray[char]): CodeBytesRef =
CodeBytesRef.init(bytes.toOpenArrayByte(0, bytes.high()))