示例#1
0
func registerFactomIdentity(entry interfaces.IEBEntry, chainID interfaces.IHash, height uint32, st *State) error {
	extIDs := entry.ExternalIDs()
	if len(extIDs) == 0 {
		return errors.New("Identity Error Register Identity: Invalid external ID length")
	}
	if bytes.Compare([]byte{0x00}, extIDs[0]) != 0 || // Version
		!CheckExternalIDsLength(extIDs, []int{1, 24, 32, 33, 64}) { // Signiture
		return errors.New("Identity Error Register Identity: Invalid external ID length")
	}

	// find the Identity index from the chain id in the external id.  add this chainID as the management id
	idChain := primitives.NewHash(extIDs[2])
	IdentityIndex := st.isIdentityChain(idChain)
	if IdentityIndex == -1 {
		IdentityIndex = st.CreateBlankFactomIdentity(idChain)
	}

	sigmsg, err := AppendExtIDs(extIDs, 0, 2)
	if err != nil {
		return err
	} else {
		// Verify Signature
		idKey := st.Identities[IdentityIndex].Key1
		if CheckSig(idKey, extIDs[3][1:33], sigmsg, extIDs[4]) {
			st.Identities[IdentityIndex].ManagementRegistered = height
		} else {
			return errors.New("New Management Chain Register for identity [" + chainID.String()[:10] + "] is invalid. Bad signiture")
		}

	}
	st.Identities[IdentityIndex].IdentityRegistered = height

	return nil
}
示例#2
0
func addServerSigningKey(chainID interfaces.IHash, key interfaces.IHash, height uint32, st *State) {
	AuthorityIndex := st.AddAuthorityFromChainID(chainID)
	if st.IdentityChainID.IsSameAs(chainID) && len(st.serverPendingPrivKeys) > 0 {
		for i, pubKey := range st.serverPendingPubKeys {
			pubData, err := pubKey.MarshalBinary()
			if err != nil {
				break
			}
			if bytes.Compare(pubData, key.Bytes()) == 0 {
				st.serverPrivKey = st.serverPendingPrivKeys[i]
				st.serverPubKey = st.serverPendingPubKeys[i]
				if len(st.serverPendingPrivKeys) > i+1 {
					st.serverPendingPrivKeys = append(st.serverPendingPrivKeys[:i], st.serverPendingPrivKeys[i+1:]...)
					st.serverPendingPubKeys = append(st.serverPendingPubKeys[:i], st.serverPendingPubKeys[i+1:]...)
				} else {
					st.serverPendingPrivKeys = st.serverPendingPrivKeys[:i]
					st.serverPendingPubKeys = st.serverPendingPubKeys[:i]
				}
				break
			}
		}
	}
	// Add Key History
	st.Authorities[AuthorityIndex].KeyHistory = append(st.Authorities[AuthorityIndex].KeyHistory, struct {
		ActiveDBHeight uint32
		SigningKey     primitives.PublicKey
	}{height, st.Authorities[AuthorityIndex].SigningKey})
	// Replace Active Key
	st.Authorities[AuthorityIndex].SigningKey = primitives.PubKeyFromString(key.String())
}
示例#3
0
func (d *LastDirectoryBlockTransactions) ContainsTrans(txid interfaces.IHash) bool {
	for _, trans := range d.FactoidTransactions {
		if trans.TxID == txid.String() {
			return true
		}
	}
	return false
}
示例#4
0
func (d *LastDirectoryBlockTransactions) ContainsEntry(hash interfaces.IHash) bool {
	for _, entry := range d.Entries {
		if entry.Hash == hash.String() {
			return true
		}
	}
	return false
}
示例#5
0
// SendRawTransactionToBTC is the main function used to anchor factom
// dir block hash to bitcoin blockchain
func (a *Anchor) SendRawTransactionToBTC(hash interfaces.IHash, blockHeight uint32) (*wire.ShaHash, error) {
	anchorLog.Debug("SendRawTransactionToBTC: hash=", hash.String(), ", dir block height=", blockHeight) //strconv.FormatUint(blockHeight, 10))
	dirBlockInfo, err := a.sanityCheck(hash)
	if err != nil {
		return nil, err
	}
	return a.doTransaction(hash, blockHeight, dirBlockInfo)
}
示例#6
0
func TestChain(t *testing.T) {
	head, err := GetDBlockHead()
	if err != nil {
		t.Errorf("%v", err)
	}
	dHead, err := GetDBlock(head)
	if err != nil {
		t.Errorf("%v", err)
	}
	var h interfaces.IHash

	for _, e := range dHead.GetDBEntries() {
		if e.GetChainID().String() == "000000000000000000000000000000000000000000000000000000000000000a" {
			h = e.GetKeyMR()
			break
		}
	}

	for {
		if h.String() == "0000000000000000000000000000000000000000000000000000000000000000" {
			break
		}
		aBlock, err := GetABlock(h.String())
		if err != nil {
			t.Errorf("Error fetching %v - %v", h.String(), err)
			t.FailNow()
		}
		h = aBlock.GetHeader().GetPrevBackRefHash()
		t.Logf("Fetched ABlock #%v", aBlock.GetDBHeight())
	}

}
示例#7
0
func (a *Anchor) sanityCheck(hash interfaces.IHash) (*dbInfo.DirBlockInfo, error) {
	index := sort.Search(len(a.dirBlockInfoSlice), func(i int) bool {
		return a.dirBlockInfoSlice[i].GetDBMerkleRoot().IsSameAs(hash)
	})
	var dirBlockInfo *dbInfo.DirBlockInfo
	ok := false
	if index < len(a.dirBlockInfoSlice) {
		dirBlockInfo, ok = a.dirBlockInfoSlice[index].(*dbInfo.DirBlockInfo)
	}
	if dirBlockInfo == nil || !ok {
		s := fmt.Sprintf("Anchor Error: hash %s does not exist in dirBlockInfoSlice.\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 a.dclient == nil || a.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(a.balances) == 0 {
		anchorLog.Warning("len(balances) == 0, start rescan UTXO *** ")
		a.updateUTXO(a.minBalance)
	}
	if len(a.balances) == 0 {
		anchorLog.Warning("len(balances) == 0, start rescan UTXO *** ")
		a.updateUTXO(a.fee)
	}
	if len(a.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
}
示例#8
0
func CreateReceipt(dbo interfaces.DBOverlay, entryID interfaces.IHash) (*Receipt, error) {
	receipt := new(Receipt)
	receipt.Entry = new(JSON)
	receipt.Entry.Key = entryID.String()

	//EBlock

	hash, err := dbo.FetchIncludedIn(entryID)
	if err != nil {
		return nil, err
	}

	if hash == nil {
		return nil, fmt.Errorf("Block containing entry not found")
	}

	eBlock, err := dbo.FetchEBlock(hash)
	if err != nil {
		return nil, err
	}

	if eBlock == nil {
		return nil, fmt.Errorf("EBlock not found")
	}

	hash = eBlock.DatabasePrimaryIndex()
	receipt.EntryBlockKeyMR = hash.(*primitives.Hash)

	entries := eBlock.GetEntryHashes()
	//fmt.Printf("eBlock entries - %v\n\n", entries)
	branch := primitives.BuildMerkleBranchForEntryHash(entries, entryID, true)
	blockNode := new(primitives.MerkleNode)
	left, err := eBlock.HeaderHash()
	if err != nil {
		return nil, err
	}
	blockNode.Left = left.(*primitives.Hash)
	blockNode.Right = eBlock.BodyKeyMR().(*primitives.Hash)
	blockNode.Top = hash.(*primitives.Hash)
	//fmt.Printf("eBlock blockNode - %v\n\n", blockNode)
	branch = append(branch, blockNode)
	receipt.MerkleBranch = append(receipt.MerkleBranch, branch...)

	//str, _ := eBlock.JSONString()
	//fmt.Printf("eBlock - %v\n\n", str)

	//DBlock

	hash, err = dbo.FetchIncludedIn(hash)
	if err != nil {
		return nil, err
	}

	if hash == nil {
		return nil, fmt.Errorf("Block containing EBlock not found")
	}

	dBlock, err := dbo.FetchDBlock(hash)
	if err != nil {
		return nil, err
	}

	if dBlock == nil {
		return nil, fmt.Errorf("DBlock not found")
	}

	//str, _ = dBlock.JSONString()
	//fmt.Printf("dBlock - %v\n\n", str)

	entries = dBlock.GetEntryHashesForBranch()
	//fmt.Printf("dBlock entries - %v\n\n", entries)

	//merkleTree := primitives.BuildMerkleTreeStore(entries)
	//fmt.Printf("dBlock merkleTree - %v\n\n", merkleTree)

	branch = primitives.BuildMerkleBranchForEntryHash(entries, receipt.EntryBlockKeyMR, true)
	blockNode = new(primitives.MerkleNode)
	left, err = dBlock.HeaderHash()
	if err != nil {
		return nil, err
	}
	blockNode.Left = left.(*primitives.Hash)
	blockNode.Right = dBlock.BodyKeyMR().(*primitives.Hash)
	blockNode.Top = hash.(*primitives.Hash)
	//fmt.Printf("dBlock blockNode - %v\n\n", blockNode)
	branch = append(branch, blockNode)
	receipt.MerkleBranch = append(receipt.MerkleBranch, branch...)

	//DirBlockInfo

	hash = dBlock.DatabasePrimaryIndex()
	receipt.DirectoryBlockKeyMR = hash.(*primitives.Hash)

	dirBlockInfo, err := dbo.FetchDirBlockInfoByKeyMR(hash)
	if err != nil {
		return nil, err
	}

	if dirBlockInfo != nil {
		dbi := dirBlockInfo.(*dbInfo.DirBlockInfo)

		receipt.BitcoinTransactionHash = dbi.BTCTxHash.(*primitives.Hash)
		receipt.BitcoinBlockHash = dbi.BTCBlockHash.(*primitives.Hash)
	}

	return receipt, nil
}
示例#9
0
// Called by AddServer Message
func ProcessIdentityToAdminBlock(st *State, chainID interfaces.IHash, servertype int) bool {
	var matryoshkaHash interfaces.IHash
	var blockSigningKey [32]byte
	var btcKey [20]byte
	var btcKeyLevel byte
	var btcKeyType byte

	err := st.AddIdentityFromChainID(chainID)
	if err != nil {
		log.Println(err.Error())
		return true
	}

	index := st.isIdentityChain(chainID)

	if index != -1 {
		id := st.Identities[index]
		zero := primitives.NewZeroHash()

		if id.SigningKey == nil || id.SigningKey.IsSameAs(zero) {
			log.Println("New Fed/Audit server [" + chainID.String()[:10] + "] does not have an Block Signing Key associated to it")
			if !statusIsFedOrAudit(id.Status) {
				st.removeIdentity(index)
			}
			return true
		} else {
			copy(blockSigningKey[:32], id.SigningKey.Bytes()[:32])
		}

		if id.AnchorKeys == nil {
			log.Println("New Fed/Audit server [" + chainID.String()[:10] + "] does not have an BTC Anchor Key associated to it")
			if !statusIsFedOrAudit(id.Status) {
				st.removeIdentity(index)
			}
			return true
		} else {
			for _, aKey := range id.AnchorKeys {
				if strings.Compare(aKey.BlockChain, "BTC") == 0 {
					copy(btcKey[:20], aKey.SigningKey[:20])
				}
			}
		}

		if id.MatryoshkaHash == nil || id.MatryoshkaHash.IsSameAs(zero) {
			log.Println("New Fed/Audit server [" + chainID.String()[:10] + "] does not have an Matryoshka Hash associated to it")
			if !statusIsFedOrAudit(id.Status) {
				st.removeIdentity(index)
			}
			return true
		}
		matryoshkaHash = id.MatryoshkaHash

		if servertype == 0 {
			id.Status = constants.IDENTITY_PENDING_FEDERATED_SERVER
		} else if servertype == 1 {
			id.Status = constants.IDENTITY_PENDING_AUDIT_SERVER
		}
		st.Identities[index] = id
	} else {
		log.Println("New Fed/Audit server [" + chainID.String()[:10] + "] does not have an identity associated to it")
		return true
	}

	// Add to admin block
	if servertype == 0 {
		st.LeaderPL.AdminBlock.AddFedServer(chainID)
		st.Identities[index].Status = constants.IDENTITY_PENDING_FEDERATED_SERVER
	} else if servertype == 1 {
		st.LeaderPL.AdminBlock.AddAuditServer(chainID)
		st.Identities[index].Status = constants.IDENTITY_PENDING_AUDIT_SERVER
	}
	st.LeaderPL.AdminBlock.AddFederatedServerSigningKey(chainID, &blockSigningKey)
	st.LeaderPL.AdminBlock.AddMatryoshkaHash(chainID, matryoshkaHash)
	st.LeaderPL.AdminBlock.AddFederatedServerBitcoinAnchorKey(chainID, btcKeyLevel, btcKeyType, &btcKey)
	return true
}
示例#10
0
func (st *State) AddIdentityFromChainID(cid interfaces.IHash) error {
	if cid.String() == st.GetNetworkBootStrapIdentity().String() { // Ignore Bootstrap Identity
		return nil
	}

	index := st.isIdentityChain(cid)
	if index == -1 {
		index = st.CreateBlankFactomIdentity(cid)
	}

	managementChain, _ := primitives.HexToHash(MAIN_FACTOM_IDENTITY_LIST)
	dbase := st.GetAndLockDB()
	ents, err := dbase.FetchAllEntriesByChainID(managementChain)
	st.UnlockDB()
	if err != nil {
		return err
	}
	if len(ents) == 0 {
		st.removeIdentity(index)
		return errors.New("Identity Error: No main Main Factom Identity Chain chain created")
	}

	// Check Identity chain
	eblkStackRoot := make([]interfaces.IEntryBlock, 0)
	mr, err := st.DB.FetchHeadIndexByChainID(cid)
	if err != nil {
		return err
	} else if mr == nil {
		st.removeIdentity(index)
		return errors.New("Identity Error: Identity Chain not found")
	}
	for !mr.IsSameAs(primitives.NewZeroHash()) {
		eblk, err := st.DB.FetchEBlock(mr)
		if err != nil || eblk == nil {
			break
		}
		eblkStackRoot = append(eblkStackRoot, eblk)
		mr = eblk.GetHeader().GetPrevKeyMR()
	}

	for i := len(eblkStackRoot) - 1; i >= 0; i-- {
		LoadIdentityByEntryBlock(eblkStackRoot[i], st)
	}

	mr, err = st.DB.FetchHeadIndexByChainID(managementChain)
	if err != nil {
		return err
	}
	// Check Factom Main Identity List
	for !mr.IsSameAs(primitives.NewZeroHash()) {
		eblk, err := st.DB.FetchEBlock(mr)
		if err != nil {
			return err
		}
		if eblk == nil {
			break
		}
		entries := eblk.GetEntryHashes()
		height := eblk.GetDatabaseHeight()
		for _, eHash := range entries {
			hs := eHash.String()
			if hs[0:10] != "0000000000" { //ignore minute markers
				ent, err := st.DB.FetchEntry(eHash)
				if err != nil || ent == nil {
					continue
				}
				if len(ent.ExternalIDs()) > 3 {
					// This is the Register Factom Identity Message
					if len(ent.ExternalIDs()[2]) == 32 {
						idChain := primitives.NewHash(ent.ExternalIDs()[2][:32])
						if string(ent.ExternalIDs()[1]) == "Register Factom Identity" && cid.IsSameAs(idChain) {
							registerFactomIdentity(ent, cid, height, st)
							break // Found the registration
						}
					}
				}
			}
		}
		mr = eblk.GetHeader().GetPrevKeyMR()
	}

	eblkStackSub := make([]interfaces.IEntryBlock, 0)
	if st.Identities[index].ManagementChainID == nil {
		st.removeIdentity(index)
		return errors.New("Identity Error: No management chain found")
	}
	mr, err = st.DB.FetchHeadIndexByChainID(st.Identities[index].ManagementChainID)
	if err != nil {
		return err
	} else if mr == nil {
		st.removeIdentity(index)
		return nil
	}
	for !mr.IsSameAs(primitives.NewZeroHash()) {
		eblk, err := st.DB.FetchEBlock(mr)
		if err != nil {
			break
		}
		eblkStackSub = append(eblkStackSub, eblk)
		mr = eblk.GetHeader().GetPrevKeyMR()
	}
	for i := len(eblkStackSub) - 1; i >= 0; i-- {
		LoadIdentityByEntryBlock(eblkStackSub[i], st)
	}
	err = checkIdentityForFull(index, st)
	if err != nil {
		st.removeIdentity(index)
		return errors.New("Error: Identity not full - " + err.Error())
	}

	return nil
}