8 "github.com/bytom/vapor/consensus/segwit"
9 "github.com/bytom/vapor/errors"
10 "github.com/bytom/vapor/protocol/bc"
11 "github.com/bytom/vapor/protocol/bc/types"
14 // MovUtxo store the utxo information for mov order
22 // Order store all the order information
24 FromAssetID *bc.AssetID
28 RatioDenominator int64
34 // Rate return the exchange represented by float64
35 func (o *Order) Rate() float64 {
36 if o.RatioDenominator == 0 {
39 rate := big.NewRat(o.RatioNumerator, o.RatioDenominator)
40 result, _ := rate.Float64()
44 // cmpRate compares rate of x and y and returns -1 if x < y, 0 if x == y, +1 if x > y
45 func (o *Order) cmpRate(other *Order) int {
46 rate := big.NewRat(o.RatioNumerator, o.RatioDenominator)
47 otherRate := big.NewRat(other.RatioNumerator, other.RatioDenominator)
48 return rate.Cmp(otherRate)
51 // Cmp first compare the rate, if rate is equals, then compare the utxo hash
52 func (o *Order) Cmp(other *Order) int {
53 cmp := o.cmpRate(other)
55 if hex.EncodeToString(o.UTXOHash().Bytes()) < hex.EncodeToString(other.UTXOHash().Bytes()) {
63 // OrderSlice is define for order's sort
64 type OrderSlice []*Order
66 func (o OrderSlice) Len() int { return len(o) }
67 func (o OrderSlice) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
68 func (o OrderSlice) Less(i, j int) bool {
69 return o[i].Cmp(o[j]) < 0
72 // NewOrderFromOutput convert txinput to order
73 func NewOrderFromOutput(tx *types.Tx, outputIndex int, blockHeight, txIndex uint64) (*Order, error) {
74 outputID := tx.OutputID(outputIndex)
75 output, err := tx.IntraChainOutput(*outputID)
80 contractArgs, err := segwit.DecodeP2WMCProgram(output.ControlProgram.Code)
85 assetAmount := output.Source.Value
87 FromAssetID: assetAmount.AssetId,
88 ToAssetID: &contractArgs.RequestedAsset,
89 RatioNumerator: contractArgs.RatioNumerator,
90 RatioDenominator: contractArgs.RatioDenominator,
91 SellerProgram: contractArgs.SellerProgram,
92 BlockHeight: blockHeight,
95 SourceID: output.Source.Ref,
96 Amount: assetAmount.Amount,
97 SourcePos: uint64(outputIndex),
98 ControlProgram: output.ControlProgram.Code,
103 // NewOrderFromInput convert txoutput to order
104 func NewOrderFromInput(tx *types.Tx, inputIndex int) (*Order, error) {
105 input, ok := tx.Inputs[inputIndex].TypedInput.(*types.SpendInput)
107 return nil, errors.New("input is not type of spend input")
110 contractArgs, err := segwit.DecodeP2WMCProgram(input.ControlProgram)
116 FromAssetID: input.AssetId,
117 ToAssetID: &contractArgs.RequestedAsset,
118 RatioNumerator: contractArgs.RatioNumerator,
119 RatioDenominator: contractArgs.RatioDenominator,
120 SellerProgram: contractArgs.SellerProgram,
122 SourceID: &input.SourceID,
123 Amount: input.Amount,
124 SourcePos: input.SourcePosition,
125 ControlProgram: input.ControlProgram,
130 // Key return the unique key for representing this order
131 func (o *Order) Key() string {
132 return fmt.Sprintf("%s:%d", o.Utxo.SourceID, o.Utxo.SourcePos)
135 // TradePair return the trade pair info
136 func (o *Order) TradePair() *TradePair {
137 return &TradePair{FromAssetID: o.FromAssetID, ToAssetID: o.ToAssetID}
140 // UTXOHash calculate the utxo hash of this order
141 func (o *Order) UTXOHash() *bc.Hash {
142 prog := &bc.Program{VmVersion: 1, Code: o.Utxo.ControlProgram}
143 src := &bc.ValueSource{
144 Ref: o.Utxo.SourceID,
145 Value: &bc.AssetAmount{AssetId: o.FromAssetID, Amount: o.Utxo.Amount},
146 Position: o.Utxo.SourcePos,
148 hash := bc.EntryID(bc.NewIntraChainOutput(src, prog, 0))
152 // TradePair is the object for record trade pair info
153 type TradePair struct {
154 FromAssetID *bc.AssetID
155 ToAssetID *bc.AssetID
159 // Key return the unique key for representing this trade pair
160 func (t *TradePair) Key() string {
161 return fmt.Sprintf("%s:%s", t.FromAssetID, t.ToAssetID)
164 // Reverse return the reverse trade pair object
165 func (t *TradePair) Reverse() *TradePair {
167 FromAssetID: t.ToAssetID,
168 ToAssetID: t.FromAssetID,
172 // MovDatabaseState is object to record DB image status
173 type MovDatabaseState struct {