@stellar-expert/tx-meta-effects-parser 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/aggregation/events-analyzer.js +23 -9
- package/src/effect-types.js +3 -1
- package/src/effects-analyzer.js +26 -2
- package/src/index.js +3 -1
package/package.json
CHANGED
|
@@ -61,13 +61,13 @@ class EventsAnalyzer {
|
|
|
61
61
|
* @private
|
|
62
62
|
*/
|
|
63
63
|
analyzeDiagnosticEvents() {
|
|
64
|
-
const {diagnosticEvents} = this.effectsAnalyzer
|
|
64
|
+
const {diagnosticEvents, processSystemEvents} = this.effectsAnalyzer
|
|
65
65
|
if (!diagnosticEvents)
|
|
66
66
|
return
|
|
67
67
|
//diagnostic events
|
|
68
68
|
for (const evt of diagnosticEvents) {
|
|
69
|
-
if (!evt.inSuccessfulContractCall())
|
|
70
|
-
|
|
69
|
+
if (!processSystemEvents && !evt.inSuccessfulContractCall())
|
|
70
|
+
continue //throw new UnexpectedTxMetaChangeError({type: 'diagnostic_event', action: 'failed'})
|
|
71
71
|
//parse event
|
|
72
72
|
const event = evt.event()
|
|
73
73
|
const contractId = event.contractId()
|
|
@@ -90,7 +90,7 @@ class EventsAnalyzer {
|
|
|
90
90
|
if (type !== EVENT_TYPES.DIAGNOSTIC)
|
|
91
91
|
return // skip non-diagnostic events
|
|
92
92
|
const rawArgs = body.data()
|
|
93
|
-
const
|
|
93
|
+
const funcCall = {
|
|
94
94
|
type: effectTypes.contractInvoked,
|
|
95
95
|
contract: xdrParseScVal(topics[1], true),
|
|
96
96
|
function: xdrParseScVal(topics[2]),
|
|
@@ -99,21 +99,35 @@ class EventsAnalyzer {
|
|
|
99
99
|
}
|
|
100
100
|
//add the invocation to the call stack
|
|
101
101
|
if (this.callStack.length) {
|
|
102
|
-
|
|
102
|
+
funcCall.depth = this.callStack.length
|
|
103
103
|
}
|
|
104
|
-
this.callStack.push(
|
|
105
|
-
this.effectsAnalyzer.addEffect(
|
|
104
|
+
this.callStack.push(funcCall)
|
|
105
|
+
this.effectsAnalyzer.addEffect(funcCall)
|
|
106
106
|
break
|
|
107
107
|
case 'fn_return':
|
|
108
108
|
if (type !== EVENT_TYPES.DIAGNOSTIC)
|
|
109
109
|
return // skip non-diagnostic events
|
|
110
110
|
//attach execution result to the contract invocation event
|
|
111
|
-
const
|
|
111
|
+
const lastFuncCall = this.callStack.pop()
|
|
112
112
|
const result = body.data()
|
|
113
113
|
if (result.switch().name !== 'scvVoid') {
|
|
114
|
-
|
|
114
|
+
lastFuncCall.result = result.toXDR('base64')
|
|
115
115
|
}
|
|
116
116
|
break
|
|
117
|
+
case 'error':
|
|
118
|
+
if (type !== EVENT_TYPES.DIAGNOSTIC)
|
|
119
|
+
return // skip non-diagnostic events
|
|
120
|
+
this.effectsAnalyzer.addEffect({
|
|
121
|
+
type: effectTypes.contractError,
|
|
122
|
+
code: topics[1].value().value(),
|
|
123
|
+
details: processEventBodyValue(body.data())
|
|
124
|
+
})
|
|
125
|
+
break
|
|
126
|
+
case 'core_metrics':
|
|
127
|
+
if (type !== EVENT_TYPES.DIAGNOSTIC)
|
|
128
|
+
return // skip non-diagnostic events
|
|
129
|
+
this.effectsAnalyzer.addMetric(xdrParseScVal(topics[1]), parseInt(processEventBodyValue(body.data())))
|
|
130
|
+
break
|
|
117
131
|
//handle standard token contract events
|
|
118
132
|
//see https://github.com/stellar/rs-soroban-sdk/blob/main/soroban-sdk/src/token.rs
|
|
119
133
|
case 'transfer': {
|
package/src/effect-types.js
CHANGED
|
@@ -86,12 +86,14 @@ const effectTypes = {
|
|
|
86
86
|
contractUpdated: 'contractUpdated',
|
|
87
87
|
|
|
88
88
|
contractInvoked: 'contractInvoked',
|
|
89
|
+
contractError: 'contractError',
|
|
89
90
|
|
|
90
91
|
contractDataCreated: 'contractDataCreated',
|
|
91
92
|
contractDataUpdated: 'contractDataUpdated',
|
|
92
93
|
contractDataRemoved: 'contractDataRemoved',
|
|
93
94
|
|
|
94
|
-
contractEvent: 'contractEvent'
|
|
95
|
+
contractEvent: 'contractEvent',
|
|
96
|
+
contractMetrics: 'contractMetrics'
|
|
95
97
|
}
|
|
96
98
|
|
|
97
99
|
module.exports = effectTypes
|
package/src/effects-analyzer.js
CHANGED
|
@@ -9,7 +9,7 @@ const AssetSupplyAnalyzer = require('./aggregation/asset-supply-analyzer')
|
|
|
9
9
|
const {UnexpectedTxMetaChangeError, TxMetaEffectParserError} = require('./errors')
|
|
10
10
|
|
|
11
11
|
class EffectsAnalyzer {
|
|
12
|
-
constructor({operation, meta, result, network, events, diagnosticEvents, mapSac}) {
|
|
12
|
+
constructor({operation, meta, result, network, events, diagnosticEvents, mapSac, processSystemEvents}) {
|
|
13
13
|
//set execution context
|
|
14
14
|
if (!operation.source)
|
|
15
15
|
throw new TxMetaEffectParserError('Operation source is not explicitly defined')
|
|
@@ -21,6 +21,9 @@ class EffectsAnalyzer {
|
|
|
21
21
|
this.events = events
|
|
22
22
|
if (diagnosticEvents?.length) {
|
|
23
23
|
this.diagnosticEvents = diagnosticEvents
|
|
24
|
+
if (processSystemEvents) {
|
|
25
|
+
this.processSystemEvents = true
|
|
26
|
+
}
|
|
24
27
|
}
|
|
25
28
|
this.network = network
|
|
26
29
|
if (mapSac) {
|
|
@@ -69,10 +72,20 @@ class EffectsAnalyzer {
|
|
|
69
72
|
*/
|
|
70
73
|
source = ''
|
|
71
74
|
/**
|
|
72
|
-
* @type {
|
|
75
|
+
* @type {Boolean}
|
|
73
76
|
* @private
|
|
74
77
|
*/
|
|
75
78
|
isContractCall = false
|
|
79
|
+
/**
|
|
80
|
+
* @type {Boolean}
|
|
81
|
+
* @readonly
|
|
82
|
+
*/
|
|
83
|
+
processSystemEvents = false
|
|
84
|
+
/**
|
|
85
|
+
* @type {{}}
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
metrics
|
|
76
89
|
|
|
77
90
|
analyze() {
|
|
78
91
|
//find appropriate parser method
|
|
@@ -160,6 +173,17 @@ class EffectsAnalyzer {
|
|
|
160
173
|
}, position)
|
|
161
174
|
}
|
|
162
175
|
|
|
176
|
+
addMetric(metric, value) {
|
|
177
|
+
let {metrics} = this
|
|
178
|
+
if (!metrics) {
|
|
179
|
+
metrics = this.metrics = {
|
|
180
|
+
type: effectTypes.contractMetrics
|
|
181
|
+
}
|
|
182
|
+
this.addEffect(metrics)
|
|
183
|
+
}
|
|
184
|
+
metrics[metric] = value
|
|
185
|
+
}
|
|
186
|
+
|
|
163
187
|
setOptions() {
|
|
164
188
|
const sourceAccount = normalizeAddress(this.source)
|
|
165
189
|
const {before, after} = this.changes.find(ch => ch.type === 'account' && ch.before.address === sourceAccount)
|
package/src/index.js
CHANGED
|
@@ -17,9 +17,10 @@ const effectTypes = require('./effect-types')
|
|
|
17
17
|
* @param {String|Buffer|xdr.TransactionResult} [result] - Base64-encoded tx envelope result
|
|
18
18
|
* @param {String|Buffer|xdr.TransactionMeta} [meta] - Base64-encoded tx envelope meta
|
|
19
19
|
* @param {Boolean} [mapSac] - Whether to create a map SAC->Asset
|
|
20
|
+
* @param {Boolean} [processSystemEvents] - Emit effects for contract errors and resource stats
|
|
20
21
|
* @return {ParsedTxOperationsMetadata}
|
|
21
22
|
*/
|
|
22
|
-
function parseTxOperationsMeta({network, tx, result, meta, mapSac = false}) {
|
|
23
|
+
function parseTxOperationsMeta({network, tx, result, meta, mapSac = false, processSystemEvents = false}) {
|
|
23
24
|
if (!network)
|
|
24
25
|
throw new TypeError(`Network passphrase argument is required.`)
|
|
25
26
|
if (typeof network !== 'string')
|
|
@@ -138,6 +139,7 @@ function parseTxOperationsMeta({network, tx, result, meta, mapSac = false}) {
|
|
|
138
139
|
params.events = sorobanMeta.events()
|
|
139
140
|
params.diagnosticEvents = sorobanMeta.diagnosticEvents()
|
|
140
141
|
params.mapSac = mapSac
|
|
142
|
+
params.processSystemEvents = processSystemEvents
|
|
141
143
|
}
|
|
142
144
|
const analyzer = new EffectsAnalyzer(params)
|
|
143
145
|
operation.effects = analyzer.analyze()
|