func sanityCheck(hash *common.Hash) (*common.DirBlockInfo, error) { dirBlockInfo := dirBlockInfoMap[hash.String()] if dirBlockInfo == nil { s := fmt.Sprintf("Anchor Error: hash %s does not exist in dirBlockInfoMap.\n", hash.String()) anchorLog.Error(s) return nil, errors.New(s) } if dirBlockInfo.BTCConfirmed { s := fmt.Sprintf("Anchor Warning: hash %s has already been confirmed in btc block chain.\n", hash.String()) anchorLog.Error(s) return nil, errors.New(s) } //The re-anchoring is allowed now. //if !common.NewHash().IsSameAs(dirBlockInfo.BTCTxHash) { //s := fmt.Sprintf("Anchor Warning: hash %s has already been anchored but not confirmed. btc tx hash is %s\n", hash.String(), dirBlockInfo.BTCTxHash.String()) //anchorLog.Error(s) //return nil, errors.New(s) //} if dclient == nil || wclient == nil { s := fmt.Sprintf("\n\n$$$ WARNING: rpc clients and/or wallet are not initiated successfully. No anchoring for now.\n") anchorLog.Warning(s) return nil, errors.New(s) } if len(balances) == 0 { anchorLog.Warning("len(balances) == 0, start rescan UTXO *** ") updateUTXO() } if len(balances) == 0 { s := fmt.Sprintf("\n\n$$$ WARNING: No balance in your wallet. No anchoring for now.\n") anchorLog.Warning(s) return nil, errors.New(s) } return dirBlockInfo, nil }
// Validate Entry Block by merkle root func validateEBlockByMR(cid *common.Hash, mr *common.Hash) error { eb, err := db.FetchEBlockByMR(mr) if err != nil { return err } if eb == nil { return errors.New("Entry block not found in db for merkle root: " + mr.String()) } keyMR, err := eb.KeyMR() if err != nil { return err } if !mr.IsSameAs(keyMR) { return errors.New("Entry block's merkle root does not match with: " + mr.String()) } for _, ebEntry := range eb.Body.EBEntries { if !bytes.Equal(ebEntry.Bytes()[:31], common.ZERO_HASH[:31]) { entry, _ := db.FetchEntryByHash(ebEntry) if entry == nil { return errors.New("Entry not found in db for entry hash: " + ebEntry.String()) } } // Else ... we could do a bit more validation of the minute markers. } return nil }
// SendRawTransactionToBTC is the main function used to anchor factom // dir block hash to bitcoin blockchain func SendRawTransactionToBTC(hash *common.Hash, blockHeight uint32) (*wire.ShaHash, error) { anchorLog.Debug("SendRawTransactionToBTC: hash=", hash.String(), ", dir block height=", blockHeight) //strconv.FormatUint(blockHeight, 10)) dirBlockInfo, err := sanityCheck(hash) if err != nil { return nil, err } return doTransaction(hash, blockHeight, dirBlockInfo) }
// Validate Admin Block by merkle root func validateABlockByMR(mr *common.Hash) error { b, _ := db.FetchABlockByHash(mr) if b == nil { return errors.New("Admin block not found in db for merkle root: " + mr.String()) } return nil }
// Validate Entry Credit Block by merkle root func validateCBlockByMR(mr *common.Hash) error { cb, _ := db.FetchECBlockByHash(mr) if cb == nil { return errors.New("Entry Credit block not found in db for merkle root: " + mr.String()) } return nil }
// Validate FBlock by merkle root func validateFBlockByMR(mr *common.Hash) error { b, _ := db.FetchFBlockByHash(mr) if b == nil { return errors.New("Factoid block not found in db for merkle root: \n" + mr.String()) } // check that we used the KeyMR to store the block... if !bytes.Equal(b.GetKeyMR().Bytes(), mr.Bytes()) { return fmt.Errorf("Factoid block match failure: block %d \n%s\n%s", b.GetDBHeight(), "Key in the database: "+mr.String(), "Hash of the blk found: "+b.GetKeyMR().String()) } return nil }
// FetchDBlockByHash gets an entry by hash from the database. func (db *LevelDb) FetchDBlockByHash(dBlockHash *common.Hash) (*common.DirectoryBlock, error) { var key = []byte{byte(TBL_DB)} key = append(key, dBlockHash.Bytes()...) db.dbLock.RLock() data, _ := db.lDb.Get(key, db.ro) db.dbLock.RUnlock() dBlock := common.NewDBlock() if data == nil { return nil, errors.New("DBlock not found for Hash: " + dBlockHash.String()) } _, err := dBlock.UnmarshalBinaryData(data) if err != nil { return nil, err } dBlock.DBHash = dBlockHash return dBlock, nil }
func sanityCheck(hash *common.Hash) (*common.DirBlockInfo, error) { dirBlockInfo := dirBlockInfoMap[hash.String()] if dirBlockInfo == nil { s := fmt.Sprintf("Anchor Error: hash %s does not exist in dirBlockInfoMap.\n", hash.String()) anchorLog.Error(s) return nil, errors.New(s) } if dirBlockInfo.BTCConfirmed { s := fmt.Sprintf("Anchor Warning: hash %s has already been confirmed in btc block chain.\n", hash.String()) anchorLog.Error(s) return nil, errors.New(s) } if !common.NewHash().IsSameAs(dirBlockInfo.BTCTxHash) { s := fmt.Sprintf("Anchor Warning: hash %s has already been anchored but not confirmed. btc tx hash is %s\n", hash.String(), dirBlockInfo.BTCTxHash.String()) anchorLog.Error(s) return nil, errors.New(s) } if dclient == nil || wclient == nil || balances == nil { s := fmt.Sprintf("\n\n$$$ WARNING: rpc clients and/or wallet are not initiated successfully. No anchoring for now.\n") anchorLog.Warning(s) return nil, errors.New(s) } return dirBlockInfo, nil }
func getPrePaidChainKey(entryHash *common.Hash, chainIDHash *common.Hash) string { return chainIDHash.String() + entryHash.String() }