rename `DepositTreeSnapshot` -> `DepositContractSnapshot` (#6036)

EIP-4881 was never correctly implemented, the `DepositTreeSnapshot`
structure has nothing to do with its actual definition. Reflect that
by renaming the type to a Nimbus-specific `DepositContractSnapshot`,
so that an actual EIP-4881 implementation can use the correct names.

- https://eips.ethereum.org/EIPS/eip-4881#specification

Notably, `DepositTreeSnapshot` contains a compressed sequence in
`finalized`, only containing the minimally required intermediate roots.

That also explains the incorrect REST response reported in #5508.

The non-canonical representation was introduced in #4303 and is also
persisted in the database. We'll have to maintain it for a while.
This commit is contained in:
Etan Kissling 2024-03-07 18:42:52 +01:00 committed by GitHub
parent 3b4b1ccb89
commit 50a43f397f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 81 additions and 66 deletions

View File

@ -141,7 +141,7 @@ OK: 4/4 Fail: 0/4 Skip: 0/4
+ Missing Authorization header [Beacon Node] [Preset: mainnet] OK + Missing Authorization header [Beacon Node] [Preset: mainnet] OK
``` ```
OK: 5/5 Fail: 0/5 Skip: 0/5 OK: 5/5 Fail: 0/5 Skip: 0/5
## DepositTreeSnapshot ## DepositContractSnapshot
```diff ```diff
+ Migration OK + Migration OK
+ SSZ OK + SSZ OK

View File

@ -179,7 +179,7 @@ type
kOldDepositContractSnapshot kOldDepositContractSnapshot
## Deprecated: ## Deprecated:
## This was the merkleizer checkpoint produced by processing the ## This was the merkleizer checkpoint produced by processing the
## finalized deposits (similar to kDepositTreeSnapshot, but before ## finalized deposits (similar to kDepositContractSnapshot, but before
## the EIP-4881 support was introduced). Currently, we read from ## the EIP-4881 support was introduced). Currently, we read from
## it during upgrades and we keep writing data to it as a measure ## it during upgrades and we keep writing data to it as a measure
## allowing the users to downgrade to a previous version of Nimbus. ## allowing the users to downgrade to a previous version of Nimbus.
@ -194,7 +194,12 @@ type
kHashToStateDiff # Obsolete kHashToStateDiff # Obsolete
kHashToStateOnlyMutableValidators kHashToStateOnlyMutableValidators
kBackfillBlock # Obsolete, was in `unstable` for a while, but never released kBackfillBlock # Obsolete, was in `unstable` for a while, but never released
kDepositTreeSnapshot # EIP-4881-compatible deposit contract state snapshot kDepositContractSnapshot
## Deposit contract state snapshot derived from EIP-4881 data.
## This key also stores intermediate hashes that are no longer used
## for future deposits, beyond the `finalized` branch from EIP-4881.
## Those extra hashes may be set to ZERO_HASH when importing from a
## compressed EIP-4881 `DepositTreeSnapshot`.
BeaconBlockSummary* = object BeaconBlockSummary* = object
## Cache of beacon block summaries - during startup when we construct the ## Cache of beacon block summaries - during startup when we construct the
@ -909,10 +914,10 @@ proc putTailBlock*(db: BeaconChainDB, key: Eth2Digest) =
proc putGenesisBlock*(db: BeaconChainDB, key: Eth2Digest) = proc putGenesisBlock*(db: BeaconChainDB, key: Eth2Digest) =
db.keyValues.putRaw(subkey(kGenesisBlock), key) db.keyValues.putRaw(subkey(kGenesisBlock), key)
proc putDepositTreeSnapshot*(db: BeaconChainDB, proc putDepositContractSnapshot*(
snapshot: DepositTreeSnapshot) = db: BeaconChainDB, snapshot: DepositContractSnapshot) =
db.withManyWrites: db.withManyWrites:
db.keyValues.putSnappySSZ(subkey(kDepositTreeSnapshot), db.keyValues.putSnappySSZ(subkey(kDepositContractSnapshot),
snapshot) snapshot)
# TODO: We currently store this redundant old snapshot in order # TODO: We currently store this redundant old snapshot in order
# to allow the users to rollback to a previous version # to allow the users to rollback to a previous version
@ -921,12 +926,13 @@ proc putDepositTreeSnapshot*(db: BeaconChainDB,
db.keyValues.putSnappySSZ(subkey(kOldDepositContractSnapshot), db.keyValues.putSnappySSZ(subkey(kOldDepositContractSnapshot),
snapshot.toOldDepositContractSnapshot) snapshot.toOldDepositContractSnapshot)
proc hasDepositTreeSnapshot*(db: BeaconChainDB): bool = proc hasDepositContractSnapshot*(db: BeaconChainDB): bool =
expectDb(subkey(kDepositTreeSnapshot) in db.keyValues) expectDb(subkey(kDepositContractSnapshot) in db.keyValues)
proc getDepositTreeSnapshot*(db: BeaconChainDB): Opt[DepositTreeSnapshot] = proc getDepositContractSnapshot*(db: BeaconChainDB): Opt[DepositContractSnapshot] =
result.ok(default DepositTreeSnapshot) result.ok(default DepositContractSnapshot)
let r = db.keyValues.getSnappySSZ(subkey(kDepositTreeSnapshot), result.get) let r = db.keyValues.getSnappySSZ(
subkey(kDepositContractSnapshot), result.get)
if r != GetResult.found: result.err() if r != GetResult.found: result.err()
proc getUpgradableDepositSnapshot*(db: BeaconChainDB): Option[OldDepositContractSnapshot] = proc getUpgradableDepositSnapshot*(db: BeaconChainDB): Option[OldDepositContractSnapshot] =

View File

@ -166,7 +166,7 @@ proc pruneOldBlocks(chain: var Eth1Chain, depositIndex: uint64) =
if chain.finalizedDepositsMerkleizer.getChunkCount > initialChunks: if chain.finalizedDepositsMerkleizer.getChunkCount > initialChunks:
chain.finalizedBlockHash = lastBlock.hash chain.finalizedBlockHash = lastBlock.hash
chain.db.putDepositTreeSnapshot DepositTreeSnapshot( chain.db.putDepositContractSnapshot DepositContractSnapshot(
eth1Block: lastBlock.hash, eth1Block: lastBlock.hash,
depositContractState: chain.finalizedDepositsMerkleizer.toDepositContractState, depositContractState: chain.finalizedDepositsMerkleizer.toDepositContractState,
blockHeight: lastBlock.number) blockHeight: lastBlock.number)
@ -370,7 +370,7 @@ proc init*(T: type Eth1Chain,
let let
(finalizedBlockHash, depositContractState) = (finalizedBlockHash, depositContractState) =
if db != nil: if db != nil:
let treeSnapshot = db.getDepositTreeSnapshot() let treeSnapshot = db.getDepositContractSnapshot()
if treeSnapshot.isSome: if treeSnapshot.isSome:
(treeSnapshot.get.eth1Block, treeSnapshot.get.depositContractState) (treeSnapshot.get.eth1Block, treeSnapshot.get.depositContractState)
else: else:
@ -378,7 +378,7 @@ proc init*(T: type Eth1Chain,
if oldSnapshot.isSome: if oldSnapshot.isSome:
(oldSnapshot.get.eth1Block, oldSnapshot.get.depositContractState) (oldSnapshot.get.eth1Block, oldSnapshot.get.depositContractState)
else: else:
db.putDepositTreeSnapshot DepositTreeSnapshot( db.putDepositContractSnapshot DepositContractSnapshot(
eth1Block: depositContractBlockHash, eth1Block: depositContractBlockHash,
blockHeight: depositContractBlockNumber) blockHeight: depositContractBlockNumber)
(depositContractBlockHash, default(DepositContractState)) (depositContractBlockHash, default(DepositContractState))

View File

@ -646,8 +646,8 @@ proc init*(T: type BeaconNode,
if config.finalizedDepositTreeSnapshot.isSome: if config.finalizedDepositTreeSnapshot.isSome:
let let
depositTreeSnapshotPath = config.finalizedDepositTreeSnapshot.get.string depositTreeSnapshotPath = config.finalizedDepositTreeSnapshot.get.string
depositTreeSnapshot = try: depositContractSnapshot = try:
SSZ.loadFile(depositTreeSnapshotPath, DepositTreeSnapshot) SSZ.loadFile(depositTreeSnapshotPath, DepositContractSnapshot)
except SszError as err: except SszError as err:
fatal "Deposit tree snapshot loading failed", fatal "Deposit tree snapshot loading failed",
err = formatMsg(err, depositTreeSnapshotPath) err = formatMsg(err, depositTreeSnapshotPath)
@ -655,7 +655,7 @@ proc init*(T: type BeaconNode,
except CatchableError as err: except CatchableError as err:
fatal "Failed to read deposit tree snapshot file", err = err.msg fatal "Failed to read deposit tree snapshot file", err = err.msg
quit 1 quit 1
db.putDepositTreeSnapshot(depositTreeSnapshot) db.putDepositContractSnapshot(depositContractSnapshot)
let engineApiUrls = config.engineApiUrls let engineApiUrls = config.engineApiUrls

View File

@ -133,7 +133,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
# https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4881.md # https://github.com/ethereum/EIPs/blob/master/EIPS/eip-4881.md
router.api2(MethodGet, "/eth/v1/beacon/deposit_snapshot") do ( router.api2(MethodGet, "/eth/v1/beacon/deposit_snapshot") do (
) -> RestApiResponse: ) -> RestApiResponse:
let snapshot = node.db.getDepositTreeSnapshot().valueOr: let snapshot = node.db.getDepositContractSnapshot().valueOr:
# This can happen in a very short window after the client is started, # This can happen in a very short window after the client is started,
# but the snapshot record still haven't been upgraded in the database. # but the snapshot record still haven't been upgraded in the database.
# Returning 404 should be easy to handle for the clients - they just need # Returning 404 should be easy to handle for the clients - they just need

View File

@ -21,42 +21,44 @@ type
eth1Block*: Eth2Digest eth1Block*: Eth2Digest
depositContractState*: DepositContractState depositContractState*: DepositContractState
DepositTreeSnapshot* = object DepositContractSnapshot* = object
## https://eips.ethereum.org/EIPS/eip-4881
eth1Block*: Eth2Digest eth1Block*: Eth2Digest
depositContractState*: DepositContractState depositContractState*: DepositContractState
blockHeight*: uint64 blockHeight*: uint64
func toDepositTreeSnapshot*(d: OldDepositContractSnapshot, func toDepositContractSnapshot*(
blockHeight: uint64): DepositTreeSnapshot = d: OldDepositContractSnapshot,
DepositTreeSnapshot( blockHeight: uint64): DepositContractSnapshot =
DepositContractSnapshot(
eth1Block: d.eth1Block, eth1Block: d.eth1Block,
depositContractState: d.depositContractState, depositContractState: d.depositContractState,
blockHeight: blockHeight) blockHeight: blockHeight)
func toOldDepositContractSnapshot*(d: DepositTreeSnapshot): OldDepositContractSnapshot = func toOldDepositContractSnapshot*(
OldDepositContractSnapshot(eth1Block: d.eth1Block, d: DepositContractSnapshot): OldDepositContractSnapshot =
depositContractState: d.depositContractState) OldDepositContractSnapshot(
eth1Block: d.eth1Block,
depositContractState: d.depositContractState)
template getDepositCountU64*(d: OldDepositContractSnapshot | template getDepositCountU64*(
DepositTreeSnapshot): uint64 = d: OldDepositContractSnapshot | DepositContractSnapshot): uint64 =
depositCountU64(d.depositContractState.deposit_count) depositCountU64(d.depositContractState.deposit_count)
func getDepositRoot*(d: OldDepositContractSnapshot | func getDepositRoot*(
DepositTreeSnapshot): Eth2Digest = d: OldDepositContractSnapshot | DepositContractSnapshot): Eth2Digest =
var merk = DepositsMerkleizer.init(d.depositContractState) var merk = DepositsMerkleizer.init(d.depositContractState)
let hash = merk.getFinalHash() let hash = merk.getFinalHash()
# TODO: mixInLength should accept unsigned int instead of int as # TODO: mixInLength should accept unsigned int instead of int as
# this right now cuts in half the theoretical number of deposits. # this right now cuts in half the theoretical number of deposits.
return mixInLength(hash, int(merk.getChunkCount())) return mixInLength(hash, int(merk.getChunkCount()))
func isValid*(d: DepositTreeSnapshot, wantedDepositRoot: Eth2Digest): bool = func isValid*(d: DepositContractSnapshot, wantedDepositRoot: Eth2Digest): bool =
## `isValid` requires the snapshot to be self-consistent and ## `isValid` requires the snapshot to be self-consistent and
## to point to a specific Ethereum block ## to point to a specific Ethereum block
return not (d.eth1Block.isZeroMemory or return not (d.eth1Block.isZeroMemory or
d.blockHeight == 0 or d.blockHeight == 0 or
d.getDepositRoot() != wantedDepositRoot) d.getDepositRoot() != wantedDepositRoot)
func matches*(snapshot: DepositTreeSnapshot, eth1_data: Eth1Data): bool = func matches*(snapshot: DepositContractSnapshot, eth1_data: Eth1Data): bool =
snapshot.getDepositCountU64() == eth1_data.deposit_count and snapshot.getDepositCountU64() == eth1_data.deposit_count and
snapshot.getDepositRoot() == eth1_data.deposit_root snapshot.getDepositRoot() == eth1_data.deposit_root

View File

@ -24,8 +24,9 @@ const
largeRequestsTimeout = 60.seconds # Downloading large items such as states. largeRequestsTimeout = 60.seconds # Downloading large items such as states.
smallRequestsTimeout = 30.seconds # Downloading smaller items such as blocks and deposit snapshots. smallRequestsTimeout = 30.seconds # Downloading smaller items such as blocks and deposit snapshots.
proc fetchDepositSnapshot(client: RestClientRef): proc fetchDepositSnapshot(
Future[Result[DepositTreeSnapshot, string]] {.async.} = client: RestClientRef
): Future[Result[DepositContractSnapshot, string]] {.async.} =
let resp = try: let resp = try:
awaitWithTimeout(client.getDepositSnapshot(), smallRequestsTimeout): awaitWithTimeout(client.getDepositSnapshot(), smallRequestsTimeout):
return err "Fetching /eth/v1/beacon/deposit_snapshot timed out" return err "Fetching /eth/v1/beacon/deposit_snapshot timed out"
@ -33,7 +34,7 @@ proc fetchDepositSnapshot(client: RestClientRef):
return err("The trusted node likely does not support the /eth/v1/beacon/deposit_snapshot end-point:" & e.msg) return err("The trusted node likely does not support the /eth/v1/beacon/deposit_snapshot end-point:" & e.msg)
let data = resp.data.data let data = resp.data.data
let snapshot = DepositTreeSnapshot( let snapshot = DepositContractSnapshot(
eth1Block: data.execution_block_hash, eth1Block: data.execution_block_hash,
depositContractState: DepositContractState( depositContractState: DepositContractState(
branch: data.finalized, branch: data.finalized,
@ -393,7 +394,7 @@ proc doTrustedNodeSync*(
info "Writing deposit contracts snapshot", info "Writing deposit contracts snapshot",
depositRoot = depositSnapshot.get.getDepositRoot(), depositRoot = depositSnapshot.get.getDepositRoot(),
depositCount = depositSnapshot.get.getDepositCountU64 depositCount = depositSnapshot.get.getDepositCountU64
db.putDepositTreeSnapshot(depositSnapshot.get) db.putDepositContractSnapshot(depositSnapshot.get)
else: else:
warn "The downloaded deposit snapshot does not agree with the downloaded state" warn "The downloaded deposit snapshot does not agree with the downloaded state"
else: else:

View File

@ -347,15 +347,16 @@ func `as`(blk: BlockObject, T: type deneb.ExecutionPayloadHeader): T =
blob_gas_used: uint64 blk.blobGasUsed.getOrDefault(), blob_gas_used: uint64 blk.blobGasUsed.getOrDefault(),
excess_blob_gas: uint64 blk.excessBlobGas.getOrDefault()) excess_blob_gas: uint64 blk.excessBlobGas.getOrDefault())
func createDepositTreeSnapshot(deposits: seq[DepositData], func createDepositContractSnapshot(
blockHash: Eth2Digest, deposits: seq[DepositData],
blockHeight: uint64): DepositTreeSnapshot = blockHash: Eth2Digest,
blockHeight: uint64): DepositContractSnapshot =
var merkleizer = DepositsMerkleizer.init() var merkleizer = DepositsMerkleizer.init()
for i, deposit in deposits: for i, deposit in deposits:
let htr = hash_tree_root(deposit) let htr = hash_tree_root(deposit)
merkleizer.addChunk(htr.data) merkleizer.addChunk(htr.data)
DepositTreeSnapshot( DepositContractSnapshot(
eth1Block: blockHash, eth1Block: blockHash,
depositContractState: merkleizer.toDepositContractState, depositContractState: merkleizer.toDepositContractState,
blockHeight: blockHeight) blockHeight: blockHeight)
@ -473,7 +474,7 @@ proc doCreateTestnet*(config: CliConfig,
SSZ.saveFile( SSZ.saveFile(
config.outputDepositTreeSnapshot.string, config.outputDepositTreeSnapshot.string,
createDepositTreeSnapshot( createDepositContractSnapshot(
deposits, deposits,
genesisExecutionPayloadHeader.block_hash, genesisExecutionPayloadHeader.block_hash,
genesisExecutionPayloadHeader.block_number)) genesisExecutionPayloadHeader.block_number))

View File

@ -160,7 +160,7 @@ cli do(slots = SLOTS_PER_EPOCH * 7,
defer: db.close() defer: db.close()
ChainDAGRef.preInit(db, genesisState[]) ChainDAGRef.preInit(db, genesisState[])
db.putDepositTreeSnapshot(depositTreeSnapshot) db.putDepositContractSnapshot(depositTreeSnapshot)
let rng = HmacDrbgContext.new() let rng = HmacDrbgContext.new()
var var

View File

@ -16,7 +16,7 @@ from std/stats import RunningStat, mean, push, standardDeviationS
from std/strformat import `&` from std/strformat import `&`
from std/times import cpuTime from std/times import cpuTime
from ../beacon_chain/filepath import secureCreatePath from ../beacon_chain/filepath import secureCreatePath
from ../beacon_chain/spec/deposit_snapshots import DepositTreeSnapshot from ../beacon_chain/spec/deposit_snapshots import DepositContractSnapshot
template withTimer*(stats: var RunningStat, body: untyped) = template withTimer*(stats: var RunningStat, body: untyped) =
# TODO unify timing somehow # TODO unify timing somehow
@ -63,8 +63,9 @@ func getSimulationConfig*(): RuntimeConfig {.compileTime.} =
cfg.DENEB_FORK_EPOCH = 2.Epoch cfg.DENEB_FORK_EPOCH = 2.Epoch
cfg cfg
proc loadGenesis*(validators: Natural, validate: bool): proc loadGenesis*(
(ref ForkedHashedBeaconState, DepositTreeSnapshot) = validators: Natural,
validate: bool): (ref ForkedHashedBeaconState, DepositContractSnapshot) =
const genesisDir = "test_sim" const genesisDir = "test_sim"
if (let res = secureCreatePath(genesisDir); res.isErr): if (let res = secureCreatePath(genesisDir); res.isErr):
fatal "Could not create directory", fatal "Could not create directory",
@ -110,7 +111,7 @@ proc loadGenesis*(validators: Natural, validate: bool):
let contractSnapshot = let contractSnapshot =
try: try:
SSZ.loadFile(contractSnapshotFn, DepositTreeSnapshot) SSZ.loadFile(contractSnapshotFn, DepositContractSnapshot)
except IOError as exc: except IOError as exc:
fatal "Deposit contract snapshot failed to load", fatal "Deposit contract snapshot failed to load",
fileName = contractSnapshotFn, exc = exc.msg fileName = contractSnapshotFn, exc = exc.msg
@ -133,7 +134,7 @@ proc loadGenesis*(validators: Natural, validate: bool):
var merkleizer = init DepositsMerkleizer var merkleizer = init DepositsMerkleizer
for d in deposits: for d in deposits:
merkleizer.addChunk hash_tree_root(d).data merkleizer.addChunk hash_tree_root(d).data
let contractSnapshot = DepositTreeSnapshot( let contractSnapshot = DepositContractSnapshot(
depositContractState: merkleizer.toDepositContractState) depositContractState: merkleizer.toDepositContractState)
let res = (ref ForkedHashedBeaconState)( let res = (ref ForkedHashedBeaconState)(

View File

@ -55,7 +55,7 @@ proc run() {.async.} =
let let
elManager = newClone ELManager.init( elManager = newClone ELManager.init(
defaultRuntimeConfig, db = nil, nil, @[paramStr(1)], defaultRuntimeConfig, db = nil, nil, @[paramStr(1)],
none(DepositTreeSnapshot), none(Eth1Network), false, none(DepositContractSnapshot), none(Eth1Network), false,
some readJwtSecret(paramStr(2)).get) some readJwtSecret(paramStr(2)).get)
try: try:

View File

@ -25,15 +25,16 @@ template databaseRoot: string = getTempDir().joinPath(ROOT)
template key1: array[1, byte] = [byte(kOldDepositContractSnapshot)] template key1: array[1, byte] = [byte(kOldDepositContractSnapshot)]
type type
DepositSnapshotUpgradeProc = proc(old: OldDepositContractSnapshot): DepositTreeSnapshot DepositSnapshotUpgradeProc = proc(
{.gcsafe, raises: [].} old: OldDepositContractSnapshot
): DepositContractSnapshot {.gcsafe, raises: [].}
proc ifNecessaryMigrateDCS(db: BeaconChainDB, proc ifNecessaryMigrateDCS(db: BeaconChainDB,
upgradeProc: DepositSnapshotUpgradeProc) = upgradeProc: DepositSnapshotUpgradeProc) =
if not db.hasDepositTreeSnapshot(): if not db.hasDepositContractSnapshot():
let oldSnapshot = db.getUpgradableDepositSnapshot() let oldSnapshot = db.getUpgradableDepositSnapshot()
if oldSnapshot.isSome: if oldSnapshot.isSome:
db.putDepositTreeSnapshot upgradeProc(oldSnapshot.get) db.putDepositContractSnapshot upgradeProc(oldSnapshot.get)
# Hexlified copy of # Hexlified copy of
# eth2-networks/shared/mainnet/genesis_deposit_contract_snapshot.ssz # eth2-networks/shared/mainnet/genesis_deposit_contract_snapshot.ssz
@ -84,7 +85,8 @@ proc fixture1() =
kv.put(key1, compressed).expect("") kv.put(key1, compressed).expect("")
db.close() db.close()
proc inspectDCS(snapshot: OldDepositContractSnapshot | DepositTreeSnapshot) = proc inspectDCS(
snapshot: OldDepositContractSnapshot | DepositContractSnapshot) =
## Inspects a DCS and checks if all of its data corresponds to ## Inspects a DCS and checks if all of its data corresponds to
## what's encoded in ds1. ## what's encoded in ds1.
const zero = toDigest("0000000000000000000000000000000000000000000000000000000000000000") const zero = toDigest("0000000000000000000000000000000000000000000000000000000000000000")
@ -118,11 +120,11 @@ proc inspectDCS(snapshot: OldDepositContractSnapshot | DepositTreeSnapshot) =
# Check deposit root. # Check deposit root.
check(snapshot.getDepositRoot == root) check(snapshot.getDepositRoot == root)
proc inspectDCS(snapshot: DepositTreeSnapshot, wantedBlockHeight: uint64) = proc inspectDCS(snapshot: DepositContractSnapshot, wantedBlockHeight: uint64) =
inspectDCS(snapshot) inspectDCS(snapshot)
check(snapshot.blockHeight == wantedBlockHeight) check(snapshot.blockHeight == wantedBlockHeight)
suite "DepositTreeSnapshot": suite "DepositContractSnapshot":
setup: setup:
randomize() randomize()
@ -139,21 +141,22 @@ suite "DepositTreeSnapshot":
# Start with a fresh database. # Start with a fresh database.
removeDir(databaseRoot) removeDir(databaseRoot)
createDir(databaseRoot) createDir(databaseRoot)
# Make sure there's no DepositTreeSnapshot yet. # Make sure there's no DepositContractSnapshot yet.
let db = BeaconChainDB.new(databaseRoot, inMemory=false) let db = BeaconChainDB.new(databaseRoot, inMemory=false)
check(db.getDepositTreeSnapshot().isErr()) check(db.getDepositContractSnapshot().isErr())
# Setup fixture. # Setup fixture.
fixture1() fixture1()
# Make sure there's still no DepositTreeSnapshot as # Make sure there's still no DepositContractSnapshot as
# BeaconChainDB::getDepositTreeSnapshot() checks only for DCSv2. # BeaconChainDB::getDepositContractSnapshot() checks only for DCSv2.
check(db.getDepositTreeSnapshot().isErr()) check(db.getDepositContractSnapshot().isErr())
# Migrate DB. # Migrate DB.
db.ifNecessaryMigrateDCS do (d: OldDepositContractSnapshot) -> DepositTreeSnapshot: db.ifNecessaryMigrateDCS do (
d.toDepositTreeSnapshot(11052984) d: OldDepositContractSnapshot) -> DepositContractSnapshot:
d.toDepositContractSnapshot(11052984)
# Make sure now there actually is a snapshot. # Make sure now there actually is a snapshot.
check(db.getDepositTreeSnapshot().isOk()) check(db.getDepositContractSnapshot().isOk())
# Inspect content. # Inspect content.
let snapshot = db.getDepositTreeSnapshot().expect("") let snapshot = db.getDepositContractSnapshot().expect("")
inspectDCS(snapshot, 11052984) inspectDCS(snapshot, 11052984)
test "depositCount": test "depositCount":
@ -169,7 +172,7 @@ suite "DepositTreeSnapshot":
var model: OldDepositContractSnapshot var model: OldDepositContractSnapshot
check(decodeSSZ(ds1, model)) check(decodeSSZ(ds1, model))
# Check blockHeight. # Check blockHeight.
var dcs = model.toDepositTreeSnapshot(0) var dcs = model.toDepositContractSnapshot(0)
check(not dcs.isValid(ds1Root)) check(not dcs.isValid(ds1Root))
dcs.blockHeight = 11052984 dcs.blockHeight = 11052984
check(dcs.isValid(ds1Root)) check(dcs.isValid(ds1Root))
@ -188,5 +191,6 @@ suite "DepositTreeSnapshot":
for i in 0..len(dcs.depositContractState.deposit_count)-1: for i in 0..len(dcs.depositContractState.deposit_count)-1:
dcs.depositContractState.deposit_count[i] = 0 dcs.depositContractState.deposit_count[i] = 0
check(not dcs.isValid(ds1Root)) check(not dcs.isValid(ds1Root))
dcs.depositContractState.deposit_count = model.depositContractState.deposit_count dcs.depositContractState.deposit_count =
model.depositContractState.deposit_count
check(dcs.isValid(ds1Root)) check(dcs.isValid(ds1Root))