Skip to content

Commit

Permalink
fix build after rebasing to master branch
Browse files Browse the repository at this point in the history
add snapshot metadata verification to utxo snapshot test
  • Loading branch information
Naviabheeman committed Jun 12, 2024
1 parent 81557f9 commit 444b183
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 18 deletions.
1 change: 0 additions & 1 deletion src/utxo_snapshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#ifndef BITCOIN_UTXO_SNAPSHOT_H
#define BITCOIN_UTXO_SNAPSHOT_H

#include <cs_main.h>
#include <serialize.h>
#include <sync.h>
#include <uint256.h>
Expand Down
34 changes: 26 additions & 8 deletions test/functional/rpc_utxosnapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
sha256sum_file,
get_datadir_path,
NetworkDirName,
hex_str_to_bytes
hex_str_to_bytes,
TAPYRUS_NETWORK_PARAMS,
TAPYRUS_MODES
)
from test_framework.messages import CBlock
from test_framework.messages import CSnapshotMetadata
from io import BytesIO
import os.path

Expand All @@ -43,29 +45,45 @@ def run_test(self):
generate_blocks(100, node, hex_str_to_bytes(self.signblockpubkey), self.signblockprivkey)
self.sync_all()

#create snapshot
out = node.utxosnapshot(FILENAME)
expected_path = os.path.join(get_datadir_path(self.options.tmpdir, 0), NetworkDirName(), FILENAME)
# recreating the same snapshot file causes error.
assert_raises_rpc_error(
-8, 'path already exists', node.utxosnapshot, FILENAME)

assert os.path.exists(expected_path) and os.path.isfile(expected_path)

# verify stats
assert_equal(out['coins_written'], 100)
assert_equal(out['base_height'], 100)
assert_equal(out['path'], str(expected_path))
assert_equal(out['base_hash'], node.getblockhash(100))
assert_equal(out['nchaintx'], 101)

#these hashes should be deterministic
assert_equal(out['txoutset_hash'], '1a3a974c72d75c933dfb6e6d11983813c593ae8387260a2f7fbaa0cb41894ac1')
assert_equal(out['base_hash'], '2e51e8eb5b86c37f0e8e86e88cc311dac30197a746ce707e001703f6a53aa95d')

node.stop()

# verify snapshot file
assert os.path.exists(expected_path) and os.path.isfile(expected_path)
assert_equal(
sha256sum_file(str(expected_path)).hex(),
'a4884b966b64239b8b24280b445d8310c996467ec1b1d1bd78a9ff767a9ae64a')

assert_equal(out['txoutset_hash'], '1a3a974c72d75c933dfb6e6d11983813c593ae8387260a2f7fbaa0cb41894ac1')
# verify snapshot metadata
snapshot = CSnapshotMetadata(out['base_hash'], out['coins_written'])
with open(expected_path, 'rb') as f:
data = f.read(68)
snapshot.deserialize(BytesIO(data))

# Specifying a path to an existing or invalid file will fail.
assert_raises_rpc_error(
-8, 'path already exists', node.utxosnapshot, FILENAME)
assert_equal(snapshot.version, 1)
assert_equal(snapshot.networkid, TAPYRUS_MODES.DEV.value)
assert_equal(snapshot.network_mode, bytes(TAPYRUS_NETWORK_PARAMS[TAPYRUS_MODES.DEV][0], 'utf8'))
assert_equal(snapshot.base_blockhash, out['base_hash'])
assert_equal(snapshot.coins_count, out['coins_written'])

# Specifying an invalid file will fail.
invalid_path = os.path.join(get_datadir_path(self.options.tmpdir, 0), "invalid", "path")
assert_raises_rpc_error(
-8, "Couldn't open file temp file for writing", node.utxosnapshot, invalid_path)
Expand Down
32 changes: 23 additions & 9 deletions test/functional/test_framework/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import time

from test_framework.siphash import siphash256
from test_framework.util import hex_str_to_bytes, bytes_to_hex_str
from test_framework.util import hex_str_to_bytes, bytes_to_hex_str, TAPYRUS_NETWORK_PARAMS, TAPYRUS_MODES
from test_framework.key import CECKey
from test_framework.schnorr import Schnorr

Expand Down Expand Up @@ -1405,25 +1405,39 @@ def serialize(self):
return r

class CSnapshotMetadata():
def __init__(self, networkid, base_blockhash, coins_count):
self.networkid = networkid
SNAPSHOT_MAGIC_BYTES = b'utxo\xff'

def __init__(self, base_blockhash, coins_count):
self.version = 1
self.supported_versions = [1]
self.networkid = TAPYRUS_MODES.DEV
self.base_blockhash = base_blockhash
self.coins_count = coins_count

def deserialize(self, f):
self.networkid = struct.unpack("<i", f.read(8))[0]
self.base_blockhash = deser_uint256_vector(f)
self.coins_count = struct.unpack("<i", f.read(8))[0]
magic_bytes = f.read(5)
if magic_bytes != self.SNAPSHOT_MAGIC_BYTES:
raise Exception("UTXO Snapshot corrupt %s", magic_bytes)
self.version = struct.unpack("<H", f.read(2))[0]
self.networkid = struct.unpack("<q", f.read(8))[0]
if self.networkid != TAPYRUS_MODES.DEV.value:
raise Exception("UTXO Snapshot is not from this network. It belongs to %d", self.networkid)
self.network_mode = deser_string(f)
self.base_blockhash = encode(f.read(32)[::-1], 'hex_codec').decode('ascii')
self.coins_count = struct.unpack("<q", f.read(8))[0]

def serialize(self):
r = b""
r += struct.pack(" ", self.SNAPSHOT_MAGIC_BYTES)
r += struct.pack("<i", self.version)
r += struct.pack("<i", self.networkid)
r += ser_uint256_vector(self.base_blockhash)
r += ser_string(TAPYRUS_NETWORK_PARAMS[self.networkid][0])
r += ser_uint256(self.base_blockhash)
r += struct.pack("<i", self.coins_count)
return r

def __repr__(self):
return "CSnapshotMetadata(networkid=%i base_blockhash=%s coins_count=%i)" \
% (self.networkid, str([hex(x) for x in self.base_blockhash]),self.coins_count)
return "CSnapshotMetadata(version=%i networkid=%i mode=%s, base_blockhash=%s coins_count=%i)" \
% (self.version, self.networkid, TAPYRUS_NETWORK_PARAMS[self.networkid][0], str([hex(x) for x in self.base_blockhash]),self.coins_count)


0 comments on commit 444b183

Please sign in to comment.