"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}
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
}
}
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
)
func TestReserveBtmUtxoChain(t *testing.T) {
- chainTxUtxoNum = 3
+ txbuilder.ChainTxUtxoNum = 3
utxos := []*UTXO{}
m := mockAccountManager(t)
for i := uint64(1); i <= 20; i++ {
OutputID: bc.Hash{V0: i},
AccountID: "TestAccountID",
AssetID: *consensus.BTMAssetID,
- Amount: i * chainTxMergeGas,
+ Amount: i * txbuilder.ChainTxMergeGas,
}
utxos = append(utxos, utxo)
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},
},
}
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) {
}
func TestBuildBtmTxChain(t *testing.T) {
- chainTxUtxoNum = 3
+ txbuilder.ChainTxUtxoNum = 3
m := mockAccountManager(t)
cases := []struct {
inputUtxo []uint64
inputUtxo: []uint64{5},
wantInput: [][]uint64{},
wantOutput: [][]uint64{},
- wantUtxo: 5 * chainTxMergeGas,
+ wantUtxo: 5 * txbuilder.ChainTxMergeGas,
},
{
inputUtxo: []uint64{5, 4},
wantOutput: [][]uint64{
[]uint64{8},
},
- wantUtxo: 8 * chainTxMergeGas,
+ wantUtxo: 8 * txbuilder.ChainTxMergeGas,
},
{
inputUtxo: []uint64{5, 4, 1, 1},
[]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},
[]uint64{3038},
[]uint64{3491},
},
- wantUtxo: 3491 * chainTxMergeGas,
+ wantUtxo: 3491 * txbuilder.ChainTxMergeGas,
},
}
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,
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) {
}
func TestCalcMergeGas(t *testing.T) {
- chainTxUtxoNum = 10
+ txbuilder.ChainTxUtxoNum = 10
cases := []struct {
utxoNum int
gas uint64
},
{
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,
},
}
"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: