-
Notifications
You must be signed in to change notification settings - Fork 209
Expand file tree
/
Copy pathtransaction.go
More file actions
136 lines (116 loc) · 3.84 KB
/
transaction.go
File metadata and controls
136 lines (116 loc) · 3.84 KB
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
134
135
136
package fvm
import (
otelTrace "go.opentelemetry.io/otel/trace"
"github.com/onflow/flow-go/fvm/errors"
"github.com/onflow/flow-go/fvm/programs"
"github.com/onflow/flow-go/fvm/state"
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/module"
"github.com/onflow/flow-go/module/trace"
)
// TODO(patrick): pass in initial snapshot time when we start supporting
// speculative pre-processing / execution.
func Transaction(tx *flow.TransactionBody, txIndex uint32) *TransactionProcedure {
return &TransactionProcedure{
ID: tx.ID(),
Transaction: tx,
InitialSnapshotTxIndex: txIndex,
TxIndex: txIndex,
}
}
type TransactionProcessor interface {
Process(
Context,
*TransactionProcedure,
*state.TransactionState,
*programs.TransactionPrograms,
) error
}
type TransactionProcedure struct {
ID flow.Identifier
Transaction *flow.TransactionBody
InitialSnapshotTxIndex uint32
TxIndex uint32
Logs []string
Events []flow.Event
ServiceEvents []flow.Event
ComputationUsed uint64
MemoryEstimate uint64
Err errors.CodedError
TraceSpan otelTrace.Span
}
func (proc *TransactionProcedure) SetTraceSpan(traceSpan otelTrace.Span) {
proc.TraceSpan = traceSpan
}
func (proc *TransactionProcedure) IsSampled() bool {
return proc.TraceSpan != nil
}
func (proc *TransactionProcedure) StartSpanFromProcTraceSpan(
tracer module.Tracer,
spanName trace.SpanName) otelTrace.Span {
if tracer != nil && proc.IsSampled() {
return tracer.StartSpanFromParent(proc.TraceSpan, spanName)
}
return trace.NoopSpan
}
func (proc *TransactionProcedure) Run(
ctx Context,
txnState *state.TransactionState,
programs *programs.TransactionPrograms,
) error {
for _, p := range ctx.TransactionProcessors {
err := p.Process(ctx, proc, txnState, programs)
txErr, failure := errors.SplitErrorTypes(err)
if failure != nil {
// log the full error path
ctx.Logger.Err(err).Msg("fatal error when execution a transaction")
return failure
}
if txErr != nil {
proc.Err = txErr
// TODO we should not break here we should continue for fee deductions
break
}
}
return nil
}
func (proc *TransactionProcedure) ComputationLimit(ctx Context) uint64 {
// TODO for BFT (enforce max computation limit, already checked by collection nodes)
// TODO replace tx.Gas with individual limits for computation and memory
// decide computation limit
computationLimit := proc.Transaction.GasLimit
// if the computation limit is set to zero by user, fallback to the gas limit set by the context
if computationLimit == 0 {
computationLimit = ctx.ComputationLimit
// if the context computation limit is also zero, fallback to the default computation limit
if computationLimit == 0 {
computationLimit = DefaultComputationLimit
}
}
return computationLimit
}
func (proc *TransactionProcedure) MemoryLimit(ctx Context) uint64 {
// TODO for BFT (enforce max memory limit, already checked by collection nodes)
// TODO let user select a lower limit for memory (when its part of fees)
memoryLimit := ctx.MemoryLimit // TODO use the one set by tx
// if the context memory limit is also zero, fallback to the default memory limit
if memoryLimit == 0 {
memoryLimit = DefaultMemoryLimit
}
return memoryLimit
}
func (proc *TransactionProcedure) ShouldDisableMemoryAndInteractionLimits(
ctx Context,
) bool {
return ctx.DisableMemoryAndInteractionLimits ||
proc.Transaction.Payer == ctx.Chain.ServiceAddress()
}
func (TransactionProcedure) Type() ProcedureType {
return TransactionProcedureType
}
func (proc *TransactionProcedure) InitialSnapshotTime() programs.LogicalTime {
return programs.LogicalTime(proc.InitialSnapshotTxIndex)
}
func (proc *TransactionProcedure) ExecutionTime() programs.LogicalTime {
return programs.LogicalTime(proc.TxIndex)
}