// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. func (msg *MsgAcknowledgement) BtcDecode(r io.Reader, pver uint32) error { //err := readElements(r, &msg.Height, msg.ChainID, &msg.Index, &msg.Type, msg.Affirmation, &msg.SerialHash, &msg.Signature) newData, err := ioutil.ReadAll(r) if err != nil { return fmt.Errorf("MsgAcknowledgement.BtcDecode reader is invalid") } if len(newData) != 169 { return fmt.Errorf("MsgAcknowledgement.BtcDecode reader does not have right length: ", len(newData)) } msg.Height, newData = binary.BigEndian.Uint32(newData[0:4]), newData[4:] msg.ChainID = common.NewHash() newData, _ = msg.ChainID.UnmarshalBinaryData(newData) msg.Index, newData = binary.BigEndian.Uint32(newData[0:4]), newData[4:] msg.Type, newData = newData[0], newData[1:] msg.Affirmation, _ = NewShaHash(newData[0:32]) newData = newData[32:] copy(msg.SerialHash[:], newData[0:32]) newData = newData[32:] copy(msg.Signature[:], newData[0:63]) return 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 { 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 }
func atoh(a string) (*common.Hash, error) { h := common.NewHash() p, err := hex.DecodeString(a) if err != nil { return h, err } h.SetBytes(p) return h, nil }
func TestEBlockMarshal(t *testing.T) { t.Logf("\n---\nTestEBlockMarshal\n---\n") // build an EBlock for testing eb := common.NewEBlock() eb.Header.ChainID.SetBytes(byteof(0x11)) eb.Header.BodyMR.SetBytes(byteof(0x22)) eb.Header.PrevKeyMR.SetBytes(byteof(0x33)) eb.Header.PrevLedgerKeyMR.SetBytes(byteof(0x44)) eb.Header.EBSequence = 5 eb.Header.EBHeight = 6 eb.Header.EntryCount = 7 ha := common.NewHash() ha.SetBytes(byteof(0xaa)) hb := common.NewHash() hb.SetBytes(byteof(0xbb)) eb.Body.EBEntries = append(eb.Body.EBEntries, ha) eb.AddEndOfMinuteMarker(0xcc) eb.Body.EBEntries = append(eb.Body.EBEntries, hb) t.Log(eb) p, err := eb.MarshalBinary() if err != nil { t.Error(err) } eb2 := common.NewEBlock() if err := eb2.UnmarshalBinary(p); err != nil { t.Error(err) } t.Log(eb2) p2, err := eb2.MarshalBinary() if err != nil { t.Error(err) } if string(p) != string(p2) { t.Logf("eb1 = %x\n", p) t.Logf("eb2 = %x\n", p2) t.Fail() } }
// Sign the directory block func SignDirectoryBlock() error { // Only Servers can write the anchor to Bitcoin network if nodeMode == common.SERVER_NODE && dchain.NextDBHeight > 0 { // get the previous directory block from db dbBlock, _ := db.FetchDBlockByHeight(dchain.NextDBHeight - 1) dbHeaderBytes, _ := dbBlock.Header.MarshalBinary() identityChainID := common.NewHash() // 0 ID for milestone 1 sig := serverPrivKey.Sign(dbHeaderBytes) achain.NextBlock.AddABEntry(common.NewDBSignatureEntry(identityChainID, sig)) } return nil }
// NewMsgAcknowledgement returns a new bitcoin ping message that conforms to the Message // interface. See MsgAcknowledgement for details. func NewMsgAcknowledgement(height uint32, index uint32, affirm *ShaHash, ackType byte) *MsgAcknowledgement { if affirm == nil { affirm = new(ShaHash) } return &MsgAcknowledgement{ Height: height, ChainID: common.NewHash(), //TODO: get the correct chain id from processor Index: index, Affirmation: affirm, Type: ackType, } }
// 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 }
// 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 }
// FetchDBHashByHeight gets a dBlockHash from the database. func (db *LevelDb) FetchDBHashByHeight(dBlockHeight uint32) (*common.Hash, error) { var key = []byte{byte(TBL_DB_NUM)} var buf bytes.Buffer binary.Write(&buf, binary.BigEndian, dBlockHeight) key = append(key, buf.Bytes()...) db.dbLock.RLock() data, err := db.lDb.Get(key, db.ro) db.dbLock.RUnlock() if err != nil { return nil, err } dBlockHash := common.NewHash() _, err = dBlockHash.UnmarshalBinaryData(data) if err != nil { return nil, err } return dBlockHash, nil }
func buildIncreaseBalance(msg *wire.MsgFactoidTX) { t := msg.Transaction for i, ecout := range t.GetECOutputs() { ib := common.NewIncreaseBalance() pub := new([32]byte) copy(pub[:], ecout.GetAddress().Bytes()) ib.ECPubKey = pub th := common.NewHash() th.SetBytes(t.GetHash().Bytes()) ib.TXID = th cred := int32(ecout.GetAmount() / uint64(FactoshisPerCredit)) ib.NumEC = uint64(cred) ib.Index = uint64(i) ecchain.NextBlock.AddEntry(ib) } }
// 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 }
// 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 }
// FetchABlockByHeight gets an admin block by hash from the database. func (db *LevelDb) FetchABlockByHeight(height uint32) (aBlock *common.AdminBlock, err error) { var key = []byte{byte(TBL_AB_NUM)} var buf bytes.Buffer binary.Write(&buf, binary.BigEndian, height) key = append(key, common.ADMIN_CHAINID...) key = append(key, buf.Bytes()...) var data []byte db.dbLock.RLock() data, err = db.lDb.Get(key, db.ro) db.dbLock.RUnlock() if err != nil { return nil, err } aBlockHash := common.NewHash() _, err = aBlockHash.UnmarshalBinaryData(data) if err != nil { return nil, err } return db.FetchABlockByHash(aBlockHash) }
// FetchECBlockByHeight gets an Entry Credit block by hash from the database. func (db *LevelDb) FetchECBlockByHeight(height uint32) (ecBlock *common.ECBlock, err error) { var key = []byte{byte(TBL_CB_NUM)} var buf bytes.Buffer binary.Write(&buf, binary.BigEndian, height) key = append(key, common.EC_CHAINID...) key = append(key, buf.Bytes()...) //fmt.Println("FetchECBlockByHeight: key=", hex.EncodeToString(key)) var data []byte db.dbLock.RLock() data, err = db.lDb.Get(key, db.ro) db.dbLock.RUnlock() if err != nil { return nil, err } ecBlockHash := common.NewHash() _, err = ecBlockHash.UnmarshalBinaryData(data) if err != nil { return nil, err } //fmt.Println("FetchECBlockByHeight: data=", hex.EncodeToString(data), ", hash=", ecBlockHash) return db.FetchECBlockByHash(ecBlockHash) }
// Initialize the processor func initProcessor() { wire.Init() // init server private key or pub key initServerKeys() // init mem pools fMemPool = new(ftmMemPool) fMemPool.init_ftmMemPool() // init wire.FChainID wire.FChainID = common.NewHash() wire.FChainID.SetBytes(common.FACTOID_CHAINID) FactoshisPerCredit = 666666 // .001 / .15 * 100000000 (assuming a Factoid is .15 cents, entry credit = .1 cents // init Directory Block Chain initDChain() procLog.Info("Loaded ", dchain.NextDBHeight, " Directory blocks for chain: "+dchain.ChainID.String()) // init Entry Credit Chain initECChain() procLog.Info("Loaded ", ecchain.NextBlockHeight, " Entry Credit blocks for chain: "+ecchain.ChainID.String()) // init Admin Chain initAChain() procLog.Info("Loaded ", achain.NextBlockHeight, " Admin blocks for chain: "+achain.ChainID.String()) initFctChain() //common.FactoidState.LoadState() procLog.Info("Loaded ", fchain.NextBlockHeight, " factoid blocks for chain: "+fchain.ChainID.String()) //Init anchor for server if nodeMode == common.SERVER_NODE { anchor.InitAnchor(db, inMsgQueue, serverPrivKey) } // build the Genesis blocks if the current height is 0 if dchain.NextDBHeight == 0 && nodeMode == common.SERVER_NODE { buildGenesisBlocks() } else { // To be improved in milestone 2 SignDirectoryBlock() } // init process list manager initProcessListMgr() // init Entry Chains initEChains() for _, chain := range chainIDMap { initEChainFromDB(chain) procLog.Info("Loaded ", chain.NextBlockHeight, " blocks for chain: "+chain.ChainID.String()) } // Validate all dir blocks err := validateDChain(dchain) if err != nil { if nodeMode == common.SERVER_NODE { panic("Error found in validating directory blocks: " + err.Error()) } else { dchain.IsValidated = false } } }
chainIDMapBackup map[string]*common.EChain //previous block bakcup - ChainIDMap with chainID string([32]byte) as key eCreditMapBackup map[string]int32 // backup from previous block - eCreditMap with public key string([32]byte) as key, credit balance as value fMemPool *ftmMemPool plMgr *consensus.ProcessListMgr //Server Private key and Public key for milestone 1 serverPrivKey common.PrivateKey serverPubKey common.PublicKey FactoshisPerCredit uint64 // .001 / .15 * 100000000 (assuming a Factoid is .15 cents, entry credit = .1 cents FactomdUser string FactomdPass string zeroHash = common.NewHash() ) var ( directoryBlockInSeconds int dataStorePath string ldbpath string nodeMode string devNet bool serverPrivKeyHex string serverIndex = common.NewServerIndexNumber() ) // Get the configurations func LoadConfigurations(cfg *util.FactomdConfig) {