[NOD-383] Fix updateAddedChainBlocks and updateRemovedChainHashes to update IsChainBlock and AcceptingBlockID appropriately

This commit is contained in:
Ori Newman 2019-10-31 15:36:46 +02:00 committed by Mike Zak
parent 0e278ca22b
commit f7fbfbf5c4

View File

@ -314,6 +314,11 @@ func insertBlock(dbTx *gorm.DB, rawBlock btcjson.GetBlockVerboseResult) (*dbmode
IsChainBlock: false, // This must be false for updateSelectedParentChain to work properly IsChainBlock: false, // This must be false for updateSelectedParentChain to work properly
Mass: rawBlock.Mass, Mass: rawBlock.Mass,
} }
// Set genesis block as the initial chain block
if len(rawBlock.ParentHashes) == 0 {
dbBlock.IsChainBlock = true
}
dbResult := dbTx.Create(&dbBlock) dbResult := dbTx.Create(&dbBlock)
dbErrors := dbResult.GetErrors() dbErrors := dbResult.GetErrors()
if httpserverutils.HasDBError(dbErrors) { 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 dbBlock.IsChainBlock = false
dbResult = dbTx.Save(&dbBlock) dbResult = dbTx.Save(&dbBlock)
dbErrors = dbResult.GetErrors() dbErrors = dbResult.GetErrors()
@ -707,6 +722,21 @@ func updateRemovedChainHashes(dbTx *gorm.DB, removedHash string) error {
// * The block is set IsChainBlock = true // * The block is set IsChainBlock = true
// This function will return an error if any of the above are in an unexpected state // 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 { 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 { for _, acceptedBlock := range addedBlock.AcceptedBlocks {
var dbAccepedBlock dbmodels.Block var dbAccepedBlock dbmodels.Block
dbResult := dbTx. dbResult := dbTx.
@ -719,8 +749,8 @@ func updateAddedChainBlocks(dbTx *gorm.DB, addedBlock *btcjson.ChainBlock) error
if httpserverutils.IsDBRecordNotFoundError(dbErrors) { if httpserverutils.IsDBRecordNotFoundError(dbErrors) {
return fmt.Errorf("missing block for hash: %s", acceptedBlock.Hash) return fmt.Errorf("missing block for hash: %s", acceptedBlock.Hash)
} }
if dbAccepedBlock.IsChainBlock { if dbAccepedBlock.AcceptingBlockID != nil && *dbAccepedBlock.AcceptingBlockID == dbAddedBlock.ID {
return fmt.Errorf("block erroneously marked as a chain block: %s", acceptedBlock.Hash) return fmt.Errorf("block %s erroneously marked as accepted by %s", acceptedBlock.Hash, addedBlock.Hash)
} }
transactionIDsIn := make([]string, len(acceptedBlock.AcceptedTxIDs)) 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) dbResult = dbTx.Save(&dbAccepedBlock)
dbErrors = dbResult.GetErrors() dbErrors = dbResult.GetErrors()
if httpserverutils.HasDBError(dbErrors) { if httpserverutils.HasDBError(dbErrors) {
return httpserverutils.NewErrorFromDBErrors("failed to update block: ", 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 return nil
} }