github.com/mavryk-network/mvgo@v1.19.9/rpc/transaction.go (about)

     1  // Copyright (c) 2020-2021 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc
     3  
     4  package rpc
     5  
     6  import (
     7  	"github.com/mavryk-network/mvgo/mavryk"
     8  	"github.com/mavryk-network/mvgo/micheline"
     9  )
    10  
    11  // Ensure Transaction implements the TypedOperation interface.
    12  var _ TypedOperation = (*Transaction)(nil)
    13  
    14  // Transaction represents a transaction operation
    15  type Transaction struct {
    16  	Manager
    17  	Destination mavryk.Address        `json:"destination"`
    18  	Amount      int64                 `json:"amount,string"`
    19  	Parameters  *micheline.Parameters `json:"parameters,omitempty"`
    20  }
    21  
    22  // Costs returns operation cost to implement TypedOperation interface.
    23  func (t Transaction) Costs() mavryk.Costs {
    24  	res := t.Metadata.Result
    25  	cost := mavryk.Costs{
    26  		Fee:         t.Manager.Fee,
    27  		GasUsed:     res.Gas(),
    28  		StorageUsed: res.PaidStorageSizeDiff,
    29  	}
    30  	if !t.Result().IsSuccess() {
    31  		return cost
    32  	}
    33  	var i int
    34  	for _, v := range res.BalanceUpdates {
    35  		if v.Kind != CONTRACT {
    36  			continue
    37  		}
    38  		if t.Amount > 0 && v.AmountAbs() == t.Amount {
    39  			continue
    40  		}
    41  		burn := v.Amount()
    42  		if burn >= 0 {
    43  			continue
    44  		}
    45  		if res.PaidStorageSizeDiff > 0 && i == 0 {
    46  			cost.StorageBurn += -burn
    47  			cost.Burn += -burn
    48  			i++
    49  		} else if res.Allocated {
    50  			cost.AllocationBurn += -burn
    51  			cost.Burn += -burn
    52  			i++
    53  		}
    54  	}
    55  	for _, in := range t.Metadata.InternalResults {
    56  		cost = cost.Add(in.Costs())
    57  	}
    58  	return cost
    59  }
    60  
    61  type InternalResult struct {
    62  	Kind          mavryk.OpType         `json:"kind"`
    63  	Source        mavryk.Address        `json:"source"`
    64  	Nonce         int64                 `json:"nonce"`
    65  	Result        OperationResult       `json:"result"`
    66  	Destination   *mavryk.Address       `json:"destination,omitempty"` // transaction
    67  	Delegate      *mavryk.Address       `json:"delegate,omitempty"`    // delegation
    68  	Parameters    *micheline.Parameters `json:"parameters,omitempty"`  // transaction
    69  	Amount        int64                 `json:"amount,string"`         // transaction
    70  	Balance       int64                 `json:"balance,string"`        // origination
    71  	Script        *micheline.Script     `json:"script,omitempty"`      // origination
    72  	Type          micheline.Prim        `json:"type"`                  // event
    73  	Payload       micheline.Prim        `json:"payload"`               // event
    74  	Tag           string                `json:"tag"`                   // event
    75  	TicketUpdates []TicketUpdate        `json:"ticket_receipt"`        // v015
    76  }
    77  
    78  func (r InternalResult) Costs() mavryk.Costs {
    79  	cost := mavryk.Costs{
    80  		GasUsed:     r.Result.Gas(),
    81  		StorageUsed: r.Result.PaidStorageSizeDiff,
    82  	}
    83  	var i int
    84  	for _, v := range r.Result.BalanceUpdates {
    85  		if v.Kind != CONTRACT {
    86  			continue
    87  		}
    88  		if r.Amount > 0 && v.AmountAbs() == r.Amount {
    89  			continue
    90  		}
    91  		burn := v.Amount()
    92  		if burn >= 0 {
    93  			continue
    94  		}
    95  		switch {
    96  		case r.Result.PaidStorageSizeDiff > 0 && i == 0:
    97  			cost.StorageBurn += -burn
    98  			cost.Burn += -burn
    99  			i++
   100  		case len(r.Result.OriginatedContracts) > 0 && i == 1:
   101  			cost.AllocationBurn += -burn
   102  			cost.Burn += -burn
   103  			i++
   104  		case r.Result.Allocated:
   105  			cost.AllocationBurn += -burn
   106  			cost.Burn += -burn
   107  			i++
   108  		}
   109  	}
   110  	return cost
   111  }
   112  
   113  // found in block metadata from v010+
   114  type ImplicitResult struct {
   115  	Kind                mavryk.OpType     `json:"kind"`
   116  	BalanceUpdates      BalanceUpdates    `json:"balance_updates"`
   117  	ConsumedGas         int64             `json:"consumed_gas,string"`
   118  	ConsumedMilliGas    int64             `json:"consumed_milligas,string"`
   119  	Storage             *micheline.Prim   `json:"storage,omitempty"`
   120  	StorageSize         int64             `json:"storage_size,string"`
   121  	OriginatedContracts []mavryk.Address  `json:"originated_contracts,omitempty"`
   122  	PaidStorageSizeDiff int64             `json:"paid_storage_size_diff,string"`
   123  	Script              *micheline.Script `json:"script,omitempty"`
   124  }
   125  
   126  func (r ImplicitResult) Gas() int64 {
   127  	if r.ConsumedMilliGas > 0 {
   128  		return r.ConsumedMilliGas / 1000
   129  	}
   130  	return r.ConsumedGas
   131  }
   132  
   133  func (r ImplicitResult) MilliGas() int64 {
   134  	if r.ConsumedMilliGas > 0 {
   135  		return r.ConsumedMilliGas
   136  	}
   137  	return r.ConsumedGas * 1000
   138  }