From f7fbfbf5c40481c0241ff6d1fa8265d210bce122 Mon Sep 17 00:00:00 2001 From: Ori Newman Date: Thu, 31 Oct 2019 15:36:46 +0200 Subject: [PATCH] [NOD-383] Fix updateAddedChainBlocks and updateRemovedChainHashes to update IsChainBlock and AcceptingBlockID appropriately --- apiserver/sync.go | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/apiserver/sync.go b/apiserver/sync.go index 951d97089..7df471e4c 100644 --- a/apiserver/sync.go +++ b/apiserver/sync.go @@ -314,6 +314,11 @@ func insertBlock(dbTx *gorm.DB, rawBlock btcjson.GetBlockVerboseResult) (*dbmode IsChainBlock: false, // This must be false for updateSelectedParentChain to work properly Mass: rawBlock.Mass, } + + // Set genesis block as the initial chain block + if len(rawBlock.ParentHashes) == 0 { + dbBlock.IsChainBlock = true + } dbResult := dbTx.Create(&dbBlock) dbErrors := dbResult.GetErrors() if httpserverutils.HasDBError(dbErrors) { @@ -690,6 +695,16 @@ func updateRemovedChainHashes(dbTx *gorm.DB, removedHash string) error { } } + dbResult = dbTx. + Model(&dbmodels.Block{}). + Where(&dbmodels.Block{AcceptingBlockID: btcjson.Uint64(dbBlock.ID)}). + Updates(map[string]interface{}{"AcceptingBlockID": nil}) + + dbErrors = dbResult.GetErrors() + if httpserverutils.HasDBError(dbErrors) { + return httpserverutils.NewErrorFromDBErrors("failed to update blocks: ", dbErrors) + } + dbBlock.IsChainBlock = false dbResult = dbTx.Save(&dbBlock) dbErrors = dbResult.GetErrors() @@ -707,6 +722,21 @@ func updateRemovedChainHashes(dbTx *gorm.DB, removedHash string) error { // * The block is set IsChainBlock = true // This function will return an error if any of the above are in an unexpected state func updateAddedChainBlocks(dbTx *gorm.DB, addedBlock *btcjson.ChainBlock) error { + var dbAddedBlock dbmodels.Block + dbResult := dbTx. + Where(&dbmodels.Block{BlockHash: addedBlock.Hash}). + First(&dbAddedBlock) + dbErrors := dbResult.GetErrors() + if httpserverutils.HasDBError(dbErrors) { + return httpserverutils.NewErrorFromDBErrors("failed to find block: ", dbErrors) + } + if httpserverutils.IsDBRecordNotFoundError(dbErrors) { + return fmt.Errorf("missing block for hash: %s", addedBlock.Hash) + } + if dbAddedBlock.IsChainBlock { + return fmt.Errorf("block erroneously marked as a chain block: %s", addedBlock.Hash) + } + for _, acceptedBlock := range addedBlock.AcceptedBlocks { var dbAccepedBlock dbmodels.Block dbResult := dbTx. @@ -719,8 +749,8 @@ func updateAddedChainBlocks(dbTx *gorm.DB, addedBlock *btcjson.ChainBlock) error if httpserverutils.IsDBRecordNotFoundError(dbErrors) { return fmt.Errorf("missing block for hash: %s", acceptedBlock.Hash) } - if dbAccepedBlock.IsChainBlock { - return fmt.Errorf("block erroneously marked as a chain block: %s", acceptedBlock.Hash) + if dbAccepedBlock.AcceptingBlockID != nil && *dbAccepedBlock.AcceptingBlockID == dbAddedBlock.ID { + return fmt.Errorf("block %s erroneously marked as accepted by %s", acceptedBlock.Hash, addedBlock.Hash) } transactionIDsIn := make([]string, len(acceptedBlock.AcceptedTxIDs)) @@ -764,13 +794,21 @@ func updateAddedChainBlocks(dbTx *gorm.DB, addedBlock *btcjson.ChainBlock) error } } - dbAccepedBlock.IsChainBlock = true + dbAccepedBlock.AcceptingBlockID = btcjson.Uint64(dbAddedBlock.ID) dbResult = dbTx.Save(&dbAccepedBlock) dbErrors = dbResult.GetErrors() if httpserverutils.HasDBError(dbErrors) { return httpserverutils.NewErrorFromDBErrors("failed to update block: ", dbErrors) } } + + dbAddedBlock.IsChainBlock = true + dbResult = dbTx.Save(&dbAddedBlock) + dbErrors = dbResult.GetErrors() + if httpserverutils.HasDBError(dbErrors) { + return httpserverutils.NewErrorFromDBErrors("failed to update block: ", dbErrors) + } + return nil }