func (e *ServerFault) UpdateState(state interfaces.IState) error { core, err := e.MarshalCore() if err != nil { return err } verifiedSignatures := 0 for _, fullSig := range e.SignatureList.List { sig := fullSig.GetSignature() v, err := state.VerifyAuthoritySignature(core, sig, state.GetLeaderHeight()) if err != nil { if err.Error() != "Signature Key Invalid or not Federated Server Key" { return err } } if v == 1 { verifiedSignatures++ } } feds := state.GetFedServers(state.GetLeaderHeight()) //50% threshold if verifiedSignatures <= len(feds)/2 { return fmt.Errorf("Quorum not reached for ServerFault") } //TODO: do /* state.AddFedServer(e.DBHeight, e.IdentityChainID) state.UpdateAuthorityFromABEntry(e) */ return nil }
func (m *Heartbeat) FollowerExecute(state interfaces.IState) { for _, auditServer := range state.GetAuditServers(state.GetLeaderHeight()) { if auditServer.GetChainID().IsSameAs(m.IdentityChainID) { if m.IdentityChainID.IsSameAs(state.GetIdentityChainID()) { if m.SecretNumber != state.GetSalt(m.Timestamp) { panic("We have seen a heartbeat using our Identity that isn't ours") } } auditServer.SetOnline(true) } } }
// Validate the message, given the state. Three possible results: // < 0 -- Message is invalid. Discard // 0 -- Cannot tell if message is Valid // 1 -- Message is valid // Also return the matching commit, if 1 (Don't put it back into the Commit List) func (m *RevealEntryMsg) ValidateRTN(state interfaces.IState) (interfaces.IMsg, int) { commit := state.NextCommit(m.Entry.GetHash()) if commit == nil { return nil, 0 } // // Make sure one of the two proper commits got us here. var okChain, okEntry bool m.commitChain, okChain = commit.(*CommitChainMsg) m.commitEntry, okEntry = commit.(*CommitEntryMsg) if !okChain && !okEntry { // Discard any invalid entries in the map. Should never happen. fmt.Println("dddd Bad EB Commit", state.GetFactomNodeName()) return m.ValidateRTN(state) } // Now make sure the proper amount of credits were paid to record the entry. // The chain must exist if okEntry { m.IsEntry = true ECs := int(m.commitEntry.CommitEntry.Credits) if m.Entry.KSize() > ECs { fmt.Println("dddd EB Commit is short", state.GetFactomNodeName()) return m.ValidateRTN(state) // Discard commits that are not funded properly. } // Make sure we have a chain. If we don't, then bad things happen. db := state.GetAndLockDB() dbheight := state.GetLeaderHeight() eb := state.GetNewEBlocks(dbheight, m.Entry.GetChainID()) eb_db := state.GetNewEBlocks(dbheight-1, m.Entry.GetChainID()) if eb_db == nil { eb_db, _ = db.FetchEBlockHead(m.Entry.GetChainID()) } if eb_db == nil && eb == nil { // If we don't have a chain, put the commit back. Don't want to lose it. state.PutCommit(m.Entry.GetHash(), commit) return nil, 0 } } else { m.IsEntry = false ECs := int(m.commitChain.CommitChain.Credits) if m.Entry.KSize()+10 > ECs { // Discard commits that are not funded properly return m.ValidateRTN(state) } } return commit, 1 }
func (m *ChangeServerKeyMsg) Validate(state interfaces.IState) int { return 1 // Check to see if identity exists and is audit or fed server if !state.VerifyIsAuthority(m.IdentityChainID) { fmt.Println("ChangeServerKey Error. Server is not an authority") return -1 } // Should only be 20 bytes in the hash if m.AdminBlockChange == constants.TYPE_ADD_BTC_ANCHOR_KEY { for _, b := range m.Key.Bytes()[21:] { if b != 0 { fmt.Println("ChangeServerKey Error. Newkey is invalid length") return -1 } } } // Check signatures bytes, err := m.MarshalForSignature() if err != nil { fmt.Println("ChangeServerKey Error: Err is not nil, err: ", err.Error()) return -1 } if m.Signature == nil { fmt.Println("ChangeServerKey Error: No signiture on ChangeServerKeyMessage") return -1 } sig := m.Signature.GetSignature() authSigned, err := state.VerifyAuthoritySignature(bytes, sig, state.GetLeaderHeight()) //ackSigned, err := m.VerifySignature() if err != nil { fmt.Println("ChangeServerKey Error: Err is not nil, err: ", err.Error()) return -1 } if authSigned < 1 { fmt.Println("ChangeServerKey Error: Message not signed by an authority") return -1 } return 1 }
func HandleV2ChainHead(state interfaces.IState, params interface{}) (interface{}, *primitives.JSONError) { chainid := new(ChainIDRequest) err := MapToObject(params, chainid) if err != nil { return nil, NewInvalidParamsError() } h, err := primitives.HexToHash(chainid.ChainID) if err != nil { return nil, NewInvalidHashError() } dbase := state.GetAndLockDB() defer state.UnlockDB() c := new(ChainHeadResponse) // get the pending chain head from the current or previous process list in // the state lh := state.GetLeaderHeight() pend1 := state.GetNewEBlocks(lh, h) pend2 := state.GetNewEBlocks(lh-1, h) if pend1 != nil || pend2 != nil { c.ChainInProcessList = true } // get the chain head from the database mr, err := dbase.FetchHeadIndexByChainID(h) if err != nil { return nil, NewInvalidHashError() } if mr == nil { if c.ChainInProcessList == false { return nil, NewMissingChainHeadError() } } else { c.ChainHead = mr.String() } return c, nil }