Skip to content

Commit 756fc0f

Browse files
authored
Merge pull request #39 from skip-mev/na/catalyst-types
chore: use catalyst types instead of duplicated internal types
2 parents 0cc7b29 + 17e59d6 commit 756fc0f

File tree

9 files changed

+152
-345
lines changed

9 files changed

+152
-345
lines changed

activities/loadtest/loadtest.go

+17-127
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"github.com/skip-mev/catalyst/pkg/types"
78
"sync"
89
"time"
910

@@ -22,132 +23,21 @@ import (
2223
"gopkg.in/yaml.v3"
2324
)
2425

25-
type MsgType string
26-
27-
// LoadTestResult represents the results of a load test
28-
type LoadTestResult struct {
29-
Overall OverallStats
30-
ByMessage map[MsgType]MessageStats
31-
ByNode map[string]NodeStats
32-
ByBlock []BlockStat
33-
Error string `json:"error,omitempty"`
34-
}
35-
36-
// OverallStats represents the overall statistics of the load test
37-
type OverallStats struct {
38-
TotalTransactions int
39-
SuccessfulTransactions int
40-
FailedTransactions int
41-
AvgGasPerTransaction int64
42-
AvgBlockGasUtilization float64
43-
Runtime time.Duration
44-
StartTime time.Time
45-
EndTime time.Time
46-
BlocksProcessed int
47-
}
48-
49-
// MessageStats represents statistics for a specific message type
50-
type MessageStats struct {
51-
Transactions TransactionStats
52-
Gas GasStats
53-
Errors ErrorStats
54-
}
55-
56-
// TransactionStats represents transaction-related statistics
57-
type TransactionStats struct {
58-
Total int
59-
Successful int
60-
Failed int
61-
}
62-
63-
// GasStats represents gas-related statistics
64-
type GasStats struct {
65-
Average int64
66-
Min int64
67-
Max int64
68-
Total int64
69-
}
70-
71-
// ErrorStats represents error-related statistics
72-
type ErrorStats struct {
73-
BroadcastErrors []BroadcastError
74-
ErrorCounts map[string]int // Error type to count
75-
}
76-
77-
// NodeStats represents statistics for a specific node
78-
type NodeStats struct {
79-
Address string
80-
TransactionStats TransactionStats
81-
MessageCounts map[MsgType]int
82-
GasStats GasStats
83-
}
84-
85-
// BlockStat represents statistics for a specific block
86-
type BlockStat struct {
87-
BlockHeight int64
88-
Timestamp time.Time
89-
GasLimit int
90-
TotalGasUsed int64
91-
MessageStats map[MsgType]MessageBlockStats
92-
GasUtilization float64
93-
}
94-
95-
// MessageBlockStats represents message-specific statistics within a block
96-
type MessageBlockStats struct {
97-
TransactionsSent int
98-
SuccessfulTxs int
99-
FailedTxs int
100-
GasUsed int64
101-
}
102-
103-
// BroadcastError represents errors during broadcasting transactions
104-
type BroadcastError struct {
105-
BlockHeight int64 // Block height where the error occurred (0 indicates tx did not make it to a block)
106-
TxHash string // Hash of the transaction that failed
107-
Error string // Error message
108-
MsgType MsgType // Type of message that failed
109-
NodeAddress string // Address of the node that returned the error
110-
}
111-
11226
type PackagedState struct {
11327
ProviderState []byte
11428
ChainState []byte
115-
Result LoadTestResult
116-
}
117-
118-
type LoadTestConfig struct {
119-
ChainID string `yaml:"chain_id"`
120-
BlockGasLimitTarget float64 `yaml:"block_gas_limit_target,omitempty"`
121-
NumOfTxs int `yaml:"num_of_txs,omitempty"`
122-
NumOfBlocks int `yaml:"num_of_blocks"`
123-
NodesAddresses []Node `yaml:"nodes_addresses"`
124-
Mnemonics []string `yaml:"mnemonics"`
125-
GasDenom string `yaml:"gas_denom"`
126-
Bech32Prefix string `yaml:"bech32_prefix"`
127-
Msgs []Message `yaml:"msgs"`
128-
}
129-
130-
type Node struct {
131-
GRPC string `yaml:"grpc"`
132-
RPC string `yaml:"rpc"`
133-
}
134-
135-
type Message struct {
136-
Type string `yaml:"type" json:"type"`
137-
Weight float64 `yaml:"weight" json:"weight"`
138-
NumMsgs int `yaml:"num_msgs,omitempty" json:"NumMsgs,omitempty"`
139-
ContainedType MsgType `yaml:"contained_type,omitempty" json:"ContainedType,omitempty"`
140-
NumOfRecipients int `yaml:"num_of_recipients,omitempty" json:"NumOfRecipients,omitempty"` // Number of recipients to include for MsgMultiSend
29+
Result types.LoadTestResult
14130
}
14231

14332
type Activity struct {
14433
DOToken string
14534
TailscaleSettings digitalocean.TailscaleSettings
14635
}
14736

148-
func generateLoadTestConfig(ctx context.Context, logger *zap.Logger, chain *chain.Chain, chainID string, loadTestConfig *LoadTestConfig) ([]byte, error) {
37+
func generateLoadTestSpec(ctx context.Context, logger *zap.Logger, chain *chain.Chain, chainID string,
38+
loadTestSpec *types.LoadTestSpec) ([]byte, error) {
14939
validators := chain.GetValidators()
150-
var nodes []Node
40+
var nodes []types.NodeAddress
15141
for _, v := range validators {
15242
grpcAddr, err := v.GetIP(ctx)
15343
grpcAddr = grpcAddr + ":9090"
@@ -161,7 +51,7 @@ func generateLoadTestConfig(ctx context.Context, logger *zap.Logger, chain *chai
16151
return nil, err
16252
}
16353

164-
nodes = append(nodes, Node{
54+
nodes = append(nodes, types.NodeAddress{
16555
GRPC: grpcAddr,
16656
RPC: fmt.Sprintf("http://%s", rpcAddr),
16757
})
@@ -227,20 +117,20 @@ func generateLoadTestConfig(ctx context.Context, logger *zap.Logger, chain *chai
227117
}
228118
time.Sleep(5 * time.Second)
229119

230-
config := LoadTestConfig{
120+
config := types.LoadTestSpec{
231121
ChainID: chainID,
232-
NumOfBlocks: loadTestConfig.NumOfBlocks,
122+
NumOfBlocks: loadTestSpec.NumOfBlocks,
233123
NodesAddresses: nodes,
234124
Mnemonics: mnemonics,
235125
GasDenom: chain.GetConfig().Denom,
236126
Bech32Prefix: chain.GetConfig().Bech32Prefix,
237-
Msgs: loadTestConfig.Msgs,
127+
Msgs: loadTestSpec.Msgs,
238128
}
239129

240-
if loadTestConfig.NumOfTxs > 0 {
241-
config.NumOfTxs = loadTestConfig.NumOfTxs
242-
} else if loadTestConfig.BlockGasLimitTarget > 0 {
243-
config.BlockGasLimitTarget = loadTestConfig.BlockGasLimitTarget
130+
if loadTestSpec.NumOfTxs > 0 {
131+
config.NumOfTxs = loadTestSpec.NumOfTxs
132+
} else if loadTestSpec.BlockGasLimitTarget > 0 {
133+
config.BlockGasLimitTarget = loadTestSpec.BlockGasLimitTarget
244134
} else {
245135
return nil, fmt.Errorf("failed to generate load test config, either BlockGasLimitTarget or NumOfTxs must be provided")
246136
}
@@ -250,7 +140,7 @@ func generateLoadTestConfig(ctx context.Context, logger *zap.Logger, chain *chai
250140
}
251141

252142
func (a *Activity) RunLoadTest(ctx context.Context, chainState []byte,
253-
loadTestConfig *LoadTestConfig, runnerType string, providerState []byte) (PackagedState, error) {
143+
loadTestSpec *types.LoadTestSpec, runnerType string, providerState []byte) (PackagedState, error) {
254144
logger, _ := zap.NewDevelopment()
255145

256146
var p provider.ProviderI
@@ -280,7 +170,7 @@ func (a *Activity) RunLoadTest(ctx context.Context, chainState []byte,
280170
return PackagedState{}, err
281171
}
282172

283-
configBytes, err := generateLoadTestConfig(ctx, logger, chain, chain.GetConfig().ChainId, loadTestConfig)
173+
configBytes, err := generateLoadTestSpec(ctx, logger, chain, chain.GetConfig().ChainId, loadTestSpec)
284174
if err != nil {
285175
return PackagedState{}, err
286176
}
@@ -289,7 +179,7 @@ func (a *Activity) RunLoadTest(ctx context.Context, chainState []byte,
289179
Name: "catalyst",
290180
ContainerName: "catalyst",
291181
Image: provider.ImageDefinition{
292-
Image: "ghcr.io/skip-mev/catalyst:latest",
182+
Image: "ghcr.io/skip-mev/catalyst:dev",
293183
UID: "100",
294184
GID: "100",
295185
},
@@ -340,7 +230,7 @@ func (a *Activity) RunLoadTest(ctx context.Context, chainState []byte,
340230
return PackagedState{}, fmt.Errorf("failed to read result file: %w", err)
341231
}
342232

343-
var result LoadTestResult
233+
var result types.LoadTestResult
344234
if err := json.Unmarshal(resultBytes, &result); err != nil {
345235
return PackagedState{}, fmt.Errorf("failed to parse result file: %w", err)
346236
}

app/commands.go

+13-39
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7+
catalyst_types "github.com/skip-mev/catalyst/pkg/types"
78
"regexp"
89
"strings"
910

@@ -90,7 +91,8 @@ func (a *App) generatedFailedCommandComment(command string, err error) (string,
9091
return mdOut.String(), nil
9192
}
9293

93-
func (a *App) generateStartedTestComment(chainConfig types.ChainsConfig, loadTestConfig types.LoadTestConfig, workflowId, runId string, runnerType testnettypes.RunnerType) (string, error) {
94+
func (a *App) generateStartedTestComment(chainConfig types.ChainsConfig, loadTestSpec catalyst_types.LoadTestSpec,
95+
workflowId, runId string, runnerType testnettypes.RunnerType) (string, error) {
9496
var mdOut bytes.Buffer
9597
var chainDetails bytes.Buffer
9698
var loadTestDetails bytes.Buffer
@@ -107,14 +109,14 @@ func (a *App) generateStartedTestComment(chainConfig types.ChainsConfig, loadTes
107109
}
108110

109111
loadTestMd := markdown.NewMarkdown(&loadTestDetails)
110-
loadTestMd = loadTestMd.LF().PlainText(fmt.Sprintf("Load test config: `%v`", loadTestConfig)).LF()
112+
loadTestMd = loadTestMd.LF().PlainText(fmt.Sprintf("Load test config: `%v`", loadTestSpec)).LF()
111113

112114
if err := loadTestMd.Build(); err != nil {
113115
return "", err
114116
}
115117

116118
md := markdown.NewMarkdown(&mdOut)
117-
md = md.PlainText(fmt.Sprintf("Ironbird has started a testnet for chain `%s` using loadtest `%s` with runner `%s`", chainConfig.Name, loadTestConfig.Name, runnerType)).LF()
119+
md = md.PlainText(fmt.Sprintf("Ironbird has started a testnet for chain `%s` using loadtest `%s` with runner `%s`", chainConfig.Name, loadTestSpec.Name, runnerType)).LF()
118120
md = md.Details("Chain details", chainDetails.String())
119121
md = md.Details("Load test details", loadTestDetails.String())
120122

@@ -179,43 +181,15 @@ func (a *App) HandleCommand(ctx context.Context, comment *Comment, command strin
179181
return nil
180182
}
181183

182-
func (a *App) parseCustomLoadTestConfig(yamlStr string) (*types.LoadTestConfig, error) {
183-
var customConfig types.LoadTestConfig
184+
func (a *App) parseCustomLoadTestSpec(yamlStr string) (*catalyst_types.LoadTestSpec, error) {
185+
var customConfig catalyst_types.LoadTestSpec
184186
if err := yaml.Unmarshal([]byte(yamlStr), &customConfig); err != nil {
185187
return nil, fmt.Errorf("failed to parse custom load test config: %w", err)
186188
}
187189

188-
if customConfig.Name == "" {
189-
customConfig.Name = "custom"
190-
}
191-
192-
if customConfig.BlockGasLimitTarget <= 0 && customConfig.NumOfTxs <= 0 {
193-
return nil, fmt.Errorf("either block_gas_limit_target or num_of_txs must be set")
194-
}
195-
196-
if customConfig.BlockGasLimitTarget > 0 && customConfig.NumOfTxs > 0 {
197-
return nil, fmt.Errorf("only one of block_gas_limit_target or num_of_txs should be set, not both")
198-
}
199-
200-
if customConfig.BlockGasLimitTarget > 1 {
201-
return nil, fmt.Errorf("block gas limit target must be between 0 and 1, got %f", customConfig.BlockGasLimitTarget)
202-
}
203-
204-
if customConfig.NumOfBlocks <= 0 {
205-
return nil, fmt.Errorf("num_of_blocks must be greater than 0")
206-
}
207-
208-
if len(customConfig.Msgs) == 0 {
209-
return nil, fmt.Errorf("at least one message type must be specified")
210-
}
211-
212-
totalWeight := 0.0
213-
for _, msg := range customConfig.Msgs {
214-
totalWeight += msg.Weight
215-
}
216-
217-
if totalWeight != 1.0 {
218-
return nil, fmt.Errorf("message weights must sum to exactly 1.0 (got %.2f)", totalWeight)
190+
err := customConfig.Validate()
191+
if err != nil {
192+
return nil, fmt.Errorf("failed to validate custom load test config: %w", err)
219193
}
220194

221195
return &customConfig, nil
@@ -299,9 +273,9 @@ func (a *App) commandStart(ctx context.Context, comment *Comment, command string
299273
return fmt.Errorf("unknown chain %s", chainName)
300274
}
301275

302-
var loadTest types.LoadTestConfig
276+
var loadTest catalyst_types.LoadTestSpec
303277
if hasCustomConfig {
304-
customLoadTest, err := a.parseCustomLoadTestConfig(customConfig[1])
278+
customLoadTest, err := a.parseCustomLoadTestSpec(customConfig[1])
305279
if err != nil {
306280
return err
307281
}
@@ -325,7 +299,7 @@ func (a *App) commandStart(ctx context.Context, comment *Comment, command string
325299
Repo: comment.Issue.Repo,
326300
SHA: *pr.Head.SHA,
327301
ChainConfig: chain,
328-
LoadTestConfig: &loadTest,
302+
LoadTestSpec: &loadTest,
329303
RunnerType: runnerType,
330304
})
331305

0 commit comments

Comments
 (0)