state

package
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2024 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BaseRound

type BaseRound struct {
	// contains filtered or unexported fields
}

func NewBaseRound

func NewBaseRound(selfID party.ID, partyIDs party.IDSlice) (*BaseRound, error)

func (*BaseRound) MarshalJSON

func (r *BaseRound) MarshalJSON() ([]byte, error)

func (BaseRound) PartyIDs

func (r BaseRound) PartyIDs() party.IDSlice

func (*BaseRound) ProcessMessage

func (r *BaseRound) ProcessMessage(*messages.Message) *Error

func (BaseRound) SelfID

func (r BaseRound) SelfID() party.ID

func (*BaseRound) UnmarshalJSON

func (r *BaseRound) UnmarshalJSON(data []byte) error

type Error

type Error struct {
	PartyID     party.ID
	RoundNumber int
	// contains filtered or unexported fields
}

Error represents an error related to the protocol execution, and requires an abort. If PartyID is 0, then it was not possible to attribute the fault to one particular party.

func NewError

func NewError(partyID party.ID, err error) *Error

NewError wraps err in an Error and attaches the culprit's ID

func (Error) Error

func (e Error) Error() string

Error implement error

type Round

type Round interface {
	// ProcessMessage takes a message and validates the contents.
	// It then stores the message as part of the Round's own state.
	// If an Error is returned then the protocol must abort.
	//
	// Round0 does not need to implement this function since it is inherited from BaseRound
	ProcessMessage(msg *messages.Message) *Error

	// GenerateMessages returns a slice of messages to be sent out at the end of this Round.
	// It assumes that ProcessMessage has run correctly for messages from all other parties.
	// At the end of this method, it is assumed that no more operations are needed for the round.
	// If an Error is returned then the protocol must abort.
	GenerateMessages() ([]*messages.Message, *Error)

	// NextRound returns the next round of the protocol.
	// This does not take into account an error having occurred.
	// The final round of the protocol should return nil, to indicate that the protocol is finished.
	NextRound() Round

	// AcceptedMessageTypes should return a slice containing the messages types the protocol accepts.
	// It is constant for all rounds and should therefore be implemented by a "base" round.
	AcceptedMessageTypes() []messages.MessageType

	// Reset is expected to zero out any sensitive data that may have been copied by the round.
	// It is called by State when the protocol finishes, either because of an abort or because we finish.
	// It only needs to be implemented in Round0 if all state is held there.
	Reset()

	// SelfID returns the ID of the round participant
	SelfID() party.ID

	// PartyIDs returns a set containing all parties participating in the round
	PartyIDs() party.IDSlice

	GetOutput() interface{}
}

A Round represents the internal state of protocol from the perspective of the party. It only takes care of receiving proper messages addressed to the party, and can output messages that should be sent off.

The methods ProcessMessage, GenerateMessages and NextRound should all run in this order. Doing otherwise will most likely result in undefined behaviour.

The suggested implementation of a Round based protocol is the following:

type round0 struct {
    *BaseRound
    // other state variable for the entire protocol
}

func (r *round0) Reset() {} func (r *round0) AcceptedMessageTypes() []messages.MessageType { return []messages.MessageType{...} } func (r *round0) GenerateMessages() ([]*messages.Message, *Error) { ... } func (r *round0) NextRound() Round { return &round_N-1_{r} }

For all defined rounds N=1,2,... :

type round_N_ struct {
    *round_N-1_
}

func (r *roundN) ProcessMessage(msg *messages.Message) *Error { ... } func (r *roundN) GenerateMessages() ([]*messages.Message, *Error) { ... } func (r *roundN) NextRound() Round { return &round_N-1_{r} }

type State

type State struct {
	RoundData []byte
	// contains filtered or unexported fields
}

State is a struct that manages the state for the round based protocol.

It handles the initial message reception, by storing them internally and feeding them to the the current round when all messages have been received

func NewBaseState

func NewBaseState(round Round, timeout time.Duration) (*State, error)

func (*State) Done

func (s *State) Done() <-chan struct{}

Done should be called like context.Done:

select {
  case <-s.Done():
  // other cases

func (*State) Err

func (s *State) Err() error

func (*State) GetRound

func (s *State) GetRound() Round

func (*State) GetRoundNumber

func (s *State) GetRoundNumber() int

func (*State) HandleMessage

func (s *State) HandleMessage(msg *messages.Message) error

HandleMessage should be called on an unmarshalled messages.Message appropriate for the protocol execution. It performs basic checks to see whether the message can be used. - Is the protocol already done - Is msg is valid for this round or a future one - Is msg for us and not from us - Is the sender a party in the protocol - Have we already received a message from the party for this round?

If all these checks pass, then the message is either stored for the current round, or put in a queue for later rounds.

Note: the properties of the messages are checked in ProcessAll. Therefore, the check here should be a quite fast.

func (*State) IsFinished

func (s *State) IsFinished() bool

IsFinished returns true if the protocol has aborted or successfully finished.

func (*State) MarshalJSON

func (s *State) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaller interface.

func (*State) ProcessAll

func (s *State) ProcessAll() []*messages.Message

ProcessAll checks whether all messages for this round have been received. If so then all messages are fed to Round.ProcessMessage. If no error was detected, then the round is processed and new messages are generated. These messages are returned to the caller and should be processed. If all went correctly, we take the messages for the next round out of the queue, and move on to the next round.

func (*State) SetRound

func (s *State) SetRound(round Round)

func (*State) UnmarshalJSON

func (s *State) UnmarshalJSON(data []byte) error

func (*State) WaitForError

func (s *State) WaitForError() error

WaitForError blocks until the protocol is done. This happens either when the protocol has finished correctly, or if an error has been detected.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL