96 lines
3.0 KiB
Nim
96 lines
3.0 KiB
Nim
# nimbus-eth1
|
|
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
|
# Licensed under either of
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
|
# http://opensource.org/licenses/MIT)
|
|
# at your option. This file may not be copied, modified, or distributed
|
|
# except according to those terms.
|
|
|
|
## Kvt DB -- Transaction fork helpers
|
|
## ==================================
|
|
##
|
|
{.push raises: [].}
|
|
|
|
import
|
|
results,
|
|
./tx_frame,
|
|
".."/[kvt_desc, kvt_layers]
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Public functions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc txFork*(tx: KvtTxRef): Result[KvtDbRef,KvtError] =
|
|
## Clone a transaction into a new DB descriptor accessing the same backend
|
|
## (if any) database as the argument `db`. The new descriptor is linked to
|
|
## the transaction parent and is fully functional as a forked instance (see
|
|
## comments on `kvt_desc.reCentre()` for details.)
|
|
##
|
|
## The new DB descriptor will contain a copy of the argument transaction
|
|
## `tx` as top layer of level 1 (i.e. this is he only transaction.) Rolling
|
|
## back will end up at the backend layer (incl. backend filter.)
|
|
##
|
|
## Use `kvt_desc.forget()` to clean up this descriptor.
|
|
##
|
|
let db = tx.db
|
|
|
|
# Verify `tx` argument
|
|
if db.txRef == tx:
|
|
if db.top.txUid != tx.txUid:
|
|
return err(TxArgStaleTx)
|
|
elif db.stack.len <= tx.level:
|
|
return err(TxArgStaleTx)
|
|
elif db.stack[tx.level].txUid != tx.txUid:
|
|
return err(TxArgStaleTx)
|
|
|
|
# Set up clone associated to `db`
|
|
let txClone = ? db.fork()
|
|
txClone.top = db.layersCc tx.level
|
|
txClone.stack = @[LayerRef.init()] # Provide tx level 1 stack
|
|
txClone.top.txUid = 1
|
|
txClone.txUidGen = 1 # Used value of `txClone.top.txUid`
|
|
|
|
# Install transaction similar to `tx` on clone
|
|
txClone.txRef = KvtTxRef(
|
|
db: txClone,
|
|
txUid: 1,
|
|
level: 1)
|
|
|
|
ok(txClone)
|
|
|
|
|
|
proc txForkTop*(db: KvtDbRef): Result[KvtDbRef,KvtError] =
|
|
## Variant of `forkTx()` for the top transaction if there is any. Otherwise
|
|
## the top layer is cloned, and an empty transaction is set up. After
|
|
## successful fork the returned descriptor has transaction level 1.
|
|
##
|
|
## Use `kvt_desc.forget()` to clean up this descriptor.
|
|
##
|
|
if db.txRef.isNil:
|
|
let dbClone = ? db.fork(noToplayer=true)
|
|
dbClone.top = db.layersCc()
|
|
|
|
discard dbClone.txFrameBegin()
|
|
return ok(dbClone)
|
|
|
|
db.txRef.txFork
|
|
|
|
|
|
proc txForkBase*(
|
|
db: KvtDbRef;
|
|
): Result[KvtDbRef,KvtError] =
|
|
if db.txRef.isNil:
|
|
return db.txForkTop()
|
|
|
|
let txClone = ? db.fork(noToplayer=true, noFilter=false)
|
|
txClone.top = db.layersCc 0
|
|
|
|
discard txClone.txFrameBegin()
|
|
ok(txClone)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# End
|
|
# ------------------------------------------------------------------------------
|