13
13
# limitations under the License.
14
14
15
15
from typing import TYPE_CHECKING
16
- from unittest .mock import Mock
17
16
18
17
from structlog import get_logger
19
18
20
19
from hathor .conf .get_settings import get_global_settings
21
- from hathor .transaction import BaseTransaction
22
- from hathor .transaction .static_metadata import BlockStaticMetadata , TransactionStaticMetadata , VertexStaticMetadata
20
+ from hathor .transaction import Block , Transaction
21
+ from hathor .transaction .static_metadata import BlockStaticMetadata , TransactionStaticMetadata
23
22
from hathor .transaction .storage .migrations import BaseMigration
24
23
from hathor .util import progress
25
24
@@ -40,48 +39,29 @@ def run(self, storage: 'TransactionStorage') -> None:
40
39
"""This migration takes attributes from existing vertex metadata and saves them as static metadata."""
41
40
log = logger .new ()
42
41
settings = get_global_settings ()
43
- # We have to iterate over metadata instead of vertices because the storage doesn't allow us to get a vertex if
44
- # its static metadata is not set. We also use raw dict metadata because `metadata.create_from_json()` doesn't
45
- # include attributes that should be static, which are exactly the ones we need for this migration.
46
- metadata_iter = storage .iter_all_raw_metadata ()
47
42
48
- for vertex_id , raw_metadata in progress (metadata_iter , log = log , total = None ):
49
- height = raw_metadata ['height' ]
50
- min_height = raw_metadata ['min_height' ]
51
- bit_counts = raw_metadata .get ('feature_activation_bit_counts' )
43
+ # First we migrate static metadata using the storage itself since it uses internal structures.
44
+ log .info ('creating static metadata...' )
45
+ storage .migrate_static_metadata (log )
52
46
53
- assert isinstance (height , int )
54
- assert isinstance (min_height , int )
47
+ # Now that static metadata is set, we can use the topological iterator normally
48
+ log .info ('removing old metadata and validating...' )
49
+ topological_iter = storage .topological_iterator ()
55
50
56
- static_metadata : VertexStaticMetadata
57
- is_block = (vertex_id == settings .GENESIS_BLOCK_HASH or height != 0 )
58
-
59
- if is_block :
60
- assert isinstance (bit_counts , list )
61
- for item in bit_counts :
62
- assert isinstance (item , int )
51
+ for vertex in progress (topological_iter , log = log , total = None ):
52
+ # We re-save the vertex's metadata so it's serialized with the new `to_bytes()` method, excluding fields
53
+ # that were migrated.
54
+ storage .save_transaction (vertex , only_metadata = True )
63
55
64
- static_metadata = BlockStaticMetadata (
65
- height = height ,
66
- min_height = min_height ,
67
- feature_activation_bit_counts = bit_counts ,
68
- feature_states = {}, # This will be populated in the next PR
56
+ # We re-create the static metadata from scratch and compare it with the value that was created by the
57
+ # migration above, as a sanity check.
58
+ if isinstance ( vertex , Block ):
59
+ assert vertex . static_metadata == BlockStaticMetadata . create_from_storage (
60
+ vertex , settings , storage
69
61
)
70
- else :
71
- assert bit_counts is None or bit_counts == []
72
- static_metadata = TransactionStaticMetadata (
73
- min_height = min_height
62
+ elif isinstance (vertex , Transaction ):
63
+ assert vertex .static_metadata == TransactionStaticMetadata .create_from_storage (
64
+ vertex , settings , storage
74
65
)
75
-
76
- # We create a fake vertex with just the hash and static metadata, so we can use the existing
77
- # `storage._save_static_metadata()` instead of having to create an unsafe storage API that takes those
78
- # two arguments.
79
- mock_vertex = Mock (spec_set = BaseTransaction )
80
- mock_vertex .hash = vertex_id
81
- mock_vertex .static_metadata = static_metadata
82
- storage ._save_static_metadata (mock_vertex )
83
-
84
- # Now we can take the actual vertex from the storage and save its metadata. It'll be serialized with the
85
- # new `to_bytes()` method, excluding fields that were migrated.
86
- vertex = storage .get_transaction (vertex_id )
87
- storage .save_transaction (vertex , only_metadata = True )
66
+ else :
67
+ raise NotImplementedError
0 commit comments