From 0e36a17e5b55b0a6c662d9f53977e74ede5f0010 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Mon, 15 Jul 2024 15:02:23 +0200 Subject: [PATCH] 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 --- nimbus/db/ledger/backend/accounts_ledger.nim | 8 ++++++-- nimbus/evm/code_bytes.nim | 13 +++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/nimbus/db/ledger/backend/accounts_ledger.nim b/nimbus/db/ledger/backend/accounts_ledger.nim index 73be25700..ab4fb1175 100644 --- a/nimbus/db/ledger/backend/accounts_ledger.nim +++ b/nimbus/db/ledger/backend/accounts_ledger.nim @@ -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() diff --git a/nimbus/evm/code_bytes.nim b/nimbus/evm/code_bytes.nim index 9e78d1aed..78cb2659e 100644 --- a/nimbus/evm/code_bytes.nim +++ b/nimbus/evm/code_bytes.nim @@ -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()))