X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=application%2Fmov%2Fmov_core.go;fp=application%2Fmov%2Fmov_core.go;h=298055360e97eb23e67621d99fa19fcd2f765fe0;hb=c3da0e7253209c3b89ea90f21299c6f0821019b7;hp=4a08cf5ae9176151529f11417442cccf601522a2;hpb=77cc98c7744df353f5bdcb3984fcbb56451fd902;p=bytom%2Fvapor.git diff --git a/application/mov/mov_core.go b/application/mov/mov_core.go index 4a08cf5a..29805536 100644 --- a/application/mov/mov_core.go +++ b/application/mov/mov_core.go @@ -62,11 +62,11 @@ func (m *Core) ApplyBlock(block *types.Block) error { return m.InitChainStatus(&blockHash) } - if err := m.validateMatchedTxSequence(block.Transactions); err != nil { + if err := m.validateMatchedTxSequence(movTxs(block)); err != nil { return err } - addOrders, deleteOrders, err := decodeTxsOrders(block.Transactions) + addOrders, deleteOrders, err := decodeTxsOrders(movTxs(block)) if err != nil { return err } @@ -74,24 +74,36 @@ func (m *Core) ApplyBlock(block *types.Block) error { return m.movStore.ProcessOrders(addOrders, deleteOrders, &block.BlockHeader) } +// Tx contains raw transaction and the sequence of tx in block +type Tx struct { + rawTx *types.Tx + blockHeight uint64 + txIndex uint64 +} + +// NewTx create a new Tx instance +func NewTx(tx *types.Tx, blockHeight, txIndex uint64) *Tx { + return &Tx{rawTx: tx, blockHeight: blockHeight, txIndex: txIndex} +} + // BeforeProposalBlock return all transactions than can be matched, and the number of transactions cannot exceed the given capacity. -func (m *Core) BeforeProposalBlock(txs []*types.Tx, blockHeight uint64, gasLeft int64, isTimeout func() bool) ([]*types.Tx, error) { - if blockHeight <= m.startBlockHeight { +func (m *Core) BeforeProposalBlock(block *types.Block, gasLeft int64, isTimeout func() bool) ([]*types.Tx, error) { + if block.Height <= m.startBlockHeight { return nil, nil } - orderBook, err := buildOrderBook(m.movStore, txs) + orderBook, err := buildOrderBook(m.movStore, movTxs(block)) if err != nil { return nil, err } - program, _ := getRewardProgram(blockHeight) + program, _ := getRewardProgram(block.Height) rewardProgram, err := hex.DecodeString(program) if err != nil { return nil, errNotConfiguredRewardProgram } - matchEngine := match.NewEngine(orderBook, match.NewDefaultFeeStrategy(), rewardProgram) + matchEngine := match.NewEngine(orderBook, rewardProgram) tradePairIterator := database.NewTradePairIterator(m.movStore) matchCollector := newMatchTxCollector(matchEngine, tradePairIterator, gasLeft, isTimeout) return matchCollector.result() @@ -123,7 +135,7 @@ func (m *Core) DetachBlock(block *types.Block) error { return nil } - deleteOrders, addOrders, err := decodeTxsOrders(block.Transactions) + deleteOrders, addOrders, err := decodeTxsOrders(movTxs(block)) if err != nil { return err } @@ -294,7 +306,7 @@ func validateMatchedTx(tx *types.Tx, blockHeight uint64) error { toAssetIDMap[order.ToAssetID.String()] = true } - if len(fromAssetIDMap) != len(tx.Inputs) || len(toAssetIDMap) != len(tx.Inputs) { + if inputSize := len(tx.Inputs); len(fromAssetIDMap) != inputSize || len(toAssetIDMap) != inputSize { return errAssetIDMustUniqueInMatchedTx } @@ -313,38 +325,38 @@ func validateMatchedTxFee(tx *types.Tx, blockHeight uint64) error { } } - orders, err := getDeleteOrdersFromTx(tx) + orders, err := parseDeleteOrdersFromTx(tx) if err != nil { return err } - receivedAmount, _ := match.CalcReceivedAmount(orders) + receivedAmount, priceDiffs := match.CalcReceivedAmount(orders) feeAmounts := make(map[bc.AssetID]uint64) for assetID, fee := range matchedTxFees { feeAmounts[assetID] = fee.amount } feeStrategy := match.NewDefaultFeeStrategy() - return feeStrategy.Validate(receivedAmount, feeAmounts) + return feeStrategy.Validate(receivedAmount, priceDiffs, feeAmounts, blockHeight) } -func (m *Core) validateMatchedTxSequence(txs []*types.Tx) error { +func (m *Core) validateMatchedTxSequence(txs []*Tx) error { orderBook := match.NewOrderBook(m.movStore, nil, nil) for _, tx := range txs { - if common.IsMatchedTx(tx) { - tradePairs, err := getTradePairsFromMatchedTx(tx) + if common.IsMatchedTx(tx.rawTx) { + tradePairs, err := parseTradePairsFromMatchedTx(tx.rawTx) if err != nil { return err } orders := orderBook.PeekOrders(tradePairs) - if err := validateSpendOrders(tx, orders); err != nil { + if err := validateSpendOrders(tx.rawTx, orders); err != nil { return err } orderBook.PopOrders(tradePairs) - } else if common.IsCancelOrderTx(tx) { - orders, err := getDeleteOrdersFromTx(tx) + } else if common.IsCancelOrderTx(tx.rawTx) { + orders, err := parseDeleteOrdersFromTx(tx.rawTx) if err != nil { return err } @@ -354,7 +366,7 @@ func (m *Core) validateMatchedTxSequence(txs []*types.Tx) error { } } - addOrders, err := getAddOrdersFromTx(tx) + addOrders, err := parseAddOrdersFromTx(tx) if err != nil { return err } @@ -390,11 +402,11 @@ func validateSpendOrders(tx *types.Tx, orders []*common.Order) error { return nil } -func decodeTxsOrders(txs []*types.Tx) ([]*common.Order, []*common.Order, error) { +func decodeTxsOrders(txs []*Tx) ([]*common.Order, []*common.Order, error) { deleteOrderMap := make(map[string]*common.Order) addOrderMap := make(map[string]*common.Order) for _, tx := range txs { - addOrders, err := getAddOrdersFromTx(tx) + addOrders, err := parseAddOrdersFromTx(tx) if err != nil { return nil, nil, err } @@ -403,7 +415,7 @@ func decodeTxsOrders(txs []*types.Tx) ([]*common.Order, []*common.Order, error) addOrderMap[order.Key()] = order } - deleteOrders, err := getDeleteOrdersFromTx(tx) + deleteOrders, err := parseDeleteOrdersFromTx(tx.rawTx) if err != nil { return nil, nil, err } @@ -417,15 +429,15 @@ func decodeTxsOrders(txs []*types.Tx) ([]*common.Order, []*common.Order, error) return addOrders, deleteOrders, nil } -func buildOrderBook(store database.MovStore, txs []*types.Tx) (*match.OrderBook, error) { +func buildOrderBook(store database.MovStore, txs []*Tx) (*match.OrderBook, error) { var arrivalAddOrders, arrivalDelOrders []*common.Order for _, tx := range txs { - addOrders, err := getAddOrdersFromTx(tx) + addOrders, err := parseAddOrdersFromTx(tx) if err != nil { return nil, err } - delOrders, err := getDeleteOrdersFromTx(tx) + delOrders, err := parseDeleteOrdersFromTx(tx.rawTx) if err != nil { return nil, err } @@ -437,9 +449,9 @@ func buildOrderBook(store database.MovStore, txs []*types.Tx) (*match.OrderBook, return match.NewOrderBook(store, arrivalAddOrders, arrivalDelOrders), nil } -func getAddOrdersFromTx(tx *types.Tx) ([]*common.Order, error) { +func parseAddOrdersFromTx(tx *Tx) ([]*common.Order, error) { var orders []*common.Order - for i, output := range tx.Outputs { + for i, output := range tx.rawTx.Outputs { if output.OutputType() != types.IntraChainOutputType || !segwit.IsP2WMCScript(output.ControlProgram()) { continue } @@ -448,7 +460,7 @@ func getAddOrdersFromTx(tx *types.Tx) ([]*common.Order, error) { continue } - order, err := common.NewOrderFromOutput(tx, i) + order, err := common.NewOrderFromOutput(tx.rawTx, i, tx.blockHeight, tx.txIndex) if err != nil { return nil, err } @@ -458,7 +470,7 @@ func getAddOrdersFromTx(tx *types.Tx) ([]*common.Order, error) { return orders, nil } -func getDeleteOrdersFromTx(tx *types.Tx) ([]*common.Order, error) { +func parseDeleteOrdersFromTx(tx *types.Tx) ([]*common.Order, error) { var orders []*common.Order for i, input := range tx.Inputs { if input.InputType() != types.SpendInputType || !segwit.IsP2WMCScript(input.ControlProgram()) { @@ -475,7 +487,7 @@ func getDeleteOrdersFromTx(tx *types.Tx) ([]*common.Order, error) { return orders, nil } -func getTradePairsFromMatchedTx(tx *types.Tx) ([]*common.TradePair, error) { +func parseTradePairsFromMatchedTx(tx *types.Tx) ([]*common.TradePair, error) { var tradePairs []*common.TradePair for _, tx := range tx.Inputs { contractArgs, err := segwit.DecodeP2WMCProgram(tx.ControlProgram()) @@ -504,6 +516,14 @@ func mergeOrders(addOrderMap, deleteOrderMap map[string]*common.Order) ([]*commo return addOrders, deleteOrders } +func movTxs(block *types.Block) []*Tx { + var movTxs []*Tx + for i, tx := range block.Transactions { + movTxs = append(movTxs, NewTx(tx, block.Height, uint64(i))) + } + return movTxs +} + // getRewardProgram return the reward program by specified block height // if no reward program configured, then will return empty string // if reward program of 0-100 height is configured, but the specified height is 200, then will return 0-100's reward program