Add Holesky testnet configuration
This commit is contained in:
parent
0ee448c1eb
commit
26ede94a73
|
@ -50,10 +50,6 @@ type
|
||||||
config* : ChainConfig
|
config* : ChainConfig
|
||||||
genesis*: Genesis
|
genesis*: Genesis
|
||||||
|
|
||||||
AddressBalance = object
|
|
||||||
address {.rlpCustomSerialization.}: EthAddress
|
|
||||||
account {.rlpCustomSerialization.}: GenesisAccount
|
|
||||||
|
|
||||||
GenesisFile* = object
|
GenesisFile* = object
|
||||||
config : ChainConfig
|
config : ChainConfig
|
||||||
nonce* : BlockNonce
|
nonce* : BlockNonce
|
||||||
|
@ -76,9 +72,9 @@ const
|
||||||
CustomNet* = 0.NetworkId
|
CustomNet* = 0.NetworkId
|
||||||
# these are public network id
|
# these are public network id
|
||||||
MainNet* = 1.NetworkId
|
MainNet* = 1.NetworkId
|
||||||
# No longer used: MordenNet = 2
|
|
||||||
GoerliNet* = 5.NetworkId
|
GoerliNet* = 5.NetworkId
|
||||||
SepoliaNet* = 11155111.NetworkId
|
SepoliaNet* = 11155111.NetworkId
|
||||||
|
HoleskyNet* = 17000.NetworkId
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Private helper functions
|
# Private helper functions
|
||||||
|
@ -92,14 +88,61 @@ proc writeValue(writer: var JsonWriter, value: Option[EthTime])
|
||||||
else:
|
else:
|
||||||
writer.writeValue JsonString("null")
|
writer.writeValue JsonString("null")
|
||||||
|
|
||||||
proc read(rlp: var Rlp, x: var AddressBalance, _: type EthAddress): EthAddress
|
type
|
||||||
{.gcsafe, raises: [RlpError].} =
|
Slots = object
|
||||||
let val = rlp.read(UInt256).toBytesBE()
|
key: UInt256
|
||||||
result[0 .. ^1] = val.toOpenArray(12, val.high)
|
val: UInt256
|
||||||
|
|
||||||
proc read(rlp: var Rlp, x: var AddressBalance, _: type GenesisAccount): GenesisAccount
|
Misc = object
|
||||||
{.gcsafe, raises: [RlpError].} =
|
nonce: uint64
|
||||||
GenesisAccount(balance: rlp.read(UInt256))
|
code : seq[byte]
|
||||||
|
storage: seq[Slots]
|
||||||
|
|
||||||
|
AddressBalance = object
|
||||||
|
address: EthAddress
|
||||||
|
account: GenesisAccount
|
||||||
|
|
||||||
|
proc read*(rlp: var Rlp, T: type AddressBalance): T {.gcsafe, raises: [RlpError].}=
|
||||||
|
let listLen = rlp.listLen
|
||||||
|
rlp.tryEnterList()
|
||||||
|
let val = rlp.read(UInt256).toBytesBE()
|
||||||
|
result.address[0..^1] = val.toOpenArray(12, val.high)
|
||||||
|
result.account.balance = rlp.read(UInt256)
|
||||||
|
if listLen == 3:
|
||||||
|
var misc = rlp.read(Misc)
|
||||||
|
result.account.nonce = misc.nonce
|
||||||
|
result.account.code = system.move(misc.code)
|
||||||
|
for x in misc.storage:
|
||||||
|
result.account.storage[x.key] = x.val
|
||||||
|
|
||||||
|
proc append*(w: var RlpWriter, ab: AddressBalance) =
|
||||||
|
var listLen = 2
|
||||||
|
if ab.account.storage.len > 0 or
|
||||||
|
ab.account.nonce != 0.AccountNonce or
|
||||||
|
ab.account.code.len > 0:
|
||||||
|
inc listLen
|
||||||
|
|
||||||
|
w.startList(listLen)
|
||||||
|
var tmp: array[32, byte]
|
||||||
|
tmp[12..^1] = ab.address[0..^1]
|
||||||
|
var val = UInt256.fromBytesBE(tmp)
|
||||||
|
w.append(val)
|
||||||
|
w.append(ab.account.balance)
|
||||||
|
if listLen == 3:
|
||||||
|
var misc: Misc
|
||||||
|
misc.nonce = ab.account.nonce
|
||||||
|
misc.code = ab.account.code
|
||||||
|
for k, v in ab.account.storage:
|
||||||
|
misc.storage.add Slots(key:k, val: v)
|
||||||
|
w.append(misc)
|
||||||
|
|
||||||
|
proc append*(w: var RlpWriter, ga: GenesisAlloc) =
|
||||||
|
var list: seq[AddressBalance]
|
||||||
|
for k, v in ga:
|
||||||
|
list.add AddressBalance(
|
||||||
|
address: k, account: v
|
||||||
|
)
|
||||||
|
w.append(list)
|
||||||
|
|
||||||
func decodePrealloc*(data: seq[byte]): GenesisAlloc
|
func decodePrealloc*(data: seq[byte]): GenesisAlloc
|
||||||
{.gcsafe, raises: [RlpError].} =
|
{.gcsafe, raises: [RlpError].} =
|
||||||
|
@ -173,11 +216,15 @@ proc readValue(reader: var JsonReader, value: var BlockNonce)
|
||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
reader.raiseUnexpectedValue(ex.msg)
|
reader.raiseUnexpectedValue(ex.msg)
|
||||||
|
|
||||||
# genesis timestamp is in hex
|
# genesis timestamp is in hex/dec
|
||||||
proc readValue(reader: var JsonReader, value: var EthTime)
|
proc readValue(reader: var JsonReader, value: var EthTime)
|
||||||
{.gcsafe, raises: [SerializationError, IOError].} =
|
{.gcsafe, raises: [SerializationError, IOError].} =
|
||||||
try:
|
try:
|
||||||
value = fromHex[int64](reader.readValue(string)).EthTime
|
let data = reader.readValue(string)
|
||||||
|
if data.len > 2 and data[1] == 'x':
|
||||||
|
value = fromHex[int64](data).EthTime
|
||||||
|
else:
|
||||||
|
value = parseInt(data).EthTime
|
||||||
except ValueError as ex:
|
except ValueError as ex:
|
||||||
reader.raiseUnexpectedValue(ex.msg)
|
reader.raiseUnexpectedValue(ex.msg)
|
||||||
|
|
||||||
|
@ -446,7 +493,26 @@ proc chainConfigForNetwork*(id: NetworkId): ChainConfig =
|
||||||
londonBlock: some(0.toBlockNumber),
|
londonBlock: some(0.toBlockNumber),
|
||||||
mergeForkBlock: some(1735371.toBlockNumber),
|
mergeForkBlock: some(1735371.toBlockNumber),
|
||||||
terminalTotalDifficulty: some(sepoliaTTD),
|
terminalTotalDifficulty: some(sepoliaTTD),
|
||||||
shanghaiTime: some(1_677_557_088.EthTime)
|
shanghaiTime: some(1_677_557_088.EthTime),
|
||||||
|
)
|
||||||
|
of HoleskyNet:
|
||||||
|
ChainConfig(
|
||||||
|
consensusType: ConsensusType.POS,
|
||||||
|
chainId: HoleskyNet.ChainId,
|
||||||
|
homesteadBlock: some(0.toBlockNumber),
|
||||||
|
eip150Block: some(0.toBlockNumber),
|
||||||
|
eip155Block: some(0.toBlockNumber),
|
||||||
|
eip158Block: some(0.toBlockNumber),
|
||||||
|
byzantiumBlock: some(0.toBlockNumber),
|
||||||
|
constantinopleBlock: some(0.toBlockNumber),
|
||||||
|
petersburgBlock: some(0.toBlockNumber),
|
||||||
|
istanbulBlock: some(0.toBlockNumber),
|
||||||
|
berlinBlock: some(0.toBlockNumber),
|
||||||
|
londonBlock: some(0.toBlockNumber),
|
||||||
|
mergeForkBlock: some(0.toBlockNumber),
|
||||||
|
terminalTotalDifficulty: some(0.u256),
|
||||||
|
terminalTotalDifficultyPassed: some(true),
|
||||||
|
shanghaiTime: some(1_696_000_704.EthTime),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
ChainConfig()
|
ChainConfig()
|
||||||
|
@ -480,6 +546,14 @@ proc genesisBlockForNetwork*(id: NetworkId): Genesis
|
||||||
difficulty: 0x20000.u256,
|
difficulty: 0x20000.u256,
|
||||||
alloc: decodePrealloc(sepoliaAllocData)
|
alloc: decodePrealloc(sepoliaAllocData)
|
||||||
)
|
)
|
||||||
|
of HoleskyNet:
|
||||||
|
Genesis(
|
||||||
|
difficulty: 0x01.u256,
|
||||||
|
gasLimit: 0x17D7840,
|
||||||
|
nonce: 0x1234.toBlockNonce,
|
||||||
|
timestamp: EthTime(1_695_902_100),
|
||||||
|
alloc: decodePrealloc(holeskyAllocData)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
Genesis()
|
Genesis()
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -213,11 +213,12 @@ type
|
||||||
|
|
||||||
network {.
|
network {.
|
||||||
separator: "\pETHEREUM NETWORK OPTIONS:"
|
separator: "\pETHEREUM NETWORK OPTIONS:"
|
||||||
desc: "Name or id number of Ethereum network(mainnet(1), goerli(5), sepolia(11155111), other=custom)"
|
desc: "Name or id number of Ethereum network(mainnet(1), goerli(5), sepolia(11155111), holesky(17000), other=custom)"
|
||||||
longDesc:
|
longDesc:
|
||||||
"- mainnet: Ethereum main network\n" &
|
"- mainnet: Ethereum main network\n" &
|
||||||
"- goerli: Test network (proof-of-authority, works across all clients)\n" &
|
"- goerli: Test network (proof-of-authority, works across all clients)\n" &
|
||||||
"- sepolia: Test network (proof-of-work)"
|
"- sepolia: Test network (proof-of-work)\n" &
|
||||||
|
"- holesky: The holesovice post-merge testnet"
|
||||||
defaultValue: "" # the default value is set in makeConfig
|
defaultValue: "" # the default value is set in makeConfig
|
||||||
defaultValueDesc: "mainnet(1)"
|
defaultValueDesc: "mainnet(1)"
|
||||||
abbr: "i"
|
abbr: "i"
|
||||||
|
@ -654,6 +655,7 @@ proc getNetworkId(conf: NimbusConf): Option[NetworkId] =
|
||||||
of "mainnet": return some MainNet
|
of "mainnet": return some MainNet
|
||||||
of "goerli" : return some GoerliNet
|
of "goerli" : return some GoerliNet
|
||||||
of "sepolia": return some SepoliaNet
|
of "sepolia": return some SepoliaNet
|
||||||
|
of "holesky": return some HoleskyNet
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
some parseInt(network).NetworkId
|
some parseInt(network).NetworkId
|
||||||
|
@ -732,6 +734,8 @@ proc getBootNodes*(conf: NimbusConf): seq[ENode] =
|
||||||
bootstrapNodes.setBootnodes(GoerliBootnodes)
|
bootstrapNodes.setBootnodes(GoerliBootnodes)
|
||||||
of SepoliaNet:
|
of SepoliaNet:
|
||||||
bootstrapNodes.setBootnodes(SepoliaBootnodes)
|
bootstrapNodes.setBootnodes(SepoliaBootnodes)
|
||||||
|
of HoleskyNet:
|
||||||
|
bootstrapNodes.setBootnodes(HoleskyBootnodes)
|
||||||
else:
|
else:
|
||||||
# custom network id
|
# custom network id
|
||||||
discard
|
discard
|
||||||
|
|
|
@ -4,7 +4,9 @@ import
|
||||||
|
|
||||||
from ../nimbus/common/chain_config import
|
from ../nimbus/common/chain_config import
|
||||||
MainNet,
|
MainNet,
|
||||||
GoerliNet
|
GoerliNet,
|
||||||
|
SepoliaNet,
|
||||||
|
HoleskyNet
|
||||||
|
|
||||||
type
|
type
|
||||||
ConfigStatus* = enum
|
ConfigStatus* = enum
|
||||||
|
@ -62,6 +64,8 @@ proc processNetId(val: string, o: var NetworkId): ConfigStatus =
|
||||||
case val.toLowerAscii()
|
case val.toLowerAscii()
|
||||||
of "main": o = MainNet
|
of "main": o = MainNet
|
||||||
of "goerli": o = GoerliNet
|
of "goerli": o = GoerliNet
|
||||||
|
of "sepolia": o = SepoliaNet
|
||||||
|
of "holesky": o = HoleskyNet
|
||||||
|
|
||||||
template checkArgument(fun, o, value: untyped) =
|
template checkArgument(fun, o, value: untyped) =
|
||||||
## Checks if arguments got processed successfully
|
## Checks if arguments got processed successfully
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -57,6 +57,12 @@ const
|
||||||
(number: 1735372'u64, time: 1677557088'u64, id: (crc: 0xf7f9bc08'u32, next: 0'u64)), # First Shanghai block
|
(number: 1735372'u64, time: 1677557088'u64, id: (crc: 0xf7f9bc08'u32, next: 0'u64)), # First Shanghai block
|
||||||
]
|
]
|
||||||
|
|
||||||
|
HoleskyNetIDs = [
|
||||||
|
(number: 0'u64, time: 0'u64, id: (crc: 0xc61a6098'u32, next: 1696000704'u64)), # Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris block
|
||||||
|
(number: 123'u64, time: 0'u64, id: (crc: 0xc61a6098'u32, next: 1696000704'u64)), # First MergeNetsplit block
|
||||||
|
(number: 123'u64, time: 1696000704'u64, id: (crc: 0xfd4f016b'u32, next: 0'u64)), # Last MergeNetsplit block
|
||||||
|
]
|
||||||
|
|
||||||
template runTest(network: untyped, name: string) =
|
template runTest(network: untyped, name: string) =
|
||||||
test name:
|
test name:
|
||||||
var
|
var
|
||||||
|
@ -122,6 +128,7 @@ proc forkIdMain*() =
|
||||||
runTest(MainNet, "MainNet")
|
runTest(MainNet, "MainNet")
|
||||||
runTest(GoerliNet, "GoerliNet")
|
runTest(GoerliNet, "GoerliNet")
|
||||||
runTest(SepoliaNet, "SepoliaNet")
|
runTest(SepoliaNet, "SepoliaNet")
|
||||||
|
runTest(HoleskyNet, "HoleskyNet")
|
||||||
test "Genesis Time Fork ID":
|
test "Genesis Time Fork ID":
|
||||||
runGenesisTimeIdTests()
|
runGenesisTimeIdTests()
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,11 @@ proc genesisTest() =
|
||||||
let b = makeGenesis(SepoliaNet)
|
let b = makeGenesis(SepoliaNet)
|
||||||
check b.blockHash == "25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9".toDigest
|
check b.blockHash == "25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9".toDigest
|
||||||
|
|
||||||
|
test "Correct holesky hash":
|
||||||
|
let b = makeGenesis(HoleskyNet)
|
||||||
|
check b.blockHash == "b5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4".toDigest
|
||||||
|
check b.stateRoot == "69D8C9D72F6FA4AD42D4702B433707212F90DB395EB54DC20BC85DE253788783".toDigest
|
||||||
|
|
||||||
proc customGenesisTest() =
|
proc customGenesisTest() =
|
||||||
suite "Custom Genesis":
|
suite "Custom Genesis":
|
||||||
test "loadCustomGenesis":
|
test "loadCustomGenesis":
|
||||||
|
@ -89,6 +94,16 @@ proc customGenesisTest() =
|
||||||
check com.ttd.get == ttd
|
check com.ttd.get == ttd
|
||||||
check com.consensus == ConsensusType.POW
|
check com.consensus == ConsensusType.POW
|
||||||
|
|
||||||
|
test "Holesky":
|
||||||
|
var cg: NetworkParams
|
||||||
|
check loadNetworkParams("holesky.json".findFilePath, cg)
|
||||||
|
let com = CommonRef.new(newCoreDbRef LegacyDbMemory, params = cg)
|
||||||
|
let stateRoot = "69D8C9D72F6FA4AD42D4702B433707212F90DB395EB54DC20BC85DE253788783".toDigest
|
||||||
|
let genesisHash = "b5f7f912443c940f21fd611f12828d75b534364ed9e95ca4e307729a4661bde4".toDigest
|
||||||
|
check com.genesisHeader.stateRoot == stateRoot
|
||||||
|
check com.genesisHeader.blockHash == genesisHash
|
||||||
|
check com.chainId == 17000.ChainId
|
||||||
|
|
||||||
proc genesisMain*() =
|
proc genesisMain*() =
|
||||||
genesisTest()
|
genesisTest()
|
||||||
customGenesisTest()
|
customGenesisTest()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1bae1d84268117c4559f15794cfe6b69b9ffb9e2
|
Subproject commit 4b00b230d0948a567816d562efb22ee0545cd636
|
Loading…
Reference in New Issue