Skip to content

Commit

Permalink
Add merge set and IsChainBlock to the RPC (#1961)
Browse files Browse the repository at this point in the history
* Add merge set and IsChainBlock to the RPC

* Fix BlockInfo.Clone()
  • Loading branch information
someone235 authored Feb 25, 2022
1 parent 9b23bbc commit 9f02a24
Show file tree
Hide file tree
Showing 13 changed files with 860 additions and 690 deletions.
17 changes: 10 additions & 7 deletions app/appmessage/rpc_submit_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,14 @@ type RPCBlockLevelParents struct {

// RPCBlockVerboseData holds verbose data about a block
type RPCBlockVerboseData struct {
Hash string
Difficulty float64
SelectedParentHash string
TransactionIDs []string
IsHeaderOnly bool
BlueScore uint64
ChildrenHashes []string
Hash string
Difficulty float64
SelectedParentHash string
TransactionIDs []string
IsHeaderOnly bool
BlueScore uint64
ChildrenHashes []string
MergeSetBluesHashes []string
MergeSetRedsHashes []string
IsChainBlock bool
}
24 changes: 16 additions & 8 deletions app/rpc/rpccontext/verbosedata.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,29 @@ func (ctx *Context) PopulateBlockWithVerboseData(block *appmessage.RPCBlock, dom
"invalid block")
}

_, selectedParentHash, childrenHashes, err := ctx.Domain.Consensus().GetBlockRelations(blockHash)
_, childrenHashes, err := ctx.Domain.Consensus().GetBlockRelations(blockHash)
if err != nil {
return err
}

isChainBlock, err := ctx.Domain.Consensus().IsChainBlock(blockHash)
if err != nil {
return err
}

block.VerboseData = &appmessage.RPCBlockVerboseData{
Hash: blockHash.String(),
Difficulty: ctx.GetDifficultyRatio(domainBlockHeader.Bits(), ctx.Config.ActiveNetParams),
ChildrenHashes: hashes.ToStrings(childrenHashes),
IsHeaderOnly: blockInfo.BlockStatus == externalapi.StatusHeaderOnly,
BlueScore: blockInfo.BlueScore,
Hash: blockHash.String(),
Difficulty: ctx.GetDifficultyRatio(domainBlockHeader.Bits(), ctx.Config.ActiveNetParams),
ChildrenHashes: hashes.ToStrings(childrenHashes),
IsHeaderOnly: blockInfo.BlockStatus == externalapi.StatusHeaderOnly,
BlueScore: blockInfo.BlueScore,
MergeSetBluesHashes: hashes.ToStrings(blockInfo.MergeSetBlues),
MergeSetRedsHashes: hashes.ToStrings(blockInfo.MergeSetReds),
IsChainBlock: isChainBlock,
}
// selectedParentHash will be nil in the genesis block
if selectedParentHash != nil {
block.VerboseData.SelectedParentHash = selectedParentHash.String()
if blockInfo.SelectedParent != nil {
block.VerboseData.SelectedParentHash = blockInfo.SelectedParent.String()
}

if blockInfo.BlockStatus == externalapi.StatusHeaderOnly {
Expand Down
28 changes: 19 additions & 9 deletions domain/consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,13 +286,15 @@ func (s *consensus) GetBlockInfo(blockHash *externalapi.DomainHash) (*externalap

blockInfo.BlueScore = ghostdagData.BlueScore()
blockInfo.BlueWork = ghostdagData.BlueWork()
blockInfo.SelectedParent = ghostdagData.SelectedParent()
blockInfo.MergeSetBlues = ghostdagData.MergeSetBlues()
blockInfo.MergeSetReds = ghostdagData.MergeSetReds()

return blockInfo, nil
}

func (s *consensus) GetBlockRelations(blockHash *externalapi.DomainHash) (
parents []*externalapi.DomainHash, selectedParent *externalapi.DomainHash,
children []*externalapi.DomainHash, err error) {
parents []*externalapi.DomainHash, children []*externalapi.DomainHash, err error) {

s.lock.Lock()
defer s.lock.Unlock()
Expand All @@ -301,15 +303,10 @@ func (s *consensus) GetBlockRelations(blockHash *externalapi.DomainHash) (

blockRelation, err := s.blockRelationStores[0].BlockRelation(s.databaseContext, stagingArea, blockHash)
if err != nil {
return nil, nil, nil, err
}

blockGHOSTDAGData, err := s.ghostdagDataStores[0].Get(s.databaseContext, stagingArea, blockHash, false)
if err != nil {
return nil, nil, nil, err
return nil, nil, err
}

return blockRelation.Parents, blockGHOSTDAGData.SelectedParent(), blockRelation.Children, nil
return blockRelation.Parents, blockRelation.Children, nil
}

func (s *consensus) GetBlockAcceptanceData(blockHash *externalapi.DomainHash) (externalapi.AcceptanceData, error) {
Expand Down Expand Up @@ -824,3 +821,16 @@ func (s *consensus) TrustedGHOSTDAGData(blockHash *externalapi.DomainHash) (*ext

return ghostdagData, nil
}

func (s *consensus) IsChainBlock(blockHash *externalapi.DomainHash) (bool, error) {
s.lock.Lock()
defer s.lock.Unlock()

stagingArea := model.NewStagingArea()
virtualGHOSTDAGData, err := s.ghostdagDataStores[0].Get(s.databaseContext, stagingArea, model.VirtualBlockHash, false)
if err != nil {
return false, err
}

return s.dagTopologyManagers[0].IsInSelectedParentChainOf(stagingArea, blockHash, virtualGHOSTDAGData.SelectedParent())
}
22 changes: 14 additions & 8 deletions domain/consensus/model/externalapi/blockinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@ import "math/big"

// BlockInfo contains various information about a specific block
type BlockInfo struct {
Exists bool
BlockStatus BlockStatus
BlueScore uint64
BlueWork *big.Int
Exists bool
BlockStatus BlockStatus
BlueScore uint64
BlueWork *big.Int
SelectedParent *DomainHash
MergeSetBlues []*DomainHash
MergeSetReds []*DomainHash
}

// Clone returns a clone of BlockInfo
func (bi *BlockInfo) Clone() *BlockInfo {
return &BlockInfo{
Exists: bi.Exists,
BlockStatus: bi.BlockStatus.Clone(),
BlueScore: bi.BlueScore,
BlueWork: new(big.Int).Set(bi.BlueWork),
Exists: bi.Exists,
BlockStatus: bi.BlockStatus.Clone(),
BlueScore: bi.BlueScore,
BlueWork: new(big.Int).Set(bi.BlueWork),
SelectedParent: bi.SelectedParent,
MergeSetBlues: CloneHashes(bi.MergeSetBlues),
MergeSetReds: CloneHashes(bi.MergeSetReds),
}
}
52 changes: 52 additions & 0 deletions domain/consensus/model/externalapi/blockinfo_clone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,83 @@ func initTestBlockInfoStructsForClone() []*BlockInfo {
BlockStatus(0x01),
0,
big.NewInt(0),
nil,
[]*DomainHash{},
[]*DomainHash{},
}, {
true,
BlockStatus(0x02),
0,
big.NewInt(0),
nil,
[]*DomainHash{},
[]*DomainHash{},
}, {
true,
1,
1,
big.NewInt(0),
nil,
[]*DomainHash{},
[]*DomainHash{},
}, {
true,
255,
2,
big.NewInt(0),
nil,
[]*DomainHash{},
[]*DomainHash{},
}, {
true,
0,
3,
big.NewInt(0),
nil,
[]*DomainHash{},
[]*DomainHash{},
}, {
true,
BlockStatus(0x01),
0,
big.NewInt(1),
nil,
[]*DomainHash{},
[]*DomainHash{},
}, {
false,
BlockStatus(0x01),
0,
big.NewInt(1),
NewDomainHashFromByteArray(&[DomainHashSize]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}),
[]*DomainHash{
NewDomainHashFromByteArray(&[DomainHashSize]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}),
NewDomainHashFromByteArray(&[DomainHashSize]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}),
},
[]*DomainHash{
NewDomainHashFromByteArray(&[DomainHashSize]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04}),
NewDomainHashFromByteArray(&[DomainHashSize]byte{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}),
},
},
}
return tests
Expand Down
3 changes: 2 additions & 1 deletion domain/consensus/model/externalapi/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Consensus interface {
GetBlockEvenIfHeaderOnly(blockHash *DomainHash) (*DomainBlock, error)
GetBlockHeader(blockHash *DomainHash) (BlockHeader, error)
GetBlockInfo(blockHash *DomainHash) (*BlockInfo, error)
GetBlockRelations(blockHash *DomainHash) (parents []*DomainHash, selectedParent *DomainHash, children []*DomainHash, err error)
GetBlockRelations(blockHash *DomainHash) (parents []*DomainHash, children []*DomainHash, err error)
GetBlockAcceptanceData(blockHash *DomainHash) (AcceptanceData, error)

GetHashesBetween(lowHash, highHash *DomainHash, maxBlocks uint64) (hashes []*DomainHash, actualHighHash *DomainHash, err error)
Expand Down Expand Up @@ -50,4 +50,5 @@ type Consensus interface {
TrustedDataDataDAAHeader(trustedBlockHash, daaBlockHash *DomainHash, daaBlockWindowIndex uint64) (*TrustedDataDataDAAHeader, error)
TrustedBlockAssociatedGHOSTDAGDataBlockHashes(blockHash *DomainHash) ([]*DomainHash, error)
TrustedGHOSTDAGData(blockHash *DomainHash) (*BlockGHOSTDAGData, error)
IsChainBlock(blockHash *DomainHash) (bool, error)
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9f02a24

Please sign in to comment.