mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[NOD-1517] Properly initialize consensus with Genesis block (#1009)
* [NOD-1517] Properly initialize consensus with Genesis block * [NOD-1517] Remove redundant AddHeaderTip * [NOD-1517] Don't return nil from dbHash<->DomainHash converters * [NOD-1517] Use pointer receivers * [NOD-1517] Use domain block in dagParams * [NOD-1517] Remove boolean from SelectedTip * [NOD-1517] Rename hasHeader to isHeadersOnlyBlock * [NOD-1517] Add comment * [NOD-1517] Change genesis version * [NOD-1517] Rename TestNewFactory->TestNewConsensus
This commit is contained in:
parent
281944762d
commit
9a344152aa
@ -1,12 +1,20 @@
|
||||
package serialization
|
||||
|
||||
import "github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
// BlockGHOSTDAGDataToDBBlockGHOSTDAGData converts BlockGHOSTDAGData to DbBlockGhostdagData
|
||||
func BlockGHOSTDAGDataToDBBlockGHOSTDAGData(blockGHOSTDAGData *model.BlockGHOSTDAGData) *DbBlockGhostdagData {
|
||||
var selectedParent *DbHash
|
||||
if blockGHOSTDAGData.SelectedParent != nil {
|
||||
selectedParent = DomainHashToDbHash(blockGHOSTDAGData.SelectedParent)
|
||||
}
|
||||
|
||||
return &DbBlockGhostdagData{
|
||||
BlueScore: blockGHOSTDAGData.BlueScore,
|
||||
SelectedParent: DomainHashToDbHash(blockGHOSTDAGData.SelectedParent),
|
||||
SelectedParent: selectedParent,
|
||||
MergeSetBlues: DomainHashesToDbHashes(blockGHOSTDAGData.MergeSetBlues),
|
||||
MergeSetReds: DomainHashesToDbHashes(blockGHOSTDAGData.MergeSetReds),
|
||||
BluesAnticoneSizes: bluesAnticoneSizesToDBBluesAnticoneSizes(blockGHOSTDAGData.BluesAnticoneSizes),
|
||||
@ -15,9 +23,13 @@ func BlockGHOSTDAGDataToDBBlockGHOSTDAGData(blockGHOSTDAGData *model.BlockGHOSTD
|
||||
|
||||
// DBBlockGHOSTDAGDataToBlockGHOSTDAGData converts DbBlockGhostdagData to BlockGHOSTDAGData
|
||||
func DBBlockGHOSTDAGDataToBlockGHOSTDAGData(dbBlockGHOSTDAGData *DbBlockGhostdagData) (*model.BlockGHOSTDAGData, error) {
|
||||
selectedParent, err := DbHashToDomainHash(dbBlockGHOSTDAGData.SelectedParent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var selectedParent *externalapi.DomainHash
|
||||
if dbBlockGHOSTDAGData.SelectedParent != nil {
|
||||
var err error
|
||||
selectedParent, err = DbHashToDomainHash(dbBlockGHOSTDAGData.SelectedParent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
mergetSetBlues, err := DbHashesToDomainHashes(dbBlockGHOSTDAGData.MergeSetBlues)
|
||||
|
@ -2,12 +2,18 @@ package serialization
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
)
|
||||
|
||||
func reachablityTreeNodeToDBReachablityTreeNode(reachabilityTreeNode *model.ReachabilityTreeNode) *DbReachabilityTreeNode {
|
||||
var parent *DbHash
|
||||
if reachabilityTreeNode.Parent != nil {
|
||||
parent = DomainHashToDbHash(reachabilityTreeNode.Parent)
|
||||
}
|
||||
|
||||
return &DbReachabilityTreeNode{
|
||||
Children: DomainHashesToDbHashes(reachabilityTreeNode.Children),
|
||||
Parent: DomainHashToDbHash(reachabilityTreeNode.Parent),
|
||||
Parent: parent,
|
||||
Interval: reachablityIntervalToDBReachablityInterval(reachabilityTreeNode.Interval),
|
||||
}
|
||||
}
|
||||
@ -18,9 +24,13 @@ func dbReachablityTreeNodeToReachablityTreeNode(dbReachabilityTreeNode *DbReacha
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parent, err := DbHashToDomainHash(dbReachabilityTreeNode.Parent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var parent *externalapi.DomainHash
|
||||
if dbReachabilityTreeNode.Parent != nil {
|
||||
var err error
|
||||
parent, err = DbHashToDomainHash(dbReachabilityTreeNode.Parent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &model.ReachabilityTreeNode{
|
||||
|
@ -9,23 +9,23 @@ type dbTransaction struct {
|
||||
transaction database.Transaction
|
||||
}
|
||||
|
||||
func (d dbTransaction) Put(key model.DBKey, value []byte) error {
|
||||
func (d *dbTransaction) Put(key model.DBKey, value []byte) error {
|
||||
return d.transaction.Put(dbKeyToDatabaseKey(key), value)
|
||||
}
|
||||
|
||||
func (d dbTransaction) Delete(key model.DBKey) error {
|
||||
func (d *dbTransaction) Delete(key model.DBKey) error {
|
||||
return d.transaction.Delete(dbKeyToDatabaseKey(key))
|
||||
}
|
||||
|
||||
func (d dbTransaction) Rollback() error {
|
||||
func (d *dbTransaction) Rollback() error {
|
||||
return d.transaction.Rollback()
|
||||
}
|
||||
|
||||
func (d dbTransaction) Commit() error {
|
||||
return d.Commit()
|
||||
func (d *dbTransaction) Commit() error {
|
||||
return d.transaction.Commit()
|
||||
}
|
||||
|
||||
func (d dbTransaction) RollbackUnlessClosed() error {
|
||||
func (d *dbTransaction) RollbackUnlessClosed() error {
|
||||
return d.RollbackUnlessClosed()
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,14 @@ func (brs *blockRelationStore) BlockRelation(dbContext model.DBReader, blockHash
|
||||
return brs.deserializeBlockRelations(blockRelationsBytes)
|
||||
}
|
||||
|
||||
func (brs *blockRelationStore) Has(dbContext model.DBReader, blockHash *externalapi.DomainHash) (bool, error) {
|
||||
if _, ok := brs.staging[*blockHash]; ok {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return dbContext.Has(brs.hashAsKey(blockHash))
|
||||
}
|
||||
|
||||
func (brs *blockRelationStore) hashAsKey(hash *externalapi.DomainHash) model.DBKey {
|
||||
return bucket.Key(hash[:])
|
||||
}
|
||||
|
@ -18,14 +18,14 @@ func New() model.ConsensusStateStore {
|
||||
return &consensusStateStore{}
|
||||
}
|
||||
|
||||
func (c consensusStateStore) Discard() {
|
||||
func (c *consensusStateStore) Discard() {
|
||||
c.stagedTips = nil
|
||||
c.stagedVirtualUTXODiff = nil
|
||||
c.stagedVirtualDiffParents = nil
|
||||
c.stagedVirtualUTXOSet = nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) Commit(dbTx model.DBTransaction) error {
|
||||
func (c *consensusStateStore) Commit(dbTx model.DBTransaction) error {
|
||||
err := c.commitTips(dbTx)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -50,7 +50,7 @@ func (c consensusStateStore) Commit(dbTx model.DBTransaction) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) IsStaged() bool {
|
||||
func (c *consensusStateStore) IsStaged() bool {
|
||||
return c.stagedTips != nil ||
|
||||
c.stagedVirtualDiffParents != nil ||
|
||||
c.stagedVirtualUTXODiff != nil
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
var tipsKey = dbkeys.MakeBucket().Key([]byte("tips"))
|
||||
|
||||
func (c consensusStateStore) Tips(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
|
||||
func (c *consensusStateStore) Tips(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
|
||||
if c.stagedTips != nil {
|
||||
return c.stagedTips, nil
|
||||
}
|
||||
@ -22,11 +22,11 @@ func (c consensusStateStore) Tips(dbContext model.DBReader) ([]*externalapi.Doma
|
||||
return hashes.DeserializeHashSlice(tipsBytes)
|
||||
}
|
||||
|
||||
func (c consensusStateStore) StageTips(tipHashes []*externalapi.DomainHash) {
|
||||
func (c *consensusStateStore) StageTips(tipHashes []*externalapi.DomainHash) {
|
||||
c.stagedTips = tipHashes
|
||||
}
|
||||
|
||||
func (c consensusStateStore) commitTips(dbTx model.DBTransaction) error {
|
||||
func (c *consensusStateStore) commitTips(dbTx model.DBTransaction) error {
|
||||
tipsBytes := hashes.SerializeHashSlice(c.stagedTips)
|
||||
|
||||
err := dbTx.Put(tipsKey, tipsBytes)
|
||||
|
@ -18,7 +18,7 @@ func utxoKey(outpoint *externalapi.DomainOutpoint) (model.DBKey, error) {
|
||||
return utxoSetBucket.Key(serializedOutpoint), nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff *model.UTXODiff) error {
|
||||
func (c *consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff *model.UTXODiff) error {
|
||||
if c.stagedVirtualUTXOSet != nil {
|
||||
return errors.New("cannot stage virtual UTXO diff while virtual UTXO set is staged")
|
||||
}
|
||||
@ -27,11 +27,15 @@ func (c consensusStateStore) StageVirtualUTXODiff(virtualUTXODiff *model.UTXODif
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction) error {
|
||||
func (c *consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction) error {
|
||||
if c.stagedVirtualUTXOSet != nil {
|
||||
return errors.New("cannot commit virtual UTXO diff while virtual UTXO set is staged")
|
||||
}
|
||||
|
||||
if c.stagedVirtualUTXODiff == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for toRemoveOutpoint := range c.stagedVirtualUTXODiff.ToRemove {
|
||||
dbKey, err := utxoKey(&toRemoveOutpoint)
|
||||
if err != nil {
|
||||
@ -61,7 +65,7 @@ func (c consensusStateStore) commitVirtualUTXODiff(dbTx model.DBTransaction) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) commitVirtualUTXOSet(dbTx model.DBTransaction) error {
|
||||
func (c *consensusStateStore) commitVirtualUTXOSet(dbTx model.DBTransaction) error {
|
||||
if c.stagedVirtualUTXODiff != nil {
|
||||
return errors.New("cannot commit virtual UTXO set while virtual UTXO diff is staged")
|
||||
}
|
||||
@ -84,7 +88,7 @@ func (c consensusStateStore) commitVirtualUTXOSet(dbTx model.DBTransaction) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) UTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) (
|
||||
func (c *consensusStateStore) UTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) (
|
||||
*externalapi.UTXOEntry, error) {
|
||||
|
||||
if c.stagedVirtualUTXOSet != nil {
|
||||
@ -94,7 +98,7 @@ func (c consensusStateStore) UTXOByOutpoint(dbContext model.DBReader, outpoint *
|
||||
return c.utxoByOutpointFromStagedVirtualUTXODiff(dbContext, outpoint)
|
||||
}
|
||||
|
||||
func (c consensusStateStore) utxoByOutpointFromStagedVirtualUTXODiff(dbContext model.DBReader,
|
||||
func (c *consensusStateStore) utxoByOutpointFromStagedVirtualUTXODiff(dbContext model.DBReader,
|
||||
outpoint *externalapi.DomainOutpoint) (
|
||||
*externalapi.UTXOEntry, error) {
|
||||
|
||||
@ -120,7 +124,7 @@ func (c consensusStateStore) utxoByOutpointFromStagedVirtualUTXODiff(dbContext m
|
||||
return deserializeUTXOEntry(serializedUTXOEntry)
|
||||
}
|
||||
|
||||
func (c consensusStateStore) utxoByOutpointFromStagedVirtualUTXOSet(outpoint *externalapi.DomainOutpoint) (
|
||||
func (c *consensusStateStore) utxoByOutpointFromStagedVirtualUTXOSet(outpoint *externalapi.DomainOutpoint) (
|
||||
*externalapi.UTXOEntry, error) {
|
||||
if utxoEntry, ok := c.stagedVirtualUTXOSet[*outpoint]; ok {
|
||||
return utxoEntry, nil
|
||||
@ -129,7 +133,7 @@ func (c consensusStateStore) utxoByOutpointFromStagedVirtualUTXOSet(outpoint *ex
|
||||
return nil, errors.Errorf("outpoint was not found")
|
||||
}
|
||||
|
||||
func (c consensusStateStore) HasUTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) (bool, error) {
|
||||
func (c *consensusStateStore) HasUTXOByOutpoint(dbContext model.DBReader, outpoint *externalapi.DomainOutpoint) (bool, error) {
|
||||
if c.stagedVirtualUTXOSet != nil {
|
||||
return c.hasUTXOByOutpointFromStagedVirtualUTXOSet(outpoint), nil
|
||||
}
|
||||
@ -137,7 +141,7 @@ func (c consensusStateStore) HasUTXOByOutpoint(dbContext model.DBReader, outpoin
|
||||
return c.hasUTXOByOutpointFromStagedVirtualUTXODiff(dbContext, outpoint)
|
||||
}
|
||||
|
||||
func (c consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXODiff(dbContext model.DBReader,
|
||||
func (c *consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXODiff(dbContext model.DBReader,
|
||||
outpoint *externalapi.DomainOutpoint) (bool, error) {
|
||||
if _, ok := c.stagedVirtualUTXODiff.ToRemove[*outpoint]; ok {
|
||||
return false, nil
|
||||
@ -154,12 +158,12 @@ func (c consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXODiff(dbContex
|
||||
return dbContext.Has(key)
|
||||
}
|
||||
|
||||
func (c consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXOSet(outpoint *externalapi.DomainOutpoint) bool {
|
||||
func (c *consensusStateStore) hasUTXOByOutpointFromStagedVirtualUTXOSet(outpoint *externalapi.DomainOutpoint) bool {
|
||||
_, ok := c.stagedVirtualUTXOSet[*outpoint]
|
||||
return ok
|
||||
}
|
||||
|
||||
func (c consensusStateStore) VirtualUTXOSetIterator(dbContext model.DBReader) (model.ReadOnlyUTXOSetIterator, error) {
|
||||
func (c *consensusStateStore) VirtualUTXOSetIterator(dbContext model.DBReader) (model.ReadOnlyUTXOSetIterator, error) {
|
||||
cursor, err := dbContext.Cursor(utxoSetBucket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -204,7 +208,7 @@ func (u utxoSetIterator) Get() (outpoint *externalapi.DomainOutpoint, utxoEntry
|
||||
return outpoint, utxoEntry, nil
|
||||
}
|
||||
|
||||
func (c consensusStateStore) StageVirtualUTXOSet(virtualUTXOSetIterator model.ReadOnlyUTXOSetIterator) error {
|
||||
func (c *consensusStateStore) StageVirtualUTXOSet(virtualUTXOSetIterator model.ReadOnlyUTXOSetIterator) error {
|
||||
if c.stagedVirtualUTXODiff != nil {
|
||||
return errors.New("cannot stage virtual UTXO set while virtual UTXO diff is staged")
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
var virtualDiffParentsKey = dbkeys.MakeBucket().Key([]byte("virtual-diff-parents"))
|
||||
|
||||
func (c consensusStateStore) VirtualDiffParents(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
|
||||
func (c *consensusStateStore) VirtualDiffParents(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
|
||||
if c.stagedVirtualDiffParents != nil {
|
||||
return c.stagedVirtualDiffParents, nil
|
||||
}
|
||||
@ -22,11 +22,11 @@ func (c consensusStateStore) VirtualDiffParents(dbContext model.DBReader) ([]*ex
|
||||
return hashes.DeserializeHashSlice(virtualDiffParentsBytes)
|
||||
}
|
||||
|
||||
func (c consensusStateStore) StageVirtualDiffParents(tipHashes []*externalapi.DomainHash) {
|
||||
func (c *consensusStateStore) StageVirtualDiffParents(tipHashes []*externalapi.DomainHash) {
|
||||
c.stagedVirtualDiffParents = tipHashes
|
||||
}
|
||||
|
||||
func (c consensusStateStore) commitVirtualDiffParents(dbTx model.DBTransaction) error {
|
||||
func (c *consensusStateStore) commitVirtualDiffParents(dbTx model.DBTransaction) error {
|
||||
virtualDiffParentsBytes := hashes.SerializeHashSlice(c.stagedVirtualDiffParents)
|
||||
|
||||
err := dbTx.Put(virtualDiffParentsKey, virtualDiffParentsBytes)
|
||||
|
@ -14,28 +14,46 @@ type headerTipsStore struct {
|
||||
staging []*externalapi.DomainHash
|
||||
}
|
||||
|
||||
func (h headerTipsStore) Discard() {
|
||||
func (h *headerTipsStore) HasTips(dbContext model.DBReader) (bool, error) {
|
||||
if h.staging != nil {
|
||||
return len(h.staging) > 0, nil
|
||||
}
|
||||
|
||||
return dbContext.Has(headerTipsKey)
|
||||
}
|
||||
|
||||
func (h *headerTipsStore) Discard() {
|
||||
h.staging = nil
|
||||
}
|
||||
|
||||
func (h headerTipsStore) Commit(dbTx model.DBTransaction) error {
|
||||
func (h *headerTipsStore) Commit(dbTx model.DBTransaction) error {
|
||||
if h.staging == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
tipsBytes, err := h.serializeTips(h.staging)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return dbTx.Put(headerTipsKey, tipsBytes)
|
||||
err = dbTx.Put(headerTipsKey, tipsBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h.Discard()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h headerTipsStore) Stage(tips []*externalapi.DomainHash) {
|
||||
func (h *headerTipsStore) Stage(tips []*externalapi.DomainHash) {
|
||||
h.staging = tips
|
||||
}
|
||||
|
||||
func (h headerTipsStore) IsStaged() bool {
|
||||
func (h *headerTipsStore) IsStaged() bool {
|
||||
return h.staging != nil
|
||||
}
|
||||
|
||||
func (h headerTipsStore) Tips(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
|
||||
func (h *headerTipsStore) Tips(dbContext model.DBReader) ([]*externalapi.DomainHash, error) {
|
||||
if h.staging != nil {
|
||||
return h.staging, nil
|
||||
}
|
||||
@ -48,12 +66,12 @@ func (h headerTipsStore) Tips(dbContext model.DBReader) ([]*externalapi.DomainHa
|
||||
return h.deserializeTips(tipsBytes)
|
||||
}
|
||||
|
||||
func (h headerTipsStore) serializeTips(tips []*externalapi.DomainHash) ([]byte, error) {
|
||||
func (h *headerTipsStore) serializeTips(tips []*externalapi.DomainHash) ([]byte, error) {
|
||||
dbTips := serialization.HeaderTipsToDBHeaderTips(tips)
|
||||
return proto.Marshal(dbTips)
|
||||
}
|
||||
|
||||
func (h headerTipsStore) deserializeTips(tipsBytes []byte) ([]*externalapi.DomainHash, error) {
|
||||
func (h *headerTipsStore) deserializeTips(tipsBytes []byte) ([]*externalapi.DomainHash, error) {
|
||||
dbTips := &serialization.DbHeaderTips{}
|
||||
err := proto.Unmarshal(tipsBytes, dbTips)
|
||||
if err != nil {
|
||||
|
@ -41,24 +41,27 @@ func (ps *pruningStore) Discard() {
|
||||
}
|
||||
|
||||
func (ps *pruningStore) Commit(dbTx model.DBTransaction) error {
|
||||
pruningPointBytes, err := ps.serializePruningPoint(ps.pruningPointStaging)
|
||||
if err != nil {
|
||||
return err
|
||||
if ps.pruningPointStaging != nil {
|
||||
pruningPointBytes, err := ps.serializePruningPoint(ps.pruningPointStaging)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = dbTx.Put(pruningBlockHashKey, pruningPointBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = dbTx.Put(pruningBlockHashKey, pruningPointBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if ps.serializedUTXOSetStaging != nil {
|
||||
utxoSetBytes, err := ps.serializeUTXOSetBytes(ps.serializedUTXOSetStaging)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
utxoSetBytes, err := ps.serializeUTXOSetBytes(ps.serializedUTXOSetStaging)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = dbTx.Put(pruningSerializedUTXOSetkey, utxoSetBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
err = dbTx.Put(pruningSerializedUTXOSetkey, utxoSetBytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
ps.Discard()
|
||||
|
@ -88,6 +88,14 @@ func (rds *reachabilityDataStore) ReachabilityData(dbContext model.DBReader,
|
||||
return rds.deserializeReachabilityData(reachabilityDataBytes)
|
||||
}
|
||||
|
||||
func (rds *reachabilityDataStore) HasReachabilityData(dbContext model.DBReader, blockHash *externalapi.DomainHash) (bool, error) {
|
||||
if _, ok := rds.reachabilityDataStaging[*blockHash]; ok {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return dbContext.Has(rds.reachabilityDataBlockHashAsKey(blockHash))
|
||||
}
|
||||
|
||||
// ReachabilityReindexRoot returns the current reachability reindex root
|
||||
func (rds *reachabilityDataStore) ReachabilityReindexRoot(dbContext model.DBReader) (*externalapi.DomainHash, error) {
|
||||
if rds.reachabilityReindexRootStaging != nil {
|
||||
|
@ -221,7 +221,7 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
|
||||
blockHeaderStore,
|
||||
headerTipsStore)
|
||||
|
||||
return &consensus{
|
||||
c := &consensus{
|
||||
databaseContext: dbManager,
|
||||
|
||||
blockProcessor: blockProcessor,
|
||||
@ -235,7 +235,21 @@ func (f *factory) NewConsensus(dagParams *dagconfig.Params, db infrastructuredat
|
||||
pruningStore: pruningStore,
|
||||
ghostdagDataStore: ghostdagDataStore,
|
||||
blockStatusStore: blockStatusStore,
|
||||
}, nil
|
||||
}
|
||||
|
||||
genesisInfo, err := c.GetBlockInfo(genesisHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !genesisInfo.Exists {
|
||||
err = c.ValidateAndInsertBlock(dagParams.GenesisBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// NewFactory creates a new Consensus factory
|
||||
|
29
domain/consensus/factory_test.go
Normal file
29
domain/consensus/factory_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
package consensus
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/dagconfig"
|
||||
"github.com/kaspanet/kaspad/infrastructure/db/database/ldb"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNewConsensus(t *testing.T) {
|
||||
f := NewFactory()
|
||||
|
||||
dagParams := &dagconfig.DevnetParams
|
||||
|
||||
tmpDir, err := ioutil.TempDir("", "TestNewConsensus")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
db, err := ldb.NewLevelDB(tmpDir)
|
||||
if err != nil {
|
||||
t.Fatalf("error in NewLevelDB: %s", err)
|
||||
}
|
||||
|
||||
_, err = f.NewConsensus(dagParams, db)
|
||||
if err != nil {
|
||||
t.Fatalf("error in NewConsensus: %+v", err)
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ package externalapi
|
||||
// states of the consensus
|
||||
const (
|
||||
SyncStateNormal SyncState = iota
|
||||
SyncStateMissingGenesis
|
||||
SyncStateHeadersFirst
|
||||
SyncStateMissingUTXOSet
|
||||
SyncStateMissingBlockBodies
|
||||
|
@ -8,4 +8,5 @@ type BlockRelationStore interface {
|
||||
StageBlockRelation(blockHash *externalapi.DomainHash, blockRelations *BlockRelations)
|
||||
IsStaged() bool
|
||||
BlockRelation(dbContext DBReader, blockHash *externalapi.DomainHash) (*BlockRelations, error)
|
||||
Has(dbContext DBReader, blockHash *externalapi.DomainHash) (bool, error)
|
||||
}
|
||||
|
@ -8,4 +8,5 @@ type HeaderTipsStore interface {
|
||||
Stage(tips []*externalapi.DomainHash)
|
||||
IsStaged() bool
|
||||
Tips(dbContext DBReader) ([]*externalapi.DomainHash, error)
|
||||
HasTips(dbContext DBReader) (bool, error)
|
||||
}
|
||||
|
@ -9,5 +9,6 @@ type ReachabilityDataStore interface {
|
||||
StageReachabilityReindexRoot(reachabilityReindexRoot *externalapi.DomainHash)
|
||||
IsAnythingStaged() bool
|
||||
ReachabilityData(dbContext DBReader, blockHash *externalapi.DomainHash) (*ReachabilityData, error)
|
||||
HasReachabilityData(dbContext DBReader, blockHash *externalapi.DomainHash) (bool, error)
|
||||
ReachabilityReindexRoot(dbContext DBReader) (*externalapi.DomainHash, error)
|
||||
}
|
||||
|
@ -58,11 +58,6 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = bp.headerTipsManager.AddHeaderTip(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if mode.State == externalapi.SyncStateHeadersFirst {
|
||||
@ -78,12 +73,21 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock)
|
||||
return err
|
||||
}
|
||||
|
||||
oldHeadersSelectedTip, err := bp.headerTipsManager.SelectedTip()
|
||||
hasTips, err := bp.headerTipsStore.HasTips(bp.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if mode.State == externalapi.SyncStateHeadersFirst {
|
||||
var oldHeadersSelectedTip *externalapi.DomainHash
|
||||
if hasTips {
|
||||
var err error
|
||||
oldHeadersSelectedTip, err = bp.headerTipsManager.SelectedTip()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if mode.State == externalapi.SyncStateHeadersFirst || mode.State == externalapi.SyncStateMissingGenesis {
|
||||
err = bp.headerTipsManager.AddHeaderTip(hash)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -102,21 +106,26 @@ func (bp *blockProcessor) validateAndInsertBlock(block *externalapi.DomainBlock)
|
||||
bp.headerTipsStore.Stage(tips)
|
||||
}
|
||||
|
||||
err = bp.updateReachabilityReindexRoot(oldHeadersSelectedTip)
|
||||
if err != nil {
|
||||
return err
|
||||
if mode.State != externalapi.SyncStateMissingGenesis {
|
||||
err = bp.updateReachabilityReindexRoot(oldHeadersSelectedTip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger pruning, which will check if the pruning point changed and delete the data if it did.
|
||||
err = bp.pruningManager.FindNextPruningPoint()
|
||||
if err != nil {
|
||||
return err
|
||||
if mode.State == externalapi.SyncStateNormal {
|
||||
// Trigger pruning, which will check if the pruning point changed and delete the data if it did.
|
||||
err = bp.pruningManager.FindNextPruningPoint()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return bp.commitAllChanges()
|
||||
}
|
||||
|
||||
func (bp *blockProcessor) updateReachabilityReindexRoot(oldHeadersSelectedTip *externalapi.DomainHash) error {
|
||||
|
||||
headersSelectedTip, err := bp.headerTipsManager.SelectedTip()
|
||||
if err != nil {
|
||||
return err
|
||||
@ -156,15 +165,28 @@ func (bp *blockProcessor) checkBlockStatus(hash *externalapi.DomainHash, mode *e
|
||||
}
|
||||
|
||||
func (bp *blockProcessor) validateBlock(block *externalapi.DomainBlock, mode *externalapi.SyncInfo) error {
|
||||
// If any validation until (included) proof-of-work fails, simply
|
||||
// return an error without writing anything in the database.
|
||||
// This is to prevent spamming attacks.
|
||||
err := bp.validatePreProofOfWork(block)
|
||||
blockHash := consensusserialization.HeaderHash(block.Header)
|
||||
hasHeader, err := bp.hasHeader(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !hasHeader {
|
||||
bp.blockHeaderStore.Stage(blockHash, block.Header)
|
||||
err = bp.dagTopologyManager.SetParents(blockHash, block.Header.ParentHashes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// If any validation until (included) proof-of-work fails, simply
|
||||
// return an error without writing anything in the database.
|
||||
// This is to prevent spamming attacks.
|
||||
err = bp.validatePreProofOfWork(block)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
blockHash := consensusserialization.BlockHash(block)
|
||||
err = bp.blockValidator.ValidateProofOfWorkAndDifficulty(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -224,12 +246,6 @@ func (bp *blockProcessor) validatePostProofOfWork(block *externalapi.DomainBlock
|
||||
}
|
||||
|
||||
if !hasHeader {
|
||||
bp.blockHeaderStore.Stage(blockHash, block.Header)
|
||||
|
||||
err := bp.dagTopologyManager.SetParents(blockHash, block.Header.ParentHashes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = bp.blockValidator.ValidateHeaderInContext(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -26,12 +26,12 @@ func (v *blockValidator) ValidateHeaderInContext(blockHash *externalapi.DomainHa
|
||||
return err
|
||||
}
|
||||
|
||||
status, err := v.blockStatusStore.Get(v.databaseContext, blockHash)
|
||||
isHeadersOnlyBlock, err := v.isHeadersOnlyBlock(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if status != externalapi.StatusHeaderOnly {
|
||||
if !isHeadersOnlyBlock {
|
||||
err = v.ghostdagManager.GHOSTDAG(blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -51,6 +51,24 @@ func (v *blockValidator) ValidateHeaderInContext(blockHash *externalapi.DomainHa
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *blockValidator) isHeadersOnlyBlock(blockHash *externalapi.DomainHash) (bool, error) {
|
||||
exists, err := v.blockStatusStore.Exists(v.databaseContext, blockHash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if !exists {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
status, err := v.blockStatusStore.Get(v.databaseContext, blockHash)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return status == externalapi.StatusHeaderOnly, nil
|
||||
}
|
||||
|
||||
// checkParentsIncest validates that no parent is an ancestor of another parent
|
||||
func (v *blockValidator) checkParentsIncest(header *externalapi.DomainBlockHeader) error {
|
||||
for _, parentA := range header.ParentHashes {
|
||||
|
@ -103,14 +103,22 @@ func isHashInSlice(hash *externalapi.DomainHash, hashes []*externalapi.DomainHas
|
||||
}
|
||||
|
||||
func (dtm *dagTopologyManager) SetParents(blockHash *externalapi.DomainHash, parentHashes []*externalapi.DomainHash) error {
|
||||
// Go over the block's current relations (if they exist), and remove the block from all it's current parents
|
||||
// Note: In theory we should also remove the block from all it's children, however, in practice no block
|
||||
// ever has it's relations updated after getting any children, therefore we skip this step
|
||||
currentRelations, err := dtm.blockRelationStore.BlockRelation(dtm.databaseContext, blockHash)
|
||||
|
||||
hasRelations, err := dtm.blockRelationStore.Has(dtm.databaseContext, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if currentRelations != nil {
|
||||
|
||||
if hasRelations {
|
||||
// Go over the block's current relations (if they exist), and remove the block from all its current parents
|
||||
// Note: In theory we should also remove the block from all its children, however, in practice no block
|
||||
// ever has its relations updated after getting any children, therefore we skip this step
|
||||
|
||||
currentRelations, err := dtm.blockRelationStore.BlockRelation(dtm.databaseContext, blockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, currentParent := range currentRelations.Parents {
|
||||
parentRelations, err := dtm.blockRelationStore.BlockRelation(dtm.databaseContext, currentParent)
|
||||
if err != nil {
|
||||
|
@ -35,14 +35,18 @@ func (gm *ghostdagManager) GHOSTDAG(blockHash *externalapi.DomainHash) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
selectedParent, err := gm.findSelectedParent(blockParents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newBlockData.SelectedParent = selectedParent
|
||||
newBlockData.MergeSetBlues = append(newBlockData.MergeSetBlues, selectedParent)
|
||||
newBlockData.BluesAnticoneSizes[*selectedParent] = 0
|
||||
isGenesis := len(blockParents) == 0
|
||||
if !isGenesis {
|
||||
selectedParent, err := gm.findSelectedParent(blockParents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newBlockData.SelectedParent = selectedParent
|
||||
newBlockData.MergeSetBlues = append(newBlockData.MergeSetBlues, selectedParent)
|
||||
newBlockData.BluesAnticoneSizes[*selectedParent] = 0
|
||||
}
|
||||
|
||||
mergeSetWithoutSelectedParent, err := gm.mergeSetWithoutSelectedParent(newBlockData.SelectedParent, blockParents)
|
||||
if err != nil {
|
||||
@ -67,11 +71,16 @@ func (gm *ghostdagManager) GHOSTDAG(blockHash *externalapi.DomainHash) error {
|
||||
}
|
||||
}
|
||||
|
||||
selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, newBlockData.SelectedParent)
|
||||
if err != nil {
|
||||
return err
|
||||
if !isGenesis {
|
||||
selectedParentGHOSTDAGData, err := gm.ghostdagDataStore.Get(gm.databaseContext, newBlockData.SelectedParent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newBlockData.BlueScore = selectedParentGHOSTDAGData.BlueScore + uint64(len(newBlockData.MergeSetBlues))
|
||||
} else {
|
||||
// Genesis's blue score is defined to be 0.
|
||||
newBlockData.BlueScore = 0
|
||||
}
|
||||
newBlockData.BlueScore = selectedParentGHOSTDAGData.BlueScore + uint64(len(newBlockData.MergeSetBlues))
|
||||
|
||||
gm.ghostdagDataStore.Stage(blockHash, newBlockData)
|
||||
return nil
|
||||
|
@ -26,11 +26,20 @@ func New(databaseContext model.DBReader,
|
||||
}
|
||||
|
||||
func (h headerTipsManager) AddHeaderTip(hash *externalapi.DomainHash) error {
|
||||
tips, err := h.headerTipsStore.Tips(h.databaseContext)
|
||||
tips := []*externalapi.DomainHash{}
|
||||
hasTips, err := h.headerTipsStore.HasTips(h.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if hasTips {
|
||||
var err error
|
||||
tips, err = h.headerTipsStore.Tips(h.databaseContext)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
newTips := make([]*externalapi.DomainHash, 0, len(tips)+1)
|
||||
for _, tip := range tips {
|
||||
isAncestorOf, err := h.dagTopologyManager.IsAncestorOf(tip, hash)
|
||||
|
@ -8,5 +8,10 @@ func (h headerTipsManager) SelectedTip() (*externalapi.DomainHash, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return h.ghostdagManager.ChooseSelectedParent(tips...)
|
||||
selectedTip, err := h.ghostdagManager.ChooseSelectedParent(tips...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return selectedTip, nil
|
||||
}
|
||||
|
@ -45,6 +45,11 @@ func (mdm *mergeDepthManager) CheckBoundedMergeDepth(blockHash *externalapi.Doma
|
||||
return err
|
||||
}
|
||||
|
||||
// Return nil on genesis
|
||||
if ghostdagData.SelectedParent == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
finalityPoint, err := mdm.finalityPoint(ghostdagData)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -6,6 +6,18 @@ import (
|
||||
)
|
||||
|
||||
func (rt *reachabilityManager) data(blockHash *externalapi.DomainHash) (*model.ReachabilityData, error) {
|
||||
hasData, err := rt.reachabilityDataStore.HasReachabilityData(rt.databaseContext, blockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !hasData {
|
||||
return &model.ReachabilityData{
|
||||
TreeNode: nil,
|
||||
FutureCoveringSet: nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return rt.reachabilityDataStore.ReachabilityData(rt.databaseContext, blockHash)
|
||||
}
|
||||
|
||||
|
@ -825,7 +825,7 @@ func (rt *reachabilityManager) findAncestorOfThisAmongChildrenOfOther(this, othe
|
||||
|
||||
ancestor, ok := rt.findAncestorOfNode(otherChildren, this)
|
||||
if !ok {
|
||||
return nil, errors.Errorf("node is not an ancestor of node")
|
||||
return nil, errors.Errorf("node is not an ancestor of this")
|
||||
}
|
||||
|
||||
return ancestor, nil
|
||||
|
@ -32,6 +32,15 @@ func (sm *syncManager) syncInfo() (*externalapi.SyncInfo, error) {
|
||||
}
|
||||
|
||||
func (sm *syncManager) resolveSyncState() (externalapi.SyncState, error) {
|
||||
hasTips, err := sm.headerTipsStore.HasTips(sm.databaseContext)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !hasTips {
|
||||
return externalapi.SyncStateMissingGenesis, nil
|
||||
}
|
||||
|
||||
headerVirtualSelectedParentHash, err := sm.headerVirtualSelectedParentHash()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
@ -41,5 +41,6 @@ func serializeHeader(w io.Writer, header *externalapi.DomainBlockHeader) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return writeElements(w, header.HashMerkleRoot, header.AcceptedIDMerkleRoot, header.UTXOCommitment, timestamp, header.Bits, header.Nonce)
|
||||
return writeElements(w, &header.HashMerkleRoot, &header.AcceptedIDMerkleRoot, &header.UTXOCommitment, timestamp,
|
||||
header.Bits, header.Nonce)
|
||||
}
|
||||
|
26
domain/consensus/utils/transactionhelper/new.go
Normal file
26
domain/consensus/utils/transactionhelper/new.go
Normal file
@ -0,0 +1,26 @@
|
||||
package transactionhelper
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
|
||||
)
|
||||
|
||||
// NewSubnetworkTransaction returns a new trsnactions in the specified subnetwork with specified gas and payload
|
||||
func NewSubnetworkTransaction(version int32, inputs []*externalapi.DomainTransactionInput,
|
||||
outputs []*externalapi.DomainTransactionOutput, subnetworkID *externalapi.DomainSubnetworkID,
|
||||
gas uint64, payload []byte) *externalapi.DomainTransaction {
|
||||
|
||||
payloadHash := hashes.HashData(payload)
|
||||
return &externalapi.DomainTransaction{
|
||||
Version: version,
|
||||
Inputs: inputs,
|
||||
Outputs: outputs,
|
||||
LockTime: 0,
|
||||
SubnetworkID: *subnetworkID,
|
||||
Gas: gas,
|
||||
PayloadHash: *payloadHash,
|
||||
Payload: payload,
|
||||
Fee: 0,
|
||||
Mass: 0,
|
||||
}
|
||||
}
|
@ -5,13 +5,12 @@
|
||||
package dagconfig
|
||||
|
||||
import (
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"
|
||||
"github.com/kaspanet/kaspad/util/mstime"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/transactionhelper"
|
||||
)
|
||||
|
||||
var genesisTxOuts = []*appmessage.TxOut{}
|
||||
var genesisTxOuts = []*externalapi.DomainTransactionOutput{}
|
||||
|
||||
var genesisTxPayload = []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Blue score
|
||||
@ -23,16 +22,16 @@ var genesisTxPayload = []byte{
|
||||
|
||||
// genesisCoinbaseTx is the coinbase transaction for the genesis blocks for
|
||||
// the main network.
|
||||
var genesisCoinbaseTx = appmessage.NewSubnetworkMsgTx(1, []*appmessage.TxIn{}, genesisTxOuts,
|
||||
var genesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1, []*externalapi.DomainTransactionInput{}, genesisTxOuts,
|
||||
&subnetworks.SubnetworkIDCoinbase, 0, genesisTxPayload)
|
||||
|
||||
// genesisHash is the hash of the first block in the block DAG for the main
|
||||
// network (genesis block).
|
||||
var genesisHash = externalapi.DomainHash{
|
||||
0x67, 0x8b, 0x44, 0x41, 0x59, 0xe5, 0x99, 0xe0,
|
||||
0x8e, 0x01, 0xad, 0x77, 0xce, 0x8b, 0x18, 0xe7,
|
||||
0x1f, 0x61, 0x8c, 0x7d, 0x0c, 0x2f, 0x98, 0xbe,
|
||||
0x63, 0xf4, 0x13, 0x89, 0x41, 0xc6, 0xdb, 0x9b,
|
||||
0x37, 0xf9, 0x09, 0x98, 0x0e, 0x12, 0xf6, 0xa2,
|
||||
0xaa, 0x0d, 0x09, 0xfa, 0x41, 0xad, 0x95, 0x1a,
|
||||
0x5b, 0x38, 0x14, 0x12, 0xe9, 0x02, 0x14, 0xcd,
|
||||
0xba, 0x64, 0xf6, 0x84, 0x72, 0xc4, 0xa4, 0x3a,
|
||||
}
|
||||
|
||||
// genesisMerkleRoot is the hash of the first transaction in the genesis block
|
||||
@ -46,21 +45,21 @@ var genesisMerkleRoot = externalapi.DomainHash{
|
||||
|
||||
// genesisBlock defines the genesis block of the block DAG which serves as the
|
||||
// public transaction ledger for the main network.
|
||||
var genesisBlock = appmessage.MsgBlock{
|
||||
Header: appmessage.BlockHeader{
|
||||
Version: 0x10000000,
|
||||
var genesisBlock = externalapi.DomainBlock{
|
||||
Header: &externalapi.DomainBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{},
|
||||
HashMerkleRoot: &genesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: &externalapi.DomainHash{},
|
||||
UTXOCommitment: &externalapi.DomainHash{},
|
||||
Timestamp: mstime.UnixMilliseconds(0x1730a81bdb4),
|
||||
HashMerkleRoot: genesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: externalapi.DomainHash{},
|
||||
UTXOCommitment: externalapi.DomainHash{},
|
||||
TimeInMilliseconds: 0x1730a81bdb4,
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x1,
|
||||
},
|
||||
Transactions: []*appmessage.MsgTx{genesisCoinbaseTx},
|
||||
Transactions: []*externalapi.DomainTransaction{genesisCoinbaseTx},
|
||||
}
|
||||
|
||||
var devnetGenesisTxOuts = []*appmessage.TxOut{}
|
||||
var devnetGenesisTxOuts = []*externalapi.DomainTransactionOutput{}
|
||||
|
||||
var devnetGenesisTxPayload = []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Blue score
|
||||
@ -73,44 +72,45 @@ var devnetGenesisTxPayload = []byte{
|
||||
|
||||
// devnetGenesisCoinbaseTx is the coinbase transaction for the genesis blocks for
|
||||
// the development network.
|
||||
var devnetGenesisCoinbaseTx = appmessage.NewSubnetworkMsgTx(1, []*appmessage.TxIn{}, devnetGenesisTxOuts,
|
||||
var devnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1,
|
||||
[]*externalapi.DomainTransactionInput{}, devnetGenesisTxOuts,
|
||||
&subnetworks.SubnetworkIDCoinbase, 0, devnetGenesisTxPayload)
|
||||
|
||||
// devGenesisHash is the hash of the first block in the block DAG for the development
|
||||
// network (genesis block).
|
||||
var devnetGenesisHash = externalapi.DomainHash{
|
||||
0x3e, 0x0f, 0xb1, 0x20, 0x3b, 0xa1, 0x6f, 0xc5,
|
||||
0x92, 0x63, 0x67, 0x09, 0x76, 0x38, 0x35, 0xea,
|
||||
0x30, 0x89, 0xe6, 0x3a, 0x63, 0xe9, 0xf9, 0x6e,
|
||||
0x31, 0x0a, 0x54, 0xb7, 0x24, 0x02, 0xd0, 0xec,
|
||||
0xd3, 0xad, 0xd6, 0xe4, 0x6b, 0xc2, 0x33, 0xa9,
|
||||
0x20, 0x03, 0x1e, 0xf3, 0xe6, 0x8a, 0xf4, 0x08,
|
||||
0x91, 0xa1, 0x25, 0xc7, 0xc1, 0xf1, 0x5b, 0x3e,
|
||||
0x74, 0x72, 0xb5, 0x8a, 0xa0, 0x10, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// devnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
|
||||
// for the devopment network.
|
||||
var devnetGenesisMerkleRoot = externalapi.DomainHash{
|
||||
0x68, 0x60, 0xe7, 0x77, 0x47, 0x74, 0x7f, 0xd5,
|
||||
0x55, 0x58, 0x8a, 0xb5, 0xc2, 0x29, 0x0c, 0xa6,
|
||||
0x65, 0x44, 0xb4, 0x4f, 0xfa, 0x31, 0x7a, 0xfa,
|
||||
0x55, 0xe0, 0xcf, 0xac, 0x9c, 0x86, 0x30, 0x2a,
|
||||
0x00, 0x94, 0xfd, 0xff, 0x4d, 0xb2, 0x4d, 0x18,
|
||||
0x95, 0x21, 0x36, 0x2a, 0x14, 0xfb, 0x19, 0x7a,
|
||||
0x99, 0x51, 0x7e, 0x3f, 0x44, 0xf6, 0x2e, 0x0b,
|
||||
0xe7, 0xb3, 0xc0, 0xbb, 0x00, 0x3b, 0x0b, 0xbd,
|
||||
}
|
||||
|
||||
// devnetGenesisBlock defines the genesis block of the block DAG which serves as the
|
||||
// public transaction ledger for the development network.
|
||||
var devnetGenesisBlock = appmessage.MsgBlock{
|
||||
Header: appmessage.BlockHeader{
|
||||
Version: 0x10000000,
|
||||
var devnetGenesisBlock = externalapi.DomainBlock{
|
||||
Header: &externalapi.DomainBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{},
|
||||
HashMerkleRoot: &devnetGenesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: &externalapi.DomainHash{},
|
||||
UTXOCommitment: &externalapi.DomainHash{},
|
||||
Timestamp: mstime.UnixMilliseconds(0x17305b05694),
|
||||
HashMerkleRoot: devnetGenesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: externalapi.DomainHash{},
|
||||
UTXOCommitment: externalapi.DomainHash{},
|
||||
TimeInMilliseconds: 0x17305b05694,
|
||||
Bits: 0x1e7fffff,
|
||||
Nonce: 0x10bb,
|
||||
Nonce: 282366,
|
||||
},
|
||||
Transactions: []*appmessage.MsgTx{devnetGenesisCoinbaseTx},
|
||||
Transactions: []*externalapi.DomainTransaction{devnetGenesisCoinbaseTx},
|
||||
}
|
||||
|
||||
var simnetGenesisTxOuts = []*appmessage.TxOut{}
|
||||
var simnetGenesisTxOuts = []*externalapi.DomainTransactionOutput{}
|
||||
|
||||
var simnetGenesisTxPayload = []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Blue score
|
||||
@ -122,16 +122,17 @@ var simnetGenesisTxPayload = []byte{
|
||||
}
|
||||
|
||||
// simnetGenesisCoinbaseTx is the coinbase transaction for the simnet genesis block.
|
||||
var simnetGenesisCoinbaseTx = appmessage.NewSubnetworkMsgTx(1, []*appmessage.TxIn{}, simnetGenesisTxOuts,
|
||||
var simnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1,
|
||||
[]*externalapi.DomainTransactionInput{}, simnetGenesisTxOuts,
|
||||
&subnetworks.SubnetworkIDCoinbase, 0, simnetGenesisTxPayload)
|
||||
|
||||
// simnetGenesisHash is the hash of the first block in the block DAG for
|
||||
// the simnet (genesis block).
|
||||
var simnetGenesisHash = externalapi.DomainHash{
|
||||
0x9d, 0x89, 0xb0, 0x6e, 0xb3, 0x47, 0xb5, 0x6e,
|
||||
0xcd, 0x6c, 0x63, 0x99, 0x45, 0x91, 0xd5, 0xce,
|
||||
0x9b, 0x43, 0x05, 0xc1, 0xa5, 0x5e, 0x2a, 0xda,
|
||||
0x90, 0x4c, 0xf0, 0x6c, 0x4d, 0x5f, 0xd3, 0x62,
|
||||
0xad, 0x47, 0xba, 0xd5, 0x6e, 0x1e, 0x62, 0x99,
|
||||
0x43, 0x81, 0xd2, 0xaf, 0xda, 0x1d, 0xe6, 0xda,
|
||||
0x0b, 0x50, 0xcb, 0x76, 0x8e, 0x5d, 0x9e, 0x41,
|
||||
0x20, 0x98, 0x28, 0xb1, 0x7e, 0x88, 0xb9, 0xb5,
|
||||
}
|
||||
|
||||
// simnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
|
||||
@ -145,21 +146,21 @@ var simnetGenesisMerkleRoot = externalapi.DomainHash{
|
||||
|
||||
// simnetGenesisBlock defines the genesis block of the block DAG which serves as the
|
||||
// public transaction ledger for the development network.
|
||||
var simnetGenesisBlock = appmessage.MsgBlock{
|
||||
Header: appmessage.BlockHeader{
|
||||
Version: 0x10000000,
|
||||
var simnetGenesisBlock = externalapi.DomainBlock{
|
||||
Header: &externalapi.DomainBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{},
|
||||
HashMerkleRoot: &simnetGenesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: &externalapi.DomainHash{},
|
||||
UTXOCommitment: &externalapi.DomainHash{},
|
||||
Timestamp: mstime.UnixMilliseconds(0x173001df3d5),
|
||||
HashMerkleRoot: simnetGenesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: externalapi.DomainHash{},
|
||||
UTXOCommitment: externalapi.DomainHash{},
|
||||
TimeInMilliseconds: 0x173001df3d5,
|
||||
Bits: 0x207fffff,
|
||||
Nonce: 0x0,
|
||||
},
|
||||
Transactions: []*appmessage.MsgTx{simnetGenesisCoinbaseTx},
|
||||
Transactions: []*externalapi.DomainTransaction{simnetGenesisCoinbaseTx},
|
||||
}
|
||||
|
||||
var testnetGenesisTxOuts = []*appmessage.TxOut{}
|
||||
var testnetGenesisTxOuts = []*externalapi.DomainTransactionOutput{}
|
||||
|
||||
var testnetGenesisTxPayload = []byte{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Blue score
|
||||
@ -169,16 +170,17 @@ var testnetGenesisTxPayload = []byte{
|
||||
}
|
||||
|
||||
// testnetGenesisCoinbaseTx is the coinbase transaction for the testnet genesis block.
|
||||
var testnetGenesisCoinbaseTx = appmessage.NewSubnetworkMsgTx(1, []*appmessage.TxIn{}, testnetGenesisTxOuts,
|
||||
var testnetGenesisCoinbaseTx = transactionhelper.NewSubnetworkTransaction(1,
|
||||
[]*externalapi.DomainTransactionInput{}, testnetGenesisTxOuts,
|
||||
&subnetworks.SubnetworkIDCoinbase, 0, testnetGenesisTxPayload)
|
||||
|
||||
// testnetGenesisHash is the hash of the first block in the block DAG for the test
|
||||
// network (genesis block).
|
||||
var testnetGenesisHash = externalapi.DomainHash{
|
||||
0x91, 0xe2, 0x7f, 0x78, 0x4e, 0xe5, 0xf9, 0x3c,
|
||||
0xff, 0x58, 0x45, 0xc3, 0xa6, 0x1f, 0x03, 0x80,
|
||||
0x55, 0xbe, 0xf4, 0xf2, 0xd6, 0xdd, 0xe3, 0x38,
|
||||
0xb7, 0xac, 0xd6, 0x3d, 0xc5, 0xb7, 0x1c, 0x73,
|
||||
0x29, 0x0c, 0x43, 0x42, 0x66, 0x2d, 0x1b, 0x05,
|
||||
0x0b, 0xc7, 0xb2, 0x26, 0x8d, 0x53, 0x16, 0xbf,
|
||||
0x5a, 0x2d, 0x7e, 0xff, 0xee, 0x06, 0xb7, 0x2b,
|
||||
0x41, 0x9f, 0xe8, 0xf0, 0xfa, 0xc7, 0xd1, 0x1a,
|
||||
}
|
||||
|
||||
// testnetGenesisMerkleRoot is the hash of the first transaction in the genesis block
|
||||
@ -192,16 +194,16 @@ var testnetGenesisMerkleRoot = externalapi.DomainHash{
|
||||
|
||||
// testnetGenesisBlock defines the genesis block of the block DAG which serves as the
|
||||
// public transaction ledger for testnet.
|
||||
var testnetGenesisBlock = appmessage.MsgBlock{
|
||||
Header: appmessage.BlockHeader{
|
||||
Version: 0x10000000,
|
||||
var testnetGenesisBlock = externalapi.DomainBlock{
|
||||
Header: &externalapi.DomainBlockHeader{
|
||||
Version: 1,
|
||||
ParentHashes: []*externalapi.DomainHash{},
|
||||
HashMerkleRoot: &testnetGenesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: &externalapi.DomainHash{},
|
||||
UTXOCommitment: &externalapi.DomainHash{},
|
||||
Timestamp: mstime.UnixMilliseconds(0x1730a66a9d9),
|
||||
HashMerkleRoot: testnetGenesisMerkleRoot,
|
||||
AcceptedIDMerkleRoot: externalapi.DomainHash{},
|
||||
UTXOCommitment: externalapi.DomainHash{},
|
||||
TimeInMilliseconds: 0x1730a66a9d9,
|
||||
Bits: 0x1e7fffff,
|
||||
Nonce: 0x162ca,
|
||||
},
|
||||
Transactions: []*appmessage.MsgTx{testnetGenesisCoinbaseTx},
|
||||
Transactions: []*externalapi.DomainTransaction{testnetGenesisCoinbaseTx},
|
||||
}
|
||||
|
@ -7,21 +7,17 @@ package dagconfig
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/kaspanet/kaspad/app/appmessage"
|
||||
"github.com/kaspanet/kaspad/domain/consensus/utils/consensusserialization"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// TestGenesisBlock tests the genesis block of the main network for validity by
|
||||
// checking the encoded hash.
|
||||
func TestGenesisBlock(t *testing.T) {
|
||||
// Check hash of the block against expected hash.
|
||||
hash := consensusserialization.BlockHash(appmessage.MsgBlockToDomainBlock(MainnetParams.GenesisBlock))
|
||||
hash := consensusserialization.BlockHash(MainnetParams.GenesisBlock)
|
||||
if *MainnetParams.GenesisHash != *hash {
|
||||
t.Fatalf("TestGenesisBlock: Genesis block hash does "+
|
||||
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
||||
spew.Sdump(MainnetParams.GenesisHash))
|
||||
"not appear valid - got %v, want %v", hash, MainnetParams.GenesisHash)
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,11 +25,11 @@ func TestGenesisBlock(t *testing.T) {
|
||||
// validity by checking the hash.
|
||||
func TestTestnetGenesisBlock(t *testing.T) {
|
||||
// Check hash of the block against expected hash.
|
||||
hash := consensusserialization.BlockHash(appmessage.MsgBlockToDomainBlock(TestnetParams.GenesisBlock))
|
||||
hash := consensusserialization.BlockHash(TestnetParams.GenesisBlock)
|
||||
if *TestnetParams.GenesisHash != *hash {
|
||||
t.Fatalf("TestTestnetGenesisBlock: Genesis block hash does "+
|
||||
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
||||
spew.Sdump(TestnetParams.GenesisHash))
|
||||
"not appear valid - got %v, want %v", hash,
|
||||
TestnetParams.GenesisHash)
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,11 +37,11 @@ func TestTestnetGenesisBlock(t *testing.T) {
|
||||
// for validity by checking the hash.
|
||||
func TestSimnetGenesisBlock(t *testing.T) {
|
||||
// Check hash of the block against expected hash.
|
||||
hash := consensusserialization.BlockHash(appmessage.MsgBlockToDomainBlock(SimnetParams.GenesisBlock))
|
||||
hash := consensusserialization.BlockHash(SimnetParams.GenesisBlock)
|
||||
if *SimnetParams.GenesisHash != *hash {
|
||||
t.Fatalf("TestSimnetGenesisBlock: Genesis block hash does "+
|
||||
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
||||
spew.Sdump(SimnetParams.GenesisHash))
|
||||
"not appear valid - got %v, want %v", hash,
|
||||
SimnetParams.GenesisHash)
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,10 +49,10 @@ func TestSimnetGenesisBlock(t *testing.T) {
|
||||
// for validity by checking the encoded hash.
|
||||
func TestDevnetGenesisBlock(t *testing.T) {
|
||||
// Check hash of the block against expected hash.
|
||||
hash := consensusserialization.BlockHash(appmessage.MsgBlockToDomainBlock(DevnetParams.GenesisBlock))
|
||||
hash := consensusserialization.BlockHash(DevnetParams.GenesisBlock)
|
||||
if *DevnetParams.GenesisHash != *hash {
|
||||
t.Fatalf("TestDevnetGenesisBlock: Genesis block hash does "+
|
||||
"not appear valid - got %v, want %v", spew.Sdump(hash),
|
||||
spew.Sdump(DevnetParams.GenesisHash))
|
||||
"not appear valid - got %v, want %v", hash,
|
||||
DevnetParams.GenesisHash)
|
||||
}
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ type Params struct {
|
||||
DNSSeeds []string
|
||||
|
||||
// GenesisBlock defines the first block of the DAG.
|
||||
GenesisBlock *appmessage.MsgBlock
|
||||
GenesisBlock *externalapi.DomainBlock
|
||||
|
||||
// GenesisHash is the starting block hash.
|
||||
GenesisHash *externalapi.DomainHash
|
||||
|
Loading…
x
Reference in New Issue
Block a user