match

package
v0.0.0-...-7ad0b1f Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2022 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package match provides utilities and useful structures for building exchange systems.

Index

Constants

View Source
const (
	Debit = SettleType(iota%2 == 0)
	Credit
)
View Source
const (
	Buy  = Side(true)  // This should serialize to 0x01
	Sell = Side(false) // This should serialize to 0x00

)

Variables

This section is empty.

Functions

func CalculateClearingPrice

func CalculateClearingPrice(book map[float64][]*AuctionOrderIDPair) (clearingPrice float64, err error)

CalculateClearingPrice calculates the clearing price for orders based on their intersections. In the future the error will be used potentially since the divide operation at the end might be real bad.

func GenerateClearingExecs

func GenerateClearingExecs(book map[float64][]*AuctionOrderIDPair, clearingPrice float64) (orderExecs []*OrderExecution, settlementExecs []*SettlementExecution, err error)

GenerateClearingExecs goes through an orderbook with a clearing price, and generates executions based on the clearing matching algorithm

func MatchClearingAlgorithm

func MatchClearingAlgorithm(book map[float64][]*AuctionOrderIDPair) (orderExecs []*OrderExecution, settlementExecs []*SettlementExecution, err error)

MatchClearingAlgorithm runs the matching algorithm based on a uniform clearing price, first calculating the clearing price and then generating executions based on it.

func MatchPrioritizedOrders

func MatchPrioritizedOrders(buyOrders []*LimitOrderIDPair, sellOrders []*LimitOrderIDPair) (orderExecs []*OrderExecution, settlementExecs []*SettlementExecution, err error)

MatchPrioritizedOrders matches separated buy and sell orders that are properly sorted in price-time priority. These are the orders that should match. This should never return a list of order executions containing the same ID for more than one execution

func MatchTwoOpposite

func MatchTwoOpposite(buyLp *LimitOrderIDPair, sellLp *LimitOrderIDPair) (buyExec OrderExecution, sellExec OrderExecution, settlementExecs []*SettlementExecution, err error)

MatchTwo matches a buy order order with the sell order supplied as an argument, giving this order priority.

func NumberOfOrders

func NumberOfOrders(book map[float64][]*AuctionOrderIDPair) (numberOfOrders uint64)

NumberOfOrders computes the number of order pairs in a map representation of an orderbook

func SolveRC5AuctionOrderAsync

func SolveRC5AuctionOrderAsync(e *EncryptedAuctionOrder, puzzleResChan chan *OrderPuzzleResult)

SolveRC5AuctionOrderAsync solves order puzzles and creates auction orders from them. This should be run in a goroutine.

Types

type Asset

type Asset byte

Asset is a type which represents an asset

const (
	// BTC is a constant used to represent a BTC token
	BTC Asset = 0x00
	// VTC is a constant used to represent a VTC token
	VTC Asset = 0x01

	// BTCTest is a constant used to represent a BTC Test net token
	BTCTest Asset = 0x03
	// VTCTest is a constant used to represent a VTC Test net token
	VTCTest Asset = 0x04
	// LTCTest is a constant used to represent a LTC Test net token
	LTCTest Asset = 0x05
	// BTCReg is a constant used to represent a BTC Reg net token
	BTCReg Asset = 0x06
	// VTCReg is a constant used to represent a VTC Reg net token
	VTCReg Asset = 0x07
	// LTCReg is a constant used to represent a LTC Reg net token
	LTCReg Asset = 0x08
)

func AssetFromCoinParam

func AssetFromCoinParam(cpm *coinparam.Params) (a Asset, err error)

AssetFromCoinParam gets a byte representation of an asset from a coinparam

func AssetFromString

func AssetFromString(name string) (a Asset, err error)

AssetFromString returns an asset from a string

func (Asset) CoinParamFromAsset

func (a Asset) CoinParamFromAsset() (coinType *coinparam.Params, err error)

CoinParamFromAsset is the reverse of AssetFromCoinParam. TODO: change the coinparam so it has an inherent ID anyways?

func (Asset) String

func (a Asset) String() string

type AssetAmount

type AssetAmount struct {
	Asset  Asset  `json:"asset"`
	Amount uint64 `json:"amount"`
}

AssetAmount represents an asset and amount pair.

type AuctionBatch

type AuctionBatch struct {
	Batch     []*OrderPuzzleResult
	AuctionID [32]byte
}

AuctionBatch is a struct that represents a batch of auction order results

type AuctionBatcher

type AuctionBatcher interface {
	// RegisterAuction registers a new auction with a specified Auction ID, which will be an array of
	// 32 bytes.
	RegisterAuction(auctionID [32]byte) (err error)

	// AddEncrypted adds an encrypted order to an auction. This should error if either the auction doesn't
	// exist, or the auction is ended.
	AddEncrypted(order *EncryptedAuctionOrder) (err error)

	// EndAuction ends the auction with the specified auction ID, and returns the channel which will
	// receive a batch of orders puzzle results. This is like a promise. This channel should be of size 1.
	EndAuction(auctionID [32]byte) (batchChan chan *AuctionBatch, err error)

	// ActiveAuctions returns a map of auction id to time TODO: figure out if this is really necessary
	ActiveAuctions() (activeBatches map[[32]byte]time.Time)
}

AuctionBatcher is an interface for a service that collects orders and handles batching per auction. This is abstracted because solving puzzles is a task that should be easily outsourceable, and should not be integrated into the core logic. One could easily see a server that performs puzzle solving that is separate from the actual exchange. The exchange doesn't need to schedule puzzle solving, or worry about scaling it, but the auction batcher does. The auction batcher needs to involve solving many puzzles at once.

type AuctionEngine

type AuctionEngine interface {
	PlaceAuctionOrder(order *AuctionOrder, auctionID *AuctionID) (idRes *AuctionOrderIDPair, err error)
	CancelAuctionOrder(id *OrderID) (cancelled *CancelledOrder, cancelSettlement *SettlementExecution, err error)
	MatchAuctionOrders(auctionID *AuctionID) (orderExecs []*OrderExecution, settlementExecs []*SettlementExecution, err error)
}

The AuctionEngine is the interface for the internal matching engine. This should be the lowest level interface for the representation of a matching engine. One of these should be made for every pair.

type AuctionID

type AuctionID [32]byte

AuctionID represents an auction's unique ID. This is a byte array alias because sometimes the ID will be represented as text, and sometimes it will be represented as bytes. We conform it to the BinaryMarshaler interface and TextMarshaler interface.

func (*AuctionID) MarshalBinary

func (a *AuctionID) MarshalBinary() (data []byte, err error)

MarshalBinary encodes the receiver into a binary form and returns the result. This conforms to the BinaryMarshaler interface

func (*AuctionID) MarshalText

func (a *AuctionID) MarshalText() (text []byte, err error)

MarshalText encodes the receiver into UTF-8-encoded text and returns the result. This conforms to the TextMarshaler interface

func (*AuctionID) UnmarshalBinary

func (a *AuctionID) UnmarshalBinary(data []byte) (err error)

UnmarshalBinary decodes the form generated by MarshalBinary. This conforms to the BinaryMarshaler interface

func (*AuctionID) UnmarshalText

func (a *AuctionID) UnmarshalText(text []byte) (err error)

UnmarshalText deocdes the form generated by MarshalText. This conforms to the TextMarshaler interface

type AuctionOrder

type AuctionOrder struct {
	Pubkey      [33]byte `json:"pubkey"`
	Side        Side     `json:"side"`
	TradingPair Pair     `json:"pair"`
	// amount of assetHave the user would like to trade
	AmountHave uint64 `json:"amounthave"`
	// amount of assetWant the user wants for their assetHave
	AmountWant uint64 `json:"amountwant"`
	// IntendedAuction as the auctionID this should be in. We need this to protect against
	// the exchange withholding an order.
	AuctionID AuctionID `json:"auctionid"`
	// 2 byte nonce (So there can be max 2^16 of the same-looking orders by the same pubkey in the same batch)
	// This is used to protect against the exchange trying to replay a bunch of orders
	Nonce     [2]byte `json:"nonce"`
	Signature []byte  `json:"signature"`
}

AuctionOrder represents a batch order

func (*AuctionOrder) Deserialize

func (a *AuctionOrder) Deserialize(data []byte) (err error)

Deserialize deserializes an order into the struct ptr it's being called on

func (*AuctionOrder) GenerateExecutionFromPrice

func (a *AuctionOrder) GenerateExecutionFromPrice(orderID *OrderID, execPrice float64, amountToFill uint64) (orderExec OrderExecution, setExecs []*SettlementExecution, fillRemainder uint64, err error)

GenerateExecutionFromPrice generates a trade execution from a price and an amount to fill. This is intended to be used by the matching engine when a price is determined for this order to execute at. amountToFill refers to the amount of AssetWant that can be filled. So the other side's "AmountHave" can be passed in as a parameter. The order ID will be filled in, as it's being passed as a parameter. This returns a fillRemainder, which is the amount that is left over from amountToFill after filling orderID at execPrice and amountToFill

func (*AuctionOrder) GenerateOrderFill

func (a *AuctionOrder) GenerateOrderFill(orderID *OrderID, execPrice float64) (orderExec OrderExecution, setExecs []*SettlementExecution, err error)

GenerateOrderFill creates an execution that will fill an order (AmountHave at the end is 0) and provides an order and settlement execution. This does not assume anything about the price of the order, as we can't infer what price the order was placed at. TODO: Figure out whether or not these should be pointers

func (*AuctionOrder) IsBuySide

func (a *AuctionOrder) IsBuySide() bool

IsBuySide returns true if the limit order is buying

func (*AuctionOrder) IsSellSide

func (a *AuctionOrder) IsSellSide() bool

IsSellSide returns true if the limit order is selling

func (*AuctionOrder) OppositeSide

func (a *AuctionOrder) OppositeSide() (sideStr Side)

OppositeSide is a helper to get the opposite side of the order

func (*AuctionOrder) Price

func (a *AuctionOrder) Price() (price float64, err error)

Price gets a float price for the order. This determines how it will get matched. The exchange should figure out if it can take some of the

func (*AuctionOrder) Serialize

func (a *AuctionOrder) Serialize() (buf []byte)

Serialize serializes an order, possible replay attacks here since this is what you're signing? but anyways this is the order: [33 byte pubkey] pair amountHave amountWant <length side> side [32 byte auctionid]

func (*AuctionOrder) SerializeSignable

func (a *AuctionOrder) SerializeSignable() (buf []byte)

SerializeSignable serializes the fields that are hashable, and will be signed. These are also what would get verified.

func (*AuctionOrder) SetAmountWant

func (a *AuctionOrder) SetAmountWant(price float64) (err error)

SetAmountWant sets the amountwant value of the limit order according to a price

func (*AuctionOrder) String

func (a *AuctionOrder) String() string

func (*AuctionOrder) TurnIntoEncryptedOrder

func (a *AuctionOrder) TurnIntoEncryptedOrder(t uint64) (encrypted *EncryptedAuctionOrder, err error)

TurnIntoEncryptedOrder creates a puzzle for this auction order given the time. We make no assumptions about whether or not the order is signed.

type AuctionOrderIDPair

type AuctionOrderIDPair struct {
	OrderID OrderID
	Price   float64
	Order   *AuctionOrder
}

AuctionOrderIDPair is a pair of order ID and auction order, used for generating executions in the auction matching algorithm

type AuctionOrderbook

type AuctionOrderbook interface {
	// UpdateBookExec takes in an order execution and updates the orderbook.
	UpdateBookExec(orderExec *OrderExecution) (err error)
	// UpdateBookCancel takes in an order cancellation and updates the orderbook.
	UpdateBookCancel(cancel *CancelledOrder) (err error)
	// UpdateBookPlace takes in an order, ID, auction ID and adds the order to the orderbook.
	UpdateBookPlace(auctionIDPair *AuctionOrderIDPair) (err error)
	// GetOrder gets an order from an OrderID
	GetOrder(orderID *OrderID) (limOrder *AuctionOrderIDPair, err error)
	// CalculatePrice takes in a pair and returns the calculated price based on the orderbook.
	// This only works for a specific auction
	CalculatePrice(auctionID *AuctionID) (price float64, err error)
	// GetOrdersForPubkey gets orders for a specific pubkey.
	GetOrdersForPubkey(pubkey *koblitz.PublicKey) (orders map[float64][]*AuctionOrderIDPair, err error)
	// ViewAuctionOrderBook takes in a trading pair and returns the orderbook as a map
	ViewAuctionOrderBook() (book map[float64][]*AuctionOrderIDPair, err error)
}

AuctionOrderbook is the interface for an auction order book. The difference between the order book and the matching engine is that the matching engine is what processes orders and generates executions, whereas the limit orderbook does not. The order book takes in executions, and allows read access to the state of the orderbook.

type BatchResult

type BatchResult struct {
	OriginalBatch *AuctionBatch
	// RejectedResults and AcceptedResults should be disjoint sets
	RejectedResults []*OrderPuzzleResult
	AcceptedResults []*OrderPuzzleResult
}

BatchResult is a struct that represents the result of a batch auction.

type CancelledOrder

type CancelledOrder struct {
	OrderID *OrderID
}

CancelledOrder is broadcasted from the matching engine, marking an order as cancelled.

type CommitResponse

type CommitResponse struct {
	CommResponseSig    [65]byte      `json:"commresponse"`
	PuzzleAnswerReveal SolutionOrder `json:"puzzleanswer"`
}

CommitResponse is the commitment response. The sig is the puzzleanswerreveal + the commitment + the commitsig

func (*CommitResponse) Deserialize

func (cr *CommitResponse) Deserialize(raw []byte) (err error)

Deserialize turns the commit response from bytes into a usable struct.

func (*CommitResponse) Serialize

func (cr *CommitResponse) Serialize() (raw []byte, err error)

Serialize uses gob encoding to turn the commit response into bytes.

type Deposit

type Deposit struct {
	Pubkey              *koblitz.PublicKey
	Address             string
	Amount              uint64
	Txid                string
	CoinType            *coinparam.Params
	BlockHeightReceived uint64
	Confirmations       uint64
}

Deposit is a struct that represents a deposit on chain

func (*Deposit) String

func (d *Deposit) String() string

type EncryptedAuctionOrder

type EncryptedAuctionOrder struct {
	OrderCiphertext []byte
	OrderPuzzle     crypto.Puzzle
	IntendedAuction AuctionID
	IntendedPair    Pair
}

EncryptedAuctionOrder represents an encrypted Auction Order, so a ciphertext and a puzzle whos solution is a key, and an intended auction.

func (*EncryptedAuctionOrder) Deserialize

func (e *EncryptedAuctionOrder) Deserialize(raw []byte) (err error)

Deserialize deserializes the raw bytes into the encrypted auction order receiver

func (*EncryptedAuctionOrder) Serialize

func (e *EncryptedAuctionOrder) Serialize() (raw []byte, err error)

Serialize serializes the encrypted order using gob

type EncryptedSolutionOrder

type EncryptedSolutionOrder struct {
	OrderCiphertext []byte        `json:"orderciphertext"`
	OrderPuzzle     rsw.PuzzleRSW `json:"orderpuzzle"`
	IntendedAuction AuctionID     `json:"intendedauction"`
	IntendedPair    Pair          `json:"intendedpair"`
}

EncryptedSolutionOrder represents an encrypted Solution Order, so a ciphertext and a puzzle solution that is a key, and an intended auction.

func (*EncryptedSolutionOrder) Deserialize

func (es *EncryptedSolutionOrder) Deserialize(raw []byte) (err error)

Deserialize turns the encrypted solution order from bytes into a usable struct.

func (*EncryptedSolutionOrder) Serialize

func (es *EncryptedSolutionOrder) Serialize() (raw []byte, err error)

Serialize uses gob encoding to turn the encrypted solution order into bytes.

type Entry

type Entry struct {
	Amount uint64 `json:"amount"`
	Asset  Asset  `json:"asset"`
}

Entry represents either a credit or debit of some asset for some amount

func (*Entry) String

func (e *Entry) String() string

String returns a json representation of the Entry

type LightningDeposit

type LightningDeposit struct {
	Pubkey   *koblitz.PublicKey // maybe switch to real pubkey later
	Amount   uint64
	CoinType *coinparam.Params
	ChanIdx  uint32
}

LightningDeposit is a struct that represents a deposit made with lightning

func (*LightningDeposit) String

func (ld *LightningDeposit) String() string

type LimitBookStruct

type LimitBookStruct struct {
	PriceLevels []LimitQueue
}

LimitBookStruct is a struct that represents a Limit Orderbook. It tries to be very quick to access and manipulate, so the orderbook is represented as an array.

type LimitEngine

type LimitEngine interface {
	PlaceLimitOrder(order *LimitOrder) (idRes *LimitOrderIDPair, err error)
	CancelLimitOrder(id *OrderID) (cancelled *CancelledOrder, cancelSettlement *SettlementExecution, err error)
	MatchLimitOrders() (orderExecs []*OrderExecution, settlementExecs []*SettlementExecution, err error)
}

The LimitEngine is the interface for the internal matching engine. This should be the lowest level interface for the representation of a matching engine. One of these should be made for every pair.

type LimitOrder

type LimitOrder struct {
	Pubkey      [33]byte `json:"pubkey"`
	Side        Side     `json:"side"`
	TradingPair Pair     `json:"pair"`
	// amount of assetHave the user would like to trade
	AmountHave uint64 `json:"amounthave"`
	// amount of assetWant the user wants for their assetHave
	AmountWant uint64 `json:"amountwant"`
}

LimitOrder represents a limit order, implementing the order interface

func (*LimitOrder) GenerateExecutionFromPrice

func (l *LimitOrder) GenerateExecutionFromPrice(orderID *OrderID, execPrice float64, amountToFill uint64) (orderExec OrderExecution, setExecs []*SettlementExecution, fillRemainder uint64, err error)

GenerateExecutionFromPrice generates a trade execution from a price and an amount to fill. This is intended to be used by the matching engine when a price is determined for this order to execute at. amountToFill refers to the amount of AssetWant that can be filled. So the other side's "AmountHave" can be passed in as a parameter. The order ID will be filled in, as it's being passed as a parameter. This returns a fillRemainder, which is the amount that is left over from amountToFill after filling orderID at execPrice and amountToFill

func (*LimitOrder) GenerateOrderFill

func (l *LimitOrder) GenerateOrderFill(orderID *OrderID, execPrice float64) (orderExec OrderExecution, setExecs []*SettlementExecution, err error)

GenerateOrderFill creates an execution that will fill an order (AmountHave at the end is 0) and provides an order and settlement execution. This does not assume anything about the price of the order, as we can't infer what price the order was placed at. TODO: Figure out whether or not these should be pointers

func (*LimitOrder) Price

func (l *LimitOrder) Price() (price float64, err error)

Price gets a float price for the order. This determines how it will get matched. The exchange should figure out if it can take some of the

func (*LimitOrder) Serialize

func (l *LimitOrder) Serialize() (buf []byte, err error)

Serialize serializes an order, possible replay attacks here since this is what you're signing?

type LimitOrderIDPair

type LimitOrderIDPair struct {
	Timestamp time.Time   `json:"timestamp"`
	Price     float64     `json:"price"`
	OrderID   *OrderID    `json:"orderid"`
	Order     *LimitOrder `json:"limitorder"`
}

LimitOrderIDPair is order ID, order, price, and time, used for generating executions in limit order matching algorithms

type LimitOrderbook

type LimitOrderbook interface {
	// UpdateBookExec takes in an order execution and updates the orderbook.
	UpdateBookExec(orderExec *OrderExecution) (err error)
	// UpdateBookCancel takes in an order cancellation and updates the orderbook.
	UpdateBookCancel(cancel *CancelledOrder) (err error)
	// UpdateBookPlace takes in an order, ID, timestamp, and adds the order to the orderbook.
	UpdateBookPlace(limitIDPair *LimitOrderIDPair) (err error)
	// GetOrder gets an order from an OrderID
	GetOrder(orderID *OrderID) (limOrder *LimitOrderIDPair, err error)
	// CalculatePrice takes in a pair and returns the calculated price based on the orderbook.
	CalculatePrice() (price float64, err error)
	// GetOrdersForPubkey gets orders for a specific pubkey.
	GetOrdersForPubkey(pubkey *koblitz.PublicKey) (orders map[float64][]*LimitOrderIDPair, err error)
	// ViewLimitOrderbook takes in a trading pair and returns the orderbook as a map
	ViewLimitOrderBook() (book map[float64][]*LimitOrderIDPair, err error)
}

LimitOrderbook is the interface for a limit order book. The difference between the order book and the matching engine is that the matching engine is what processes orders and generates executions, whereas the limit orderbook does not. The order book takes in executions, and allows read access to the state of the orderbook. This can only be updated using the outputs of the matching engine.

type LimitQueue

type LimitQueue struct {
	BuyOrders  []LimitOrder
	SellOrders []LimitOrder
}

LimitQueue represents a time-ordered queue for buy and sell orders

type OrderExecution

type OrderExecution struct {
	OrderID       OrderID `json:"orderid"`
	NewAmountWant uint64  `json:"newamtwant"`
	NewAmountHave uint64  `json:"newamthave"`
	Filled        bool    `json:"filled"`
}

OrderExecution contains a simple order execution struct. This is what is being used in the clearing matching algorithm. We generate order executions so it stays independent of the settlement, and then pass those executions upwards. An execution is the output of a matching algorithm, so it's essentially the change in state from one orderbook matching step to the next.

What won't change when an order is executed:

  • Pubkey
  • AuctionID
  • Nonce
  • Signature
  • TradingPair
  • Side

What definitely will change:

  • AmountWant
  • AmountHave

What can happen?

  • The order is completely filled and should be deleted from the orderbook

In this case the amount debited or credited can be different than the AmountWant and AmountHave specified due to slippage. If the order is not deleted then it is partially filled. In the case that the order is not deleted and it is instead partially filled, the order will have an updated AmountWant and AmountHave, as well as assets credited and debited.

So what data do we include in an execution? We don't want to assume anything about the format of the user information, but we can assume that two orders are somehow distinguishable. This is why we include an order ID. It's also probably safe to assume that there will be user information associated with an order. We include:

  • Order identifying information (so an order ID)
  • The amount and asset debited to the user associated with the order ID.
  • The amount and asset credited from the user associated with the order ID.
  • The updated AmountWant
  • The updated AmountHave
  • Whether or not the order was filled completely.
  • If yes, that means the order gets deleted.

The asset for AmountWant and AmountHave can be determined from what they are in the order associated with the order ID.

Ideally, we want to make sure that either the order is filled completely, or we have the updated AmountWant and AmountHave. This would be a great place for some sort of enum, but unfortunately we'll have to go with a bool.

TODO: in the future, when AmountWant and AmountHave are replaced with a new price struct, this will need to change as well. The NewAmountWant and NewAmountHave can be replaced.

On a typical exchange, say $ per btc, if you place a buy order at a high $/btc and someone else places a sell order at an even lower $/btc (want/have) after, then your buy order will be executed at your price. However if someone else places a sell order at a low-ish price, and you place a buy order at a price higher, then it will be executed at a lower price.

Buy orders can only be matched at the price they are placed, or lower. Sell orders can only be matched at the price they are placed, or higher. You should never have an order be deleted and it yield less than you originally requested for the same value you provided.

The good thing is, order executions do not depend on the type of order.

func (*OrderExecution) Equal

func (oe *OrderExecution) Equal(otherExec *OrderExecution) bool

Equal compares one OrderExecution with another OrderExecution and returns true if all of the fields are the same.

func (*OrderExecution) String

func (oe *OrderExecution) String() string

String returns a json representation of the OrderExecution

type OrderID

type OrderID [32]byte

OrderID represents an order's unique ID. This is a byte array alias because sometimes the ID will be represented as text, and sometimes it will be represented as bytes. We conform it to the BinaryMarshaler interface and TextMarshaler interface.

func (*OrderID) GobDecode

func (o *OrderID) GobDecode(in []byte) (err error)

GobDecode overwrites the receiver, which must be a pointer, with the value represented by the byte slice, which was written by GobEncode, usually for the same concrete type.

func (*OrderID) GobEncode

func (o *OrderID) GobEncode() (ret []byte, err error)

GobEncode returns a byte slice representing the encoding of the receiver for transmission to a GobDecoder, usually of the same concrete type.

func (*OrderID) MarshalBinary

func (o *OrderID) MarshalBinary() (data []byte, err error)

MarshalBinary encodes the receiver into a binary form and returns the result. This conforms to the BinaryMarshaler interface

func (*OrderID) MarshalText

func (o *OrderID) MarshalText() (text []byte, err error)

MarshalText encodes the receiver into UTF-8-encoded text and returns the result. This conforms to the TextMarshaler interface

func (*OrderID) UnmarshalBinary

func (o *OrderID) UnmarshalBinary(data []byte) (err error)

UnmarshalBinary decodes the form generated by MarshalBinary. This conforms to the BinaryMarshaler interface

func (*OrderID) UnmarshalText

func (o *OrderID) UnmarshalText(text []byte) (err error)

UnmarshalText deocdes the form generated by MarshalText. This conforms to the TextMarshaler interface

type OrderPuzzleResult

type OrderPuzzleResult struct {
	Encrypted *EncryptedAuctionOrder
	Auction   *AuctionOrder
	Err       error
}

OrderPuzzleResult is a struct that is used as the type for a channel so we can atomically receive the original encrypted order, decrypted order, and an error

type Pair

type Pair struct {
	// AssetWant is the asset that buyers want, and that sellers are selling. debit buyers with this.
	AssetWant Asset `json:"assetWant"`
	// AssetHave is the asset that sellers are buying, and that buyers have. debit sellers with this.
	AssetHave Asset `json:"assetHave"`
}

Pair is a struct that represents a trading pair

func GenerateAssetPairs

func GenerateAssetPairs(coinList []*coinparam.Params) (pairList []*Pair, err error)

GenerateAssetPairs generates unique asset pairs based on the coinparams you pass it

func (*Pair) Deserialize

func (p *Pair) Deserialize(buf []byte) (err error)

Deserialize deserializes a byte array into a pair

func (*Pair) FromString

func (p *Pair) FromString(pairString string) (err error)

FromString creates a pair object from a string. This is for user input only, hence the slash

func (*Pair) PrettyString

func (p *Pair) PrettyString() string

PrettyString is used to do asset1/asset2 rather than the database-safe asset1_asset2

func (*Pair) Serialize

func (p *Pair) Serialize() []byte

Serialize serializes the pair into a byte array

func (*Pair) String

func (p *Pair) String() string

String is the tostring function for a pair

type Price

type Price struct {
	AmountWant uint64
	AmountHave uint64
}

Price represents an exchange rate. It's basically a fancy fraction. It follows the Want / Have method of doing things. TODO: The price and side can be represented as a single struct that contains the Asset the user wants (AssetWant), the Asset that the user has (AssetHave), the amount of AssetHave the user is willing to give up, and the amount of AssetWant that the user would like. This way there is no reason to have a "side" field, and prices can be represented more fairly, where you do not need to worry about precision other than the maximum precision of the asset, which is usually within a uint64. We don't want this to be a big int because that means it can't really be sent over the wire. We're not multiple precision here, but we do want some standard, reasonable level of precision

func (*Price) Cmp

func (p *Price) Cmp(otherPrice *Price) (compIndicator int)

Cmp compares p and otherPrice and returns:

-1 if x <  y
 0 if x == y (incl. -0 == 0, -Inf == -Inf, and +Inf == +Inf)
+1 if x >  y

func (*Price) ToFloat

func (p *Price) ToFloat() (price float64, err error)

ToFloat converts the price to a float value

type SettleType

type SettleType bool

SettleType is a type that represents either a credit or a debit

func (*SettleType) String

func (st *SettleType) String() string

String returns the string representation of a credit or debit

func (*SettleType) UnmarshalJSON

func (st *SettleType) UnmarshalJSON(b []byte) (err error)

type SettlementEngine

type SettlementEngine interface {
	// ApplySettlementExecution is a method that applies a settlement execution.
	// TODO: switch this over to have setExec []*SettlementExecution as the param
	// and setRes []*SettlementResult as the return value
	ApplySettlementExecution(setExec *SettlementExecution) (setRes *SettlementResult, err error)
	// CheckValid is a method that returns true if the settlement execution would be valid.
	CheckValid(setExec *SettlementExecution) (valid bool, err error)
}

SettlementEngine is an interface for something that keeps track of balances for users for a certain asset. One of these should be made for every asset.

type SettlementExecution

type SettlementExecution struct {
	Pubkey [33]byte `json:"pubkey"`
	Amount uint64   `json:"amount"`
	Asset  Asset    `json:"asset"`
	// SettleType is a type that determines whether or not this is a debit or credit
	Type SettleType `json:"settletype"`
}

TODO: replace with this once ready SettlementExecution is the "settlement part" of an execution. It defines the operations that should be done to the settlement engine.

func (*SettlementExecution) Equal

func (se *SettlementExecution) Equal(otherExec *SettlementExecution) bool

Equal compares one SettlementExecution with another SettlementExecution and returns true if all of the fields are the same.

func (*SettlementExecution) String

func (se *SettlementExecution) String() string

String returns a string representation of the SettlementExecution

type SettlementResult

type SettlementResult struct {
	NewBal         uint64               `json:"newbal"`
	SuccessfulExec *SettlementExecution `json:"successfulexec"`
}

SettlementResult is the settlement exec and the new balance

func (*SettlementResult) String

func (sr *SettlementResult) String() string

String returns the string representation of a settlement result

type Side

type Side bool

Side is a representation of buy or sell side

func (Side) FromString

func (s Side) FromString(str string) (err error)

FromString takes a string and, if valid, sets the Side to the correct value based on the string

func (Side) MarshalBinary

func (s Side) MarshalBinary() (data []byte, err error)

MarshalBinary implements the BinaryMarshaler interface from encoding.

func (Side) String

func (s Side) String() string

String returns the string representation of a buy or sell side

func (*Side) UnmarshalBinary

func (s *Side) UnmarshalBinary(data []byte) (err error)

UnmarshalBinary implements the BinaryUnmarshaler interface from encoding. This takes a pointer as a receiver because it's not possible nor does it make sense to try to modify the value being called.

func (Side) UnmarshalJSON

func (s Side) UnmarshalJSON(b []byte) (err error)

UnmarshalJSON implements the JSON unmarshalling interface

type SignedEncSolOrder

type SignedEncSolOrder struct {
	EncSolOrder EncryptedSolutionOrder `json:"encsolorder"`
	Signature   []byte                 `json:"signature"`
}

SignedEncSolOrder is a signed EncryptedSolutionOrder

func (*SignedEncSolOrder) Deserialize

func (se *SignedEncSolOrder) Deserialize(raw []byte) (err error)

Deserialize turns the signed encrypted solution order from bytes into a usable struct.

func (*SignedEncSolOrder) Serialize

func (se *SignedEncSolOrder) Serialize() (raw []byte, err error)

Serialize uses gob encoding to turn the encrypted solution order into bytes.

type SolutionOrder

type SolutionOrder struct {
	P *big.Int `json:"p"`
	Q *big.Int `json:"q"`
}

SolutionOrder is an order and modulus that are together. This includes an order, and the puzzle modulus factors.

func NewSolutionOrder

func NewSolutionOrder(rsaKeyBits uint64) (solOrder SolutionOrder, err error)

NewSolutionOrder creates a new SolutionOrder from an already existing AuctionOrder, with a specified number of bits for an rsa key.

func (*SolutionOrder) Deserialize

func (so *SolutionOrder) Deserialize(raw []byte) (err error)

Deserialize turns the solution order from bytes into a usable struct.

func (*SolutionOrder) EncryptSolutionOrder

func (so *SolutionOrder) EncryptSolutionOrder(auctionOrder AuctionOrder, t uint64) (encSolOrder EncryptedSolutionOrder, err error)

EncryptSolutionOrder encrypts a solution order and creates a puzzle along with the encrypted order

func (*SolutionOrder) Serialize

func (so *SolutionOrder) Serialize() (raw []byte, err error)

Serialize uses gob encoding to turn the solution order into bytes.

type Transcript

type Transcript struct {
	BatchId       AuctionID           `json:batchid`
	BatchIdSig    []byte              `json:"signature"`
	PuzzledOrders []SignedEncSolOrder `json:"puzzledorders"`
	Commitment    [32]byte            `json:"commitment"`
	CommitSig     []byte              `json:"commitsig"`
	Responses     []CommitResponse    `json:"responses"`
	Solutions     []AuctionOrder      `json:"solutions"`
}

Transcript is the representation of a non front running proof transcript. Puzzled orders are the "batch" and this should be able to be verified quickly.

func (*Transcript) Deserialize

func (tr *Transcript) Deserialize(raw []byte) (err error)

Deserialize turns the transcript from bytes into a usable struct.

func (*Transcript) Serialize

func (tr *Transcript) Serialize() (raw []byte, err error)

Serialize uses gob encoding to turn the transcript into bytes.

func (*Transcript) Solve

func (tr *Transcript) Solve() (solvedOrders []AuctionOrder, invalidResponses []CommitResponse, err error)

Solve processes the encrypted solution orders and the commitment Responses to partition the encrypted orders into those solvable by Responses and those that are unsolvable.

func (*Transcript) Verify

func (tr *Transcript) Verify() (valid bool, err error)

Verify verifies the signatures in the transcript and ensures that the batch was carried out correctly. In this implementation, the exchange is signing the set of all orders in plaintext, so the 'e' value in the signature is the hash of all of the orders.

type Withdrawal

type Withdrawal struct {
	Asset   Asset
	Amount  uint64
	Address string
	// This tells whether or not this is a lightning withdrawal. Default value is false so that makes it easier to not mess up
	Lightning bool
}

Withdrawal is a representation of a withdrawal. This is because withdrawals are now signed.

func (*Withdrawal) Serialize

func (w *Withdrawal) Serialize() (buf []byte)

Serialize serializes the withdrawal

Jump to

Keyboard shortcuts

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