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 }