Beispiel #1
0
func (db *Overlay) FetchAllEntriesByChainID(chainID interfaces.IHash) ([]interfaces.IEBEntry, error) {
	list, err := db.FetchAllBlocksFromBucket(chainID.Bytes(), entryBlock.NewEntry())
	if err != nil {
		return nil, err
	}
	return toEntryList(list), nil
}
Beispiel #2
0
// End of Block means packing the current block away, and setting
// up the next
func (fs *FactoidState) ProcessEndOfBlock(state interfaces.IState) {
	var hash, hash2 interfaces.IHash

	if fs.GetCurrentBlock() == nil {
		panic("Invalid state on initialization")
	}

	hash = fs.CurrentBlock.GetHash()
	hash2 = fs.CurrentBlock.GetLedgerKeyMR()

	state.GetCurrentDirectoryBlock().GetDBEntries()[2].SetKeyMR(hash)

	if err := state.GetDB().SaveFactoidBlockHead(fs.CurrentBlock); err != nil {
		panic(err)
	}

	state.SetPrevFactoidKeyMR(hash)

	fs.CurrentBlock = block.NewFBlock(fs.GetFactoshisPerEC(), state.GetDBHeight()+1)

	t := coinbase.GetCoinbase(primitives.GetTimeMilli())
	err := fs.CurrentBlock.AddCoinbase(t)
	if err != nil {
		panic(err.Error())
	}
	fs.UpdateTransaction(t)

	if hash != nil {
		fs.CurrentBlock.SetPrevKeyMR(hash.Bytes())
		fs.CurrentBlock.SetPrevLedgerKeyMR(hash2.Bytes())
	}

}
Beispiel #3
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())
}
Beispiel #4
0
// HashMerkleBranches takes two hashes, treated as the left and right tree
// nodes, and returns the hash of their concatenation.  This is a helper
// function used to aid in the generation of a merkle tree.
func HashMerkleBranches(left interfaces.IHash, right interfaces.IHash) interfaces.IHash {
	// Concatenate the left and right nodes.
	var barray []byte = make([]byte, constants.ADDRESS_LENGTH*2)
	copy(barray[:constants.ADDRESS_LENGTH], left.Bytes())
	copy(barray[constants.ADDRESS_LENGTH:], right.Bytes())

	newSha := Sha(barray)
	return newSha
}
Beispiel #5
0
func (db *Overlay) FetchPrimaryIndexBySecondaryIndex(secondaryIndexBucket []byte, key interfaces.IHash) (interfaces.IHash, error) {
	block, err := db.DB.Get(secondaryIndexBucket, key.Bytes(), new(primitives.Hash))
	if err != nil {
		return nil, err
	}
	if block == nil {
		return nil, nil
	}
	return block.(interfaces.IHash), nil
}
Beispiel #6
0
func (db *Overlay) FetchBlock(bucket []byte, key interfaces.IHash, dst interfaces.DatabaseBatchable) (interfaces.DatabaseBatchable, error) {
	block, err := db.DB.Get(bucket, key.Bytes(), dst)
	if err != nil {
		return nil, err
	}
	if block == nil {
		return nil, nil
	}
	return block.(interfaces.DatabaseBatchable), nil
}
Beispiel #7
0
func (db *Overlay) FetchPaidFor(hash interfaces.IHash) (interfaces.IHash, error) {
	block, err := db.DB.Get(PAID_FOR, hash.Bytes(), new(primitives.Hash))
	if err != nil {
		return nil, err
	}
	if block == nil {
		return nil, nil
	}
	return block.(interfaces.IHash), nil
}
Beispiel #8
0
func (db *Overlay) FetchIncludedIn(hash interfaces.IHash) (interfaces.IHash, error) {
	block, err := db.DB.Get(INCLUDED_IN, hash.Bytes(), new(primitives.Hash))
	if err != nil {
		return nil, err
	}
	if block == nil {
		return nil, nil
	}
	return block.(interfaces.IHash), nil
}
Beispiel #9
0
// Compare two Hashes
func (a Hash) IsSameAs(b interfaces.IHash) bool {
	if b == nil {
		return false
	}

	if bytes.Compare(a[:], b.Bytes()) == 0 {
		return true
	}

	return false
}
Beispiel #10
0
func (db *Overlay) SavePaidFor(entry, ecEntry interfaces.IHash) error {
	if entry == nil || ecEntry == nil {
		return nil
	}
	batch := []interfaces.Record{}

	batch = append(batch, interfaces.Record{PAID_FOR, entry.Bytes(), ecEntry})

	err := db.DB.PutInBatch(batch)
	if err != nil {
		return err
	}

	return nil
}
Beispiel #11
0
func (db *Overlay) SaveIncludedIn(entry, block interfaces.IHash) error {
	if entry == nil || block == nil {
		return nil
	}
	batch := []interfaces.Record{}

	batch = append(batch, interfaces.Record{INCLUDED_IN, entry.Bytes(), block})

	err := db.DB.PutInBatch(batch)
	if err != nil {
		return err
	}

	return nil
}
Beispiel #12
0
// Returns true and the index of this server, or false and the insertion point for this server
func (p *ProcessList) GetAuditServerIndexHash(identityChainID interfaces.IHash) (bool, int) {

	if p == nil {
		return false, 0
	}

	p.SortAuditServers()

	scid := identityChainID.Bytes()

	for i, fs := range p.AuditServers {
		// Find and remove
		if bytes.Compare(scid, fs.GetChainID().Bytes()) == 0 {
			return true, i
		}
	}
	return false, len(p.AuditServers)
}
Beispiel #13
0
// FetchHeadMRByChainID gets an index of the highest block from the database.
func (db *Overlay) FetchHeadIndexByChainID(chainID interfaces.IHash) (interfaces.IHash, error) {
	if chainID == nil {
		return nil, nil
	}

	bucket := []byte{byte(CHAIN_HEAD)}
	key := chainID.Bytes()

	block, err := db.DB.Get(bucket, key, new(primitives.Hash))
	if err != nil {
		return nil, err
	}
	if block == nil {
		return nil, nil
	}

	return block.(interfaces.IHash), nil
}
Beispiel #14
0
// FetchAllEBlocksByChain gets all of the blocks by chain id
func (db *Overlay) FetchAllEBlocksByChain(chainID interfaces.IHash) ([]interfaces.IEntryBlock, error) {
	bucket := append([]byte{byte(ENTRYBLOCK_CHAIN_NUMBER)}, chainID.Bytes()...)
	keyList, err := db.FetchAllBlocksFromBucket(bucket, new(primitives.Hash))
	if err != nil {
		return nil, err
	}

	list := make([]interfaces.IEntryBlock, len(keyList))

	for i, v := range keyList {
		block, err := db.FetchEBlockByKeyMR(v.(interfaces.IHash))
		if err != nil {
			return nil, err
		}
		list[i] = block
	}

	return list, nil
}
Beispiel #15
0
func (db *Overlay) SavePaidForMultiFromBlock(block interfaces.IEntryCreditBlock, checkForDuplicateEntries bool) error {
	if block == nil {
		return nil
	}
	batch := []interfaces.Record{}

	for _, entry := range block.GetBody().GetEntries() {
		if entry.ECID() != entryCreditBlock.ECIDChainCommit && entry.ECID() != entryCreditBlock.ECIDEntryCommit {
			continue
		}
		var entryHash interfaces.IHash

		if entry.ECID() == entryCreditBlock.ECIDChainCommit {
			entryHash = entry.(*entryCreditBlock.CommitChain).EntryHash
		}
		if entry.ECID() == entryCreditBlock.ECIDEntryCommit {
			entryHash = entry.(*entryCreditBlock.CommitEntry).EntryHash
		}

		if checkForDuplicateEntries == true {
			loaded, err := db.Get(PAID_FOR, entryHash.Bytes(), primitives.NewZeroHash())
			if err != nil {
				return err
			}
			if loaded != nil {
				continue
			}
		}
		batch = append(batch, interfaces.Record{PAID_FOR, entryHash.Bytes(), entry.Hash()})
	}
	if len(batch) == 0 {
		return nil
	}

	err := db.DB.PutInBatch(batch)
	if err != nil {
		return err
	}

	return nil
}
Beispiel #16
0
func (a *Anchor) doTransaction(hash interfaces.IHash, blockHeight uint32, dirBlockInfo *dbInfo.DirBlockInfo) (*wire.ShaHash, error) {
	b := a.balances[0]
	a.balances = a.balances[1:]
	anchorLog.Info("new balances.len=", len(a.balances))

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

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

	if dirBlockInfo != nil {
		dirBlockInfo.BTCTxHash = toHash(shaHash)
		dirBlockInfo.SetTimestamp(primitives.NewTimestampNow())
		a.db.SaveDirBlockInfo(dirBlockInfo)
	}

	return shaHash, nil
}
// Create a new DB Signature Entry
func NewAddFederatedServer(identityChainID interfaces.IHash, dbheight uint32) (e *AddFederatedServer) {
	e = new(AddFederatedServer)
	e.DBHeight = dbheight
	e.IdentityChainID = primitives.NewHash(identityChainID.Bytes())
	return
}
Beispiel #18
0
func toShaHash(hash interfaces.IHash) *wire.ShaHash {
	h, _ := wire.NewShaHash(hash.Bytes())
	return h
}
Beispiel #19
0
func (m *MessageBase) SetFullMsgHash(hash interfaces.IHash) {
	m.GetFullMsgHash().SetBytes(hash.Bytes())
}
Beispiel #20
0
func CreateAddress(hash interfaces.IHash) interfaces.IAddress {
	return NewAddress(hash.Bytes())
}
Beispiel #21
0
func (db *Overlay) FetchAllEntryIDsByChainID(chainID interfaces.IHash) ([]interfaces.IHash, error) {
	return db.FetchAllBlockKeysFromBucket(chainID.Bytes())
}
Beispiel #22
0
// Process messages and update our state.
func (p *ProcessList) Process(state *State) (progress bool) {

	dbht := state.GetHighestCompletedBlock()
	if dbht >= p.DBHeight {
		return true
	}

	state.PLProcessHeight = p.DBHeight

	p.AskDBState(0, p.VMs[0].Height) // Look for a possible dbstate at this height.

	if len(p.System.List) > 0 {
	systemloop:
		for i, f := range p.System.List[p.System.Height:] {
			fault, ok := f.(*messages.FullServerFault)

			if ok {
				vm := p.VMs[fault.VMIndex]
				if vm.Height < int(fault.Height) {
					break systemloop
				}
				if !fault.Process(p.DBHeight, p.State) {
					return false
				}
				p.System.Height++
				progress = true
			}
			if fault == nil {
				p.Ask(-1, i, 10, 100)
			}
		}
	}

	for i := 0; i < len(p.FedServers); i++ {
		vm := p.VMs[i]

		if !p.State.Syncing {
			vm.whenFaulted = 0
			p.Unfault()
		} else {
			if !vm.Synced {
				eomFault(p, vm, i, len(vm.List), 0)
			}
		}

		if vm.Height == len(vm.List) && p.State.Syncing && !vm.Synced {
			// means that we are missing an EOM
			p.Ask(i, vm.Height, 0, 1)
		}

		// If we haven't heard anything from a VM, ask for a message at the last-known height
		if vm.Height == len(vm.List) {
			p.Ask(i, vm.Height, 20, 2)
		}

		if vm.whenFaulted > 0 && vm.Height > vm.faultHeight {
			if p.AmINegotiator && i == p.NegotiatorVMIndex {
				p.AmINegotiator = false
			}
			vm.faultHeight = -1
			vm.whenFaulted = 0

			p.Unfault()
		}

	VMListLoop:
		for j := vm.Height; j < len(vm.List); j++ {
			if vm.List[j] == nil {
				p.Ask(i, j, 0, 3)
				break VMListLoop
			}

			thisAck := vm.ListAck[j]

			var expectedSerialHash interfaces.IHash
			var err error

			if vm.Height == 0 {
				expectedSerialHash = thisAck.SerialHash
			} else {
				last := vm.ListAck[vm.Height-1]
				expectedSerialHash, err = primitives.CreateHash(last.MessageHash, thisAck.MessageHash)
				if err != nil {
					p.Ask(i, j, 3, 4)
					break VMListLoop
				}

				// compare the SerialHash of this acknowledgement with the
				// expected serialHash (generated above)
				if !expectedSerialHash.IsSameAs(thisAck.SerialHash) {
					fmt.Printf("dddd %20s %10s --- %10s %10x %10s %10x \n", "Conflict", p.State.FactomNodeName, "expected", expectedSerialHash.Bytes()[:3], "This", thisAck.Bytes()[:3])
					fmt.Printf("dddd Error detected on %s\nSerial Hash failure: Fed Server %d  Leader ID %x List Ht: %d \nDetected on: %s\n",
						state.GetFactomNodeName(),
						i,
						p.FedServers[i].GetChainID().Bytes()[:3],
						j,
						vm.List[j].String())
					fmt.Printf("dddd Last Ack: %6x  Last Serial: %6x\n", last.GetHash().Bytes()[:3], last.SerialHash.Bytes()[:3])
					fmt.Printf("dddd This Ack: %6x  This Serial: %6x\n", thisAck.GetHash().Bytes()[:3], thisAck.SerialHash.Bytes()[:3])
					fmt.Printf("dddd Expected: %6x\n", expectedSerialHash.Bytes()[:3])
					fmt.Printf("dddd The message that didn't work: %s\n\n", vm.List[j].String())
					// the SerialHash of this acknowledgment is incorrect
					// according to this node's processList

					//fault(p, i, 0, vm, 0, j, 2)
					p.State.Reset()
					return
				}
			}

			// So here is the deal.  After we have processed a block, we have to allow the DirectoryBlockSignatures a chance to save
			// to disk.  Then we can insist on having the entry blocks.
			diff := p.DBHeight - state.EntryBlockDBHeightComplete
			_, dbsig := vm.List[j].(*messages.DirectoryBlockSignature)

			// Keep in mind, the process list is processing at a height one greater than the database. 1 is caught up.  2 is one behind.
			// Until the signatures are processed, we will be 2 behind.
			if (dbsig && diff <= 2) || diff <= 1 {
				// If we can't process this entry (i.e. returns false) then we can't process any more.
				p.NextHeightToProcess[i] = j + 1
				if vm.List[j].Process(p.DBHeight, state) { // Try and Process this entry
					vm.heartBeat = 0
					vm.Height = j + 1 // Don't process it again if the process worked.

					//p.Unfault()

					progress = true
				} else {
					break VMListLoop // Don't process further in this list, go to the next.
				}
			} else {
				// If we don't have the Entry Blocks (or we haven't processed the signatures) we can't do more.
				break VMListLoop
			}
		}
	}
	return
}