-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
100 lines (87 loc) · 4.08 KB
/
index.ts
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
import { SorobanRpc, scValToNative } from '@stellar/stellar-sdk'
export function sorobill(sim: SorobanRpc.Api.SimulateTransactionSuccessResponse, tx?: SorobanRpc.Api.GetSuccessfulTransactionResponse) {
const events = sim.events.map((e) => {
const event = e.event()
if (event.type().name !== 'contract')
return 0
return event.toXDR().length
})
const events_and_return_bytes = (
events.reduce(
(accumulator: number, currentValue: number) => accumulator + currentValue, // events
sim.result?.retval.toXDR().length || 0 // return value size
)
)
const sorobanTransactionData = sim.transactionData
const resources = sorobanTransactionData.build().resources()
const rwro = [
sorobanTransactionData.getReadWrite()
.flatMap((rw) => rw.toXDR().length),
sorobanTransactionData.getReadOnly()
.flatMap((ro) => ro.toXDR().length)
].flat()
const metrics: any = {
mem_byte: Number(sim.cost.memBytes),
cpu_insn: Number(sim.cost.cpuInsns)
}
tx?.resultMetaXdr
.v3()
.sorobanMeta()
?.diagnosticEvents()
.forEach((e) => {
const event = e.event()
const topics = event.body().v0().topics()
const is_core_metrics_event = topics.some((topic) => scValToNative(topic) === 'core_metrics')
for (const metric in metrics) {
const is_metric = topics.some((topic) => scValToNative(topic) === metric)
if (is_core_metrics_event && is_metric)
metrics[metric] = Number(scValToNative(event.body().v0().data()))
}
})
const entries = tx?.resultMetaXdr
.v3()
.operations()
.flatMap((op) =>
op.changes().flatMap((change) => {
switch (change.switch().name) {
case 'ledgerEntryCreated':
return change.created().data().value().toXDR().length
case 'ledgerEntryUpdated':
return change.updated().data().value().toXDR().length
// NOTE this one is different and unsure if it's relevant as it's key removal not addition
// case 'ledgerEntryRemoved':
// return change.removed().data().toXDR().length
// NOTE unsure if this one is needed either as I'm unclear what it's for
// case 'ledgerEntryState':
// return change.state().data().value().toXDR().length
default:
return 0
}
})
)
const stats = {
cpu_insns: metrics.cpu_insn,
mem_bytes: metrics.mem_byte,
entry_reads: resources.footprint().readOnly().length,
entry_writes: resources.footprint().readWrite().length,
read_bytes: resources.readBytes(),
// NOTE This covers both `contractDataEntrySizeBytes` in the case of a contract invocation and `contractMaxSizeBytes` in the case of a WASM install
write_bytes: resources.writeBytes(),
events_and_return_bytes,
/* NOTE
This field isn't terribly useful as the actual tx size may be larger once you've added all the signatures
If the tx doesn't even have the sorobanData or auth applied this will be even less useful (and so we `undefined` it)
*/
min_txn_bytes: tx ? tx.envelopeXdr.toXDR().length : undefined,
/* NOTE
This limit is the max single ledger entry size
You can write 25 keys with a sum total size of 65 KB and a single key max of 64 KB
It currently cannot be derived from either the tx or the simulation (boo)
(see https://discord.com/channels/897514728459468821/966788672164855829/1212887348191166484)
If you're submitting a wasm upload up the max value is likely the wasm binary size
*/
max_entry_bytes: tx ? entries?.length ? Math.max(...entries) : 0 : undefined,
max_key_bytes: Math.max(...rwro),
}
return stats
}