mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-19 13:27:35 +02:00
HF: Dyanfed pruned header now has extra root
This commit is contained in:
parent
687e427b81
commit
aec8b6caf5
6 changed files with 54 additions and 17 deletions
|
|
@ -94,7 +94,7 @@ DynaFedParamEntry ComputeNextBlockCurrentParameters(const CBlockIndex* pindexPre
|
||||||
// Return appropriate format based on epoch age
|
// Return appropriate format based on epoch age
|
||||||
if (epoch_age > 0) {
|
if (epoch_age > 0) {
|
||||||
// TODO implement "prune" function to remove fields in place and change serialize type
|
// TODO implement "prune" function to remove fields in place and change serialize type
|
||||||
return DynaFedParamEntry(entry.m_signblockscript, entry.m_signblock_witness_limit);
|
return DynaFedParamEntry(entry.m_signblockscript, entry.m_signblock_witness_limit, entry.CalculateExtraRoot());
|
||||||
} else {
|
} else {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
||||||
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
|
fIncludeWitness = IsWitnessEnabled(pindexPrev, chainparams.GetConsensus());
|
||||||
|
|
||||||
if (IsDynaFedEnabled(pindexPrev, chainparams.GetConsensus())) {
|
if (IsDynaFedEnabled(pindexPrev, chainparams.GetConsensus())) {
|
||||||
DynaFedParamEntry current_params = ComputeNextBlockCurrentParameters(chainActive.Tip(), chainparams.GetConsensus());
|
const DynaFedParamEntry current_params = ComputeNextBlockCurrentParameters(chainActive.Tip(), chainparams.GetConsensus());
|
||||||
DynaFedParams block_params(current_params, proposed_entry ? *proposed_entry : DynaFedParamEntry());
|
const DynaFedParams block_params(current_params, proposed_entry ? *proposed_entry : DynaFedParamEntry());
|
||||||
pblock->m_dynafed_params = block_params;
|
pblock->m_dynafed_params = block_params;
|
||||||
nBlockWeight += ::GetSerializeSize(block_params, PROTOCOL_VERSION)*WITNESS_SCALE_FACTOR;
|
nBlockWeight += ::GetSerializeSize(block_params, PROTOCOL_VERSION)*WITNESS_SCALE_FACTOR;
|
||||||
nBlockWeight += current_params.m_signblock_witness_limit; // Note witness discount
|
nBlockWeight += current_params.m_signblock_witness_limit; // Note witness discount
|
||||||
|
|
|
||||||
|
|
@ -43,19 +43,39 @@ std::string CBlock::ToString() const
|
||||||
|
|
||||||
uint256 DynaFedParamEntry::CalculateRoot() const
|
uint256 DynaFedParamEntry::CalculateRoot() const
|
||||||
{
|
{
|
||||||
if (IsNull()) {
|
if (m_serialize_type == 0) {
|
||||||
return uint256();
|
return uint256();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint256> compact_leaves;
|
||||||
|
compact_leaves.push_back(SerializeHash(m_signblockscript, SER_GETHASH, 0));
|
||||||
|
compact_leaves.push_back(SerializeHash(m_signblock_witness_limit, SER_GETHASH, 0));
|
||||||
|
uint256 compact_root(ComputeFastMerkleRoot(compact_leaves));
|
||||||
|
|
||||||
|
uint256 extra_root;
|
||||||
|
if (m_serialize_type ==1 ) {
|
||||||
|
// It's pruned, take the stored value
|
||||||
|
extra_root = m_elided_root;
|
||||||
|
} else if (m_serialize_type == 2) {
|
||||||
|
// It's unpruned, compute the node value
|
||||||
|
extra_root = CalculateExtraRoot();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint256> leaves;
|
std::vector<uint256> leaves;
|
||||||
leaves.push_back(SerializeHash(m_signblockscript, SER_GETHASH, 0));
|
leaves.push_back(compact_root);
|
||||||
leaves.push_back(SerializeHash(m_signblock_witness_limit, SER_GETHASH, 0));
|
leaves.push_back(extra_root);
|
||||||
leaves.push_back(SerializeHash(m_fedpeg_program, SER_GETHASH, 0));
|
|
||||||
leaves.push_back(SerializeHash(m_fedpegscript, SER_GETHASH, 0));
|
|
||||||
leaves.push_back(SerializeHash(m_extension_space, SER_GETHASH, 0));
|
|
||||||
return ComputeFastMerkleRoot(leaves);
|
return ComputeFastMerkleRoot(leaves);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint256 DynaFedParamEntry::CalculateExtraRoot() const
|
||||||
|
{
|
||||||
|
std::vector<uint256> extra_leaves;
|
||||||
|
extra_leaves.push_back(SerializeHash(m_fedpeg_program, SER_GETHASH, 0));
|
||||||
|
extra_leaves.push_back(SerializeHash(m_fedpegscript, SER_GETHASH, 0));
|
||||||
|
extra_leaves.push_back(SerializeHash(m_extension_space, SER_GETHASH, 0));
|
||||||
|
return ComputeFastMerkleRoot(extra_leaves);
|
||||||
|
}
|
||||||
|
|
||||||
uint256 DynaFedParams::CalculateRoot() const
|
uint256 DynaFedParams::CalculateRoot() const
|
||||||
{
|
{
|
||||||
if (IsNull()) {
|
if (IsNull()) {
|
||||||
|
|
|
||||||
|
|
@ -58,18 +58,25 @@ public:
|
||||||
class DynaFedParamEntry
|
class DynaFedParamEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
unsigned char m_serialize_type; // Determines how it is serialized, defaults to null
|
// Determines how these entries are serialized and stored
|
||||||
|
// 0 -> Null. Only used for proposed parameter "null votes"
|
||||||
|
// 1 -> Pruned. Doesn't have non-signblockscript data. That elided data
|
||||||
|
// is committed to in m_elided_root, and validated against chainstate.
|
||||||
|
// 2 -> Full. Typically only consensus-legal at epoch start.
|
||||||
|
unsigned char m_serialize_type;
|
||||||
|
|
||||||
CScript m_signblockscript;
|
CScript m_signblockscript;
|
||||||
uint32_t m_signblock_witness_limit; // Max block signature witness serialized size
|
uint32_t m_signblock_witness_limit; // Max block signature witness serialized size
|
||||||
CScript m_fedpeg_program; // The "scriptPubKey" of the fedpegscript
|
CScript m_fedpeg_program; // The "scriptPubKey" of the fedpegscript
|
||||||
CScript m_fedpegscript; // The witnessScript for witness v0 or undefined otherwise.
|
CScript m_fedpegscript; // The witnessScript for witness v0 or undefined otherwise.
|
||||||
// No consensus meaning to the particular bytes, currently we interpret as PAK keys, details in pak.h
|
// No consensus meaning to the particular bytes, currently we interpret as PAK keys, details in pak.h
|
||||||
std::vector<std::vector<unsigned char>> m_extension_space;
|
std::vector<std::vector<unsigned char>> m_extension_space;
|
||||||
|
uint256 m_elided_root; // non-zero only when m_serialize_type == 1
|
||||||
|
|
||||||
// Each constructor sets its own serialization type implicitly based on which
|
// Each constructor sets its own serialization type implicitly based on which
|
||||||
// arguments are given
|
// arguments are given
|
||||||
DynaFedParamEntry() { m_signblock_witness_limit = 0; m_serialize_type = 0; };
|
DynaFedParamEntry() { m_signblock_witness_limit = 0; m_serialize_type = 0; };
|
||||||
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in) { m_serialize_type = 1; };
|
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in, const uint256 elided_root_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in), m_elided_root(elided_root_in) { m_serialize_type = 1; };
|
||||||
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in, const CScript& fedpeg_program_in, const CScript& fedpegscript_in, const std::vector<std::vector<unsigned char>> extension_space_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in), m_fedpeg_program(fedpeg_program_in), m_fedpegscript(fedpegscript_in), m_extension_space(extension_space_in) { m_serialize_type = 2; };
|
DynaFedParamEntry(const CScript& signblockscript_in, const uint32_t sbs_wit_limit_in, const CScript& fedpeg_program_in, const CScript& fedpegscript_in, const std::vector<std::vector<unsigned char>> extension_space_in) : m_signblockscript(signblockscript_in), m_signblock_witness_limit(sbs_wit_limit_in), m_fedpeg_program(fedpeg_program_in), m_fedpegscript(fedpegscript_in), m_extension_space(extension_space_in) { m_serialize_type = 2; };
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
@ -84,6 +91,7 @@ public:
|
||||||
case 1:
|
case 1:
|
||||||
READWRITE(m_signblockscript);
|
READWRITE(m_signblockscript);
|
||||||
READWRITE(m_signblock_witness_limit);
|
READWRITE(m_signblock_witness_limit);
|
||||||
|
READWRITE(m_elided_root);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
READWRITE(m_signblockscript);
|
READWRITE(m_signblockscript);
|
||||||
|
|
@ -98,6 +106,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 CalculateRoot() const;
|
uint256 CalculateRoot() const;
|
||||||
|
// Calculates root for the non-blocksigning merkle fields
|
||||||
|
uint256 CalculateExtraRoot() const;
|
||||||
|
|
||||||
bool IsNull() const
|
bool IsNull() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -216,14 +216,16 @@ class BlockSignTest(BitcoinTestFramework):
|
||||||
|
|
||||||
# Next let's activate dynafed
|
# Next let's activate dynafed
|
||||||
blocks_til_dynafed = 431 - self.nodes[0].getblockcount()
|
blocks_til_dynafed = 431 - self.nodes[0].getblockcount()
|
||||||
|
self.log.info("Activating dynafed")
|
||||||
self.mine_blocks(blocks_til_dynafed, False)
|
self.mine_blocks(blocks_til_dynafed, False)
|
||||||
self.check_height(111+blocks_til_dynafed)
|
self.check_height(111+blocks_til_dynafed)
|
||||||
|
|
||||||
assert_equal(self.nodes[0].getblockchaininfo()['bip9_softforks']['dynafed']['status'], "active")
|
assert_equal(self.nodes[0].getblockchaininfo()['bip9_softforks']['dynafed']['status'], "active")
|
||||||
|
|
||||||
self.log.info("Mine some dynamic federation blocks without and with txns")
|
self.log.info("Mine some dynamic federation blocks without txns")
|
||||||
self.mine_blocks(50, False)
|
self.mine_blocks(10, False)
|
||||||
self.mine_blocks(50, True)
|
self.log.info("Mine some dynamic federation blocks with txns")
|
||||||
|
self.mine_blocks(10, True)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
BlockSignTest().main()
|
BlockSignTest().main()
|
||||||
|
|
|
||||||
|
|
@ -836,13 +836,13 @@ class CProof:
|
||||||
% (self.challenge, self.solution)
|
% (self.challenge, self.solution)
|
||||||
|
|
||||||
class DynaFedParamEntry:
|
class DynaFedParamEntry:
|
||||||
__slots__ = ("m_serialize_type", "m_signblockscript", "m_signblock_witness_limit", "m_fedpeg_program", "m_fedpegscript", "m_extension_space")
|
__slots__ = ("m_serialize_type", "m_signblockscript", "m_signblock_witness_limit", "m_fedpeg_program", "m_fedpegscript", "m_extension_space", "m_elided_root")
|
||||||
|
|
||||||
# Constructor args will define serialization type:
|
# Constructor args will define serialization type:
|
||||||
# null = 0
|
# null = 0
|
||||||
# signblock-related fields = 1, required for m_current on non-epoch-starts
|
# signblock-related fields = 1, required for m_current on non-epoch-starts
|
||||||
# all fields = 2, required for epoch starts
|
# all fields = 2, required for epoch starts
|
||||||
def __init__(self, m_signblockscript=b"", m_signblock_witness_limit=0, m_fedpeg_program=b"", m_fedpegscript=b"", m_extension_space=[]):
|
def __init__(self, m_signblockscript=b"", m_signblock_witness_limit=0, m_fedpeg_program=b"", m_fedpegscript=b"", m_extension_space=[], m_elided_root=0):
|
||||||
self.m_signblockscript = m_signblockscript
|
self.m_signblockscript = m_signblockscript
|
||||||
self.m_signblock_witness_limit = m_signblock_witness_limit
|
self.m_signblock_witness_limit = m_signblock_witness_limit
|
||||||
self.m_fedpeg_program = m_fedpeg_program
|
self.m_fedpeg_program = m_fedpeg_program
|
||||||
|
|
@ -850,8 +850,10 @@ class DynaFedParamEntry:
|
||||||
self.m_extension_space = m_extension_space
|
self.m_extension_space = m_extension_space
|
||||||
if self.is_null():
|
if self.is_null():
|
||||||
self.m_serialize_type = 0
|
self.m_serialize_type = 0
|
||||||
elif m_fedpegscript==b"" and m_extension_space == []:
|
elif m_fedpegscript==b"" and m_fedpeg_program==b"" and m_extension_space == []:
|
||||||
self.m_serialize_type = 1
|
self.m_serialize_type = 1
|
||||||
|
# We also set the "extra root" in this case
|
||||||
|
self.m_elided_root = m_elided_root
|
||||||
else:
|
else:
|
||||||
self.m_serialize_type = 2
|
self.m_serialize_type = 2
|
||||||
|
|
||||||
|
|
@ -862,6 +864,7 @@ class DynaFedParamEntry:
|
||||||
self.m_fedpegscript = b""
|
self.m_fedpegscript = b""
|
||||||
self.m_extension_space = []
|
self.m_extension_space = []
|
||||||
self.m_serialize_type = 0
|
self.m_serialize_type = 0
|
||||||
|
self.m_elided_root = 0
|
||||||
|
|
||||||
def is_null(self):
|
def is_null(self):
|
||||||
return self.m_signblockscript == b"" and self.m_signblock_witness_limit == 0 and \
|
return self.m_signblockscript == b"" and self.m_signblock_witness_limit == 0 and \
|
||||||
|
|
@ -874,6 +877,7 @@ class DynaFedParamEntry:
|
||||||
if self.m_serialize_type == 1:
|
if self.m_serialize_type == 1:
|
||||||
r += ser_string(self.m_signblockscript)
|
r += ser_string(self.m_signblockscript)
|
||||||
r += struct.pack("<I", self.m_signblock_witness_limit)
|
r += struct.pack("<I", self.m_signblock_witness_limit)
|
||||||
|
r += ser_uint256(self.m_elided_root)
|
||||||
elif self.m_serialize_type == 2:
|
elif self.m_serialize_type == 2:
|
||||||
r += ser_string(self.m_signblockscript)
|
r += ser_string(self.m_signblockscript)
|
||||||
r += struct.pack("<I", self.m_signblock_witness_limit)
|
r += struct.pack("<I", self.m_signblock_witness_limit)
|
||||||
|
|
@ -889,6 +893,7 @@ class DynaFedParamEntry:
|
||||||
if self.m_serialize_type == 1:
|
if self.m_serialize_type == 1:
|
||||||
self.m_signblockscript = deser_string(f)
|
self.m_signblockscript = deser_string(f)
|
||||||
self.m_signblock_witness_limit = struct.unpack("<I", f.read(4))[0]
|
self.m_signblock_witness_limit = struct.unpack("<I", f.read(4))[0]
|
||||||
|
self.m_elided_root = deser_uint256(f)
|
||||||
elif self.m_serialize_type == 2:
|
elif self.m_serialize_type == 2:
|
||||||
self.m_signblockscript = deser_string(f)
|
self.m_signblockscript = deser_string(f)
|
||||||
self.m_signblock_witness_limit = struct.unpack("<I", f.read(4))[0]
|
self.m_signblock_witness_limit = struct.unpack("<I", f.read(4))[0]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue