Kludge needed for setting up custom network (#944)

* Kludge needed for setting up custom network

why:
  Some non-features in the persistent hexary trie DB produce an assert
  error when initiating the Kinsugi network.

details:
  This fix should be temporary, only.

* Fix OS detection

why:
  directive detectOs() bails out on Windows if checking for Ubuntu
This commit is contained in:
Jordan Hrycaj 2022-02-01 12:04:20 +00:00 committed by GitHub
parent ebdf8a0de5
commit 77c9b8c2f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 28 deletions

View File

@ -1,6 +1,6 @@
import
std/tables,
eth/[common, rlp, trie, p2p],
eth/[common, rlp, p2p],
chronicles, eth/trie/[db, trie_defs],
./db/[db_chain, state_db],
"."/[constants, chain_config, forks, p2p/gaslimit]
@ -9,12 +9,45 @@ proc toBlock*(g: Genesis, db: BaseChainDB = nil):
BlockHeader {.raises: [Defect, RlpError].} =
let (tdb, pruneTrie) = if db.isNil: (newMemoryDB(), true)
else: (db.db, db.pruneTrie)
tdb.put(emptyRlpHash.data, emptyRlp)
# For `eth/trie/db.newMemoryDB()`, the following initialiation is part of
# the constructor function which is missing for the permanent constructor
# function `eth/trie/db.trieDB()`.
if not db.isNil:
tdb.put(emptyRlpHash.data, emptyRlp)
var sdb = newAccountStateDB(tdb, emptyRlpHash, pruneTrie)
for address, account in g.alloc:
sdb.setAccount(address, newAccount(account.nonce, account.balance))
sdb.setCode(address, account.code)
# Kludge:
#
# With the pruning persistent version, the initial/trivial key-value
# pair `(emptyRlpHash.data,emptyRlp)` will have been deleted after
# adding a non-trivial key-value pair in one of the above functions.
# This happens in the function/template
#
# eth/trie/db.del() called by
# eth/trie/hexary.prune() invoked by
# eth/trie/hexary.origWithNewValue() invoked by
# eth/trie/hexary.mergeAt() called by
# eth/trie/hexary.put()
#
# if the database contains the trivial key-value pair, only.
# Unfortunately, the *trie* is now empty but the previous root hash
# is re-used. This leads to an assert exception in any subsequent
# invocation of `eth/trie/hexary.put()`.
#
# See also https://github.com/status-im/nim-eth/issues/9 where other,
# probably related debilities are discussed.
#
# This kludge also fixes the initial crash described in
# https://github.com/status-im/nimbus-eth1/issues/932.
if not db.isNil and db.pruneTrie:
tdb.put(emptyRlpHash.data, emptyRlp) # <-- kludge
for k, v in account.storage:
sdb.setStorage(address, k, v)
@ -44,6 +77,7 @@ proc toBlock*(g: Genesis, db: BaseChainDB = nil):
if g.difficulty.isZero:
result.difficulty = GENESIS_DIFFICULTY
proc initializeEmptyDb*(db: BaseChainDB) =
trace "Writing genesis to DB"
let b = db.genesis.toBlock(db)

View File

@ -9,19 +9,41 @@
# according to those terms.
import
std/[os, strformat, strutils],
std/[distros, os, strformat, strutils],
../nimbus/[chain_config, config, genesis],
../nimbus/db/[db_chain, select_backend],
eth/[common, p2p, trie/db],
unittest2
const
isLinux32bit = defined(linux) and int.sizeof == 4
baseDir = [".", "tests", ".." / "tests", $DirSep] # path containg repo
repoDir = ["status", "replay"] # alternative repo paths
jFile = "nimbus_kintsugi.json"
when defined(windows):
const isUbuntu32bit = false
else:
# The `detectOs(Ubuntu)` directive is not Windows compatible, causes an
# error when running the system command `lsb_release -d` in the background.
let isUbuntu32bit = detectOs(Ubuntu) and int.sizeof == 4
let
# There is a problem with the Github/CI which results in spurious crashes
# when leaving the `runner()` if the persistent BaseChainDB initialisation
# was present. The Github/CI set up for Linux/i386 is
#
# Ubuntu 10.04.06 LTS
# with repo kernel 5.4.0-1065-azure (see 'uname -a')
#
# base OS architecture is amd64
# with i386 foreign architecture
#
# nimbus binary is an
# ELF 32-bit LSB shared object,
# Intel 80386, version 1 (SYSV), dynamically linked,
#
disablePersistentDB = isUbuntu32bit
# ------------------------------------------------------------------------------
# Helpers
# ------------------------------------------------------------------------------
@ -53,27 +75,16 @@ proc runner(noisy = true; file = jFile) =
fileInfo = file.splitFile.name.split(".")[0]
filePath = file.findFilePath
# There is a crash problem with the persistent BaseChainDB initialisation
# and clean up on the Github/CI Linux/i386 engines running Ubuntu 18.04.06.
# It will result in spurious segfaults for some reason.
#
# This could not be reproduced on a virtual Qemu machine running
# Debian/bullseye i386, see also
# https://github.com/status-im/nimbus-eth2/issues/3121, some observations
# similar to this one.
when isLinux32bit:
let tmpDir = "*notused*"
else:
let tmpDir = filePath.splitFile.dir / "tmp"
defer: tmpDir.flushDbDir
tmpDir = if disablePersistentDB: "*notused*"
else: filePath.splitFile.dir / "tmp"
defer:
if not disablePersistentDB: tmpDir.flushDbDir
suite &"Kintsugi test scenario":
var
params: NetworkParams
mdb: BaseChainDB
when not isLinux32bit:
var ddb: BaseChainDB
mdb, ddb: BaseChainDB
test &"Load params from {fileInfo}":
check filePath.loadNetworkParams(params)
@ -85,11 +96,7 @@ proc runner(noisy = true; file = jFile) =
params = params)
test &"Construct persistent BaseChainDB on {tmpDir}":
when isLinux32bit:
# Crazy enough, on the Github/CI Linux/i386 engines running
# Ubuntu 18.04.06, some of the VM variants crash already if
# the constructor below is present without even applying it
# (e.g. as `ddb.initializeEmptyDb`.)
if disablePersistentDB:
skip()
else:
# Before allocating the database, the data directory needs to be
@ -115,12 +122,20 @@ proc runner(noisy = true; file = jFile) =
test "Initialise in-memory Genesis":
mdb.initializeEmptyDb
#[
test "Initialise persistent Genesis, expect AssertionError":
when isLinux32bit:
if disablePersistentDB:
skip()
else:
expect AssertionError:
ddb.initializeEmptyDb
#]#
test "Initialise persistent Genesis (kludge)":
if disablePersistentDB:
skip()
else:
ddb.initializeEmptyDb
# ------------------------------------------------------------------------------
# Main function(s)