Example #1
0
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
}
Example #2
0
// HaveBlockInDB returns whether or not the chain instance has the block represented
// by the passed hash.  This includes checking the various places a block can
// be like part of the main chain, on a side chain, or in the orphan pool.
//
// This function is NOT safe for concurrent access.
func HaveBlockInDB(hash *common.Hash) (bool, error) {
	//util.Trace(spew.Sdump(hash))
	blk, _ := db.FetchDBlockByHash(hash)
	if blk != nil {
		fmt.Println("HaveBlockInDB. true. ", hash.BTCString())
		return true, nil
	}
	return false, nil

	/*
		if hash == nil || dchain.Blocks == nil || len(dchain.Blocks) == 0 {
			return false, nil
		}

		// double check the block ids
		for i := 0; i < len(dchain.Blocks); i = i + 1 {
			if dchain.Blocks[i] == nil {
				continue
			}
			if dchain.Blocks[i].DBHash == nil {
				dchain.Blocks[i].DBHash, _ = common.CreateHash(dchain.Blocks[i])
			}
			if dchain.Blocks[i].DBHash.IsSameAs(hash) {
				return true, nil
			}
		}

		return false, nil */
}
Example #3
0
// 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)
}
Example #4
0
// UpdateBlockHeightCache updates the dir block height cache in db
func (db *LevelDb) UpdateBlockHeightCache(dirBlkHeigh uint32, dirBlkHash *common.Hash) error {

	// Update DirBlock Height cache
	db.lastDirBlkHeight = int64(dirBlkHeigh)
	db.lastDirBlkSha, _ = wire.NewShaHash(dirBlkHash.Bytes())
	db.lastDirBlkShaCached = true
	return nil
}
Example #5
0
// 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
}
Example #6
0
// 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
}
Example #7
0
// FetchEntry gets an entry by hash from the database.
func (db *LevelDb) FetchEntryByHash(entrySha *common.Hash) (entry *common.Entry, err error) {
	var key []byte = []byte{byte(TBL_ENTRY)}
	key = append(key, entrySha.Bytes()...)
	db.dbLock.RLock()
	data, err := db.lDb.Get(key, db.ro)
	db.dbLock.RUnlock()

	if data != nil {
		entry = new(common.Entry)
		_, err := entry.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}
	return entry, nil
}
Example #8
0
// FetchECBlockByHash gets an Entry Credit block by hash from the database.
func (db *LevelDb) FetchECBlockByHash(ecBlockHash *common.Hash) (ecBlock *common.ECBlock, err error) {
	db.dbLock.Lock()
	defer db.dbLock.Unlock()

	var key []byte = []byte{byte(TBL_CB)}
	key = append(key, ecBlockHash.Bytes()...)
	data, err := db.lDb.Get(key, db.ro)

	if data != nil {
		ecBlock = common.NewECBlock()
		_, err := ecBlock.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}
	return ecBlock, nil
}
Example #9
0
// FetchFBlockByHash gets an factoid block by hash from the database.
func (db *LevelDb) FetchFBlockByHash(hash *common.Hash) (FBlock block.IFBlock, err error) {
	db.dbLock.Lock()
	defer db.dbLock.Unlock()

	var key []byte = []byte{byte(TBL_SC)}
	key = append(key, hash.Bytes()...)
	data, err := db.lDb.Get(key, db.ro)

	if data != nil {
		FBlock = new(block.FBlock)
		_, err := FBlock.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}
	return FBlock, nil
}
Example #10
0
// FetchABlockByHash gets an admin block by hash from the database.
func (db *LevelDb) FetchABlockByHash(aBlockHash *common.Hash) (aBlock *common.AdminBlock, err error) {
	var key = []byte{byte(TBL_AB)}
	key = append(key, aBlockHash.Bytes()...)
	var data []byte
	db.dbLock.RLock()
	data, err = db.lDb.Get(key, db.ro)
	db.dbLock.RUnlock()

	if data != nil {
		aBlock = new(common.AdminBlock)
		_, err := aBlock.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}
	return aBlock, nil
}
Example #11
0
// FetchDirBlockInfoByHash gets an DirBlockInfo obj
func (db *LevelDb) FetchDirBlockInfoByHash(dbHash *common.Hash) (dirBlockInfo *common.DirBlockInfo, err error) {
	db.dbLock.Lock()
	defer db.dbLock.Unlock()

	var key []byte = []byte{byte(TBL_DB_INFO)}
	key = append(key, dbHash.Bytes()...)
	data, err := db.lDb.Get(key, db.ro)

	if data != nil {
		dirBlockInfo = new(common.DirBlockInfo)
		_, err := dirBlockInfo.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}

	return dirBlockInfo, nil
}
Example #12
0
// FetchEBHashByMR gets an entry by hash from the database.
func (db *LevelDb) FetchEBHashByMR(eBMR *common.Hash) (*common.Hash, error) {
	var key []byte = []byte{byte(TBL_EB_MR)}
	key = append(key, eBMR.Bytes()...)
	db.dbLock.RLock()
	data, err := db.lDb.Get(key, db.ro)
	db.dbLock.RUnlock()
	if err != nil {
		return nil, err
	}

	eBlockHash := common.NewHash()
	_, err = eBlockHash.UnmarshalBinaryData(data)
	if err != nil {
		return nil, err
	}

	return eBlockHash, nil
}
Example #13
0
// FetchDBHashByMR gets a DBHash by MR from the database.
func (db *LevelDb) FetchDBHashByMR(dBMR *common.Hash) (*common.Hash, error) {
	db.dbLock.Lock()
	defer db.dbLock.Unlock()

	var key []byte = []byte{byte(TBL_DB_MR)}
	key = append(key, dBMR.Bytes()...)
	data, err := db.lDb.Get(key, db.ro)
	if err != nil {
		return nil, err
	}

	dBlockHash := common.NewHash()
	_, err = dBlockHash.UnmarshalBinaryData(data)
	if err != nil {
		return nil, err
	}

	return dBlockHash, nil
}
Example #14
0
// FetchEntryBlock gets an entry by hash from the database.
func (db *LevelDb) FetchEBlockByHash(eBlockHash *common.Hash) (*common.EBlock, error) {
	var key []byte = []byte{byte(TBL_EB)}
	key = append(key, eBlockHash.Bytes()...)
	db.dbLock.RLock()
	data, err := db.lDb.Get(key, db.ro)
	db.dbLock.RUnlock()
	if err != nil {
		return nil, err
	}

	eBlock := common.NewEBlock()
	if data != nil {
		_, err := eBlock.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}
	return eBlock, nil
}
Example #15
0
// 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
}
Example #16
0
// FetchChainByHash gets a chain by chainID
func (db *LevelDb) FetchChainByHash(chainID *common.Hash) (*common.EChain, error) {
	var key []byte = []byte{byte(TBL_CHAIN_HASH)}
	key = append(key, chainID.Bytes()...)
	db.dbLock.RLock()
	data, err := db.lDb.Get(key, db.ro)
	db.dbLock.RUnlock()
	if err != nil {
		return nil, err
	}

	chain := common.NewEChain()
	if data != nil {
		_, err := chain.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}
	return chain, nil
}
Example #17
0
func doTransaction(hash *common.Hash, blockHeight uint64, dirBlockInfo *common.DirBlockInfo) (*wire.ShaHash, error) {
	b := balances[0]
	i := copy(balances, balances[1:])
	balances[i] = b

	msgtx, err := createRawTransaction(b, hash.Bytes(), blockHeight)
	if err != nil {
		return nil, fmt.Errorf("cannot create Raw Transaction: %s", err)
	}

	shaHash, err := sendRawTransaction(msgtx)
	if err != nil {
		return nil, fmt.Errorf("cannot send Raw Transaction: %s", err)
	}
	// for test purpose
	if dirBlockInfo != nil {
		dirBlockInfo.BTCTxHash = toHash(shaHash)
	}
	return shaHash, nil
}
Example #18
0
func doTransaction(hash *common.Hash, blockHeight uint32, dirBlockInfo *common.DirBlockInfo) (*wire.ShaHash, error) {
	b := balances[0]
	balances = balances[1:]
	anchorLog.Info("new balances.len=", len(balances))

	msgtx, err := createRawTransaction(b, hash.Bytes(), blockHeight)
	if err != nil {
		return nil, fmt.Errorf("cannot create Raw Transaction: %s", err)
	}

	shaHash, err := sendRawTransaction(msgtx)
	if err != nil {
		return nil, fmt.Errorf("cannot send Raw Transaction: %s", err)
	}

	if dirBlockInfo != nil {
		dirBlockInfo.BTCTxHash = toHash(shaHash)
	}

	return shaHash, nil
}
Example #19
0
// FetchAllEBlocksByChain gets all of the blocks by chain id
func (db *LevelDb) FetchAllEBlocksByChain(chainID *common.Hash) (eBlocks *[]common.EBlock, err error) {
	db.dbLock.RLock()
	defer db.dbLock.RUnlock()

	var fromkey []byte = []byte{byte(TBL_EB_CHAIN_NUM)} // Table Name (1 bytes)
	fromkey = append(fromkey, chainID.Bytes()...)       // Chain Type (32 bytes)
	var tokey []byte = addOneToByteArray(fromkey)

	eBlockSlice := make([]common.EBlock, 0, 10)

	iter := db.lDb.NewIterator(&util.Range{Start: fromkey, Limit: tokey}, db.ro)

	for iter.Next() {
		eBlockHash := common.NewHash()
		_, err := eBlockHash.UnmarshalBinaryData(iter.Value())
		if err != nil {
			return nil, err
		}

		var key []byte = []byte{byte(TBL_EB)}
		key = append(key, eBlockHash.Bytes()...)
		data, err := db.lDb.Get(key, db.ro)
		if err != nil {
			return nil, err
		}

		eBlock := common.NewEBlock()
		if data != nil {
			_, err := eBlock.UnmarshalBinaryData(data)
			if err != nil {
				return nil, err
			}
			eBlockSlice = append(eBlockSlice, *eBlock)
		}
	}
	iter.Release()
	err = iter.Error()

	return &eBlockSlice, nil
}
Example #20
0
// 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
}
Example #21
0
// FetchECBlockByHash gets an Entry Credit block by hash from the database.
func (db *LevelDb) FetchECBlockByHash(ecBlockHash *common.Hash) (ecBlock *common.ECBlock, err error) {
	var key = []byte{byte(TBL_CB)}
	key = append(key, ecBlockHash.Bytes()...)
	var data []byte
	db.dbLock.RLock()
	data, err = db.lDb.Get(key, db.ro)
	db.dbLock.RUnlock()
	if err != nil {
		return nil, err
	}
	//fmt.Println("FetchECBlockByHash: key=", hex.EncodeToString(key), ", data=", string(data))

	if data != nil {
		ecBlock = common.NewECBlock()
		_, err := ecBlock.UnmarshalBinaryData(data)
		if err != nil {
			return nil, err
		}
	}
	//fmt.Println("FetchECBlockByHash: ecBlock=", spew.Sdump(ecBlock))
	return ecBlock, nil
}
Example #22
0
// FetchHeadMRByChainID gets a MR of the highest block from the database.
func (db *LevelDb) FetchHeadMRByChainID(chainID *common.Hash) (blkMR *common.Hash, err error) {
	if chainID == nil {
		return nil, nil
	}

	var key = []byte{byte(TBL_CHAIN_HEAD)}
	key = append(key, chainID.Bytes()...)
	db.dbLock.RLock()
	data, err := db.lDb.Get(key, db.ro)
	db.dbLock.RUnlock()
	if err != nil {
		return nil, err
	}

	blkMR = common.NewHash()
	_, err = blkMR.UnmarshalBinaryData(data)
	if err != nil {
		return nil, err
	}

	return blkMR, nil
}
Example #23
0
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
}
Example #24
0
// 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
}
Example #25
0
// Convert wire.ShaHash into factom.common.Hash
func (hash *ShaHash) ToFactomHash() *common.Hash {
	commonhash := new(common.Hash)
	commonhash.SetBytes(hash.Bytes())

	return commonhash
}
Example #26
0
func toHash(txHash *wire.ShaHash) *common.Hash {
	h := new(common.Hash)
	h.SetBytes(txHash.Bytes())
	return h
}
Example #27
0
// Convert factom.common.hash into a wire.ShaHash
func FactomHashToShaHash(ftmHash *common.Hash) *ShaHash {

	h, _ := NewShaHash(ftmHash.Bytes())
	return h

}
Example #28
0
func getPrePaidChainKey(entryHash *common.Hash, chainIDHash *common.Hash) string {
	return chainIDHash.String() + entryHash.String()
}
Example #29
0
// pushDirBlockMsg sends a dir block message for the provided block hash to the
// connected peer.  An error is returned if the block hash is not known.
func (p *peer) pushDirBlockMsg(sha *wire.ShaHash, doneChan, waitChan chan struct{}) error {
	commonhash := new(common.Hash)
	commonhash.SetBytes(sha.Bytes())
	blk, err := db.FetchDBlockByHash(commonhash)

	if err != nil {
		peerLog.Tracef("Unable to fetch requested dir block sha %v: %v",
			sha, err)

		if doneChan != nil {
			doneChan <- struct{}{}
		}
		return err
	}

	// Once we have fetched data wait for any previous operation to finish.
	if waitChan != nil {
		<-waitChan
	}

	// We only send the channel for this message if we aren't sending(sha)
	// an inv straight after.
	var dc chan struct{}
	sendInv := p.continueHash != nil && p.continueHash.IsEqual(sha)
	if !sendInv {
		dc = doneChan
	}
	msg := wire.NewMsgDirBlock()
	msg.DBlk = blk
	p.QueueMessage(msg, dc) //blk.MsgBlock(), dc)

	// When the peer requests the final block that was advertised in
	// response to a getblocks message which requested more blocks than
	// would fit into a single message, send it a new inventory message
	// to trigger it to issue another getblocks message for the next
	// batch of inventory.
	if p.continueHash != nil && p.continueHash.IsEqual(sha) {
		peerLog.Debug("continueHash: " + spew.Sdump(sha))
		// Sleep for 5 seconds for the peer to catch up
		time.Sleep(5 * time.Second)

		//
		// Note: Rather than the latest block height, we should pass
		// the last block height of this batch of wire.MaxBlockLocatorsPerMsg
		// to signal this is the end of the batch and
		// to trigger a client to send a new GetDirBlocks message
		//
		//hash, _, err := db.FetchBlockHeightCache()
		//if err == nil {
		invMsg := wire.NewMsgDirInvSizeHint(1)
		iv := wire.NewInvVect(wire.InvTypeFactomDirBlock, sha) //hash)
		invMsg.AddInvVect(iv)
		p.QueueMessage(invMsg, doneChan)
		p.continueHash = nil
		//} else if doneChan != nil {
		if doneChan != nil {
			doneChan <- struct{}{}
		}
	}
	return nil
}