@@ -835,9 +835,101 @@ def __repr__(self):
835835 return "CProof(challenge=%s solution=%s)" \
836836 % (self .challenge , self .solution )
837837
838+ class ConsensusParamEntry :
839+ __slots__ = ("m_serialize_type" , "m_signblockscript" , "m_sbs_wit_limit" , "m_fedpegscript" , "m_extension_space" )
840+
841+ # Constructor args will define serialization type:
842+ # null = 0
843+ # signblock-related fields = 1, required for m_current on non-epoch-starts
844+ # all fields = 2, required for epoch starts
845+ def __init__ (self , m_signblockscript = b"" , m_sbs_wit_limit = 0 , m_fedpegscript = b"" , m_extension_space = []):
846+ self .m_signblockscript = m_signblockscript
847+ self .m_sbs_wit_limit = m_sbs_wit_limit
848+ self .m_fedpegscript = m_fedpegscript
849+ self .m_extension_space = m_extension_space
850+ if self .is_null ():
851+ self .m_serialize_type = 0
852+ elif m_fedpegscript == b"" and m_extension_space == []:
853+ self .m_serialize_type = 1
854+ else :
855+ self .m_serialize_type = 2
856+
857+ def set_null (self ):
858+ self .m_signblockscript = b""
859+ self .m_sbs_wit_limit = 0
860+ self .m_fedpegscript = b""
861+ self .m_extension_space = []
862+ self .m_serialize_type = 0
863+
864+ def is_null (self ):
865+ return self .m_signblockscript == b"" and self .m_sbs_wit_limit == 0 and \
866+ self .m_fedpegscript == b"" and self .m_extension_space == []
867+
868+ def serialize (self ):
869+ r = b""
870+ r += struct .pack ("B" , self .m_serialize_type )
871+ if self .m_serialize_type == 1 :
872+ r += ser_string (self .m_signblockscript )
873+ r += struct .pack ("<I" , self .m_sbs_wit_limit )
874+ elif self .m_serialize_type == 2 :
875+ r += ser_string (self .m_signblockscript )
876+ r += struct .pack ("<I" , self .m_sbs_wit_limit )
877+ r += ser_string (self .m_fedpegscript )
878+ r += ser_string_vector (self .m_extension_space )
879+ elif self .m_serialize_type > 2 :
880+ raise Exception ("Invalid serialization type for ConsensusParamEntry" )
881+ return r
882+
883+ def deserialize (self , f ):
884+ self .m_serialize_type = struct .unpack ("B" , f .read (1 ))[0 ]
885+ if self .m_serialize_type == 1 :
886+ self .m_signblockscript = deser_string (f )
887+ self .m_sbs_wit_limit = struct .unpack ("<I" , f .read (4 ))[0 ]
888+ elif self .m_serialize_type == 2 :
889+ self .m_signblockscript = deser_string (f )
890+ self .m_sbs_wit_limit = struct .unpack ("<I" , f .read (4 ))[0 ]
891+ self .m_fedpegscript = deser_string (f )
892+ self .m_extension_space = deser_string_vector (f )
893+
894+ def __repr__ (self ):
895+ return "ConsensusParamEntry(m_signblockscript=%s m_fedpegscript=%s m_extension_space=%s)" \
896+ % (self .m_signblockscript , self .m_fedpegscript , self .m_extension_space )
897+
898+ class DynaFedParams :
899+ __slots__ = ("m_current" , "m_proposed" )
900+
901+ def __init__ (self , m_current = ConsensusParamEntry (), m_proposed = ConsensusParamEntry ()):
902+ self .m_current = m_current
903+ self .m_proposed = m_proposed
904+
905+ def set_null (self ):
906+ self .m_current .set_null ()
907+ self .m_proposed .set_null ()
908+
909+ def is_null (self ):
910+ return self .m_current .is_null () and self .m_proposed .is_null ()
911+
912+ def serialize (self ):
913+ r = b""
914+ r += self .m_current .serialize ()
915+ r += self .m_proposed .serialize ()
916+ return r
917+
918+ def deserialize (self , f ):
919+ self .m_current .deserialize (f )
920+ self .m_proposed .deserialize (f )
921+
922+ def __repr__ (self ):
923+ return "DynaFedParams(m_current=%s m_proposed=%s)" \
924+ % (self .m_current , self .m_proposed )
925+
926+
927+ HEADER_HF_BIT = 1 << 31
928+ HEADER_HF_MASK = 0x7fffffff
838929class CBlockHeader :
839930 __slots__ = ("hash" , "hashMerkleRoot" , "hashPrevBlock" , "nBits" , "nNonce" ,
840- "nTime" , "nVersion" , "sha256" , "block_height" , "proof" )
931+ "nTime" , "nVersion" , "sha256" , "block_height" , "proof" , "m_dyna_params" ,
932+ "m_signblock_witness" )
841933
842934 def __init__ (self , header = None ):
843935 if header is None :
@@ -851,6 +943,8 @@ def __init__(self, header=None):
851943 self .proof = header .proof
852944 self .sha256 = header .sha256
853945 self .hash = header .hash
946+ self .m_dyna_params = header .m_dyna_params
947+ self .m_signblock_witness = header .m_signblock_witness
854948 self .calc_sha256 ()
855949
856950 def set_null (self ):
@@ -860,38 +954,69 @@ def set_null(self):
860954 self .nTime = 0
861955 self .block_height = 0
862956 self .proof = CProof ()
957+ self .m_dyna_params = DynaFedParams ()
958+ self .m_signblock_witness = CScriptWitness ()
863959 self .sha256 = None
864960 self .hash = None
865961
866962 def deserialize (self , f ):
867963 self .nVersion = struct .unpack ("<i" , f .read (4 ))[0 ]
964+ is_dyna = False
965+
966+ if self .nVersion < 0 :
967+ is_dyna = True
968+ self .nVersion = HEADER_HF_MASK & self .nVersion
969+
868970 self .hashPrevBlock = deser_uint256 (f )
869971 self .hashMerkleRoot = deser_uint256 (f )
870972 self .nTime = struct .unpack ("<I" , f .read (4 ))[0 ]
871973 self .block_height = struct .unpack ("<I" , f .read (4 ))[0 ]
872- self .proof .deserialize (f )
974+ if is_dyna :
975+ self .m_dyna_params .deserialize (f )
976+ self .m_signblock_witness .stack = deser_string_vector (f )
977+ else :
978+ self .proof .deserialize (f )
873979 self .sha256 = None
874980 self .hash = None
875981
876982 def serialize (self ):
877983 r = b""
878- r += struct .pack ("<i" , self .nVersion )
984+ nVersion = self .nVersion
985+ is_dyna = False
986+ if not self .m_dyna_params .is_null ():
987+ nVersion -= HEADER_HF_BIT
988+ is_dyna = True
989+
990+ r += struct .pack ("<i" , nVersion )
879991 r += ser_uint256 (self .hashPrevBlock )
880992 r += ser_uint256 (self .hashMerkleRoot )
881993 r += struct .pack ("<I" , self .nTime )
882994 r += struct .pack ("<I" , self .block_height )
883- r += self .proof .serialize ()
995+ if is_dyna :
996+ r += self .m_dyna_params .serialize ()
997+ r += ser_string_vector (self .m_signblock_witness .stack )
998+ else :
999+ r += self .proof .serialize ()
8841000 return r
8851001
8861002 def calc_sha256 (self ):
8871003 if self .sha256 is None :
1004+ nVersion = self .nVersion
1005+ is_dyna = False
1006+ if not self .m_dyna_params .is_null ():
1007+ nVersion -= HEADER_HF_BIT
1008+ is_dyna = True
1009+
8881010 r = b""
889- r += struct .pack ("<i" , self . nVersion )
1011+ r += struct .pack ("<i" , nVersion )
8901012 r += ser_uint256 (self .hashPrevBlock )
8911013 r += ser_uint256 (self .hashMerkleRoot )
8921014 r += struct .pack ("<I" , self .nTime )
8931015 r += struct .pack ("<I" , self .block_height )
894- r += self .proof .serialize_for_hash ()
1016+ if is_dyna :
1017+ r += self .m_dyna_params .serialize ()
1018+ else :
1019+ r += self .proof .serialize_for_hash ()
8951020 self .sha256 = uint256_from_str (hash256 (r ))
8961021 self .hash = encode (hash256 (r )[::- 1 ], 'hex_codec' ).decode ('ascii' )
8971022
@@ -976,9 +1101,9 @@ def solve(self):
9761101# self.rehash()
9771102
9781103 def __repr__ (self ):
979- return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s vtx=%s)" \
1104+ return "CBlock(nVersion=%i hashPrevBlock=%064x hashMerkleRoot=%064x nTime=%s vtx=%s m_dyna_params=%s )" \
9801105 % (self .nVersion , self .hashPrevBlock , self .hashMerkleRoot ,
981- time .ctime (self .nTime ), repr (self .vtx ))
1106+ time .ctime (self .nTime ), repr (self .vtx ), self . m_dyna_params )
9821107
9831108
9841109class PrefilledTransaction :
0 commit comments