func deflateTxn(txn *msgs.Txn, seg *capn.Segment) *msgs.Txn { if isDeflated(txn) { return txn } deflatedTxn := msgs.NewTxn(seg) deflatedTxn.SetId(txn.Id()) deflatedTxn.SetRetry(txn.Retry()) deflatedTxn.SetSubmitter(txn.Submitter()) deflatedTxn.SetSubmitterBootCount(txn.SubmitterBootCount()) deflatedTxn.SetFInc(txn.FInc()) deflatedTxn.SetTopologyVersion(txn.TopologyVersion()) deflatedTxn.SetAllocations(txn.Allocations()) actionsList := txn.Actions() deflatedActionsList := msgs.NewActionList(seg, actionsList.Len()) deflatedTxn.SetActions(deflatedActionsList) for idx, l := 0, actionsList.Len(); idx < l; idx++ { deflatedAction := deflatedActionsList.At(idx) deflatedAction.SetVarId(actionsList.At(idx).VarId()) deflatedAction.SetMissing() } return &deflatedTxn }
func TxnToRootBytes(txn *msgs.Txn) []byte { seg := capn.NewBuffer(nil) txnCap := msgs.NewRootTxn(seg) txnCap.SetId(txn.Id()) txnCap.SetRetry(txn.Retry()) txnCap.SetSubmitter(txn.Submitter()) txnCap.SetSubmitterBootCount(txn.SubmitterBootCount()) txnCap.SetActions(txn.Actions()) txnCap.SetAllocations(txn.Allocations()) txnCap.SetFInc(txn.FInc()) txnCap.SetTopologyVersion(txn.TopologyVersion()) return server.SegToBytes(seg) }
func (pm *ProposerManager) TxnReceived(sender common.RMId, txnId *common.TxnId, txnCap *msgs.Txn) { // Due to failures, we can actually receive outcomes (2Bs) first, // before we get the txn to vote on it - due to failures, other // proposers will have created abort proposals, and consensus may // have already been reached. If this is the case, it is correct to // ignore this message. if _, found := pm.proposers[*txnId]; !found { server.Log(txnId, "Received") accept := true if pm.topology != nil { accept = (pm.topology.Next() == nil && pm.topology.Version == txnCap.TopologyVersion()) || // Could also do pm.topology.BarrierReached1(sender), but // would need to specialise that to rolls rather than // topology txns, and it's enforced on the sending side // anyway. One the sender has received the next topology, // it'll do the right thing and locally block until it's // in barrier1. (pm.topology.Next() != nil && pm.topology.Next().Version == txnCap.TopologyVersion()) if accept { _, found := pm.topology.RMsRemoved()[sender] accept = !found } } if accept { proposer := NewProposer(pm, txnId, txnCap, ProposerActiveVoter, pm.topology) pm.proposers[*txnId] = proposer proposer.Start() } else { server.Log(txnId, "Aborting received txn due to non-matching topology.", txnCap.TopologyVersion()) acceptors := GetAcceptorsFromTxn(txnCap) fInc := int(txnCap.FInc()) alloc := AllocForRMId(txnCap, pm.RMId) ballots := MakeAbortBallots(txnCap, alloc) pm.NewPaxosProposals(txnId, txnCap, fInc, ballots, acceptors, pm.RMId, true) // ActiveLearner is right - we don't want the proposer to // vote, but it should exist to collect the 2Bs that should // come back. proposer := NewProposer(pm, txnId, txnCap, ProposerActiveLearner, pm.topology) pm.proposers[*txnId] = proposer proposer.Start() } } }