Beispiel #1
0
// processRevealEntry validates the MsgRevealEntry and adds it to processlist
func processRevealEntry(msg *wire.MsgRevealEntry) error {
	e := msg.Entry
	bin, _ := e.MarshalBinary()
	h, _ := wire.NewShaHash(e.Hash().Bytes())

	// Check if the chain id is valid
	if e.ChainID.IsSameAs(zeroHash) || e.ChainID.IsSameAs(dchain.ChainID) || e.ChainID.IsSameAs(achain.ChainID) ||
		e.ChainID.IsSameAs(ecchain.ChainID) || e.ChainID.IsSameAs(fchain.ChainID) {
		return fmt.Errorf("This entry chain is not supported: %s", e.ChainID.String())
	}

	if c, ok := commitEntryMap[e.Hash().String()]; ok {
		if chainIDMap[e.ChainID.String()] == nil {
			fMemPool.addOrphanMsg(msg, h)
			return fmt.Errorf("This chain is not supported: %s",
				msg.Entry.ChainID.String())
		}

		// Calculate the entry credits required for the entry
		cred, err := util.EntryCost(bin)
		if err != nil {
			return err
		}

		if c.Credits < cred {
			fMemPool.addOrphanMsg(msg, h)
			return fmt.Errorf("Credit needs to paid first before an entry is revealed: %s", e.Hash().String())
		}

		// Add the msg to the Mem pool
		fMemPool.addMsg(msg, h)

		// Add to MyPL if Server Node
		if nodeMode == common.SERVER_NODE {
			if plMgr.IsMyPListExceedingLimit() {
				procLog.Warning("Exceeding MyProcessList size limit!")
				return fMemPool.addOrphanMsg(msg, h)
			}

			ack, err := plMgr.AddMyProcessListItem(msg, h,
				wire.ACK_REVEAL_ENTRY)
			if err != nil {
				return err
			} else {
				// Broadcast the ack to the network if no errors
				outMsgQueue <- ack
			}
		}

		delete(commitEntryMap, e.Hash().String())
		return nil
	} else if c, ok := commitChainMap[e.Hash().String()]; ok { //Reveal chain ---------------------------
		if chainIDMap[e.ChainID.String()] != nil {
			fMemPool.addOrphanMsg(msg, h)
			return fmt.Errorf("This chain is not supported: %s",
				msg.Entry.ChainID.String())
		}

		// add new chain to chainIDMap
		newChain := common.NewEChain()
		newChain.ChainID = e.ChainID
		newChain.FirstEntry = e
		chainIDMap[e.ChainID.String()] = newChain

		// Calculate the entry credits required for the entry
		cred, err := util.EntryCost(bin)
		if err != nil {
			return err
		}

		// 10 credit is additional for the chain creation
		if c.Credits < cred+10 {
			fMemPool.addOrphanMsg(msg, h)
			return fmt.Errorf("Credit needs to paid first before an entry is revealed: %s", e.Hash().String())
		}

		//validate chain id for the first entry
		expectedChainID := common.NewChainID(e)
		if !expectedChainID.IsSameAs(e.ChainID) {
			return fmt.Errorf("Invalid ChainID for entry: %s", e.Hash().String())
		}

		//validate chainid hash in the commitChain
		chainIDHash := common.DoubleSha(e.ChainID.Bytes())
		if !bytes.Equal(c.ChainIDHash.Bytes()[:], chainIDHash[:]) {
			return fmt.Errorf("RevealChain's chainid hash does not match with CommitChain: %s", e.Hash().String())
		}

		//validate Weld in the commitChain
		weld := common.DoubleSha(append(c.EntryHash.Bytes(), e.ChainID.Bytes()...))
		if !bytes.Equal(c.Weld.Bytes()[:], weld[:]) {
			return fmt.Errorf("RevealChain's weld does not match with CommitChain: %s", e.Hash().String())
		}

		// Add the msg to the Mem pool
		fMemPool.addMsg(msg, h)

		// Add to MyPL if Server Node
		if nodeMode == common.SERVER_NODE {
			if plMgr.IsMyPListExceedingLimit() {
				procLog.Warning("Exceeding MyProcessList size limit!")
				return fMemPool.addOrphanMsg(msg, h)
			}
			ack, err := plMgr.AddMyProcessListItem(msg, h,
				wire.ACK_REVEAL_CHAIN)
			if err != nil {
				return err
			} else {
				// Broadcast the ack to the network if no errors
				outMsgQueue <- ack
			}
		}

		delete(commitChainMap, e.Hash().String())
		return nil
	} else {
		return fmt.Errorf("No commit for entry")
	}

	return nil
}
//Construct the entry and submit it to the server
func submitEntryToAnchorChain(aRecord *AnchorRecord) error {

	//Marshal aRecord into json
	jsonARecord, err := json.Marshal(aRecord)
	anchorLog.Debug("submitEntryToAnchorChain - jsonARecord: ", string(jsonARecord))
	if err != nil {
		return err
	}
	bufARecord := new(bytes.Buffer)
	bufARecord.Write(jsonARecord)
	//Sign the json aRecord with the server key
	aRecordSig := serverPrivKey.Sign(jsonARecord)
	//Encode sig into Hex string
	bufARecord.Write([]byte(hex.EncodeToString(aRecordSig.Sig[:])))

	//Create a new entry
	entry := common.NewEntry()
	entry.ChainID = anchorChainID
	anchorLog.Debug("anchorChainID: ", anchorChainID)
	entry.Content = bufARecord.Bytes()

	buf := new(bytes.Buffer)
	// 1 byte version
	buf.Write([]byte{0})
	// 6 byte milliTimestamp (truncated unix time)
	buf.Write(milliTime())
	// 32 byte Entry Hash
	buf.Write(entry.Hash().Bytes())
	// 1 byte number of entry credits to pay
	binaryEntry, err := entry.MarshalBinary()
	if err != nil {
		return err
	}

	anchorLog.Info("jsonARecord binary entry: ", hex.EncodeToString(binaryEntry))
	if c, err := util.EntryCost(binaryEntry); err != nil {
		return err
	} else {
		buf.WriteByte(byte(c))
	}
	tmp := buf.Bytes()
	sig := serverECKey.Sign(tmp)
	buf = bytes.NewBuffer(tmp)
	buf.Write(serverECKey.Pub.Key[:])
	buf.Write(sig.Sig[:])

	commit := common.NewCommitEntry()
	err = commit.UnmarshalBinary(buf.Bytes())
	if err != nil {
		return err
	}

	// create a CommitEntry msg and send it to the local inmsgQ
	cm := factomwire.NewMsgCommitEntry()
	cm.CommitEntry = commit
	inMsgQ <- cm

	// create a RevealEntry msg and send it to the local inmsgQ
	rm := factomwire.NewMsgRevealEntry()
	rm.Entry = entry
	inMsgQ <- rm

	return nil
}