Wire ForkedChainRef properly to TxPool (#2933)

This commit is contained in:
andri lim 2024-12-13 13:21:20 +07:00 committed by GitHub
parent 847cc311eb
commit 2e5ef4fb5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 73 additions and 93 deletions

View File

@ -83,10 +83,9 @@ proc newEngineEnv*(conf: var NimbusConf, chainFile: string, enableAuth: bool): E
let
node = setupEthNode(conf, ctx)
com = makeCom(conf)
head = com.db.getCanonicalHead().expect("canonical head exists")
chain = newForkedChain(com, head)
chain = ForkedChainRef.init(com)
let txPool = TxPoolRef.new(com)
let txPool = TxPoolRef.new(chain)
node.addEthHandlerCapability(
node.peerPool,
@ -95,7 +94,7 @@ proc newEngineEnv*(conf: var NimbusConf, chainFile: string, enableAuth: bool): E
# txPool must be informed of active head
# so it can know the latest account state
doAssert txPool.smartHead(head, chain)
doAssert txPool.smartHead(chain.latestHeader)
var key: JwtSharedKey
key.fromHex(jwtSecret).isOkOr:

View File

@ -83,8 +83,9 @@ proc main() =
conf.networkId,
conf.networkParams
)
let txPool = TxPoolRef.new(com)
chain = ForkedChainRef.init(com)
txPool = TxPoolRef.new(chain)
discard importRlpBlock(blocksFile, com)
let ctx = setupGraphqlContext(com, ethNode, txPool)
@ -94,9 +95,7 @@ proc main() =
# txPool must be informed of active head
# so it can know the latest account state
# e.g. "sendRawTransaction Nonce too low" case
let head = com.db.getCanonicalHead()
let chainRef = newForkedChain(com, head)
doAssert txPool.smartHead(head, chainRef)
doAssert txPool.smartHead(chain.latestHeader)
for fileName in walkDirRec(
caseFolder, yieldFilter = {pcFile,pcLinkToFile}):

View File

@ -52,7 +52,7 @@ proc setupELClient*(conf: ChainConfig, node: JsonNode): TestEnv =
doAssert(head.blockHash == genesisHeader.blockHash)
let
txPool = TxPoolRef.new(com)
txPool = TxPoolRef.new(chain)
beaconEngine = BeaconEngineRef.new(txPool, chain)
serverApi = newServerAPI(chain, txPool)
rpcServer = newRpcHttpServer(["127.0.0.1:0"])

View File

@ -87,15 +87,14 @@ proc setupEnv*(): TestEnv =
manageAccounts(ethCtx, conf)
let head = com.db.getCanonicalHead().expect("canonical head exists")
let chainRef = newForkedChain(com, head)
let txPool = TxPoolRef.new(com)
let chain = ForkedChainRef.init(com)
let txPool = TxPoolRef.new(chain)
# txPool must be informed of active head
# so it can know the latest account state
doAssert txPool.smartHead(head, chainRef)
doAssert txPool.smartHead(chain.latestHeader)
let rpcServer = setupRpcServer(ethCtx, com, ethNode, txPool, conf, chainRef)
let rpcServer = setupRpcServer(ethCtx, com, ethNode, txPool, conf, chain)
let rpcClient = newRpcHttpClient()
waitFor rpcClient.connect("127.0.0.1", Port(8545), false)
let stopServer = stopRpcHttpServer

View File

@ -160,7 +160,7 @@ proc generateExecutionBundle*(ben: BeaconEngineRef,
if headBlock.blockHash != xp.head.blockHash:
# reorg
discard xp.smartHead(headBlock, ben.chain)
discard xp.smartHead(headBlock)
if pos.timestamp <= headBlock.timestamp:
return err "timestamp must be strictly later than parent"

View File

@ -226,14 +226,11 @@
## A piece of code using this pool architecture could look like as follows:
## ::
## # see also unit test examples, e.g. "Block packer tests"
## var db: CoreDbRef # to be initialised
## var chain: ForkedChainRef # to be initialised
## var txs: seq[Transaction] # to be initialised
##
## proc mineThatBlock(blk: EthBlock) # external function
##
## ..
##
## var xq = TxPoolRef.new(db) # initialise tx-pool
## var xq = TxPoolRef.new(chain) # initialise tx-pool
## ..
##
## xq.add(txs) # add transactions ..
@ -241,10 +238,6 @@
##
## let newBlock = xq.assembleBlock # fetch current mining block
##
## ..
## mineThatBlock(newBlock) ... # external mining & signing process
## ..
##
## xp.smartHead(newBlock.header) # update pool, new insertion point
##
##
@ -252,7 +245,7 @@
## ---------------------
## In the example, transactions are processed into buckets via `add()`.
##
## The `ethBlock()` directive assembles and retrieves a new block for mining
## The `assembleBlock()` directive assembles and retrieves a new block for mining
## derived from the current pool state. It invokes the block packer which
## accumulates txs from the `pending` buscket into the `packed` bucket which
## then go into the block.
@ -389,11 +382,11 @@ proc setHead(xp: TxPoolRef; val: Header)
# Public constructor/destructor
# ------------------------------------------------------------------------------
proc new*(T: type TxPoolRef; com: CommonRef): T
proc new*(T: type TxPoolRef; chain: ForkedChainRef): T
{.gcsafe,raises: [].} =
## Constructor, returns a new tx-pool descriptor.
new result
result.init(com)
result.init(chain)
# ------------------------------------------------------------------------------
# Public functions, task manager, pool actions serialiser
@ -422,7 +415,7 @@ proc add*(xp: TxPoolRef; tx: PooledTransaction; info = "")
## Variant of `add()` for a single transaction.
xp.add(@[tx], info)
proc smartHead*(xp: TxPoolRef; pos: Header, chain: ForkedChainRef): bool
proc smartHead*(xp: TxPoolRef; pos: Header): bool
{.gcsafe,raises: [CatchableError].} =
## This function moves the internal head cache (i.e. tx insertion point,
## vmState) and ponts it to a now block on the chain.
@ -434,7 +427,7 @@ proc smartHead*(xp: TxPoolRef; pos: Header, chain: ForkedChainRef): bool
## the internal head cache, the previously calculated actions will be
## applied.
##
let rcDiff = xp.headDiff(pos, chain)
let rcDiff = xp.headDiff(pos, xp.chain)
if rcDiff.isOk:
let changes = rcDiff.value

View File

@ -20,6 +20,7 @@ import
../../evm/types,
../../db/ledger,
../../constants,
../../core/chain/forked_chain,
../pow/header,
../eip4844,
../casper,
@ -56,6 +57,7 @@ type
lifeTime*: times.Duration ## Maximum life time of a tx in the system
priceBump*: uint ## Min precentage price when superseding
chain*: ForkedChainRef
const
txItemLifeTime = ##\
@ -137,12 +139,12 @@ proc update(xp: TxPoolRef; parent: Header) =
# Public functions, constructor
# ------------------------------------------------------------------------------
proc init*(xp: TxPoolRef; com: CommonRef) =
proc init*(xp: TxPoolRef; chain: ForkedChainRef) =
## Constructor, returns new tx-pool descriptor.
xp.startDate = getTime().utc.toTime
let head = com.db.getCanonicalHead.expect("Canonicalhead exists")
xp.vmState = setupVMState(com, head)
let head = chain.latestHeader
xp.vmState = setupVMState(chain.com, head)
xp.txDB = TxTabsRef.new
xp.lifeTime = txItemLifeTime
@ -150,6 +152,7 @@ proc init*(xp: TxPoolRef; com: CommonRef) =
xp.param.reset
xp.param.flags = txPoolFlags
xp.chain = chain
# ------------------------------------------------------------------------------
# Public functions

View File

@ -43,13 +43,13 @@ when defined(evmc_enabled):
proc basicServices(nimbus: NimbusNode,
conf: NimbusConf,
com: CommonRef) =
nimbus.txPool = TxPoolRef.new(com)
nimbus.chainRef = ForkedChainRef.init(com)
# txPool must be informed of active head
# so it can know the latest account state
# e.g. sender nonce, etc
nimbus.chainRef = ForkedChainRef.init(com)
doAssert nimbus.txPool.smartHead(nimbus.chainRef.latestHeader,nimbus.chainRef)
nimbus.txPool = TxPoolRef.new(nimbus.chainRef)
doAssert nimbus.txPool.smartHead(nimbus.chainRef.latestHeader)
nimbus.beaconEngine = BeaconEngineRef.new(nimbus.txPool, nimbus.chainRef)

View File

@ -89,13 +89,12 @@ proc setupEnv(envFork: HardFork = MergeFork,
let
com = setupCom(conf)
head = com.db.getCanonicalHead().expect("canonical head exists")
chain = ForkedChainRef.init(com)
txPool = TxPoolRef.new(com)
txPool = TxPoolRef.new(chain)
# txPool must be informed of active head
# so it can know the latest account state
doAssert txPool.smartHead(head, chain)
doAssert txPool.smartHead(chain.latestHeader)
let
server = newRpcHttpServerWithParams("127.0.0.1:0").valueOr:

View File

@ -18,29 +18,23 @@ import
../nimbus/common/[common, context],
./test_helpers
type
EthBlock = object
header: BlockHeader
transactions: seq[Transaction]
uncles: seq[BlockHeader]
const
caseFolder = "tests/graphql"
dataFolder = "tests/fixtures/eth_tests/BlockchainTests/ValidBlocks/bcUncleTest"
proc toBlock(n: JsonNode, key: string): EthBlock =
proc toBlock(n: JsonNode, key: string): Block =
let rlpBlob = hexToSeqByte(n[key].str)
rlp.decode(rlpBlob, EthBlock)
rlp.decode(rlpBlob, Block)
proc setupChain(): CommonRef =
proc setupChain(): ForkedChainRef =
let config = ChainConfig(
chainId : MainNet.ChainId,
byzantiumBlock : some(0.BlockNumber),
constantinopleBlock : some(0.BlockNumber),
petersburgBlock : some(0.BlockNumber),
istanbulBlock : some(0.BlockNumber),
muirGlacierBlock : some(0.BlockNumber),
berlinBlock : some(10.BlockNumber)
byzantiumBlock : Opt.some(0.BlockNumber),
constantinopleBlock : Opt.some(0.BlockNumber),
petersburgBlock : Opt.some(0.BlockNumber),
istanbulBlock : Opt.some(0.BlockNumber),
muirGlacierBlock : Opt.some(0.BlockNumber),
berlinBlock : Opt.some(10.BlockNumber)
)
var jn = json.parseFile(dataFolder & "/oneUncle.json")
@ -58,48 +52,41 @@ proc setupChain(): CommonRef =
mixHash : gen.header.mixHash,
coinBase : gen.header.coinbase,
timestamp : gen.header.timestamp,
baseFeePerGas: gen.header.fee
baseFeePerGas: gen.header.baseFeePerGas
)
if not parseGenesisAlloc($(jn["pre"]), genesis.alloc):
quit(QuitFailure)
let customNetwork = NetworkParams(
config: config,
genesis: genesis
)
let com = CommonRef.new(
newCoreDbRef DefaultDbMemory, nil,
CustomNet,
customNetwork
)
let blocks = jn["blocks"]
var headers: seq[BlockHeader]
var bodies: seq[BlockBody]
for n in blocks:
let ethBlock = n.toBlock("rlp")
headers.add ethBlock.header
bodies.add BlockBody(
transactions: ethBlock.transactions,
uncles: ethBlock.uncles
let
customNetwork = NetworkParams(
config: config,
genesis: genesis
)
com = CommonRef.new(
newCoreDbRef DefaultDbMemory,
taskpool = nil,
CustomNet,
customNetwork
)
chain = ForkedChainRef.init(com)
blocks = jn["blocks"]
let chain = newChain(com)
let res = chain.persistBlocks(headers, bodies)
assert res.isOk(), res.error()
for n in blocks:
let blk = n.toBlock("rlp")
chain.importBlock(blk).isOkOr:
doAssert(false, error)
com
chain
proc graphqlMain*() =
let
conf = makeTestConfig()
ethCtx = newEthContext()
ethNode = setupEthNode(conf, ethCtx, eth)
com = setupChain()
txPool = TxPoolRef.new(com)
chain = setupChain()
txPool = TxPoolRef.new(chain)
let ctx = setupGraphqlContext(com, ethNode, txPool)
let ctx = setupGraphqlContext(chain.com, ethNode, txPool)
when isMainModule:
ctx.main(caseFolder, purgeSchema = false)
else:

View File

@ -101,6 +101,7 @@ proc initEnv(): TestEnv =
conf.networkId,
conf.networkParams
)
chain = newForkedChain(com, com.genesisHeader)
TestEnv(
com : com,
@ -108,8 +109,8 @@ proc initEnv(): TestEnv =
vaultKey: privKey(hexPrivKey),
nonce : 0'u64,
chainId : conf.networkParams.config.chainId,
xp : TxPoolRef.new(com),
chain : newForkedChain(com, com.genesisHeader),
xp : TxPoolRef.new(chain),
chain : chain,
)
func makeTx(
@ -334,7 +335,7 @@ proc runLedgerTransactionTests(noisy = true) =
)
env.importBlock(Block.init(blk.header, body))
check env.xp.smartHead(blk.header, env.chain)
check env.xp.smartHead(blk.header)
for tx in body.transactions:
env.txs.add tx

View File

@ -245,11 +245,11 @@ proc rpcMain*() =
let
env = setupEnv(signer, ks2, ctx, com)
chain = ForkedChainRef.init(com)
txPool = TxPoolRef.new(com)
txPool = TxPoolRef.new(chain)
# txPool must be informed of active head
# so it can know the latest account state
doAssert txPool.smartHead(chain.latestHeader, chain)
doAssert txPool.smartHead(chain.latestHeader)
let
server = newRpcHttpServerWithParams("127.0.0.1:0").valueOr:

View File

@ -131,7 +131,7 @@ proc initEnv(envFork: HardFork): TestEnv =
conf: conf,
com: com,
chain: chain,
xp: TxPoolRef.new(com),
xp: TxPoolRef.new(chain),
vaultKey: privKey(vaultKeyHex),
chainId: conf.networkParams.config.chainId,
nonce: 0'u64,
@ -262,7 +262,7 @@ proc runTxPoolBlobhashTest() =
tx4 = env.signTxWithNonce(tx3, AccountNonce(env.nonce - 2))
xp = env.xp
check xp.smartHead(blk.header, chain)
check xp.smartHead(blk.header)
xp.add(PooledTransaction(tx: tx4))
check inPoolAndOk(xp, rlpHash(tx4)) == false
@ -318,7 +318,7 @@ proc runTxHeadDelta(noisy = true) =
# Synchronise TxPool against new chain head, register txs differences.
# In this particular case, these differences will simply flush the
# packer bucket.
check xp.smartHead(blk.header, chain)
check xp.smartHead(blk.header)
# Move TxPool chain head to new chain head and apply delta jobs
check xp.nItems.staged == 0
@ -362,7 +362,7 @@ proc runGetBlockBodyTest() =
let blk = r.get.blk
check env.chain.importBlock(blk).isOk
parentHeader = blk.header
check env.xp.smartHead(parentHeader, env.chain)
check env.xp.smartHead(parentHeader)
check blk.transactions.len == 2
test "TxPool create second block":
@ -387,7 +387,7 @@ proc runGetBlockBodyTest() =
let blk = r.get.blk
check env.chain.importBlock(blk).isOk
currentHeader = blk.header
check env.xp.smartHead(currentHeader, env.chain)
check env.xp.smartHead(currentHeader)
check blk.transactions.len == 3
let currHash = currentHeader.blockHash
check env.chain.forkChoice(currHash, currHash).isOk