// 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 }