Update block headers to include multiple levels of parent blocks (#1822)

* Replace the old parents in the block header with BlockLevelParents.

* Begin fixing compilation errors.

* Implement database serialization for block level parents.

* Implement p2p serialization for block level parents.

* Implement rpc serialization for block level parents.

* Add DirectParents() to the block header interface.

* Use DirectParents() instead of Parents() in some places.

* Revert test_block_builder.go.

* Add block level parents to hash serialization.

* Use the zero hash for genesis finality points.

* Fix failing tests.

* Fix a variable name.

* Update headerEstimatedSerializedSize.

* Add comments in blocklevelparents.go.

* Fix the rpc-stability stability test.

* Change the field number for `parents` fields in p2p.proto and rpc.proto.

* Remove MsgBlockHeader::NumParentBlocks.
This commit is contained in:
stasatdaglabs 2021-08-24 13:06:39 +04:00 committed by GitHub
parent ba5880fab1
commit 837dac68b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 2620 additions and 2277 deletions

View File

@ -31,7 +31,7 @@ func DomainBlockToMsgBlock(domainBlock *externalapi.DomainBlock) *MsgBlock {
func DomainBlockHeaderToBlockHeader(domainBlockHeader externalapi.BlockHeader) *MsgBlockHeader {
return &MsgBlockHeader{
Version: domainBlockHeader.Version(),
ParentHashes: domainBlockHeader.ParentHashes(),
Parents: domainBlockHeader.Parents(),
HashMerkleRoot: domainBlockHeader.HashMerkleRoot(),
AcceptedIDMerkleRoot: domainBlockHeader.AcceptedIDMerkleRoot(),
UTXOCommitment: domainBlockHeader.UTXOCommitment(),
@ -61,7 +61,7 @@ func MsgBlockToDomainBlock(msgBlock *MsgBlock) *externalapi.DomainBlock {
func BlockHeaderToDomainBlockHeader(blockHeader *MsgBlockHeader) externalapi.BlockHeader {
return blockheader.NewImmutableBlockHeader(
blockHeader.Version,
blockHeader.ParentHashes,
blockHeader.Parents,
blockHeader.HashMerkleRoot,
blockHeader.AcceptedIDMerkleRoot,
blockHeader.UTXOCommitment,
@ -342,9 +342,15 @@ func DomainOutpointAndUTXOEntryPairsToOutpointAndUTXOEntryPairs(
// DomainBlockToRPCBlock converts DomainBlocks to RPCBlocks
func DomainBlockToRPCBlock(block *externalapi.DomainBlock) *RPCBlock {
parents := make([]*RPCBlockLevelParents, len(block.Header.Parents()))
for i, blockLevelParents := range block.Header.Parents() {
parents[i] = &RPCBlockLevelParents{
ParentHashes: hashes.ToStrings(blockLevelParents),
}
}
header := &RPCBlockHeader{
Version: uint32(block.Header.Version()),
ParentHashes: hashes.ToStrings(block.Header.ParentHashes()),
Parents: parents,
HashMerkleRoot: block.Header.HashMerkleRoot().String(),
AcceptedIDMerkleRoot: block.Header.AcceptedIDMerkleRoot().String(),
UTXOCommitment: block.Header.UTXOCommitment().String(),
@ -367,13 +373,16 @@ func DomainBlockToRPCBlock(block *externalapi.DomainBlock) *RPCBlock {
// RPCBlockToDomainBlock converts `block` into a DomainBlock
func RPCBlockToDomainBlock(block *RPCBlock) (*externalapi.DomainBlock, error) {
parentHashes := make([]*externalapi.DomainHash, len(block.Header.ParentHashes))
for i, parentHash := range block.Header.ParentHashes {
domainParentHashes, err := externalapi.NewDomainHashFromString(parentHash)
if err != nil {
return nil, err
parents := make([]externalapi.BlockLevelParents, len(block.Header.Parents))
for i, blockLevelParents := range block.Header.Parents {
parents[i] = make(externalapi.BlockLevelParents, len(blockLevelParents.ParentHashes))
for j, parentHash := range blockLevelParents.ParentHashes {
var err error
parents[i][j], err = externalapi.NewDomainHashFromString(parentHash)
if err != nil {
return nil, err
}
}
parentHashes[i] = domainParentHashes
}
hashMerkleRoot, err := externalapi.NewDomainHashFromString(block.Header.HashMerkleRoot)
if err != nil {
@ -397,7 +406,7 @@ func RPCBlockToDomainBlock(block *RPCBlock) (*externalapi.DomainBlock, error) {
}
header := blockheader.NewImmutableBlockHeader(
uint16(block.Header.Version),
parentHashes,
parents,
hashMerkleRoot,
acceptedIDMerkleRoot,
utxoCommitment,

View File

@ -21,7 +21,7 @@ func TestBlock(t *testing.T) {
pver := ProtocolVersion
// Block 1 header.
parentHashes := blockOne.Header.ParentHashes
parents := blockOne.Header.Parents
hashMerkleRoot := blockOne.Header.HashMerkleRoot
acceptedIDMerkleRoot := blockOne.Header.AcceptedIDMerkleRoot
utxoCommitment := blockOne.Header.UTXOCommitment
@ -30,7 +30,7 @@ func TestBlock(t *testing.T) {
daaScore := blockOne.Header.DAAScore
blueWork := blockOne.Header.BlueWork
finalityPoint := blockOne.Header.FinalityPoint
bh := NewBlockHeader(1, parentHashes, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce,
bh := NewBlockHeader(1, parents, hashMerkleRoot, acceptedIDMerkleRoot, utxoCommitment, bits, nonce,
daaScore, blueWork, finalityPoint)
// Ensure the command is expected value.
@ -135,7 +135,7 @@ func TestConvertToPartial(t *testing.T) {
var blockOne = MsgBlock{
Header: MsgBlockHeader{
Version: 0,
ParentHashes: []*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash},
Parents: []externalapi.BlockLevelParents{[]*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash}},
HashMerkleRoot: mainnetGenesisMerkleRoot,
AcceptedIDMerkleRoot: exampleAcceptedIDMerkleRoot,
UTXOCommitment: exampleUTXOCommitment,

View File

@ -5,14 +5,12 @@
package appmessage
import (
"math"
"math/big"
"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/pkg/errors"
)
// BaseBlockHeaderPayload is the base number of bytes a block header can be,
@ -40,8 +38,8 @@ type MsgBlockHeader struct {
// Version of the block. This is not the same as the protocol version.
Version uint16
// Hashes of the parent block headers in the blockDAG.
ParentHashes []*externalapi.DomainHash
// Parents are the parent block hashes of the block in the DAG per superblock level.
Parents []externalapi.BlockLevelParents
// HashMerkleRoot is the merkle tree reference to hash of all transactions for the block.
HashMerkleRoot *externalapi.DomainHash
@ -72,29 +70,15 @@ type MsgBlockHeader struct {
FinalityPoint *externalapi.DomainHash
}
// NumParentBlocks return the number of entries in ParentHashes
func (h *MsgBlockHeader) NumParentBlocks() byte {
numParents := len(h.ParentHashes)
if numParents > math.MaxUint8 {
panic(errors.Errorf("number of parents is %d, which is more than one byte can fit", numParents))
}
return byte(numParents)
}
// BlockHash computes the block identifier hash for the given block header.
func (h *MsgBlockHeader) BlockHash() *externalapi.DomainHash {
return consensushashing.HeaderHash(BlockHeaderToDomainBlockHeader(h))
}
// IsGenesis returns true iff this block is a genesis block
func (h *MsgBlockHeader) IsGenesis() bool {
return h.NumParentBlocks() == 0
}
// NewBlockHeader returns a new MsgBlockHeader using the provided version, previous
// block hash, hash merkle root, accepted ID merkle root, difficulty bits, and nonce used to generate the
// block with defaults or calclulated values for the remaining fields.
func NewBlockHeader(version uint16, parentHashes []*externalapi.DomainHash, hashMerkleRoot *externalapi.DomainHash,
func NewBlockHeader(version uint16, parents []externalapi.BlockLevelParents, hashMerkleRoot *externalapi.DomainHash,
acceptedIDMerkleRoot *externalapi.DomainHash, utxoCommitment *externalapi.DomainHash, bits uint32, nonce uint64,
daaScore uint64, blueWork *big.Int, finalityPoint *externalapi.DomainHash) *MsgBlockHeader {
@ -102,7 +86,7 @@ func NewBlockHeader(version uint16, parentHashes []*externalapi.DomainHash, hash
// doesn't support better.
return &MsgBlockHeader{
Version: version,
ParentHashes: parentHashes,
Parents: parents,
HashMerkleRoot: hashMerkleRoot,
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
UTXOCommitment: utxoCommitment,

View File

@ -11,14 +11,13 @@ import (
"github.com/davecgh/go-spew/spew"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/util/mstime"
)
// TestBlockHeader tests the MsgBlockHeader API.
func TestBlockHeader(t *testing.T) {
nonce := uint64(0xba4d87a69924a93d)
hashes := []*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash}
parents := []externalapi.BlockLevelParents{[]*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash}}
merkleHash := mainnetGenesisMerkleRoot
acceptedIDMerkleRoot := exampleAcceptedIDMerkleRoot
@ -26,13 +25,13 @@ func TestBlockHeader(t *testing.T) {
daaScore := uint64(123)
blueWork := big.NewInt(456)
finalityPoint := simnetGenesisHash
bh := NewBlockHeader(1, hashes, merkleHash, acceptedIDMerkleRoot, exampleUTXOCommitment, bits, nonce,
bh := NewBlockHeader(1, parents, merkleHash, acceptedIDMerkleRoot, exampleUTXOCommitment, bits, nonce,
daaScore, blueWork, finalityPoint)
// Ensure we get the same data back out.
if !reflect.DeepEqual(bh.ParentHashes, hashes) {
t.Errorf("NewBlockHeader: wrong prev hashes - got %v, want %v",
spew.Sprint(bh.ParentHashes), spew.Sprint(hashes))
if !reflect.DeepEqual(bh.Parents, parents) {
t.Errorf("NewBlockHeader: wrong parents - got %v, want %v",
spew.Sprint(bh.Parents), spew.Sprint(parents))
}
if bh.HashMerkleRoot != merkleHash {
t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v",
@ -59,43 +58,3 @@ func TestBlockHeader(t *testing.T) {
bh.FinalityPoint, finalityPoint)
}
}
func TestIsGenesis(t *testing.T) {
nonce := uint64(123123) // 0x1e0f3
bits := uint32(0x1d00ffff)
timestamp := mstime.UnixMilliseconds(0x495fab29000)
baseBlockHdr := &MsgBlockHeader{
Version: 1,
ParentHashes: []*externalapi.DomainHash{mainnetGenesisHash, simnetGenesisHash},
HashMerkleRoot: mainnetGenesisMerkleRoot,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
genesisBlockHdr := &MsgBlockHeader{
Version: 1,
ParentHashes: []*externalapi.DomainHash{},
HashMerkleRoot: mainnetGenesisMerkleRoot,
Timestamp: timestamp,
Bits: bits,
Nonce: nonce,
}
tests := []struct {
in *MsgBlockHeader // Block header to encode
isGenesis bool // Expected result for call of .IsGenesis
}{
{genesisBlockHdr, true},
{baseBlockHdr, false},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
isGenesis := test.in.IsGenesis()
if isGenesis != test.isGenesis {
t.Errorf("MsgBlockHeader.IsGenesis: #%d got: %t, want: %t",
i, isGenesis, test.isGenesis)
}
}
}

View File

@ -53,7 +53,7 @@ func (msg *SubmitBlockResponseMessage) Command() MessageCommand {
return CmdSubmitBlockResponseMessage
}
// NewSubmitBlockResponseMessage returns a instance of the message
// NewSubmitBlockResponseMessage returns an instance of the message
func NewSubmitBlockResponseMessage() *SubmitBlockResponseMessage {
return &SubmitBlockResponseMessage{}
}
@ -70,7 +70,7 @@ type RPCBlock struct {
// used over RPC
type RPCBlockHeader struct {
Version uint32
ParentHashes []string
Parents []*RPCBlockLevelParents
HashMerkleRoot string
AcceptedIDMerkleRoot string
UTXOCommitment string
@ -82,6 +82,11 @@ type RPCBlockHeader struct {
FinalityPoint string
}
// RPCBlockLevelParents holds parent hashes for one block level
type RPCBlockLevelParents struct {
ParentHashes []string
}
// RPCBlockVerboseData holds verbose data about a block
type RPCBlockVerboseData struct {
Hash string

View File

@ -73,10 +73,10 @@ func (f *FlowContext) UnorphanBlocks(rootBlock *externalapi.DomainBlock) ([]*Uno
orphanBlock := f.orphans[orphanHash]
log.Debugf("Considering to unorphan block %s with parents %s",
orphanHash, orphanBlock.Header.ParentHashes())
orphanHash, orphanBlock.Header.DirectParents())
canBeUnorphaned := true
for _, orphanBlockParentHash := range orphanBlock.Header.ParentHashes() {
for _, orphanBlockParentHash := range orphanBlock.Header.DirectParents() {
orphanBlockParentInfo, err := f.domain.Consensus().GetBlockInfo(orphanBlockParentHash)
if err != nil {
return nil, err
@ -133,7 +133,7 @@ func (f *FlowContext) addChildOrphansToProcessQueue(blockHash *externalapi.Domai
func (f *FlowContext) findChildOrphansOfBlock(blockHash *externalapi.DomainHash) []externalapi.DomainHash {
var childOrphans []externalapi.DomainHash
for orphanHash, orphanBlock := range f.orphans {
for _, orphanBlockParentHash := range orphanBlock.Header.ParentHashes() {
for _, orphanBlockParentHash := range orphanBlock.Header.DirectParents() {
if orphanBlockParentHash.Equal(blockHash) {
childOrphans = append(childOrphans, orphanHash)
break
@ -201,7 +201,7 @@ func (f *FlowContext) GetOrphanRoots(orphan *externalapi.DomainHash) ([]*externa
continue
}
for _, parent := range block.Header.ParentHashes() {
for _, parent := range block.Header.DirectParents() {
if !addedToQueueSet.Contains(parent) {
queue = append(queue, parent)
addedToQueueSet.Add(parent)

View File

@ -150,7 +150,7 @@ func mineNextBlock(mineWhenNotSynced bool) *externalapi.DomainBlock {
atomic.AddUint64(&hashesTried, 1)
if pow.CheckProofOfWorkWithTarget(headerForMining, targetDifficulty) {
block.Header = headerForMining.ToImmutable()
log.Infof("Found block %s with parents %s", consensushashing.BlockHash(block), block.Header.ParentHashes())
log.Infof("Found block %s with parents %s", consensushashing.BlockHash(block), block.Header.DirectParents())
return block
}
}

View File

@ -12,7 +12,7 @@ import (
func DomainBlockHeaderToDbBlockHeader(domainBlockHeader externalapi.BlockHeader) *DbBlockHeader {
return &DbBlockHeader{
Version: uint32(domainBlockHeader.Version()),
ParentHashes: DomainHashesToDbHashes(domainBlockHeader.ParentHashes()),
Parents: DomainParentsToDbParents(domainBlockHeader.Parents()),
HashMerkleRoot: DomainHashToDbHash(domainBlockHeader.HashMerkleRoot()),
AcceptedIDMerkleRoot: DomainHashToDbHash(domainBlockHeader.AcceptedIDMerkleRoot()),
UtxoCommitment: DomainHashToDbHash(domainBlockHeader.UTXOCommitment()),
@ -27,7 +27,7 @@ func DomainBlockHeaderToDbBlockHeader(domainBlockHeader externalapi.BlockHeader)
// DbBlockHeaderToDomainBlockHeader converts DbBlockHeader to BlockHeader
func DbBlockHeaderToDomainBlockHeader(dbBlockHeader *DbBlockHeader) (externalapi.BlockHeader, error) {
parentHashes, err := DbHashesToDomainHashes(dbBlockHeader.ParentHashes)
parents, err := DbParentsToDomainParents(dbBlockHeader.Parents)
if err != nil {
return nil, err
}
@ -53,7 +53,7 @@ func DbBlockHeaderToDomainBlockHeader(dbBlockHeader *DbBlockHeader) (externalapi
return blockheader.NewImmutableBlockHeader(
uint16(dbBlockHeader.Version),
parentHashes,
parents,
hashMerkleRoot,
acceptedIDMerkleRoot,
utxoCommitment,

View File

@ -0,0 +1,49 @@
package serialization
import (
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
)
// DbBlockLevelParentsToDomainBlockLevelParents converts a DbBlockLevelParents to a BlockLevelParents
func DbBlockLevelParentsToDomainBlockLevelParents(dbBlockLevelParents *DbBlockLevelParents) (externalapi.BlockLevelParents, error) {
domainBlockLevelParents := make(externalapi.BlockLevelParents, len(dbBlockLevelParents.ParentHashes))
for i, parentHash := range dbBlockLevelParents.ParentHashes {
var err error
domainBlockLevelParents[i], err = externalapi.NewDomainHashFromByteSlice(parentHash.Hash)
if err != nil {
return nil, err
}
}
return domainBlockLevelParents, nil
}
// DomainBlockLevelParentsToDbBlockLevelParents converts a BlockLevelParents to a DbBlockLevelParents
func DomainBlockLevelParentsToDbBlockLevelParents(domainBlockLevelParents externalapi.BlockLevelParents) *DbBlockLevelParents {
parentHashes := make([]*DbHash, len(domainBlockLevelParents))
for i, parentHash := range domainBlockLevelParents {
parentHashes[i] = &DbHash{Hash: parentHash.ByteSlice()}
}
return &DbBlockLevelParents{ParentHashes: parentHashes}
}
// DomainParentsToDbParents converts a slice of BlockLevelParents to a slice of DbBlockLevelParents
func DomainParentsToDbParents(domainParents []externalapi.BlockLevelParents) []*DbBlockLevelParents {
dbParents := make([]*DbBlockLevelParents, len(domainParents))
for i, domainBlockLevelParents := range domainParents {
dbParents[i] = DomainBlockLevelParentsToDbBlockLevelParents(domainBlockLevelParents)
}
return dbParents
}
// DbParentsToDomainParents converts a slice of DbBlockLevelParents to a slice of BlockLevelParents
func DbParentsToDomainParents(dbParents []*DbBlockLevelParents) ([]externalapi.BlockLevelParents, error) {
domainParents := make([]externalapi.BlockLevelParents, len(dbParents))
for i, domainBlockLevelParents := range dbParents {
var err error
domainParents[i], err = DbBlockLevelParentsToDomainBlockLevelParents(domainBlockLevelParents)
if err != nil {
return nil, err
}
}
return domainParents, nil
}

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ message DbBlock {
message DbBlockHeader {
uint32 version = 1;
repeated DbHash parentHashes = 2;
repeated DbBlockLevelParents parents = 2;
DbHash hashMerkleRoot = 3;
DbHash acceptedIDMerkleRoot = 4;
DbHash utxoCommitment = 5;
@ -22,6 +22,10 @@ message DbBlockHeader {
DbHash finalityPoint = 11;
}
message DbBlockLevelParents {
repeated DbHash parentHashes = 1;
}
message DbHash {
bytes hash = 1;
}

View File

@ -57,7 +57,8 @@ type BlockHeader interface {
// BaseBlockHeader represents the header part of a Kaspa block
type BaseBlockHeader interface {
Version() uint16
ParentHashes() []*DomainHash
Parents() []BlockLevelParents
DirectParents() BlockLevelParents
HashMerkleRoot() *DomainHash
AcceptedIDMerkleRoot() *DomainHash
UTXOCommitment() *DomainHash

View File

@ -97,13 +97,11 @@ func initTestTwoTransactions() []*externalapi.DomainTransaction {
}
func initTestBlockStructsForClone() []*externalapi.DomainBlock {
tests := []*externalapi.DomainBlock{
{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
@ -118,7 +116,7 @@ func initTestBlockStructsForClone() []*externalapi.DomainBlock {
}, {
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
@ -149,7 +147,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
@ -168,7 +166,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
baseBlock: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -190,7 +188,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -208,7 +206,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -226,10 +224,10 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
},
}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -247,7 +245,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100})}, // Changed
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100})}}, // Changed
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -265,7 +263,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100}), // Changed
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -283,7 +281,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100}), // Changed
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -301,7 +299,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100}), // Changed
@ -319,7 +317,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -337,7 +335,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -355,7 +353,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -373,7 +371,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -391,7 +389,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -409,7 +407,7 @@ func initTestBlockStructsForEqual() *[]TestBlockStruct {
block: &externalapi.DomainBlock{
blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),

View File

@ -0,0 +1,38 @@
package externalapi
// BlockLevelParents represent the parents within a single super-block level
// See https://github.com/kaspanet/research/issues/3 for further details
type BlockLevelParents []*DomainHash
// Equal returns true if this BlockLevelParents is equal to `other`
func (sl BlockLevelParents) Equal(other BlockLevelParents) bool {
return HashesEqual(sl, other)
}
// Clone creates a clone of this BlockLevelParents
func (sl BlockLevelParents) Clone() BlockLevelParents {
return CloneHashes(sl)
}
// ParentsEqual returns true if all the BlockLevelParents in `a` and `b` are
// equal pairwise
func ParentsEqual(a, b []BlockLevelParents) bool {
if len(a) != len(b) {
return false
}
for i, blockLevelParents := range a {
if !blockLevelParents.Equal(b[i]) {
return false
}
}
return true
}
// CloneParents creates a clone of the given BlockLevelParents slice
func CloneParents(parents []BlockLevelParents) []BlockLevelParents {
clone := make([]BlockLevelParents, len(parents))
for i, blockLevelParents := range parents {
clone[i] = blockLevelParents.Clone()
}
return clone
}

View File

@ -169,7 +169,7 @@ func (bb *blockBuilder) newBlockCoinbaseTransaction(stagingArea *model.StagingAr
func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions []*externalapi.DomainTransaction) (
externalapi.BlockHeader, error) {
parentHashes, err := bb.newBlockParentHashes(stagingArea)
parents, err := bb.newBlockParents(stagingArea)
if err != nil {
return nil, err
}
@ -205,7 +205,7 @@ func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions
return blockheader.NewImmutableBlockHeader(
constants.MaxBlockVersion,
parentHashes,
parents,
hashMerkleRoot,
acceptedIDMerkleRoot,
utxoCommitment,
@ -218,13 +218,12 @@ func (bb *blockBuilder) buildHeader(stagingArea *model.StagingArea, transactions
), nil
}
func (bb *blockBuilder) newBlockParentHashes(stagingArea *model.StagingArea) ([]*externalapi.DomainHash, error) {
func (bb *blockBuilder) newBlockParents(stagingArea *model.StagingArea) ([]externalapi.BlockLevelParents, error) {
virtualBlockRelations, err := bb.blockRelationStore.BlockRelation(bb.databaseContext, stagingArea, model.VirtualBlockHash)
if err != nil {
return nil, err
}
return virtualBlockRelations.Parents, nil
return []externalapi.BlockLevelParents{virtualBlockRelations.Parents}, nil
}
func (bb *blockBuilder) newBlockTime(stagingArea *model.StagingArea) (int64, error) {

View File

@ -77,10 +77,12 @@ func (bb *testBlockBuilder) buildUTXOInvalidHeader(stagingArea *model.StagingAre
hashMerkleRoot := bb.newBlockHashMerkleRoot(transactions)
parents := []externalapi.BlockLevelParents{parentHashes}
bb.nonceCounter++
return blockheader.NewImmutableBlockHeader(
constants.MaxBlockVersion,
parentHashes,
parents,
hashMerkleRoot,
&externalapi.DomainHash{},
&externalapi.DomainHash{},
@ -112,7 +114,7 @@ func (bb *testBlockBuilder) buildHeaderWithParents(stagingArea *model.StagingAre
return blockheader.NewImmutableBlockHeader(
header.Version(),
header.ParentHashes(),
header.Parents(),
hashMerkleRoot,
acceptedIDMerkleRoot,
utxoCommitment,

View File

@ -66,7 +66,7 @@ func TestBlockStatus(t *testing.T) {
}
disqualifiedBlock.Header = blockheader.NewImmutableBlockHeader(
disqualifiedBlock.Header.Version(),
disqualifiedBlock.Header.ParentHashes(),
disqualifiedBlock.Header.Parents(),
disqualifiedBlock.Header.HashMerkleRoot(),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{}), // This should disqualify the block
disqualifiedBlock.Header.UTXOCommitment(),
@ -92,7 +92,7 @@ func TestBlockStatus(t *testing.T) {
invalidBlock.Transactions[0].Version = constants.MaxTransactionVersion + 1 // This should invalidate the block
invalidBlock.Header = blockheader.NewImmutableBlockHeader(
disqualifiedBlock.Header.Version(),
disqualifiedBlock.Header.ParentHashes(),
disqualifiedBlock.Header.Parents(),
merkle.CalculateHashMerkleRoot(invalidBlock.Transactions),
disqualifiedBlock.Header.AcceptedIDMerkleRoot(),
disqualifiedBlock.Header.UTXOCommitment(),

View File

@ -192,7 +192,7 @@ func TestIsFinalizedTransaction(t *testing.T) {
if err != nil {
t.Fatalf("Error getting block DAA score : %+v", err)
}
blockParents := block.Header.ParentHashes()
blockParents := block.Header.DirectParents()
parentToSpend, err := tc.GetBlock(blockParents[0])
if err != nil {
t.Fatalf("Error getting block1: %+v", err)

View File

@ -135,7 +135,7 @@ func TestCheckBlockSanity(t *testing.T) {
var unOrderedParentsBlock = externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0x00000000,
[]*externalapi.DomainHash{
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x4b, 0xb0, 0x75, 0x35, 0xdf, 0xd5, 0x8e, 0x0b,
0x3c, 0xd6, 0x4f, 0xd7, 0x15, 0x52, 0x80, 0x87,
@ -148,7 +148,7 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
0x46, 0x11, 0x89, 0x6b, 0x82, 0x1a, 0x68, 0x3b,
0x7a, 0x4e, 0xde, 0xfe, 0x2c, 0x00, 0x00, 0x00,
}),
},
}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x09, 0xaf, 0x3b, 0x09, 0xa8, 0x8f, 0xfc, 0x7e,
0x7d, 0xc6, 0x06, 0x78, 0x04, 0x2b, 0x1c, 0x8a,
@ -411,7 +411,7 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
var exampleValidBlock = externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0x00000000,
[]*externalapi.DomainHash{
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
@ -424,7 +424,7 @@ var exampleValidBlock = externalapi.DomainBlock{
0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
}),
},
}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x6e, 0xa3, 0x1a, 0xd6, 0xb8, 0xd9, 0xc1, 0xb2,
0xab, 0x18, 0xcc, 0x59, 0x6d, 0x03, 0x6b, 0x8d,
@ -715,7 +715,7 @@ var exampleValidBlock = externalapi.DomainBlock{
var blockWithWrongTxOrder = externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x16, 0x5e, 0x38, 0xe8, 0xb3, 0x91, 0x45, 0x95,
0xd9, 0xc6, 0x41, 0xf3, 0xb8, 0xee, 0xc2, 0xf3,
@ -728,7 +728,7 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
0x2a, 0x04, 0x71, 0xbc, 0xf8, 0x30, 0x95, 0x52,
0x6a, 0xce, 0x0e, 0x38, 0xc6, 0x00, 0x00, 0x00,
}),
},
}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0xfc, 0x03, 0xa8, 0x09, 0x03, 0xf6, 0x64, 0xd9,
0xba, 0xab, 0x6d, 0x50, 0x1c, 0x67, 0xcb, 0xff,
@ -1343,7 +1343,7 @@ func initBlockWithFirstTransactionDifferentThanCoinbase(consensusConfig *consens
return &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
constants.MaxBlockVersion,
[]*externalapi.DomainHash{consensusConfig.GenesisHash},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{consensusConfig.GenesisHash}},
merkle.CalculateHashMerkleRoot([]*externalapi.DomainTransaction{tx}),
&externalapi.DomainHash{},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{

View File

@ -139,7 +139,7 @@ func (v *blockValidator) checkParentsIncest(stagingArea *model.StagingArea, bloc
}
func (v *blockValidator) validateMedianTime(stagingArea *model.StagingArea, header externalapi.BlockHeader) error {
if len(header.ParentHashes()) == 0 {
if len(header.DirectParents()) == 0 {
return nil
}

View File

@ -110,7 +110,7 @@ func TestCheckParentsIncest(t *testing.T) {
directParentsRelationBlock := &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{a, b},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{a, b}},
&externalapi.DomainHash{},
&externalapi.DomainHash{},
&externalapi.DomainHash{},
@ -132,7 +132,7 @@ func TestCheckParentsIncest(t *testing.T) {
indirectParentsRelationBlock := &externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{consensusConfig.GenesisHash, b},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{consensusConfig.GenesisHash, b}},
&externalapi.DomainHash{},
&externalapi.DomainHash{},
&externalapi.DomainHash{},

View File

@ -42,13 +42,13 @@ func (v *blockValidator) ValidateHeaderInIsolation(stagingArea *model.StagingAre
func (v *blockValidator) checkParentsLimit(header externalapi.BlockHeader) error {
hash := consensushashing.HeaderHash(header)
if len(header.ParentHashes()) == 0 && !hash.Equal(v.genesisHash) {
if len(header.DirectParents()) == 0 && !hash.Equal(v.genesisHash) {
return errors.Wrapf(ruleerrors.ErrNoParents, "block has no parents")
}
if uint64(len(header.ParentHashes())) > uint64(v.maxBlockParents) {
if uint64(len(header.DirectParents())) > uint64(v.maxBlockParents) {
return errors.Wrapf(ruleerrors.ErrTooManyParents, "block header has %d parents, but the maximum allowed amount "+
"is %d", len(header.ParentHashes()), v.maxBlockParents)
"is %d", len(header.DirectParents()), v.maxBlockParents)
}
return nil
}

View File

@ -59,7 +59,7 @@ func TestCheckBlockVersion(t *testing.T) {
block.Header = blockheader.NewImmutableBlockHeader(
constants.MaxBlockVersion+1,
block.Header.ParentHashes(),
block.Header.Parents(),
block.Header.HashMerkleRoot(),
block.Header.AcceptedIDMerkleRoot(),
block.Header.UTXOCommitment(),
@ -99,7 +99,7 @@ func TestCheckBlockTimestampInIsolation(t *testing.T) {
block.Header = blockheader.NewImmutableBlockHeader(
block.Header.Version(),
block.Header.ParentHashes(),
block.Header.Parents(),
block.Header.HashMerkleRoot(),
block.Header.AcceptedIDMerkleRoot(),
block.Header.UTXOCommitment(),

View File

@ -11,8 +11,11 @@ func (v *blockValidator) headerEstimatedSerializedSize(header externalapi.BlockH
size := uint64(0)
size += 2 // Version (uint16)
size += 8 // number of parents (uint64)
size += uint64(externalapi.DomainHashSize * len(header.ParentHashes())) // parents
size += 8 // number of block levels (uint64)
for _, blockLevelParents := range header.Parents() {
size += 8 // number of parents in the block level (uint64)
size += uint64(externalapi.DomainHashSize * len(blockLevelParents)) // parents
}
size += externalapi.DomainHashSize // HashMerkleRoot
size += externalapi.DomainHashSize // AcceptedIDMerkleRoot

View File

@ -66,8 +66,8 @@ func (v *blockValidator) setParents(stagingArea *model.StagingArea,
header externalapi.BlockHeader,
isBlockWithTrustedData bool) error {
parents := make([]*externalapi.DomainHash, 0, len(header.ParentHashes()))
for _, currentParent := range header.ParentHashes() {
parents := make([]*externalapi.DomainHash, 0, len(header.DirectParents()))
for _, currentParent := range header.DirectParents() {
exists, err := v.blockStatusStore.Exists(v.databaseContext, stagingArea, currentParent)
if err != nil {
return err
@ -153,7 +153,7 @@ func (v *blockValidator) checkProofOfWork(header externalapi.BlockHeader) error
}
func (v *blockValidator) checkParentNotVirtualGenesis(header externalapi.BlockHeader) error {
for _, parent := range header.ParentHashes() {
for _, parent := range header.DirectParents() {
if parent.Equal(model.VirtualGenesisBlockHash) {
return errors.Wrapf(ruleerrors.ErrVirtualGenesisParent, "block header cannot have the virtual genesis as parent")
}
@ -171,7 +171,7 @@ func (v *blockValidator) checkParentHeadersExist(stagingArea *model.StagingArea,
}
missingParentHashes := []*externalapi.DomainHash{}
for _, parent := range header.ParentHashes() {
for _, parent := range header.DirectParents() {
parentHeaderExists, err := v.blockHeaderStore.HasBlockHeader(v.databaseContext, stagingArea, parent)
if err != nil {
return err

View File

@ -52,7 +52,7 @@ func TestPOW(t *testing.T) {
abovePowMaxTarget := big.NewInt(0).Add(big.NewInt(1), consensusConfig.PowMax)
abovePowMaxBlock.Header = blockheader.NewImmutableBlockHeader(
abovePowMaxBlock.Header.Version(),
abovePowMaxBlock.Header.ParentHashes(),
abovePowMaxBlock.Header.Parents(),
abovePowMaxBlock.Header.HashMerkleRoot(),
abovePowMaxBlock.Header.AcceptedIDMerkleRoot(),
abovePowMaxBlock.Header.UTXOCommitment(),
@ -76,7 +76,7 @@ func TestPOW(t *testing.T) {
negativeTargetBlock.Header = blockheader.NewImmutableBlockHeader(
negativeTargetBlock.Header.Version(),
negativeTargetBlock.Header.ParentHashes(),
negativeTargetBlock.Header.Parents(),
negativeTargetBlock.Header.HashMerkleRoot(),
negativeTargetBlock.Header.AcceptedIDMerkleRoot(),
negativeTargetBlock.Header.UTXOCommitment(),
@ -141,9 +141,9 @@ func TestCheckParentHeadersExist(t *testing.T) {
parentHash := externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{}) // Non existing parent hash
orphanBlock.Header = blockheader.NewImmutableBlockHeader(
orphanBlock.Header.Version(),
[]*externalapi.DomainHash{
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{
parentHash,
},
}},
orphanBlock.Header.HashMerkleRoot(),
orphanBlock.Header.AcceptedIDMerkleRoot(),
orphanBlock.Header.UTXOCommitment(),
@ -174,7 +174,7 @@ func TestCheckParentHeadersExist(t *testing.T) {
invalidBlock.Transactions[0].Version = constants.MaxTransactionVersion + 1 // This should invalidate the block
invalidBlock.Header = blockheader.NewImmutableBlockHeader(
invalidBlock.Header.Version(),
invalidBlock.Header.ParentHashes(),
invalidBlock.Header.Parents(),
merkle.CalculateHashMerkleRoot(invalidBlock.Transactions),
orphanBlock.Header.AcceptedIDMerkleRoot(),
orphanBlock.Header.UTXOCommitment(),
@ -200,7 +200,7 @@ func TestCheckParentHeadersExist(t *testing.T) {
invalidBlockChild.Header = blockheader.NewImmutableBlockHeader(
invalidBlockChild.Header.Version(),
[]*externalapi.DomainHash{invalidBlockHash},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{invalidBlockHash}},
invalidBlockChild.Header.HashMerkleRoot(),
invalidBlockChild.Header.AcceptedIDMerkleRoot(),
invalidBlockChild.Header.UTXOCommitment(),

View File

@ -32,7 +32,7 @@ func TestConsensusStateManager_pickVirtualParents(t *testing.T) {
if err != nil {
t.Fatalf("Consensus failed building a block: %v", err)
}
blockParents := block.Header.ParentHashes()
blockParents := block.Header.DirectParents()
sort.Sort(testutils.NewTestGhostDAGSorter(stagingArea, virtualRelations.Parents, tc, t))
sort.Sort(testutils.NewTestGhostDAGSorter(stagingArea, blockParents, tc, t))
if !externalapi.HashesEqual(virtualRelations.Parents, blockParents) {
@ -89,7 +89,7 @@ func TestConsensusStateManager_pickVirtualParents(t *testing.T) {
t.Fatalf("Failed Inserting block to tc: %v", err)
}
virtualSelectedParent = consensushashing.BlockHash(block)
if len(block.Header.ParentHashes()) == 1 {
if len(block.Header.DirectParents()) == 1 {
break
}
}

View File

@ -60,37 +60,37 @@ func TestBlockWindow(t *testing.T) {
{
parents: []string{"H", "F"},
id: "I",
expectedWindow: []string{"F", "H", "C", "D", "G", "B"},
expectedWindow: []string{"F", "C", "D", "H", "G", "B"},
},
{
parents: []string{"I"},
id: "J",
expectedWindow: []string{"I", "F", "H", "C", "D", "G", "B"},
expectedWindow: []string{"I", "F", "C", "D", "H", "G", "B"},
},
{
parents: []string{"J"},
id: "K",
expectedWindow: []string{"J", "I", "F", "H", "C", "D", "G", "B"},
expectedWindow: []string{"J", "I", "F", "C", "D", "H", "G", "B"},
},
{
parents: []string{"K"},
id: "L",
expectedWindow: []string{"K", "J", "I", "F", "H", "C", "D", "G", "B"},
expectedWindow: []string{"K", "J", "I", "F", "C", "D", "H", "G", "B"},
},
{
parents: []string{"L"},
id: "M",
expectedWindow: []string{"L", "K", "J", "I", "F", "H", "C", "D", "G", "B"},
expectedWindow: []string{"L", "K", "J", "I", "F", "C", "D", "H", "G", "B"},
},
{
parents: []string{"M"},
id: "N",
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "H", "C", "D", "G"},
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "C", "D", "H", "G"},
},
{
parents: []string{"N"},
id: "O",
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "H", "C", "D"},
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "C", "D", "H"},
},
},
dagconfig.TestnetParams.Name: {
@ -112,12 +112,12 @@ func TestBlockWindow(t *testing.T) {
{
parents: []string{"C", "D"},
id: "E",
expectedWindow: []string{"C", "D", "B"},
expectedWindow: []string{"D", "C", "B"},
},
{
parents: []string{"C", "D"},
id: "F",
expectedWindow: []string{"C", "D", "B"},
expectedWindow: []string{"D", "C", "B"},
},
{
parents: []string{"A"},
@ -132,37 +132,37 @@ func TestBlockWindow(t *testing.T) {
{
parents: []string{"H", "F"},
id: "I",
expectedWindow: []string{"F", "C", "H", "D", "B", "G"},
expectedWindow: []string{"F", "D", "H", "C", "G", "B"},
},
{
parents: []string{"I"},
id: "J",
expectedWindow: []string{"I", "F", "C", "H", "D", "B", "G"},
expectedWindow: []string{"I", "F", "D", "H", "C", "G", "B"},
},
{
parents: []string{"J"},
id: "K",
expectedWindow: []string{"J", "I", "F", "C", "H", "D", "B", "G"},
expectedWindow: []string{"J", "I", "F", "D", "H", "C", "G", "B"},
},
{
parents: []string{"K"},
id: "L",
expectedWindow: []string{"K", "J", "I", "F", "C", "H", "D", "B", "G"},
expectedWindow: []string{"K", "J", "I", "F", "D", "H", "C", "G", "B"},
},
{
parents: []string{"L"},
id: "M",
expectedWindow: []string{"L", "K", "J", "I", "F", "C", "H", "D", "B", "G"},
expectedWindow: []string{"L", "K", "J", "I", "F", "D", "H", "C", "G", "B"},
},
{
parents: []string{"M"},
id: "N",
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "C", "H", "D", "B"},
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "D", "H", "C", "G"},
},
{
parents: []string{"N"},
id: "O",
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "C", "H", "D"},
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "D", "H", "C"},
},
},
dagconfig.DevnetParams.Name: {
@ -256,12 +256,12 @@ func TestBlockWindow(t *testing.T) {
{
parents: []string{"D", "C"},
id: "E",
expectedWindow: []string{"D", "C", "B"},
expectedWindow: []string{"C", "D", "B"},
},
{
parents: []string{"D", "C"},
id: "F",
expectedWindow: []string{"D", "C", "B"},
expectedWindow: []string{"C", "D", "B"},
},
{
parents: []string{"A"},
@ -276,37 +276,37 @@ func TestBlockWindow(t *testing.T) {
{
parents: []string{"H", "F"},
id: "I",
expectedWindow: []string{"F", "D", "C", "H", "B", "G"},
expectedWindow: []string{"F", "H", "C", "D", "B", "G"},
},
{
parents: []string{"I"},
id: "J",
expectedWindow: []string{"I", "F", "D", "C", "H", "B", "G"},
expectedWindow: []string{"I", "F", "H", "C", "D", "B", "G"},
},
{
parents: []string{"J"},
id: "K",
expectedWindow: []string{"J", "I", "F", "D", "C", "H", "B", "G"},
expectedWindow: []string{"J", "I", "F", "H", "C", "D", "B", "G"},
},
{
parents: []string{"K"},
id: "L",
expectedWindow: []string{"K", "J", "I", "F", "D", "C", "H", "B", "G"},
expectedWindow: []string{"K", "J", "I", "F", "H", "C", "D", "B", "G"},
},
{
parents: []string{"L"},
id: "M",
expectedWindow: []string{"L", "K", "J", "I", "F", "D", "C", "H", "B", "G"},
expectedWindow: []string{"L", "K", "J", "I", "F", "H", "C", "D", "B", "G"},
},
{
parents: []string{"M"},
id: "N",
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "D", "C", "H", "B"},
expectedWindow: []string{"M", "L", "K", "J", "I", "F", "H", "C", "D", "B"},
},
{
parents: []string{"N"},
id: "O",
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "D", "C", "H"},
expectedWindow: []string{"N", "M", "L", "K", "J", "I", "F", "H", "C", "D"},
},
},
}

View File

@ -112,7 +112,7 @@ func TestGHOSTDAG(t *testing.T) {
dagTopology.parentsMap[*blockID] = StringToDomainHashSlice(testBlockData.Parents)
blockHeadersStore.dagMap[*blockID] = blockheader.NewImmutableBlockHeader(
constants.MaxBlockVersion,
StringToDomainHashSlice(testBlockData.Parents),
[]externalapi.BlockLevelParents{StringToDomainHashSlice(testBlockData.Parents)},
nil,
nil,
nil,

View File

@ -7,7 +7,7 @@ import (
type blockHeader struct {
version uint16
parentHashes []*externalapi.DomainHash
parents []externalapi.BlockLevelParents
hashMerkleRoot *externalapi.DomainHash
acceptedIDMerkleRoot *externalapi.DomainHash
utxoCommitment *externalapi.DomainHash
@ -47,8 +47,15 @@ func (bh *blockHeader) Version() uint16 {
return bh.version
}
func (bh *blockHeader) ParentHashes() []*externalapi.DomainHash {
return bh.parentHashes
func (bh *blockHeader) Parents() []externalapi.BlockLevelParents {
return bh.parents
}
func (bh *blockHeader) DirectParents() externalapi.BlockLevelParents {
if len(bh.parents) == 0 {
return externalapi.BlockLevelParents{}
}
return bh.parents[0]
}
func (bh *blockHeader) HashMerkleRoot() *externalapi.DomainHash {
@ -92,7 +99,7 @@ func (bh *blockHeader) Equal(other externalapi.BaseBlockHeader) bool {
return false
}
if !externalapi.HashesEqual(bh.parentHashes, other.ParentHashes()) {
if !externalapi.ParentsEqual(bh.parents, other.Parents()) {
return false
}
@ -138,7 +145,7 @@ func (bh *blockHeader) Equal(other externalapi.BaseBlockHeader) bool {
func (bh *blockHeader) clone() *blockHeader {
return &blockHeader{
version: bh.version,
parentHashes: externalapi.CloneHashes(bh.parentHashes),
parents: externalapi.CloneParents(bh.parents),
hashMerkleRoot: bh.hashMerkleRoot,
acceptedIDMerkleRoot: bh.acceptedIDMerkleRoot,
utxoCommitment: bh.utxoCommitment,
@ -158,7 +165,7 @@ func (bh *blockHeader) ToMutable() externalapi.MutableBlockHeader {
// NewImmutableBlockHeader returns a new immutable header
func NewImmutableBlockHeader(
version uint16,
parentHashes []*externalapi.DomainHash,
parents []externalapi.BlockLevelParents,
hashMerkleRoot *externalapi.DomainHash,
acceptedIDMerkleRoot *externalapi.DomainHash,
utxoCommitment *externalapi.DomainHash,
@ -171,7 +178,7 @@ func NewImmutableBlockHeader(
) externalapi.BlockHeader {
return &blockHeader{
version: version,
parentHashes: parentHashes,
parents: parents,
hashMerkleRoot: hashMerkleRoot,
acceptedIDMerkleRoot: acceptedIDMerkleRoot,
utxoCommitment: utxoCommitment,

View File

@ -25,7 +25,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{0})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
@ -43,7 +43,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
baseHeader: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -62,7 +62,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -78,7 +78,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
100,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -95,9 +95,9 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
header: &blockHeader{
0,
// []*externalapi.DomainHash{{1}, {2}},
[]*externalapi.DomainHash{
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -113,7 +113,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -129,7 +129,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -145,7 +145,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -161,7 +161,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{100}),
@ -177,7 +177,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -193,7 +193,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -209,7 +209,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -225,7 +225,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -241,7 +241,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),
@ -257,7 +257,7 @@ func TestDomainBlockHeader_Equal(t *testing.T) {
{
header: &blockHeader{
0,
[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})},
[]externalapi.BlockLevelParents{[]*externalapi.DomainHash{externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{1})}},
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{2}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{3}),
externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{4}),

View File

@ -35,14 +35,20 @@ func serializeHeader(w io.Writer, header externalapi.BaseBlockHeader) error {
timestamp := header.TimeInMilliseconds()
blueWork := header.BlueWork().Bytes()
numParents := len(header.ParentHashes())
numParents := len(header.Parents())
if err := serialization.WriteElements(w, header.Version(), uint64(numParents)); err != nil {
return err
}
for _, hash := range header.ParentHashes() {
if err := serialization.WriteElement(w, hash); err != nil {
for _, blockLevelParents := range header.Parents() {
numBlockLevelParents := len(blockLevelParents)
if err := serialization.WriteElements(w, uint64(numBlockLevelParents)); err != nil {
return err
}
for _, hash := range blockLevelParents {
if err := serialization.WriteElement(w, hash); err != nil {
return err
}
}
}
return serialization.WriteElements(w, header.HashMerkleRoot(), header.AcceptedIDMerkleRoot(), header.UTXOCommitment(), timestamp,
header.Bits(), header.Nonce(), header.DAAScore(), blueWork, header.FinalityPoint())

View File

@ -6,7 +6,6 @@ package dagconfig
import (
"github.com/kaspanet/go-muhash"
"github.com/kaspanet/kaspad/domain/consensus/model"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/blockheader"
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
@ -31,10 +30,10 @@ var genesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(0, []*externa
// genesisHash is the hash of the first block in the block DAG for the main
// network (genesis block).
var genesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0xf9, 0xe6, 0x59, 0x8b, 0x25, 0xb2, 0xde, 0xdd,
0xd3, 0x8e, 0x0d, 0x78, 0x89, 0x44, 0x2c, 0x9f,
0xe1, 0x2e, 0x49, 0xce, 0x58, 0x0b, 0x69, 0xb1,
0x05, 0xbf, 0x44, 0x44, 0x7d, 0x95, 0x5e, 0xfd,
0x86, 0xd0, 0x2f, 0x43, 0xd9, 0xe2, 0x54, 0xf2,
0xda, 0x51, 0x26, 0x06, 0x2b, 0x06, 0xc4, 0xfd,
0xd2, 0x7b, 0x10, 0xd8, 0xe4, 0xb0, 0x10, 0x85,
0x60, 0xaf, 0x7b, 0x76, 0xb6, 0x81, 0xae, 0x27,
})
// genesisMerkleRoot is the hash of the first transaction in the genesis block
@ -51,16 +50,16 @@ var genesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externalapi.Dom
var genesisBlock = externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{},
[]externalapi.BlockLevelParents{},
genesisMerkleRoot,
&externalapi.DomainHash{},
externalapi.NewDomainHashFromByteArray(muhash.EmptyMuHashHash.AsArray()),
0x17a99ae1020,
0x17adc150114,
0x207fffff,
0x4,
0x1,
0,
big.NewInt(0),
model.VirtualGenesisBlockHash,
&externalapi.DomainHash{},
),
Transactions: []*externalapi.DomainTransaction{genesisCoinbaseTx},
}
@ -84,10 +83,10 @@ var devnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(0,
// devGenesisHash is the hash of the first block in the block DAG for the development
// network (genesis block).
var devnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0xd8, 0x8e, 0xfe, 0x55, 0x26, 0xd0, 0xf3, 0x65,
0x21, 0xad, 0xb6, 0x5f, 0x24, 0x55, 0xd1, 0x24,
0x18, 0xbf, 0x4e, 0x78, 0x53, 0x8b, 0x3a, 0x09,
0x43, 0x3b, 0xfe, 0xba, 0x8f, 0x9d, 0xde, 0x21,
0xe4, 0xe1, 0xf7, 0xc2, 0x7e, 0xc8, 0x61, 0x94,
0x5d, 0x9d, 0xcb, 0x12, 0x4b, 0x77, 0xca, 0x57,
0x84, 0x2c, 0x90, 0x56, 0x06, 0x66, 0xc9, 0x47,
0xb7, 0x22, 0x4b, 0x73, 0xac, 0x63, 0x4f, 0x08,
})
// devnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
@ -104,16 +103,16 @@ var devnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externala
var devnetGenesisBlock = externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{},
[]externalapi.BlockLevelParents{},
devnetGenesisMerkleRoot,
&externalapi.DomainHash{},
externalapi.NewDomainHashFromByteArray(muhash.EmptyMuHashHash.AsArray()),
0x11e9db49828,
0x1e7fffff,
0x168a8,
0x23694,
0,
big.NewInt(0),
model.VirtualGenesisBlockHash,
&externalapi.DomainHash{},
),
Transactions: []*externalapi.DomainTransaction{devnetGenesisCoinbaseTx},
}
@ -136,10 +135,10 @@ var simnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(0,
// simnetGenesisHash is the hash of the first block in the block DAG for
// the simnet (genesis block).
var simnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x5b, 0x55, 0xb6, 0x3c, 0x77, 0x1b, 0x48, 0xfc,
0xc7, 0x65, 0x77, 0xd6, 0x2f, 0x1e, 0x20, 0x63,
0x85, 0x54, 0x1c, 0xb8, 0x37, 0x5a, 0x29, 0x07,
0x3e, 0xb1, 0xb2, 0xe7, 0x6f, 0x2a, 0xdb, 0x95,
0x7a, 0x83, 0x0d, 0x9e, 0x29, 0x38, 0xb1, 0x7a,
0xfc, 0x85, 0xe4, 0x3f, 0xce, 0x1f, 0x37, 0xc4,
0x52, 0x97, 0xea, 0xba, 0x11, 0x70, 0xf5, 0x4e,
0xe3, 0x2f, 0xd3, 0xb0, 0x50, 0x08, 0x67, 0xa7,
})
// simnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
@ -156,16 +155,16 @@ var simnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[externala
var simnetGenesisBlock = externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{},
[]externalapi.BlockLevelParents{},
simnetGenesisMerkleRoot,
&externalapi.DomainHash{},
externalapi.NewDomainHashFromByteArray(muhash.EmptyMuHashHash.AsArray()),
0x17a99ae10cc,
0x17adc15022f,
0x207fffff,
0x2,
0x1,
0,
big.NewInt(0),
model.VirtualGenesisBlockHash,
&externalapi.DomainHash{},
),
Transactions: []*externalapi.DomainTransaction{simnetGenesisCoinbaseTx},
}
@ -188,10 +187,10 @@ var testnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(0,
// testnetGenesisHash is the hash of the first block in the block DAG for the test
// network (genesis block).
var testnetGenesisHash = externalapi.NewDomainHashFromByteArray(&[externalapi.DomainHashSize]byte{
0x32, 0x10, 0x6a, 0x42, 0x52, 0xb7, 0x5a, 0xba,
0x68, 0xca, 0x77, 0xbc, 0x62, 0x61, 0x63, 0xe2,
0xd1, 0x44, 0xfa, 0x10, 0xbd, 0xc3, 0x0b, 0x96,
0x7d, 0xc1, 0xe7, 0x52, 0xa4, 0xe8, 0x25, 0x7c,
0x12, 0x35, 0x45, 0x64, 0x16, 0xac, 0x7b, 0x00,
0xe9, 0xa2, 0xc9, 0x97, 0x8d, 0x8b, 0xd3, 0x7c,
0xa2, 0xc2, 0x9b, 0x9e, 0x23, 0x62, 0x49, 0xb6,
0x41, 0x8a, 0xcc, 0x0a, 0x98, 0xd1, 0x10, 0x36,
})
// testnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
@ -208,16 +207,16 @@ var testnetGenesisMerkleRoot = externalapi.NewDomainHashFromByteArray(&[external
var testnetGenesisBlock = externalapi.DomainBlock{
Header: blockheader.NewImmutableBlockHeader(
0,
[]*externalapi.DomainHash{},
[]externalapi.BlockLevelParents{},
testnetGenesisMerkleRoot,
&externalapi.DomainHash{},
externalapi.NewDomainHashFromByteArray(muhash.EmptyMuHashHash.AsArray()),
0x17a99ae10cc,
0x17adc15022f,
0x1e7fffff,
0x71d0d,
0x2f291,
0,
big.NewInt(0),
model.VirtualGenesisBlockHash,
&externalapi.DomainHash{},
),
Transactions: []*externalapi.DomainTransaction{testnetGenesisCoinbaseTx},
}

View File

@ -64,7 +64,7 @@ message BlockMessage{
message BlockHeader{
uint32 version = 1;
repeated Hash parentHashes = 2;
repeated BlockLevelParents parents = 12;
Hash hashMerkleRoot = 3;
Hash acceptedIdMerkleRoot = 4;
Hash utxoCommitment = 5;
@ -76,6 +76,10 @@ message BlockHeader{
Hash finalityPoint = 11;
}
message BlockLevelParents {
repeated Hash parentHashes = 1;
}
message Hash{
bytes bytes = 1;
}

View File

@ -2,6 +2,7 @@ package protowire
import (
"github.com/kaspanet/kaspad/app/appmessage"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/util/mstime"
"github.com/pkg/errors"
"math"
@ -12,7 +13,7 @@ func (x *BlockHeader) toAppMessage() (*appmessage.MsgBlockHeader, error) {
if x == nil {
return nil, errors.Wrapf(errorNil, "BlockHeaderMessage is nil")
}
parentHashes, err := protoHashesToDomain(x.ParentHashes)
parents, err := protoParentsToDomain(x.Parents)
if err != nil {
return nil, err
}
@ -37,7 +38,7 @@ func (x *BlockHeader) toAppMessage() (*appmessage.MsgBlockHeader, error) {
}
return &appmessage.MsgBlockHeader{
Version: uint16(x.Version),
ParentHashes: parentHashes,
Parents: parents,
HashMerkleRoot: hashMerkleRoot,
AcceptedIDMerkleRoot: acceptedIDMerkleRoot,
UTXOCommitment: utxoCommitment,
@ -53,7 +54,7 @@ func (x *BlockHeader) toAppMessage() (*appmessage.MsgBlockHeader, error) {
func (x *BlockHeader) fromAppMessage(msgBlockHeader *appmessage.MsgBlockHeader) error {
*x = BlockHeader{
Version: uint32(msgBlockHeader.Version),
ParentHashes: domainHashesToProto(msgBlockHeader.ParentHashes),
Parents: domainParentsToProto(msgBlockHeader.Parents),
HashMerkleRoot: domainHashToProto(msgBlockHeader.HashMerkleRoot),
AcceptedIdMerkleRoot: domainHashToProto(msgBlockHeader.AcceptedIDMerkleRoot),
UtxoCommitment: domainHashToProto(msgBlockHeader.UTXOCommitment),
@ -66,3 +67,48 @@ func (x *BlockHeader) fromAppMessage(msgBlockHeader *appmessage.MsgBlockHeader)
}
return nil
}
func (x *BlockLevelParents) toDomain() (externalapi.BlockLevelParents, error) {
if x == nil {
return nil, errors.Wrap(errorNil, "BlockLevelParents is nil")
}
domainBlockLevelParents := make(externalapi.BlockLevelParents, len(x.ParentHashes))
for i, parentHash := range x.ParentHashes {
var err error
domainBlockLevelParents[i], err = externalapi.NewDomainHashFromByteSlice(parentHash.Bytes)
if err != nil {
return nil, err
}
}
return domainBlockLevelParents, nil
}
func protoParentsToDomain(protoParents []*BlockLevelParents) ([]externalapi.BlockLevelParents, error) {
domainParents := make([]externalapi.BlockLevelParents, len(protoParents))
for i, protoBlockLevelParents := range protoParents {
var err error
domainParents[i], err = protoBlockLevelParents.toDomain()
if err != nil {
return nil, err
}
}
return domainParents, nil
}
func domainBlockLevelParentsToProto(parentHashes externalapi.BlockLevelParents) *BlockLevelParents {
protoParentHashes := make([]*Hash, len(parentHashes))
for i, parentHash := range parentHashes {
protoParentHashes[i] = &Hash{Bytes: parentHash.ByteSlice()}
}
return &BlockLevelParents{
ParentHashes: protoParentHashes,
}
}
func domainParentsToProto(parents []externalapi.BlockLevelParents) []*BlockLevelParents {
protoParents := make([]*BlockLevelParents, len(parents))
for i, hash := range parents {
protoParents[i] = domainBlockLevelParentsToProto(hash)
}
return protoParents
}

View File

@ -27,7 +27,7 @@ message RpcBlock {
message RpcBlockHeader {
uint32 version = 1;
repeated string parentHashes = 2;
repeated RpcBlockLevelParents parents = 12;
string hashMerkleRoot = 3;
string acceptedIdMerkleRoot = 4;
string utxoCommitment = 5;
@ -39,6 +39,10 @@ message RpcBlockHeader {
string finalityPoint = 11;
}
message RpcBlockLevelParents {
repeated string parentHashes = 1;
}
message RpcBlockVerboseData{
string hash = 1;
double difficulty = 11;

View File

@ -125,9 +125,17 @@ func (x *RpcBlockHeader) toAppMessage() (*appmessage.RPCBlockHeader, error) {
if x.Version > math.MaxUint16 {
return nil, errors.Errorf("Invalid block header version - bigger then uint16")
}
parents := make([]*appmessage.RPCBlockLevelParents, len(x.Parents))
for i, blockLevelParents := range x.Parents {
var err error
parents[i], err = blockLevelParents.toAppMessage()
if err != nil {
return nil, err
}
}
return &appmessage.RPCBlockHeader{
Version: x.Version,
ParentHashes: x.ParentHashes,
Parents: parents,
HashMerkleRoot: x.HashMerkleRoot,
AcceptedIDMerkleRoot: x.AcceptedIdMerkleRoot,
UTXOCommitment: x.UtxoCommitment,
@ -141,9 +149,14 @@ func (x *RpcBlockHeader) toAppMessage() (*appmessage.RPCBlockHeader, error) {
}
func (x *RpcBlockHeader) fromAppMessage(message *appmessage.RPCBlockHeader) {
parents := make([]*RpcBlockLevelParents, len(message.Parents))
for i, blockLevelParents := range message.Parents {
parents[i] = &RpcBlockLevelParents{}
parents[i].fromAppMessage(blockLevelParents)
}
*x = RpcBlockHeader{
Version: message.Version,
ParentHashes: message.ParentHashes,
Parents: parents,
HashMerkleRoot: message.HashMerkleRoot,
AcceptedIdMerkleRoot: message.AcceptedIDMerkleRoot,
UtxoCommitment: message.UTXOCommitment,
@ -156,6 +169,21 @@ func (x *RpcBlockHeader) fromAppMessage(message *appmessage.RPCBlockHeader) {
}
}
func (x *RpcBlockLevelParents) toAppMessage() (*appmessage.RPCBlockLevelParents, error) {
if x == nil {
return nil, errors.Wrapf(errorNil, "RpcBlockLevelParents is nil")
}
return &appmessage.RPCBlockLevelParents{
ParentHashes: x.ParentHashes,
}, nil
}
func (x *RpcBlockLevelParents) fromAppMessage(message *appmessage.RPCBlockLevelParents) {
*x = RpcBlockLevelParents{
ParentHashes: message.ParentHashes,
}
}
func (x *RpcBlockVerboseData) toAppMessage() (*appmessage.RPCBlockVerboseData, error) {
if x == nil {
return nil, errors.Wrapf(errorNil, "RpcBlockVerboseData is nil")

View File

@ -1,5 +1,5 @@
{"getBlockDagInfoRequest": {}}
{"getBlockRequest": {"hash": "0000691a26e1cd33ed9d0587d774181726f4e38eecd722a858d3baaa1fd19250"}}
{"getBlockRequest": {"hash": "666661a26e1cd33ed9d0587d774181726f4e38eecd722a858d3baaa1fd19250"}}
{"submitBlockRequest": {"block": {"header":{"version":1,"parentHashes":[],"hashMerkleRoot":"0000000000000000000000000000000000000000000","acceptedIdMerkleRoot":"0000000000000000000000000000000000000000000","utxoCommitment": "0000000000000000000000000000000000000000000","timestamp":1593528309396,"bits":511705087,"nonce":282366},"transactions":[{"version":1,"inputs":[],"outputs":[],"lockTime":0,"subnetworkId":"100000000000000000000000000","gas":0,"payload":"AAAAAAAAAAAXqRTaF0XptUm9C/oaVplxx366MM1aS4drYXNwYS1kZXZuZXQ="}]}}}
{"submitBlockRequest": {"block": {"header":{"version":1,"parents":[],"hashMerkleRoot":"0000000000000000000000000000000000000000000","acceptedIdMerkleRoot":"0000000000000000000000000000000000000000000","utxoCommitment": "0000000000000000000000000000000000000000000","timestamp":1593528309396,"bits":511705087,"nonce":282366},"transactions":[{"version":1,"inputs":[],"outputs":[],"lockTime":0,"subnetworkId":"100000000000000000000000000","gas":0,"payload":"AAAAAAAAAAAXqRTaF0XptUm9C/oaVplxx366MM1aS4drYXNwYS1kZXZuZXQ="}]}}}
{"submitTransactionRequest": {"transaction": {"version":1,"inputs":[],"outputs":[],"lockTime":0,"subnetworkId":"100000000000000000000000000","gas":0,"payload":"AAAAAAAAAAAXqRTaF0XptUm9C/oaVplxx366MM1aS4drYXNwYS1kZXZuZXQ="}}}