package dashboard import ( "bytes" "crypto/ed25519" "encoding/base32" "encoding/json" "kesim.org/seal" ) type Dashboard interface { NewAuction(description *seal.SignedDescription) (auctionId string, e error) Auctions(state AuctionState) map[string]*seal.SignedDescription Join(auctionId string, commitment SignedCommitment, bidderId ed25519.PublicKey) error Commitments(auctionId string) (bidders map[string]SignedCommitment, e error) Publish(auctionId string, round uint8, message SignedMessage, bidderId ed25519.PublicKey) error Messages(auctionId string, round uint8) (messages map[string]SignedMessage, e error) Cancel(auctionId string, reason SignedMessage, bidderId ed25519.PublicKey) error Result(auctionId string) (price uint64, winner ed25519.PublicKey, e error) } type SignedMessage struct { Message []byte Signature []byte } type SignedCommitment struct { *seal.Commitment Signature []byte } type Error int const ( ErrUnknownError Error = iota ErrSellerIncorrectSignature ErrSellerAuctionExists ErrAuctionUnknown ErrAuctionNotStarted ErrAuctionNotReady ErrAuctionNotRunning ErrAuctionFinished ErrAuctionCanceled ErrAuctionTimeout ErrAuctionInvalidRound ErrBidderUnknown ErrBidderTimeout ErrBidderEmptyMessage ErrBidderIncorrectSignature ErrBidderWrongRound ErrBidderVerificationFailed ) func (d Error) Error() string { switch d { case ErrUnknownError: return "unknown error" case ErrSellerIncorrectSignature: return "incorrect seller signature" case ErrSellerAuctionExists: return "auction with that id already exists" case ErrAuctionUnknown: return "unknown auction" case ErrAuctionNotStarted: return "auction not started yet" case ErrAuctionNotReady: return "auction not ready" case ErrAuctionNotRunning: return "auction is not running" case ErrAuctionFinished: return "auction is finished" case ErrAuctionTimeout: return "action has timed out" case ErrAuctionCanceled: return "auction has been canceled" case ErrAuctionInvalidRound: return "invalid round" case ErrBidderUnknown: return "bidder is unknown" case ErrBidderTimeout: return "bidder has timed out" case ErrBidderEmptyMessage: return "empty message" case ErrBidderIncorrectSignature: return "incorrect signature from bidder" case ErrBidderWrongRound: return "wrong round" case ErrBidderVerificationFailed: return "round data couldn't be verified" default: panic("should not happen") } } type AuctionState int const ( AuctionStateUnknown AuctionState = iota AuctionStateReady AuctionStateRunning AuctionStateFinished AuctionStateCanceled AuctionStateTimeout AuctionStateLAST ) func (s *SignedMessage) Verify(pubkey ed25519.PublicKey) bool { return ed25519.Verify(pubkey, s.Message, s.Signature) } func (s *SignedCommitment) Verify(pubkey ed25519.PublicKey) bool { buf := &bytes.Buffer{} e := json.NewEncoder(buf).Encode(s.Commitment) if e != nil { return false } return ed25519.Verify(pubkey, buf.Bytes(), s.Signature) } func Pub2String(pubkey ed25519.PublicKey) string { return base32.StdEncoding.EncodeToString(pubkey) }