flip

package module
v0.0.0-...-477c5fb Latest Latest
Warning

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

Go to latest
Published: Feb 8, 2019 License: BSD-3-Clause Imports: 17 Imported by: 0

README

go-flip

A way to flip coins with your friends

Documentation

Index

Constants

View Source
const MaxClockSkew = time.Hour * 1

Variables

View Source
var ErrBadData = errors.New("rejecting bad data, likely due to a nil field")
View Source
var FlipTypeMap = map[string]FlipType{
	"BOOL":    1,
	"INT":     2,
	"BIG":     3,
	"SHUFFLE": 4,
}
View Source
var FlipTypeRevMap = map[FlipType]string{
	1: "BOOL",
	2: "INT",
	3: "BIG",
	4: "SHUFFLE",
}
View Source
var MessageTypeMap = map[string]MessageType{
	"START":               1,
	"COMMITMENT":          2,
	"COMMITMENT_COMPLETE": 3,
	"REVEAL":              4,
	"END":                 5,
}
View Source
var MessageTypeRevMap = map[MessageType]string{
	1: "START",
	2: "COMMITMENT",
	3: "COMMITMENT_COMPLETE",
	4: "REVEAL",
	5: "END",
}
View Source
var StageMap = map[string]Stage{
	"ROUND1":        1,
	"ROUND2":        2,
	"ROUND_CLEANUP": 3,
}
View Source
var StageRevMap = map[Stage]string{
	1: "ROUND1",
	2: "ROUND2",
	3: "ROUND_CLEANUP",
}
View Source
var VersionMap = map[string]Version{
	"V1": 1,
}
View Source
var VersionRevMap = map[Version]string{
	1: "V1",
}

Functions

func FlipBool

func FlipBool(cp CommitmentPayload, players []PlayerState) (bool, error)

FlipOneBool takes all the completed PlayerStates, and checks them. If no error, then outputs one random bool. If there was an error in the game setup, then it will return false and the error.

func FlipInt

func FlipInt(cp CommitmentPayload, players []PlayerState, modulus int64) (int64, error)

FlipOneInt takes all the completed PlayerStates, and checks them. If no error, then outputs one random number between 0 and the given modulus, a signed 64-bit int. If there was an error in the game setup, then it will return 0 and the error.

func FlipOneBig

func FlipOneBig(cp CommitmentPayload, players []PlayerState, modulus *big.Int) (*big.Int, error)

FlipOneBig takes all the completed PlayerStates, and checks them. If no error, then outputs one random number between 0 and the given modulus, which is an arbitrarily big number. If there was an error in the game setup, then it will return nil and the error.

func FlipProtocol

func FlipProtocol(i FlipInterface) rpc.Protocol

Types

type AbsenteesError

type AbsenteesError struct {
	Absentees []UserDevice
}

func (AbsenteesError) Error

func (l AbsenteesError) Error() string

type BadChannelError

type BadChannelError struct {
	G GameMetadata
	C ConversationID
}

func (BadChannelError) Error

func (b BadChannelError) Error() string

type BadFlipTypeError

type BadFlipTypeError struct {
	G GameMetadata
	T FlipType
}

func (BadFlipTypeError) Error

func (b BadFlipTypeError) Error() string

type BadLeaderClockError

type BadLeaderClockError struct {
	G GameMetadata
}

func (BadLeaderClockError) Error

func (b BadLeaderClockError) Error() string

type BadLocalClockError

type BadLocalClockError struct {
	G GameMetadata
}

func (BadLocalClockError) Error

func (b BadLocalClockError) Error() string

type BadMessageError

type BadMessageError struct {
	G GameMetadata
	T MessageType
}

func (BadMessageError) Error

func (b BadMessageError) Error() string

type BadMessageForStageError

type BadMessageForStageError struct {
	G           GameMetadata
	MessageType MessageType
	Stage       Stage
}

func (BadMessageForStageError) Error

func (b BadMessageForStageError) Error() string

type BadRevealError

type BadRevealError struct {
	G GameMetadata
	U UserDevice
}

func (BadRevealError) Error

func (b BadRevealError) Error() string

type BadUserDeviceError

type BadUserDeviceError struct {
	Expected UserDevice
	Actual   UserDevice
}

func (BadUserDeviceError) Error

func (b BadUserDeviceError) Error() string

type BadVersionError

type BadVersionError Version

func (BadVersionError) Error

func (b BadVersionError) Error() string

type Commitment

type Commitment [32]byte

func (Commitment) DeepCopy

func (o Commitment) DeepCopy() Commitment

func (Commitment) Eq

func (c Commitment) Eq(d Commitment) bool

type CommitmentComplete

type CommitmentComplete struct {
	Players []UserDevice `codec:"players" json:"players"`
}

func (CommitmentComplete) DeepCopy

type CommitmentPayload

type CommitmentPayload struct {
	V Version        `codec:"v" json:"v"`
	U UID            `codec:"u" json:"u"`
	D DeviceID       `codec:"d" json:"d"`
	C ConversationID `codec:"c" json:"c"`
	G GameID         `codec:"i" json:"i"`
	S Time           `codec:"s" json:"s"`
	// contains filtered or unexported fields
}

type ConversationID

type ConversationID []byte

func (ConversationID) DeepCopy

func (o ConversationID) DeepCopy() ConversationID

func (ConversationID) Eq

func (ConversationID) String

func (c ConversationID) String() string

type Dealer

type Dealer struct {
	sync.Mutex
	// contains filtered or unexported fields
}

Dealer is a peristent process that runs in the chat client that deals out a game. It can have multiple games running at once.

func NewDealer

func NewDealer(dh DealersHelper) *Dealer

NewDealer makes a new Dealer with a given DealersHelper

func (*Dealer) InjectIncomingChat

func (d *Dealer) InjectIncomingChat(ctx context.Context, sender UserDevice, conversationID ConversationID, body GameMessageEncoded) error

InjectIncomingChat should be called whenever a new flip game comes in that's relevant for flips. Call this with the sender's information, the channel informatino, and the body data that came in.

func (*Dealer) Run

func (d *Dealer) Run(ctx context.Context) error

Run a dealer in a given context. It wil run as long as it isn't shutdown.

func (*Dealer) StartFlip

func (d *Dealer) StartFlip(ctx context.Context, start Start, conversationID ConversationID) (err error)

StartFlip starts a new flip. Pass it some start parameters as well as a chat conversationID that it will take place in.

func (*Dealer) Stop

func (d *Dealer) Stop()

Stop a dealer on process shutdown.

func (*Dealer) UpdateCh

func (d *Dealer) UpdateCh() <-chan GameStateUpdateMessage

UpdateCh returns a channel that sends a sequence of GameStateUpdateMessages, each notifying the UI about changes to ongoing games.

type DealersHelper

type DealersHelper interface {
	CLogf(ctx context.Context, fmt string, args ...interface{})
	Clock() clockwork.Clock
	ServerTime(context.Context) (time.Time, error)
	ReadHistory(ctx context.Context, since time.Time) ([]GameMessageWrappedEncoded, error)
	SendChat(ctx context.Context, ch ConversationID, msg GameMessageEncoded) error
	Me() UserDevice
}

DealersHelper is an interface that calling chat clients need to implement.

type DeviceID

type DeviceID []byte

func (DeviceID) DeepCopy

func (o DeviceID) DeepCopy() DeviceID

func (DeviceID) Eq

func (d DeviceID) Eq(e DeviceID) bool

func (DeviceID) String

func (d DeviceID) String() string

type DuplicateRegistrationError

type DuplicateRegistrationError struct {
	G GameMetadata
	U UserDevice
}

func (DuplicateRegistrationError) Error

type DuplicateRevealError

type DuplicateRevealError struct {
	G GameMetadata
	U UserDevice
}

func (DuplicateRevealError) Error

func (d DuplicateRevealError) Error() string

type Error

type Error struct {
	NoCommitments  []Player
	NoReveals      []Player
	BadCommitments []Player
	Duplicates     []Player
}

func (Error) Error

func (e Error) Error() string

func (Error) IsNil

func (e Error) IsNil() bool

type FlipClient

type FlipClient struct {
	Cli rpc.GenericClient
}

type FlipInterface

type FlipInterface interface {
}

type FlipParameters

type FlipParameters struct {
	T__       FlipType `codec:"t" json:"t"`
	Int__     *int64   `codec:"int,omitempty" json:"int,omitempty"`
	Big__     *[]byte  `codec:"big,omitempty" json:"big,omitempty"`
	Shuffle__ *int64   `codec:"shuffle,omitempty" json:"shuffle,omitempty"`
}

func NewFlipParametersWithBig

func NewFlipParametersWithBig(v []byte) FlipParameters

func NewFlipParametersWithBool

func NewFlipParametersWithBool() FlipParameters

func NewFlipParametersWithInt

func NewFlipParametersWithInt(v int64) FlipParameters

func NewFlipParametersWithShuffle

func NewFlipParametersWithShuffle(v int64) FlipParameters

func (FlipParameters) Big

func (o FlipParameters) Big() (res []byte)

func (FlipParameters) DeepCopy

func (o FlipParameters) DeepCopy() FlipParameters

func (FlipParameters) Int

func (o FlipParameters) Int() (res int64)

func (FlipParameters) Shuffle

func (o FlipParameters) Shuffle() (res int64)

func (*FlipParameters) T

func (o *FlipParameters) T() (ret FlipType, err error)

type FlipType

type FlipType int
const (
	FlipType_BOOL    FlipType = 1
	FlipType_INT     FlipType = 2
	FlipType_BIG     FlipType = 3
	FlipType_SHUFFLE FlipType = 4
)

func (FlipType) DeepCopy

func (o FlipType) DeepCopy() FlipType

func (FlipType) String

func (e FlipType) String() string

type Game

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

func (*Game) CommitmentEndTime

func (g *Game) CommitmentEndTime() time.Time

func (*Game) GameMetadata

func (g *Game) GameMetadata() GameMetadata

func (*Game) RevealEndTime

func (g *Game) RevealEndTime() time.Time

type GameAlreadyStartedError

type GameAlreadyStartedError struct {
	G GameMetadata
}

func (GameAlreadyStartedError) Error

func (g GameAlreadyStartedError) Error() string

type GameFinishedError

type GameFinishedError struct {
	G GameMetadata
}

func (GameFinishedError) Error

func (g GameFinishedError) Error() string

type GameID

type GameID []byte

func GenerateGameID

func GenerateGameID() GameID

func (GameID) DeepCopy

func (o GameID) DeepCopy() GameID

func (GameID) Eq

func (g GameID) Eq(h GameID) bool

func (GameID) String

func (g GameID) String() string

func (GameID) ToKey

func (g GameID) ToKey() GameIDKey

type GameIDKey

type GameIDKey string

type GameKey

type GameKey string

type GameMessage

type GameMessage struct {
	V__  Version        `codec:"v" json:"v"`
	V1__ *GameMessageV1 `codec:"v1,omitempty" json:"v1,omitempty"`
}

func NewGameMessageDefault

func NewGameMessageDefault(v Version) GameMessage

func NewGameMessageWithV1

func NewGameMessageWithV1(v GameMessageV1) GameMessage

func (GameMessage) DeepCopy

func (o GameMessage) DeepCopy() GameMessage

func (*GameMessage) V

func (o *GameMessage) V() (ret Version, err error)

func (GameMessage) V1

func (o GameMessage) V1() (res GameMessageV1)

type GameMessageBody

type GameMessageBody struct {
	T__                  MessageType         `codec:"t" json:"t"`
	Start__              *Start              `codec:"start,omitempty" json:"start,omitempty"`
	Commitment__         *Commitment         `codec:"commitment,omitempty" json:"commitment,omitempty"`
	CommitmentComplete__ *CommitmentComplete `codec:"commitmentComplete,omitempty" json:"commitmentComplete,omitempty"`
	Reveal__             *Secret             `codec:"reveal,omitempty" json:"reveal,omitempty"`
}

func NewGameMessageBodyWithCommitment

func NewGameMessageBodyWithCommitment(v Commitment) GameMessageBody

func NewGameMessageBodyWithCommitmentComplete

func NewGameMessageBodyWithCommitmentComplete(v CommitmentComplete) GameMessageBody

func NewGameMessageBodyWithEnd

func NewGameMessageBodyWithEnd() GameMessageBody

func NewGameMessageBodyWithReveal

func NewGameMessageBodyWithReveal(v Secret) GameMessageBody

func NewGameMessageBodyWithStart

func NewGameMessageBodyWithStart(v Start) GameMessageBody

func (GameMessageBody) Commitment

func (o GameMessageBody) Commitment() (res Commitment)

func (GameMessageBody) CommitmentComplete

func (o GameMessageBody) CommitmentComplete() (res CommitmentComplete)

func (GameMessageBody) DeepCopy

func (o GameMessageBody) DeepCopy() GameMessageBody

func (GameMessageBody) Encode

func (GameMessageBody) Reveal

func (o GameMessageBody) Reveal() (res Secret)

func (GameMessageBody) Start

func (o GameMessageBody) Start() (res Start)

func (*GameMessageBody) T

func (o *GameMessageBody) T() (ret MessageType, err error)

type GameMessageEncoded

type GameMessageEncoded string

GameMessageEncoded is a game message that is shipped over the chat channel. Inside, it's a base64-encoded msgpack object (generated via AVDL->go compiler), but it's safe to think of it just as an opaque string.

func (GameMessageEncoded) Decode

func (e GameMessageEncoded) Decode() (*GameMessageV1, error)

type GameMessageV1

type GameMessageV1 struct {
	Md   GameMetadata    `codec:"md" json:"md"`
	Body GameMessageBody `codec:"body" json:"body"`
}

func (GameMessageV1) DeepCopy

func (o GameMessageV1) DeepCopy() GameMessageV1

func (GameMessageV1) Encode

func (v GameMessageV1) Encode() (GameMessageEncoded, error)

type GameMessageWrappedEncoded

type GameMessageWrappedEncoded struct {
	Sender UserDevice
	Body   GameMessageEncoded // base64-encoded GameMessaageBody that comes in over chat
}

GameMessageWrappedEncoded contains a sender and a Body. When dealer starts up, it will ask for the chat client to play back recent chats about games, via the ReadHistory interface. That will return a bunch of `GameMessageWrappedEncoded` for previous game chats that are being replayed.

func (*GameMessageWrappedEncoded) Decode

func (e *GameMessageWrappedEncoded) Decode() (*gameMessageWrapped, error)

type GameMetadata

type GameMetadata struct {
	Initiator      UserDevice     `codec:"initiator" json:"initiator"`
	ConversationID ConversationID `codec:"conversationID" json:"conversationID"`
	GameID         GameID         `codec:"gameID" json:"gameID"`
}

func (GameMetadata) DeepCopy

func (o GameMetadata) DeepCopy() GameMetadata

func (GameMetadata) String

func (g GameMetadata) String() string

func (GameMetadata) ToKey

func (g GameMetadata) ToKey() GameKey

type GamePlayerState

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

type GameReplayError

type GameReplayError struct {
	G GameID
}

func (GameReplayError) Error

func (g GameReplayError) Error() string

type GameShutdownError

type GameShutdownError struct {
	G GameMetadata
}

func (GameShutdownError) Error

func (g GameShutdownError) Error() string

type GameStateUpdateMessage

type GameStateUpdateMessage struct {
	Metadata GameMetadata
	// only one of the following will be non-nil
	Err                error
	Commitment         *UserDevice
	Reveal             *UserDevice
	CommitmentComplete *CommitmentComplete
	Result             *Result
}

GameStateUpdateMessage is sent from the game dealer out to the calling chat client, to update him on changes to game state that happened. All update messages are relative to the given GameMetadata. For each update, only one of Err, Commitment, Reveal, CommitmentComplete or Result will be non-nil.

type MessageType

type MessageType int
const (
	MessageType_START               MessageType = 1
	MessageType_COMMITMENT          MessageType = 2
	MessageType_COMMITMENT_COMPLETE MessageType = 3
	MessageType_REVEAL              MessageType = 4
	MessageType_END                 MessageType = 5
)

func (MessageType) DeepCopy

func (o MessageType) DeepCopy() MessageType

func (MessageType) String

func (e MessageType) String() string

type NoRevealError

type NoRevealError struct {
	G GameMetadata
	U UserDevice
}

func (NoRevealError) Error

func (n NoRevealError) Error() string

type PRNG

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

func Flip

func Flip(cp CommitmentPayload, players []PlayerState) (*PRNG, error)

Flip takes all the completed PlayerStates from the game, makes sure they don't have an error, and if not, outputs a PRNG from which arbirarily many ints, or bools, can be deterministically plucked. If there's an error, PRNG will be nil.

func NewPRNG

func NewPRNG(s Secret) *PRNG

func (*PRNG) Big

func (p *PRNG) Big(modulus *big.Int) *big.Int

func (*PRNG) Bool

func (p *PRNG) Bool() bool

func (*PRNG) Int

func (p *PRNG) Int(modulus int64) int64

func (*PRNG) Permutation

func (p *PRNG) Permutation(n int) []int

func (*PRNG) Read

func (p *PRNG) Read(out []byte) int

type Player

type Player string

Player is an identifier for a player in the flip game. It can be anything, but must be unique for the game. You can use user IDs in hex here, for instance, or possibly (userid||deviceID) since each user in Keybase will likely enter a flip multiple times (if many if his devices are on).

type PlayerState

type PlayerState struct {
	Player     Player
	Commitment *Commitment
	Reveal     Secret
}

PlayerState refers to all state about a player in the game. It includes the Player's name, his commitment, and his revealed preimage.

type Result

type Result struct {
	Shuffle []int
	Bool    *bool
	Int     *int64
	Big     *big.Int
}

type Secret

type Secret [32]byte

func GenerateSecret

func GenerateSecret() Secret

func (Secret) DeepCopy

func (o Secret) DeepCopy() Secret

func (Secret) Eq

func (s Secret) Eq(t Secret) bool

func (Secret) Hash

func (s Secret) Hash() Secret

func (Secret) IsNil

func (s Secret) IsNil() bool

func (*Secret) XOR

func (s *Secret) XOR(t Secret) *Secret

type Stage

type Stage int
const (
	Stage_ROUND1        Stage = 1
	Stage_ROUND2        Stage = 2
	Stage_ROUND_CLEANUP Stage = 3
)

func (Stage) DeepCopy

func (o Stage) DeepCopy() Stage

func (Stage) String

func (e Stage) String() string

type Start

type Start struct {
	StartTime            Time           `codec:"startTime" json:"startTime"`
	CommitmentWindowMsec int64          `codec:"commitmentWindowMsec" json:"commitmentWindowMsec"`
	RevealWindowMsec     int64          `codec:"revealWindowMsec" json:"revealWindowMsec"`
	SlackMsec            int64          `codec:"slackMsec" json:"slackMsec"`
	Params               FlipParameters `codec:"params" json:"params"`
}

func NewStartWithBigInt

func NewStartWithBigInt(now time.Time, mod *big.Int) Start

NewStartWithBigInt makes new start parameters that yield a coinflip game that picks big int between 0 and mod.

func NewStartWithBool

func NewStartWithBool(now time.Time) Start

NewStartWithBool makes new start parameters that yield a coinflip game.

func NewStartWithInt

func NewStartWithInt(now time.Time, mod int64) Start

NewStartWithInt makes new start parameters that yield a coinflip game that picks an int between 0 and mod.

func NewStartWithShuffle

func NewStartWithShuffle(now time.Time, n int64) Start

NewStartWithShuffle makes new start parameters for a coinflip that randomly permutes the numbers between 0 and n, exclusive. This can be used to shuffle an array of names.

func (Start) CommitmentWindowWithSlack

func (s Start) CommitmentWindowWithSlack() time.Duration

func (Start) DeepCopy

func (o Start) DeepCopy() Start

func (Start) RevealWindowWithSlack

func (s Start) RevealWindowWithSlack() time.Duration

type Time

type Time int64

func ToTime

func ToTime(t time.Time) Time

func (Time) DeepCopy

func (o Time) DeepCopy() Time

func (Time) Duration

func (t Time) Duration() time.Duration

func (Time) Time

func (t Time) Time() time.Time

type TimeoutError

type TimeoutError struct {
	G     GameMetadata
	Stage Stage
}

func (TimeoutError) Error

func (t TimeoutError) Error() string

type UID

type UID []byte

func (UID) DeepCopy

func (o UID) DeepCopy() UID

func (UID) Eq

func (u UID) Eq(v UID) bool

func (UID) String

func (u UID) String() string

type UnforwardableMessageError

type UnforwardableMessageError struct {
	G GameMetadata
}

func (UnforwardableMessageError) Error

type UnregisteredUserError

type UnregisteredUserError struct {
	G GameMetadata
	U UserDevice
}

func (UnregisteredUserError) Error

func (u UnregisteredUserError) Error() string

type UserDevice

type UserDevice struct {
	D DeviceID `codec:"d" json:"d"`
	U UID      `codec:"u" json:"u"`
}

func (UserDevice) DeepCopy

func (o UserDevice) DeepCopy() UserDevice

func (UserDevice) Eq

func (u UserDevice) Eq(v UserDevice) bool

func (UserDevice) ToKey

func (u UserDevice) ToKey() UserDeviceKey

type UserDeviceKey

type UserDeviceKey string

type Version

type Version int
const (
	Version_V1 Version = 1
)

func (Version) DeepCopy

func (o Version) DeepCopy() Version

func (Version) String

func (e Version) String() string

type WrongSenderError

type WrongSenderError struct {
	G        GameMetadata
	Expected UserDevice
	Actual   UserDevice
}

func (WrongSenderError) Error

func (w WrongSenderError) Error() string

Jump to

Keyboard shortcuts

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