auction

package
v0.0.0-...-76c1feb Latest Latest
Warning

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

Go to latest
Published: Sep 1, 2021 License: AGPL-3.0 Imports: 13 Imported by: 0

README

Setting up an auction:

Auctions are run entirely on layer two. Layer two applications are applications external to the protocol-level algod node, which could be considered layer one. Layer two solutions tend to operate on data in transaction Note fields.

Each step will first be explained in prose, followed by the console commands. Where possible, console commands have further explanation after them.

Set up algod

Create a data directory (here, called xx). Copy the genesis block, genesis.json, to the data directory. Start an algorand node using that data directory.

  • mkdir xx
  • cp installer/genesis/devnet/genesis.json xx
  • algod -d xx

Set up auctionbank

The auctionbank is a long-running process that provides Deposits, attestations that a user has credit with which to Bid. The following commands create the initial auction bank database, and then start the auctionbank process.

  • auctionbank -create
  • auctionbank

Set up auctionmaster key

The master key is the key that signs auction-starting Params and auction-ending Settlement messages. It is used by the short-lived auctionmaster process. The public master key is important, as it verifies signed auctionmaster messages and is used by the auctionbank, auctionconsole, and auctionminion to detect which transactions are related to the auction.

Create a directory to hold the auctionmaster keys (here, called am). Then, run algokey to initialize keys. Finally, fund the master key, so it can pay transaction fees.

  • mkdir am
  • algokey generate -f am/master.key -p am/master.pub
  • Transfer some money to account am/master.pub using goal or the REST API

Set up auctionminion

The auctionminion is a short-lived process that reads the blockchain to determine whether an auction has ended, and if so, what the relevant auction messages were.

Initialize the auctionminion. Edit the auctionminion.state file to indicate the auctionmaster public key (for verifying auctionmaster signatures and detecting transactions to/from the auctionmaster account). Also indicate the AlgodToken, for authorizing the auctionminion to make REST calls against the algod node.

  • auctionminion -init
  • Edit auctionminion.state, fill in AuctionKey from am/master.pub and AlgodToken from xx/algod.token

Register auction with the bank

The bank needs to know about the auction being created by the auctionmaster. Use curl to POST the auctionmaster public key to the bank's create-auctions endpoint.

  • curl -X POST --data-urlencode "auction=$(cat am/master.pub)" http://127.0.0.1:8123/create-auctions

Set up auction parameters

The initparams.json describes the initial params of the auction. Each subsequent auction params is determined from the previous params and the bids received in the previous auction.

Create the initial parameters file, initparams.json, from the provided template. Fill in desired parameters. Use auctionmaster to create a starttx (an auctionmaster-signed transaction with the params encoded into the message field).

  • auctionmaster -dir am -initparams -payfee 1000 -notesfee 1000 -currentversion https://github.com/algorand/spec/tree/a26ed78ed8f834e2b9ccb6eb7d3ee9f629a6e622 -genhash 4HkOQEL2o2bVh2P1wSpky3s6cwcEg/AAd5qlery942g=
  • cp am/initparams.json.tmpl am/initparams.json
  • Edit am/initparams.json, fill in the bank key from auctionbank, fill in other desired auction parameters. Add one or more public keys to DispensingMultisig.PKs (this could be the auction public key, for testing purposes), and adjust DispensingMultisig.Threshold as needed.
  • auctionmaster -dir am -initparams -txround $(goal -d xx node lastround) -payfee 1000 -notesfee 1000 -currentversion https://github.com/algorand/spec/tree/a26ed78ed8f834e2b9ccb6eb7d3ee9f629a6e622 -genhash 4HkOQEL2o2bVh2P1wSpky3s6cwcEg/AAd5qlery942g=

Broadcast initial auction start

Use goal's raw transaction send feature, or the equivalent REST API call, to broadcast the auction start transaction to the network.

  • goal -d xx clerk rawsend -f am/auction1.starttx

Start the auctionconsole

The auctionconsole is a long-running process used to observe an auction's progression. It needs the algod.token to make REST calls against the algorand node and the master public key to detect auction transactions and verify master signatures.

  • auctionconsole -apitoken $(cat xx/algod.token) -auctionkey $(cat am/master.pub) -debug

Participate in the auction

  • Open wallet/auction.html in a browser
  • Configure URLs and bank username; click "Reload"
  • Enter your private key mnemonic
  • Create bank username, if necessary
  • Transfer in some money
  • Enter bid currency amount and click "Go"

Settle the auction

Once the final round as described by the params message has passed, the auction is over. Run auctionminion to read all auction messages from the blockchain. Move the resulting .inputs files somewhere convenient to pass to the auctionmaster (here, the auctionmaster directory am from earlier steps is used). Again, run auctionmaster, this time consuming the .inputs files. Use a -txround value that will give sufficient time to collect the multisig signatures (see below).

  • auctionminion
  • mv auction*.inputs am/
  • auctionmaster -dir am -txround $(goal -d xx node lastround)

Broadcast auction settlement

To end the auction, use the raw transaction send feature to broadcast the resulting settletx transaction. The settletx summarizes auction results (so that observers can verify).

  • LASTID="$(cat am/lastsettled)"
  • NEXTID="$(expr $LASTID + 1)"
  • goal -d xx clerk rawsend -f am/auction${LASTID}.settletx

Sign and send payments

Finally, sign the paymenttx payment transactions to the auction winners. To do this, use algokey to add multisig signatures from as many multisig keys as needed:

  • LASTID="$(cat am/lastsettled)"
  • NEXTID="$(expr $LASTID + 1)"
  • algokey multisig -k .../some.multisig.key -t am/auction${LASTID}.paymenttx -o am/auction${LASTID}.paymenttx.signed

After enough signatures have been collected, merge the signatures and send the transactions:

  • goal -d xx clerk multisig merge -o merged.txs multiple-signed-paymenttx-files
  • goal -d xx clerk rawsend -f merged.txs

Feed auction settlement to auctionbank

The auctionbank needs to be informed of the auction outcomes, so that it can provide new accurate Deposit attestations in the next auction. In other words, it needs to know who spent their credit, and who still has credit with which to bid.

Here, curl is used to POST the settlement information to the auctionbank's settle-auction endpoint.

  • LASTID="$(cat am/lastsettled)"
  • curl -X POST --data-urlencode "auction=$(cat am/master.pub)" --data-urlencode "outcomes=$(base64 am/auction${LASTID}.outcomes)" --data-urlencode "sigsettle=$(base64 am/auction${LASTID}.settle)" http://127.0.0.1:8123/settle-auction

Cancel auction

  • auctionmaster -dir am -cancel -txround $(goal -d xx node lastround) -payfee 1000 -notesfee 1000 -currentversion https://github.com/algorand/spec/tree/a26ed78ed8f834e2b9ccb6eb7d3ee9f629a6e622 -genhash 4HkOQEL2o2bVh2P1wSpky3s6cwcEg/AAd5qlery942g=

Operating an auction:

There are two important types of keys for operating an auction: an auction key and a dispensing key. There is exactly one auction key for an auction; it is used to sign the auction start (the Params message) and to settle the auction (sign the settlement). There can be one or more dispensing keys; these form a multisig address used to dispense winnings, as configured by DispensingMultisig.PKs and DispensingMultisig.Threshold in initparams.json.

Each auction is identified by the auction public key and an auction ID. Auction IDs must be unique for a given auction key. An auction key can be reused for multiple auctions, as long as the auction IDs are not reused (e.g., by incrementing the auction IDs for each subsequent auction).

All of the keys used for operating an auction should be generated using algokey (as suggested in the above notes), and their mnemonic representation (words) should be written down on paper as a backup of that key. This backup should be used in case the computer storing the auction key (or one of the dispensing keys) crashes before the auction is settled.

As a general precaution, when operating an auction, check all of the transactions using msgpacktool -d -b32 before posting them on the blockchain. For example, before posting auction%d.starttx, examine it using cat auction%d.starttx | msgpacktool -d -b32 to make sure that the amount is 0, that the transaction is sent from the auction's address, etc.

When settling an auction, use multiple replicas to compute the outcomes, and ensure consistency of outcomes across replicas by comparing sha256sum checksums. auctionmaster -skipsign allows computing the auction%d.outcomes and auction%d.paymenttx files on a computer without a copy of master.key (but you need to distribute auction%d.param and auction%d.multisig, which aren't confidential).

Check that the payment transactions in the auction%d.paymenttx file look sensible -- the amounts seem in line with what we expect for the auction, the number of transactions is as expected, etc. Use msgpacktool -d -b32.

Sign the auction%d.paymenttx transactions using algokey multisig on each computer with a dispensing key, to form a complete multisig signature on all of the transactions. Merge the signatures using goal clerk multisig merge and post the transactions.

When settling an auction, use a -txround parameter that's far enough in advance to be able to assemble all of the multisig signatures before the transaction validity window expires.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func VerifySignedParams

func VerifySignedParams(sp SignedParams, auctionKey crypto.Digest) bool

VerifySignedParams checks the signature in a SignedParams object. The signature must verify against auctionKey. This function does NOT, however, check that the AuctionID matches any particular value. The caller must verify AuctionID as needed.

func VerifySignedSettlement

func VerifySignedSettlement(ss SignedSettlement, auctionKey crypto.Digest, auctionID uint64) bool

VerifySignedSettlement checks a SignedSettlement's signature, auction key, and auction ID.

Types

type Bid

type Bid struct {

	// BidderKey identifies the bidder placing this bid.
	BidderKey crypto.Digest `codec:"bidder"`

	// BidCurrency specifies how much external currency the bidder
	// is putting in with this bid.
	BidCurrency uint64 `codec:"cur"`

	// MaxPrice specifies the maximum price, in units of external
	// currency per Algo, that the bidder is willing to pay.
	// This must be at least as high as the current price of the
	// auction in the block in which this bid appears.
	MaxPrice uint64 `codec:"price"`

	// BidID identifies this bid.  The first bid by a bidder (identified
	// by BidderKey) with a particular BidID on the blockchain will be
	// considered, preventing replay of bids.  Specifying a different
	// BidID allows the bidder to place multiple bids in an auction.
	BidID uint64 `codec:"id"`

	// AuctionKey specifies the auction for this bid.
	AuctionKey crypto.Digest `codec:"auc"`

	// AuctionID identifies the auction for which this bid is intended.
	AuctionID uint64 `codec:"aid"`
	// contains filtered or unexported fields
}

Bid represents a bid by a user as part of an auction.

func (*Bid) CanMarshalMsg

func (_ *Bid) CanMarshalMsg(z interface{}) bool

func (*Bid) CanUnmarshalMsg

func (_ *Bid) CanUnmarshalMsg(z interface{}) bool

func (*Bid) MarshalMsg

func (z *Bid) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*Bid) MsgIsZero

func (z *Bid) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*Bid) Msgsize

func (z *Bid) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (Bid) ToBeHashed

func (b Bid) ToBeHashed() (protocol.HashID, []byte)

ToBeHashed implements the crypto.Hashable interface.

func (*Bid) UnmarshalMsg

func (z *Bid) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type BidOutcomes

type BidOutcomes struct {

	// AuctionKey is the public key for the series of auctions.
	AuctionKey crypto.Digest `codec:"auc"`

	// AuctionID specifies the auction in which these outcomes apply.
	AuctionID uint64 `codec:"aid"`

	// Price indicates the price, in units of external currency
	// per algo, at which this auction finished.
	Price uint64 `codec:"price"`

	// Cleared indicates whether the auction fully cleared.
	// It is the same as in the Settlement.
	Cleared bool `codec:"cleared"`

	// Outcomes is a list of bid outcomes, one for every placed bid
	// in the auction.
	Outcomes []BidderOutcome `codec:"outcomes,allocbound=-"`
	// contains filtered or unexported fields
}

BidOutcomes describes the outcome of an auction.

func (*BidOutcomes) CanMarshalMsg

func (_ *BidOutcomes) CanMarshalMsg(z interface{}) bool

func (*BidOutcomes) CanUnmarshalMsg

func (_ *BidOutcomes) CanUnmarshalMsg(z interface{}) bool

func (*BidOutcomes) MarshalMsg

func (z *BidOutcomes) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*BidOutcomes) MsgIsZero

func (z *BidOutcomes) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*BidOutcomes) Msgsize

func (z *BidOutcomes) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (BidOutcomes) ToBeHashed

func (o BidOutcomes) ToBeHashed() (protocol.HashID, []byte)

ToBeHashed implements the crypto.Hashable interface.

func (*BidOutcomes) UnmarshalMsg

func (z *BidOutcomes) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type BidderOutcome

type BidderOutcome struct {

	// BidderKey indicates the bidder that participated in the auction.
	BidderKey crypto.Digest `codec:"key"`

	// AlgosWon indicates the number of MicroAlgos that were won
	// by this bidder.
	AlgosWon uint64 `codec:"alg"`

	// WinningsAddress is the address to which the winning algos will
	// be sent to
	WinningsAddress crypto.Digest `codec:"out"`

	// BidID indicates the ID of the successful bid.
	BidID uint64 `codec:"id"`
	// contains filtered or unexported fields
}

BidderOutcome specifies the outcome of a particular bidder's participation in an auction.

func (*BidderOutcome) CanMarshalMsg

func (_ *BidderOutcome) CanMarshalMsg(z interface{}) bool

func (*BidderOutcome) CanUnmarshalMsg

func (_ *BidderOutcome) CanUnmarshalMsg(z interface{}) bool

func (*BidderOutcome) MarshalMsg

func (z *BidderOutcome) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*BidderOutcome) MsgIsZero

func (z *BidderOutcome) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*BidderOutcome) Msgsize

func (z *BidderOutcome) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*BidderOutcome) UnmarshalMsg

func (z *BidderOutcome) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type BidderState

type BidderState struct {
	// WinningsAddresses keeps track of the of each bidder's winnings address
	WinningsAddress crypto.Digest

	// DepositAmount keeps track of the deposit amounts for
	// every bidder.
	DepositAmount uint64

	// PlacedBidIDs keeps track of bids placed by a bidder.
	PlacedBidIDs []uint64
}

BidderState keeps track of the different data points for each bidder

type Deposit

type Deposit struct {

	// BidderKey is the hash of the bidder's public key, used to
	// authenticate bids paid for by this deposit.
	BidderKey crypto.Digest `codec:"key"`

	// WinningsAddress is the address to which the winning algos should
	// be sent to (Optional, if this field is empty, the address will be set
	// to BidderKey)
	WinningsAddress crypto.Digest `codec:"out"`

	// Currency indicates the amount of external currency deposited.
	Currency uint64 `codec:"cur"`

	// AuctionKey specifies the auction into which the currency is
	// being deposited.
	AuctionKey crypto.Digest `codec:"auc"`

	// AuctionID indicates the auction number for which this currency
	// has been deposited.
	AuctionID uint64 `codec:"aid"`

	// DepositID uniquely identifies this deposit within an auction
	// (identified by AuctionID), so that a deposit cannot be applied
	// multiple times in the same auction.
	DepositID uint64 `codec:"did"`
	// contains filtered or unexported fields
}

Deposit represents a deposit of external currency with a bank like CoinList, for a specific auction number.

func (*Deposit) CanMarshalMsg

func (_ *Deposit) CanMarshalMsg(z interface{}) bool

func (*Deposit) CanUnmarshalMsg

func (_ *Deposit) CanUnmarshalMsg(z interface{}) bool

func (*Deposit) MarshalMsg

func (z *Deposit) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*Deposit) MsgIsZero

func (z *Deposit) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*Deposit) Msgsize

func (z *Deposit) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (Deposit) ToBeHashed

func (d Deposit) ToBeHashed() (protocol.HashID, []byte)

ToBeHashed implements the crypto.Hashable interface.

func (*Deposit) UnmarshalMsg

func (z *Deposit) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

func (Deposit) WinningAddress

func (d Deposit) WinningAddress() crypto.Digest

WinningAddress returns the effective winning address

type MasterInput

type MasterInput struct {

	// Round indicates the round number in which this input appeared.
	Round uint64 `codec:"rnd"`

	// Type indicates whether this is a deposit or a bid.  Only deposit
	// and bid field types are valid here.
	Type NoteFieldType `codec:"t"`

	// SignedDeposit, for NoteDeposit type.
	SignedDeposit SignedDeposit `codec:"d"`

	// SignedBid, for NoteBid type.
	SignedBid SignedBid `codec:"b"`
	// contains filtered or unexported fields
}

MasterInput describes an input to an auction, used to feed auction deposits and bids into the auctionmaster tool.

func (*MasterInput) CanMarshalMsg

func (_ *MasterInput) CanMarshalMsg(z interface{}) bool

func (*MasterInput) CanUnmarshalMsg

func (_ *MasterInput) CanUnmarshalMsg(z interface{}) bool

func (*MasterInput) MarshalMsg

func (z *MasterInput) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*MasterInput) MsgIsZero

func (z *MasterInput) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*MasterInput) Msgsize

func (z *MasterInput) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*MasterInput) UnmarshalMsg

func (z *MasterInput) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type NoteField

type NoteField struct {

	// Type indicates which type of a message this is
	Type NoteFieldType `codec:"t"`

	// SignedDeposit, for NoteDeposit type
	SignedDeposit SignedDeposit `codec:"d"`

	// SignedBid, for NoteBid type
	SignedBid SignedBid `codec:"b"`

	// SignedSettlement, for NoteSettlement type
	SignedSettlement SignedSettlement `codec:"s"`

	// SignedParams, for NoteParams type
	SignedParams SignedParams `codec:"p"`
	// contains filtered or unexported fields
}

NoteField is the struct that represents an auction message.

func (*NoteField) CanMarshalMsg

func (_ *NoteField) CanMarshalMsg(z interface{}) bool

func (*NoteField) CanUnmarshalMsg

func (_ *NoteField) CanUnmarshalMsg(z interface{}) bool

func (*NoteField) MarshalMsg

func (z *NoteField) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*NoteField) MsgIsZero

func (z *NoteField) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*NoteField) Msgsize

func (z *NoteField) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*NoteField) UnmarshalMsg

func (z *NoteField) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type NoteFieldType

type NoteFieldType string

NoteFieldType indicates a type of auction message encoded into a transaction's Note field.

const (
	// NoteDeposit indicates a SignedDeposit message.
	NoteDeposit NoteFieldType = "d"

	// NoteBid indicates a SignedBid message.
	NoteBid NoteFieldType = "b"

	// NoteSettlement indicates a SignedSettlement message.
	NoteSettlement NoteFieldType = "s"

	// NoteParams indicates a SignedParams message.
	NoteParams NoteFieldType = "p"
)

func (NoteFieldType) CanMarshalMsg

func (_ NoteFieldType) CanMarshalMsg(z interface{}) bool

func (*NoteFieldType) CanUnmarshalMsg

func (_ *NoteFieldType) CanUnmarshalMsg(z interface{}) bool

func (NoteFieldType) MarshalMsg

func (z NoteFieldType) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (NoteFieldType) MsgIsZero

func (z NoteFieldType) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (NoteFieldType) Msgsize

func (z NoteFieldType) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*NoteFieldType) UnmarshalMsg

func (z *NoteFieldType) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type Params

type Params struct {

	// AuctionKey is the public key of the auction operator.
	// This is somewhat superfluous, because the Params struct
	// gets signed by the corresponding private key, so in order
	// to verify a SignedParams, the caller must already know
	// the correct AuctionKey to use.  However, having this field
	// here is useful to allow code to keep track of all auction
	// parameters (including the public key) using a Params struct.
	AuctionKey crypto.Digest `codec:"auc"`

	// AuctionID identifies the auction whose parameters are being
	// specified.
	AuctionID uint64 `codec:"aid"`

	// BankKey specifies the key of the external bank that will
	// be signing deposits.
	BankKey crypto.Digest `codec:"bank"`

	// DispensingKey specifies the public key of the account from
	// which auction winnings will be dispensed.
	DispensingKey crypto.Digest `codec:"dispense"`

	// LastPrice specifies the price at the end of the auction
	// (i.e., in the last chunk), in units of external currency
	// per Algo.  This is called “reserve price” in the design doc.
	LastPrice uint64 `codec:"lastprice"`

	// DepositRound specifies the first block in which deposits
	// will be considered.  This can be less than FirstRound to
	// allow the external bank (e.g., CoinList) to place deposits
	// for an auction before bidding begins.
	DepositRound uint64 `codec:"depositrnd"`

	// FirstRound specifies the first block in which bids will be
	// considered.
	FirstRound uint64 `codec:"firstrnd"`

	// PriceChunkRounds specifies the number of blocks for which
	// the price remains the same.  The auction proceeds in chunks
	// of PriceChunkRounds at a time, starting from FirstRound.
	PriceChunkRounds uint64 `codec:"chunkrnds"`

	// NumChunks specifies the number of PriceChunkRounds-sized
	// chunks for which the auction will run.  This means that
	// the last block in which a bid can be placed will be
	// (FirstRound + PriceChunkRounds*NumChunnks - 1).
	NumChunks uint64 `codec:"numchunks"`

	// MaxPriceMultiple defines the ratio between MaxPrice (the
	// starting price of the auction) and LastPrice.  Expect this
	// is on the order of 100.
	MaxPriceMultiple uint64 `codec:"maxmult"`

	// NumAlgos specifies the maximum number of MicroAlgos that will be
	// sold in this auction.
	NumAlgos uint64 `codec:"maxalgos"`

	// MinBidAlgos specifies the minimum amount of a bid, in terms
	// of the number of MicroAlgos at the bid's maximum price.  This
	// should not be less than MinBalance, otherwise the transaction
	// that dispenses winnings might be rejected.
	MinBidAlgos uint64 `codec:"minbidalgos"`
	// contains filtered or unexported fields
}

Params describes the parameters for a particular auction.

func (*Params) CanMarshalMsg

func (_ *Params) CanMarshalMsg(z interface{}) bool

func (*Params) CanUnmarshalMsg

func (_ *Params) CanUnmarshalMsg(z interface{}) bool

func (*Params) MarshalMsg

func (z *Params) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*Params) MsgIsZero

func (z *Params) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*Params) Msgsize

func (z *Params) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (Params) ToBeHashed

func (p Params) ToBeHashed() (protocol.HashID, []byte)

ToBeHashed implements the crypto.Hashable interface.

func (*Params) UnmarshalMsg

func (z *Params) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

func (Params) VerifySignedBid

func (p Params) VerifySignedBid(sb SignedBid) bool

VerifySignedBid checks a SignedBid's signature, auction key, and auction ID against the Params data.

func (Params) VerifySignedDeposit

func (p Params) VerifySignedDeposit(sd SignedDeposit) bool

VerifySignedDeposit checks a SignedDeposit's signature, auction key, and auction ID against the Params data.

func (Params) VerifySignedSettlement

func (p Params) VerifySignedSettlement(ss SignedSettlement) bool

VerifySignedSettlement can also work on a Params object.

type RunningAuction

type RunningAuction struct {
	// Params specifies the initial parameters
	Params Params

	// DepositIDs keeps track of deposits that have been made.
	DepositIDs map[uint64]struct{}

	// Bidders keeps track of every bidder'a data.
	Bidders map[crypto.Digest]BidderState

	// Bids keeps track of the bids so far, by round in which
	// the bid was placed.
	Bids map[uint64][]RunningBid

	// TotalCurrency keeps track of the sum of all bids in Bids
	// (in units of external currency, e.g., USD).  This is tracked
	// to ensure that settlement arithmetic cannot overflow.
	TotalCurrency uint64

	// Outcome describes the outcome of the auction. Outcome is set only
	// after the auction was settled.
	Outcome *BidOutcomes
}

RunningAuction keeps track of the state of an in-progress auction.

func Init

func Init(p Params) (*RunningAuction, error)

Init initializes an auction.

func InitSigned

func InitSigned(sp SignedParams, auctionKey crypto.Digest) (*RunningAuction, error)

InitSigned checks the signature on a SignedParams and then calls Init. As with VerifySignedParams(), it does not check the AuctionID.

func (*RunningAuction) Balance

func (ra *RunningAuction) Balance(addr crypto.Digest) uint64

Balance returns an address' balance, if the user hasn't deposit, it reruns 0

func (*RunningAuction) Cleared

func (ra *RunningAuction) Cleared() bool

Cleared returns true if the auction is cleared, false otherwise

func (*RunningAuction) CurrentPrice

func (ra *RunningAuction) CurrentPrice(rnd uint64) uint64

CurrentPrice computes the current unit price (external currency per Algo) in a particular round [rnd] for a running auction.

func (*RunningAuction) LastRound

func (ra *RunningAuction) LastRound() uint64

LastRound computes the last round for valid deposits and bids.

func (*RunningAuction) PlaceBid

func (ra *RunningAuction) PlaceBid(b Bid, rnd uint64) (err error)

PlaceBid handles a Bid message [b] from round [rnd]. The return value indicates if the message was processed (valid) or not (invalid).

A bid is considered valid iff: - The bid is for the correct auction key and ID. - The bid's round is between the auction's first and the last round. - The bid price is at least as high as the current round's price. - The bid amount does not exceed the bidder's currency balance. - The bid has at least enough currency for one algo at the current price. - The bid has not been already placed (duplicate BidID). - The bid does not overflow the total currency.

func (*RunningAuction) PlaceDeposit

func (ra *RunningAuction) PlaceDeposit(d Deposit, rnd uint64) (err error)

PlaceDeposit handles a Deposit message [d] from round [rnd]. The return value indicates if the message was processed (valid) or not (invalid).

A deposit is considered valid iff: - The deposit is for the correct auction key and ID. - The deposit is placed in an allowed round (DepositRound to LastRound). - The deposit has not been deposited before (by DepositID). - The deposit does not overflow the bidder's balance.

func (*RunningAuction) PlaceSignedBid

func (ra *RunningAuction) PlaceSignedBid(sb SignedBid, rnd uint64) (err error)

PlaceSignedBid checks the signature on a SignedBid and calls PlaceBid if the signature check passes.

func (*RunningAuction) PlaceSignedDeposit

func (ra *RunningAuction) PlaceSignedDeposit(sd SignedDeposit, rnd uint64) (err error)

PlaceSignedDeposit checks the signature on a SignedDeposit and calls PlaceDeposit if the signature check passes.

func (*RunningAuction) Settle

func (ra *RunningAuction) Settle(cancel bool) BidOutcomes

Settle settles the auction, after all of the auction's rounds have completed. Returns the bid outcomes, which includes the cleared flag.

Settle should *NOT* be called before the last round has passed any time the cancel flag isn't true.

type RunningBid

type RunningBid struct {
	// Bidder represents the bidder's key.
	Bidder crypto.Digest

	// Currency represents the bid's amount of external currency.
	Currency uint64

	// BidID represents the bid ID
	BidID uint64
}

RunningBid keeps track of an outstanding bid.

type SerializedRunningAuction

type SerializedRunningAuction struct {
	*RunningAuction
	// contains filtered or unexported fields
}

SerializedRunningAuction provides a wrapper around RunningAuction and guarantees that all calls to RunningAuction are serialized.

func MakeSerializedLogic

func MakeSerializedLogic(params Params) (*SerializedRunningAuction, error)

MakeSerializedLogic initializes a SerSerializedRunningAuction

func (*SerializedRunningAuction) Balance

func (sra *SerializedRunningAuction) Balance(addr crypto.Digest) uint64

Balance provides a wrapper for RunningAuction's Balance

func (*SerializedRunningAuction) Bids

func (sra *SerializedRunningAuction) Bids() []RunningBid

Bids provides a wrapper for RunningAuction's Bids

func (*SerializedRunningAuction) Cleared

func (sra *SerializedRunningAuction) Cleared() bool

Cleared provides a wrapper for RunningAuction's Cleared

func (*SerializedRunningAuction) CurrentPrice

func (sra *SerializedRunningAuction) CurrentPrice(rnd uint64) uint64

CurrentPrice provides a wrapper for RunningAuction's CurrentPrice

func (*SerializedRunningAuction) LastRound

func (sra *SerializedRunningAuction) LastRound() uint64

LastRound provides a wrapper for RunningAuction's LastRound

func (*SerializedRunningAuction) Params

func (sra *SerializedRunningAuction) Params() Params

Params provides a wrapper for RunningAuction's Params

func (*SerializedRunningAuction) PlaceBid

func (sra *SerializedRunningAuction) PlaceBid(b Bid, rnd uint64) (err error)

PlaceBid provides a wrapper for RunningAuction's PlaceBid

func (*SerializedRunningAuction) PlaceDeposit

func (sra *SerializedRunningAuction) PlaceDeposit(d Deposit, rnd uint64) (err error)

PlaceDeposit provides a wrapper for RunningAuction's PlaceDeposit

func (*SerializedRunningAuction) PlaceSignedBid

func (sra *SerializedRunningAuction) PlaceSignedBid(sb SignedBid, rnd uint64) (err error)

PlaceSignedBid provides a wrapper for RunningAuction's PlaceSignedBid

func (*SerializedRunningAuction) PlaceSignedDeposit

func (sra *SerializedRunningAuction) PlaceSignedDeposit(sd SignedDeposit, rnd uint64) (err error)

PlaceSignedDeposit provides a wrapper for RunningAuction's PlaceSignedDeposit

func (*SerializedRunningAuction) Settle

func (sra *SerializedRunningAuction) Settle(cancel bool) BidOutcomes

Settle provides a wrapper for RunningAuction's Settle

type Settlement

type Settlement struct {

	// AuctionKey is the public key for the series of auctions.
	AuctionKey crypto.Digest `codec:"auc"`

	// AuctionID identifies the auction being settled.
	AuctionID uint64 `codec:"aid"`

	// Cleared indicates whether the auction fully cleared.
	// It is the same as in the BidOutcomes.
	Cleared bool `codec:"cleared"`

	// OutcomesHash is a hash of the BidOutcomes for this auction.
	// The pre-image (the actual BidOutcomes struct) should be published
	// out-of-band (e.g., on the web site of the Algorand company).
	OutcomesHash crypto.Digest `codec:"outhash"`

	// Canceled indicates that the auction was canceled.
	// When Canceled is true, clear and OutcomeHash are false and empty, respectively.
	Canceled bool `codec:"canceled"`
	// contains filtered or unexported fields
}

Settlement describes the outcome of an auction.

func (*Settlement) CanMarshalMsg

func (_ *Settlement) CanMarshalMsg(z interface{}) bool

func (*Settlement) CanUnmarshalMsg

func (_ *Settlement) CanUnmarshalMsg(z interface{}) bool

func (*Settlement) MarshalMsg

func (z *Settlement) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*Settlement) MsgIsZero

func (z *Settlement) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*Settlement) Msgsize

func (z *Settlement) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (Settlement) ToBeHashed

func (s Settlement) ToBeHashed() (protocol.HashID, []byte)

ToBeHashed implements the crypto.Hashable interface.

func (*Settlement) UnmarshalMsg

func (z *Settlement) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

func (Settlement) VerifyBidOutcomes

func (s Settlement) VerifyBidOutcomes(bo BidOutcomes) bool

VerifyBidOutcomes checks that a BidOutcomes object matches a Settlement.

type SignedBid

type SignedBid struct {

	// Bid contains information about the bid.
	Bid Bid `codec:"bid"`

	// Sig is a signature by the bidder, as identified in the bid
	// (Bid.BidderKey) over the hash of the Bid.
	Sig crypto.Signature `codec:"sig"`
	// contains filtered or unexported fields
}

SignedBid represents a signed bid by a bidder.

func (*SignedBid) CanMarshalMsg

func (_ *SignedBid) CanMarshalMsg(z interface{}) bool

func (*SignedBid) CanUnmarshalMsg

func (_ *SignedBid) CanUnmarshalMsg(z interface{}) bool

func (*SignedBid) MarshalMsg

func (z *SignedBid) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*SignedBid) MsgIsZero

func (z *SignedBid) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*SignedBid) Msgsize

func (z *SignedBid) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*SignedBid) UnmarshalMsg

func (z *SignedBid) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type SignedDeposit

type SignedDeposit struct {

	// Deposit represents the deposit being signed.
	Deposit Deposit `codec:"dep"`

	// Sig is a signature over the hash of Deposit by the external
	// bank's key (e.g., CoinList).
	Sig crypto.Signature `codec:"sig"`
	// contains filtered or unexported fields
}

SignedDeposit represents a signed deposit message.

func (*SignedDeposit) CanMarshalMsg

func (_ *SignedDeposit) CanMarshalMsg(z interface{}) bool

func (*SignedDeposit) CanUnmarshalMsg

func (_ *SignedDeposit) CanUnmarshalMsg(z interface{}) bool

func (*SignedDeposit) MarshalMsg

func (z *SignedDeposit) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*SignedDeposit) MsgIsZero

func (z *SignedDeposit) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*SignedDeposit) Msgsize

func (z *SignedDeposit) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*SignedDeposit) UnmarshalMsg

func (z *SignedDeposit) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type SignedParams

type SignedParams struct {

	// Params specifies the parameters for the auction.
	Params Params `codec:"param"`

	// Sig is a signature over Params by the operator's key.
	Sig crypto.Signature `codec:"sig"`
	// contains filtered or unexported fields
}

SignedParams is a signed statement by the auction operator attesting to the start of an auction.

func (*SignedParams) CanMarshalMsg

func (_ *SignedParams) CanMarshalMsg(z interface{}) bool

func (*SignedParams) CanUnmarshalMsg

func (_ *SignedParams) CanUnmarshalMsg(z interface{}) bool

func (*SignedParams) MarshalMsg

func (z *SignedParams) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*SignedParams) MsgIsZero

func (z *SignedParams) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*SignedParams) Msgsize

func (z *SignedParams) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*SignedParams) UnmarshalMsg

func (z *SignedParams) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type SignedSettlement

type SignedSettlement struct {

	// Settlement describes the outcome of an auction.
	Settlement Settlement `codec:"settle"`

	// Sig is a signature by the auction operator on the hash
	// of the Settlement struct above.
	Sig crypto.Signature `codec:"sig"`
	// contains filtered or unexported fields
}

SignedSettlement is a settlement signed by the auction operator (e.g., the Algorand company).

func (*SignedSettlement) CanMarshalMsg

func (_ *SignedSettlement) CanMarshalMsg(z interface{}) bool

func (*SignedSettlement) CanUnmarshalMsg

func (_ *SignedSettlement) CanUnmarshalMsg(z interface{}) bool

func (*SignedSettlement) MarshalMsg

func (z *SignedSettlement) MarshalMsg(b []byte) (o []byte)

MarshalMsg implements msgp.Marshaler

func (*SignedSettlement) MsgIsZero

func (z *SignedSettlement) MsgIsZero() bool

MsgIsZero returns whether this is a zero value

func (*SignedSettlement) Msgsize

func (z *SignedSettlement) Msgsize() (s int)

Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message

func (*SignedSettlement) UnmarshalMsg

func (z *SignedSettlement) UnmarshalMsg(bts []byte) (o []byte, err error)

UnmarshalMsg implements msgp.Unmarshaler

type State

type State int

State represents the state of the auction

const (
	// Uninitialized indicates that no auction has started
	Uninitialized State = iota

	// Active indicates that the auction is currently running and accepting bids and deposits
	Active

	// Closed indicates that the auction does not accepts bids nor deposits but has not settled yet
	Closed

	// Settled indicates that the auction is settled
	Settled
)

type Tracker

type Tracker struct {
	// Auctions is a map from AuctionID to a RunningAuction.
	// It may not be modified after initialization.
	Auctions map[uint64]*SerializedRunningAuction

	// AuctionKey is the Auctioneer's address.
	// It may not be modified after initialization.
	AuctionKey basics.Address
	// contains filtered or unexported fields
}

Tracker is in charge of the running auction. Tracker holds the state of all seen auctions. Each auction is modeled as a simple FSM with 4 states defined above with the following transitions: - Uninitialized -> Active | Params - Active -> Active | Bid, Deposit - Active -> Closed | round has passed but no settlement message was received yet - Active -> Settled | Settlement - Closed -> Settled | Settlement - Settled -> Active | Params

func MakeTracker

func MakeTracker(startRound uint64, auctionKey string) (*Tracker, error)

MakeTracker initialized an Tracker

func (*Tracker) LastAuctionID

func (am *Tracker) LastAuctionID() (uint64, error)

LastAuctionID returns the last known auction ID

func (*Tracker) LiveUpdate

func (am *Tracker) LiveUpdate(rc client.RestClient)

LiveUpdate fetches data from the blockchain and updates the RunningAuction with every new block. LiveUpdate blocks and should be ran in a go routine.

func (*Tracker) LiveUpdateWithContext

func (am *Tracker) LiveUpdateWithContext(ctx context.Context, wg *sync.WaitGroup, rc client.RestClient)

LiveUpdateWithContext is as LiveUpdate, but with an arbitrary wrapping context

func (*Tracker) ProcessMessage

func (am *Tracker) ProcessMessage(txn v1.Transaction) error

ProcessMessage gets a transaction, decodes its note field, checks for signature validity and places it in Tracker.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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