OSDN Git Service

feat(api): add estimate-chain-tx-gas (#1791)
authorHAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
Fri, 18 Oct 2019 02:21:22 +0000 (10:21 +0800)
committerPaladz <yzhu101@uottawa.ca>
Fri, 18 Oct 2019 02:21:22 +0000 (10:21 +0800)
* fk

* do his mother a ticket

* init EstimateChainTxGas

* add sum up

* update

* fix maybe

* fix

* k

* ???

* ???

* do

* fix ci bug

* rename

* fix

account/builder.go
account/builder_test.go
api/api.go
api/transact.go
blockchain/txbuilder/estimate.go

index 0ea19d4..ec63216 100644 (file)
@@ -15,13 +15,6 @@ import (
        "github.com/bytom/protocol/vm/vmutil"
 )
 
-var (
-       //chainTxUtxoNum maximum utxo quantity in a tx
-       chainTxUtxoNum = 5
-       //chainTxMergeGas chain tx gas
-       chainTxMergeGas = uint64(10000000)
-)
-
 //DecodeSpendAction unmarshal JSON-encoded data of spend action
 func (m *Manager) DecodeSpendAction(data []byte) (txbuilder.Action, error) {
        a := &spendAction{accounts: m}
@@ -66,8 +59,8 @@ func MergeSpendAction(actions []txbuilder.Action) []txbuilder.Action {
 func calcMergeGas(num int) uint64 {
        gas := uint64(0)
        for num > 1 {
-               gas += chainTxMergeGas
-               num -= chainTxUtxoNum - 1
+               gas += txbuilder.ChainTxMergeGas
+               num -= txbuilder.ChainTxUtxoNum - 1
        }
        return gas
 }
@@ -117,11 +110,11 @@ func (m *Manager) buildBtmTxChain(utxos []*UTXO, signer *signers.Signer) ([]*txb
                }
 
                buildAmount += input.Amount()
-               if builder.InputCount() != chainTxUtxoNum && index != len(utxos)-1 {
+               if builder.InputCount() != txbuilder.ChainTxUtxoNum && index != len(utxos)-1 {
                        continue
                }
 
-               outAmount := buildAmount - chainTxMergeGas
+               outAmount := buildAmount - txbuilder.ChainTxMergeGas
                output := types.NewTxOutput(*consensus.BTMAssetID, outAmount, acp.ControlProgram)
                if err := builder.AddOutput(output); err != nil {
                        return nil, nil, err
index e29e745..9e2d4bf 100644 (file)
@@ -14,7 +14,7 @@ import (
 )
 
 func TestReserveBtmUtxoChain(t *testing.T) {
-       chainTxUtxoNum = 3
+       txbuilder.ChainTxUtxoNum = 3
        utxos := []*UTXO{}
        m := mockAccountManager(t)
        for i := uint64(1); i <= 20; i++ {
@@ -22,7 +22,7 @@ func TestReserveBtmUtxoChain(t *testing.T) {
                        OutputID:  bc.Hash{V0: i},
                        AccountID: "TestAccountID",
                        AssetID:   *consensus.BTMAssetID,
-                       Amount:    i * chainTxMergeGas,
+                       Amount:    i * txbuilder.ChainTxMergeGas,
                }
                utxos = append(utxos, utxo)
 
@@ -40,24 +40,24 @@ func TestReserveBtmUtxoChain(t *testing.T) {
                err    bool
        }{
                {
-                       amount: 1 * chainTxMergeGas,
+                       amount: 1 * txbuilder.ChainTxMergeGas,
                        want:   []uint64{1},
                },
                {
-                       amount: 888888 * chainTxMergeGas,
+                       amount: 888888 * txbuilder.ChainTxMergeGas,
                        want:   []uint64{},
                        err:    true,
                },
                {
-                       amount: 7 * chainTxMergeGas,
+                       amount: 7 * txbuilder.ChainTxMergeGas,
                        want:   []uint64{4, 3, 1},
                },
                {
-                       amount: 15 * chainTxMergeGas,
+                       amount: 15 * txbuilder.ChainTxMergeGas,
                        want:   []uint64{5, 4, 3, 2, 1, 6},
                },
                {
-                       amount: 163 * chainTxMergeGas,
+                       amount: 163 * txbuilder.ChainTxMergeGas,
                        want:   []uint64{20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 2, 1, 3},
                },
        }
@@ -72,7 +72,7 @@ func TestReserveBtmUtxoChain(t *testing.T) {
 
                got := []uint64{}
                for _, utxo := range utxos {
-                       got = append(got, utxo.Amount/chainTxMergeGas)
+                       got = append(got, utxo.Amount/txbuilder.ChainTxMergeGas)
                }
 
                if !testutil.DeepEqual(got, c.want) {
@@ -83,7 +83,7 @@ func TestReserveBtmUtxoChain(t *testing.T) {
 }
 
 func TestBuildBtmTxChain(t *testing.T) {
-       chainTxUtxoNum = 3
+       txbuilder.ChainTxUtxoNum = 3
        m := mockAccountManager(t)
        cases := []struct {
                inputUtxo  []uint64
@@ -95,7 +95,7 @@ func TestBuildBtmTxChain(t *testing.T) {
                        inputUtxo:  []uint64{5},
                        wantInput:  [][]uint64{},
                        wantOutput: [][]uint64{},
-                       wantUtxo:   5 * chainTxMergeGas,
+                       wantUtxo:   5 * txbuilder.ChainTxMergeGas,
                },
                {
                        inputUtxo: []uint64{5, 4},
@@ -105,7 +105,7 @@ func TestBuildBtmTxChain(t *testing.T) {
                        wantOutput: [][]uint64{
                                []uint64{8},
                        },
-                       wantUtxo: 8 * chainTxMergeGas,
+                       wantUtxo: 8 * txbuilder.ChainTxMergeGas,
                },
                {
                        inputUtxo: []uint64{5, 4, 1, 1},
@@ -117,7 +117,7 @@ func TestBuildBtmTxChain(t *testing.T) {
                                []uint64{9},
                                []uint64{9},
                        },
-                       wantUtxo: 9 * chainTxMergeGas,
+                       wantUtxo: 9 * txbuilder.ChainTxMergeGas,
                },
                {
                        inputUtxo: []uint64{22, 123, 53, 234, 23, 4, 2423, 24, 23, 43, 34, 234, 234, 24},
@@ -139,7 +139,7 @@ func TestBuildBtmTxChain(t *testing.T) {
                                []uint64{3038},
                                []uint64{3491},
                        },
-                       wantUtxo: 3491 * chainTxMergeGas,
+                       wantUtxo: 3491 * txbuilder.ChainTxMergeGas,
                },
        }
 
@@ -157,7 +157,7 @@ func TestBuildBtmTxChain(t *testing.T) {
                utxos := []*UTXO{}
                for _, amount := range c.inputUtxo {
                        utxos = append(utxos, &UTXO{
-                               Amount:         amount * chainTxMergeGas,
+                               Amount:         amount * txbuilder.ChainTxMergeGas,
                                AssetID:        *consensus.BTMAssetID,
                                Address:        acp.Address,
                                ControlProgram: acp.ControlProgram,
@@ -172,12 +172,12 @@ func TestBuildBtmTxChain(t *testing.T) {
                for i, tpl := range tpls {
                        gotInput := []uint64{}
                        for _, input := range tpl.Transaction.Inputs {
-                               gotInput = append(gotInput, input.Amount()/chainTxMergeGas)
+                               gotInput = append(gotInput, input.Amount()/txbuilder.ChainTxMergeGas)
                        }
 
                        gotOutput := []uint64{}
                        for _, output := range tpl.Transaction.Outputs {
-                               gotOutput = append(gotOutput, output.Amount/chainTxMergeGas)
+                               gotOutput = append(gotOutput, output.Amount/txbuilder.ChainTxMergeGas)
                        }
 
                        if !testutil.DeepEqual(c.wantInput[i], gotInput) {
@@ -540,7 +540,7 @@ func TestMergeSpendAction(t *testing.T) {
 }
 
 func TestCalcMergeGas(t *testing.T) {
-       chainTxUtxoNum = 10
+       txbuilder.ChainTxUtxoNum = 10
        cases := []struct {
                utxoNum int
                gas     uint64
@@ -555,27 +555,27 @@ func TestCalcMergeGas(t *testing.T) {
                },
                {
                        utxoNum: 9,
-                       gas:     chainTxMergeGas,
+                       gas:     txbuilder.ChainTxMergeGas,
                },
                {
                        utxoNum: 10,
-                       gas:     chainTxMergeGas,
+                       gas:     txbuilder.ChainTxMergeGas,
                },
                {
                        utxoNum: 11,
-                       gas:     chainTxMergeGas * 2,
+                       gas:     txbuilder.ChainTxMergeGas * 2,
                },
                {
                        utxoNum: 20,
-                       gas:     chainTxMergeGas * 3,
+                       gas:     txbuilder.ChainTxMergeGas * 3,
                },
                {
                        utxoNum: 21,
-                       gas:     chainTxMergeGas * 3,
+                       gas:     txbuilder.ChainTxMergeGas * 3,
                },
                {
                        utxoNum: 74,
-                       gas:     chainTxMergeGas * 9,
+                       gas:     txbuilder.ChainTxMergeGas * 9,
                },
        }
 
index e460eee..d12ead1 100644 (file)
@@ -279,6 +279,7 @@ func (a *API) buildHandler() {
        m.Handle("/submit-transaction", jsonHandler(a.submit))
        m.Handle("/submit-transactions", jsonHandler(a.submitTxs))
        m.Handle("/estimate-transaction-gas", jsonHandler(a.estimateTxGas))
+       m.Handle("/estimate-chain-transaction-gas", jsonHandler(a.estimateChainTxGas))
 
        m.Handle("/get-unconfirmed-transaction", jsonHandler(a.getUnconfirmedTx))
        m.Handle("/list-unconfirmed-transactions", jsonHandler(a.listUnconfirmedTxs))
index b444cc9..947b47e 100644 (file)
@@ -226,5 +226,18 @@ func (a *API) estimateTxGas(ctx context.Context, in struct {
        if err != nil {
                return NewErrorResponse(err)
        }
+
+       return NewSuccessResponse(txGasResp)
+}
+
+// POST /estimate-chain-transaction-gas
+func (a *API) estimateChainTxGas(ctx context.Context, in struct {
+       TxTemplates []txbuilder.Template `json:"transaction_templates"`
+}) Response {
+       txGasResp, err := txbuilder.EstimateChainTxGas(in.TxTemplates)
+       if err != nil {
+               return NewErrorResponse(err)
+       }
+
        return NewSuccessResponse(txGasResp)
 }
index 27497eb..091c36d 100644 (file)
@@ -7,20 +7,43 @@ import (
        "github.com/bytom/protocol/vm/vmutil"
 )
 
+const (
+       baseSize       = int64(176) // inputSize(112) + outputSize(64)
+       baseP2WPKHSize = int64(98)
+       baseP2WPKHGas  = int64(1409)
+)
+
+var (
+       //ChainTxUtxoNum maximum utxo quantity in a tx
+       ChainTxUtxoNum = 5
+       //ChainTxMergeGas chain tx gas
+       ChainTxMergeGas = uint64(10000000)
+)
+
 // EstimateTxGasInfo estimate transaction consumed gas
 type EstimateTxGasInfo struct {
        TotalNeu    int64 `json:"total_neu"`
        FlexibleNeu int64 `json:"flexible_neu"`
        StorageNeu  int64 `json:"storage_neu"`
        VMNeu       int64 `json:"vm_neu"`
+       ChainTxNeu  int64 `json:"chain_tx_neu,omitempty"`
+}
+
+func EstimateChainTxGas(templates []Template) (*EstimateTxGasInfo, error) {
+       estimated, err := EstimateTxGas(templates[len(templates)-1])
+       if err != nil {
+               return nil, err
+       }
+
+       if len(templates) > 1 {
+               estimated.ChainTxNeu = int64(ChainTxMergeGas) * int64(len(templates)-1)
+       }
+       return estimated, nil
 }
 
 // EstimateTxGas estimate consumed neu for transaction
 func EstimateTxGas(template Template) (*EstimateTxGasInfo, error) {
        var baseP2WSHSize, totalWitnessSize, baseP2WSHGas, totalP2WPKHGas, totalP2WSHGas, totalIssueGas int64
-       baseSize := int64(176) // inputSize(112) + outputSize(64)
-       baseP2WPKHSize := int64(98)
-       baseP2WPKHGas := int64(1409)
        for pos, input := range template.Transaction.TxData.Inputs {
                switch input.InputType() {
                case types.SpendInputType: