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