Skip to content

Commit 4bc377e

Browse files
authored
Merge pull request #6 from skip-mev/na/unordered-txs-support
feat: add unordered txs support
2 parents 9639f4e + 1447386 commit 4bc377e

File tree

8 files changed

+503
-321
lines changed

8 files changed

+503
-321
lines changed

example/petri_integration/load_test.go

+206-23
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99
"testing"
1010
"time"
1111

12+
"gopkg.in/yaml.v3"
13+
1214
"github.com/skip-mev/petri/core/v3/util"
1315

1416
"github.com/cosmos/cosmos-sdk/crypto/hd"
@@ -27,11 +29,11 @@ var (
2729
defaultChainConfig = petritypes.ChainConfig{
2830
Denom: "stake",
2931
Decimals: 6,
30-
NumValidators: 10,
32+
NumValidators: 4,
3133
NumNodes: 0,
3234
BinaryName: "/usr/bin/simd",
3335
Image: provider.ImageDefinition{
34-
Image: "ghcr.io/skip-mev/simapp:latest",
36+
Image: "ghcr.io/cosmos/simapp:v0.50",
3537
UID: "1000",
3638
GID: "1000",
3739
},
@@ -40,14 +42,14 @@ var (
4042
HomeDir: "/gaia",
4143
CoinType: "118",
4244
ChainId: "stake-1",
43-
UseGenesisSubCommand: false,
45+
UseGenesisSubCommand: true,
4446
}
4547

4648
defaultChainOptions = petritypes.ChainOptions{
4749
NodeCreator: node.CreateNode,
4850
ModifyGenesis: chain.ModifyGenesis([]chain.GenesisKV{
4951
{
50-
Key: "consensus_params.block.max_gas",
52+
Key: "consensus.params.block.max_gas",
5153
Value: "75000000",
5254
},
5355
}),
@@ -131,55 +133,236 @@ func TestPetriDockerIntegration(t *testing.T) {
131133
logger.Error("Failed to create wallet", zap.Error(err))
132134
return
133135
}
136+
logger.Debug("Successfully created load test wallet", zap.Any("address", w.FormattedAddress()))
134137

135138
walletsMutex.Lock()
136139
wallets = append(wallets, w)
140+
mnemonics = append(mnemonics, w.Mnemonic())
137141
walletsMutex.Unlock()
138142
}()
139143
}
140144

141145
wg.Wait()
146+
time.Sleep(20 * time.Second)
142147

143148
logger.Info("Successfully created wallets asynchronously", zap.Int("count", len(wallets)))
144149

145-
for _, w := range wallets {
146-
command := []string{
147-
defaultChainConfig.BinaryName,
148-
"tx", "bank", "send",
149-
faucetWallet.FormattedAddress(),
150-
w.FormattedAddress(),
151-
"1000000000stake",
152-
"--chain-id", defaultChainConfig.ChainId,
153-
"--keyring-backend", "test",
154-
"--fees", "100stake",
155-
"--yes",
156-
"--home", defaultChainConfig.HomeDir,
150+
addresses := make([]string, len(wallets))
151+
for i, w := range wallets {
152+
addresses[i] = w.FormattedAddress()
153+
}
154+
155+
command := []string{
156+
defaultChainConfig.BinaryName,
157+
"tx", "bank", "multi-send",
158+
faucetWallet.FormattedAddress(),
159+
}
160+
command = append(command, addresses...)
161+
command = append(command, "1000000000stake",
162+
"--chain-id", defaultChainConfig.ChainId,
163+
"--keyring-backend", "test",
164+
"--fees", "3000stake",
165+
"--gas", "auto",
166+
"--yes",
167+
"--home", defaultChainConfig.HomeDir,
168+
)
169+
170+
t.Log("command: ", command)
171+
stdout, stderr, exitCode, err := node.RunCommand(ctx, command)
172+
t.Log("stdout, stderr", stdout, stderr)
173+
if err != nil || exitCode != 0 {
174+
t.Fatal("Failed to fund wallets with MsgMultiSend", zap.Error(err), zap.String("stderr", stderr))
175+
}
176+
time.Sleep(5 * time.Second)
177+
178+
msgs := []loadtesttypes.LoadTestMsg{
179+
{Weight: 1, Type: loadtesttypes.MsgMultiSend},
180+
//{Weight: 1, Type: loadtesttypes.MsgSend},
181+
}
182+
183+
spec := loadtesttypes.LoadTestSpec{
184+
ChainID: defaultChainConfig.ChainId,
185+
BlockGasLimitTarget: 1,
186+
NumOfBlocks: 20,
187+
NodesAddresses: nodeAddresses,
188+
Mnemonics: mnemonics,
189+
GasDenom: defaultChainConfig.Denom,
190+
Bech32Prefix: defaultChainConfig.Bech32Prefix,
191+
Msgs: msgs,
192+
UnorderedTxs: true,
193+
TxTimeout: time.Second * 20,
194+
}
195+
196+
time.Sleep(10 * time.Second)
197+
test, err := loadtest.New(ctx, spec)
198+
if err != nil {
199+
t.Fatal("Failed to create test", zap.Error(err))
200+
}
201+
202+
result, err := test.Run(ctx, logger)
203+
if err != nil {
204+
t.Fatal("Failed to run load test", zap.Error(err))
205+
}
206+
207+
fmt.Printf("Load test results: %+v\n", result)
208+
}
209+
210+
func TestPetriDockerfileIntegration(t *testing.T) {
211+
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
212+
defer cancel()
213+
logger, _ := zap.NewDevelopment()
214+
215+
p, err := docker.CreateProvider(ctx, logger, "docker_provider")
216+
if err != nil {
217+
t.Fatal("Provider creation error", zap.Error(err))
218+
return
219+
}
220+
221+
defer func() {
222+
err := p.Teardown(context.TODO())
223+
if err != nil {
224+
t.Logf("Failed to teardown provider: %v", err)
157225
}
226+
}()
158227

159-
_, stderr, exitCode, err := node.RunCommand(ctx, command)
160-
if err != nil || exitCode != 0 {
161-
t.Fatal("Failed to fund wallet", zap.Error(err), zap.String("stderr", stderr))
228+
c, err := chain.CreateChain(ctx, logger, p, defaultChainConfig, defaultChainOptions)
229+
if err != nil {
230+
t.Fatal("Chain creation error", zap.Error(err))
231+
}
232+
err = c.Init(ctx, defaultChainOptions)
233+
if err != nil {
234+
t.Fatal("Failed to init chain", zap.Error(err))
235+
}
236+
err = c.WaitForStartup(ctx)
237+
if err != nil {
238+
t.Fatal("Failed to wait for chain startup", zap.Error(err))
239+
}
240+
241+
// Add a delay to ensure the node is fully ready
242+
time.Sleep(5 * time.Second)
243+
244+
var nodeAddresses []loadtesttypes.NodeAddress
245+
for _, n := range c.GetValidators() {
246+
grpcAddress, err := n.GetExternalAddress(ctx, "9090")
247+
if err != nil {
248+
t.Fatal("Failed to get node grpc address", zap.Error(err))
249+
}
250+
rpcAddress, err := n.GetExternalAddress(ctx, "26657")
251+
if err != nil {
252+
t.Fatal("Failed to get node rpc address", zap.Error(err))
162253
}
254+
logger.Info("Node addresses",
255+
zap.String("grpc", grpcAddress),
256+
zap.String("rpc", rpcAddress))
257+
nodeAddresses = append(nodeAddresses, loadtesttypes.NodeAddress{
258+
GRPC: grpcAddress,
259+
RPC: "http://" + rpcAddress,
260+
})
261+
}
262+
263+
var mnemonics []string
264+
var wallets []petritypes.WalletI
265+
var walletsMutex sync.Mutex
266+
var wg sync.WaitGroup
267+
268+
faucetWallet := c.GetFaucetWallet()
269+
node := c.GetValidators()[0]
270+
271+
for i := 0; i < 2; i++ {
272+
wg.Add(1)
273+
go func() {
274+
defer wg.Done()
275+
w, err := c.CreateWallet(ctx, util.RandomString(5), defaultChainOptions.WalletConfig)
276+
if err != nil {
277+
logger.Error("Failed to create wallet", zap.Error(err))
278+
return
279+
}
280+
281+
walletsMutex.Lock()
282+
wallets = append(wallets, w)
283+
walletsMutex.Unlock()
284+
}()
285+
}
286+
287+
wg.Wait()
288+
289+
logger.Info("Successfully created wallets asynchronously", zap.Int("count", len(wallets)))
163290

164-
mnemonics = append(mnemonics, w.Mnemonic())
165-
time.Sleep(5 * time.Second)
291+
addresses := make([]string, len(wallets))
292+
for i, w := range wallets {
293+
addresses[i] = w.FormattedAddress()
166294
}
295+
t.Log("addresses: ", addresses)
296+
297+
command := []string{
298+
defaultChainConfig.BinaryName,
299+
"tx", "bank", "multi-send",
300+
faucetWallet.FormattedAddress(),
301+
}
302+
command = append(command, addresses...)
303+
command = append(command, "1000000000stake",
304+
"--chain-id", defaultChainConfig.ChainId,
305+
"--keyring-backend", "test",
306+
"--fees", "500stake",
307+
"--gas", "auto",
308+
"--yes",
309+
"--home", defaultChainConfig.HomeDir,
310+
)
311+
t.Log("funding command. ", command)
312+
313+
stdout, stderr, exitCode, err := node.RunCommand(ctx, command)
314+
t.Log("stdout, stderr", stdout, stderr)
315+
if err != nil || exitCode != 0 {
316+
t.Fatal("Failed to fund wallets with MsgMultiSend", zap.Error(err), zap.String("stderr", stderr))
317+
}
318+
time.Sleep(5 * time.Second)
167319

168320
msgs := []loadtesttypes.LoadTestMsg{
169-
//{Weight: 0.5, Type: loadtesttypes.MsgSend},
170321
{Weight: 1, Type: loadtesttypes.MsgMultiSend},
171322
}
172323
spec := loadtesttypes.LoadTestSpec{
173324
ChainID: defaultChainConfig.ChainId,
174325
BlockGasLimitTarget: 1,
175-
NumOfBlocks: 50,
326+
NumOfBlocks: 20,
176327
NodesAddresses: nodeAddresses,
177328
Mnemonics: mnemonics,
178329
GasDenom: defaultChainConfig.Denom,
179330
Bech32Prefix: defaultChainConfig.Bech32Prefix,
180331
Msgs: msgs,
181332
}
182333

334+
task, err := p.CreateTask(ctx, provider.TaskDefinition{
335+
Name: "catalyst",
336+
ContainerName: "catalyst",
337+
Image: provider.ImageDefinition{
338+
Image: "ghcr.io/skip-mev/catalyst:latest",
339+
UID: "100",
340+
GID: "100",
341+
},
342+
ProviderSpecificConfig: map[string]string{
343+
"region": "ams3",
344+
"image_id": "177032231",
345+
"size": "s-1vcpu-1gb",
346+
},
347+
Command: []string{"/tmp/catalyst/loadtest.yml"},
348+
DataDir: "/tmp/catalyst",
349+
})
350+
351+
configBytes, err := yaml.Marshal(&spec)
352+
if err != nil {
353+
t.Fatal("Failed to marshal spec", zap.Error(err))
354+
}
355+
356+
if err := task.WriteFile(ctx, "loadtest.yml", configBytes); err != nil {
357+
t.Fatal("failed to write config file to task", zap.Error(err), zap.Error(err))
358+
}
359+
360+
logger.Info("starting load test")
361+
if err := task.Start(ctx); err != nil {
362+
t.Fatal("failed to starting load test", zap.Error(err), zap.Error(err))
363+
}
364+
365+
time.Sleep(360 * time.Second)
183366
test, err := loadtest.New(ctx, spec)
184367
if err != nil {
185368
t.Fatal("Failed to create test", zap.Error(err))

0 commit comments

Comments
 (0)