-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into refactor/gsw-2085
- Loading branch information
Showing
15 changed files
with
2,652 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
module github.com/gnoswap-labs/gnoswap | ||
|
||
go 1.23.5 | ||
|
||
require ( | ||
github.com/gnolang/gno v0.0.0-20250204100358-df14762147e9 | ||
github.com/rogpeppe/go-internal v1.13.1 | ||
github.com/stretchr/testify v1.10.0 | ||
) | ||
|
||
require ( | ||
dario.cat/mergo v1.0.1 // indirect | ||
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect | ||
github.com/btcsuite/btcd/btcutil v1.1.6 // indirect | ||
github.com/cenkalti/backoff/v4 v4.3.0 // indirect | ||
github.com/cockroachdb/apd/v3 v3.2.1 // indirect | ||
github.com/cosmos/ledger-cosmos-go v0.14.0 // indirect | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect | ||
github.com/go-logr/logr v1.4.2 // indirect | ||
github.com/go-logr/stdr v1.2.2 // indirect | ||
github.com/golang/protobuf v1.5.4 // indirect | ||
github.com/golang/snappy v0.0.4 // indirect | ||
github.com/google/uuid v1.6.0 // indirect | ||
github.com/gorilla/websocket v1.5.3 // indirect | ||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect | ||
github.com/libp2p/go-buffer-pool v0.1.0 // indirect | ||
github.com/pelletier/go-toml v1.9.5 // indirect | ||
github.com/peterbourgon/ff/v3 v3.4.0 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/pmezard/go-difflib v1.0.0 // indirect | ||
github.com/rs/cors v1.11.1 // indirect | ||
github.com/rs/xid v1.6.0 // indirect | ||
github.com/sig-0/insertion-queue v0.0.0-20241004125609-6b3ca841346b // indirect | ||
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect | ||
github.com/zondax/hid v0.9.2 // indirect | ||
github.com/zondax/ledger-go v0.14.3 // indirect | ||
go.etcd.io/bbolt v1.3.11 // indirect | ||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect | ||
go.opentelemetry.io/otel v1.34.0 // indirect | ||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 // indirect | ||
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 // indirect | ||
go.opentelemetry.io/otel/metric v1.34.0 // indirect | ||
go.opentelemetry.io/otel/sdk v1.34.0 // indirect | ||
go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect | ||
go.opentelemetry.io/otel/trace v1.34.0 // indirect | ||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect | ||
go.uber.org/multierr v1.11.0 // indirect | ||
golang.org/x/crypto v0.32.0 // indirect | ||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect | ||
golang.org/x/mod v0.22.0 // indirect | ||
golang.org/x/net v0.34.0 // indirect | ||
golang.org/x/sync v0.10.0 // indirect | ||
golang.org/x/sys v0.29.0 // indirect | ||
golang.org/x/term v0.28.0 // indirect | ||
golang.org/x/text v0.21.0 // indirect | ||
golang.org/x/tools v0.29.0 // indirect | ||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect | ||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect | ||
google.golang.org/grpc v1.69.4 // indirect | ||
google.golang.org/protobuf v1.36.3 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Package integration offers utilities to run txtar-based tests against the gnoland system | ||
// by extending the functionalities provided by the standard testscript package. This package is | ||
// currently in an experimental phase and may undergo significant changes in the future. | ||
// | ||
// SetupGnolandTestScript, sets up the environment for running txtar tests, introducing additional | ||
// commands like "gnoland" and "gnokey" into the test script ecosystem. Specifically, it allows the | ||
// user to initiate an in-memory gnoland node and interact with it via the `gnokey` command. | ||
// | ||
// Additional Command Overview: | ||
// | ||
// 1. `gnoland [start|stop|restart]`: | ||
// - The gnoland node doesn't start automatically. This enables the user to do some | ||
// pre-configuration or pass custom arguments to the start command. | ||
// - `gnoland restart` will simulate restarting a node, as in stopping and | ||
// starting it again, recovering state from the persisted database data. | ||
// - `gnoland start -non-validator` can be used to start a node as a non-validator node. | ||
// | ||
// 2. `gnokey`: | ||
// - Supports most of the common commands. | ||
// - `--remote`, `--insecure-password-stdin`, and `--home` flags are set automatically to | ||
// communicate with the gnoland node. | ||
// - In order to handle escape sequences like `\n` within arguments, you can enclose the argument | ||
// in `"` | ||
// | ||
// 3. `adduser`: | ||
// - Must be run before `gnoland start`. | ||
// - Creates a new user in the default keybase directory. | ||
// | ||
// 4. `adduserfrom`: | ||
// - Must be run before `gnoland start`. | ||
// - Creates a new user in the default keybase directory from a given seed. ( Optionally, account and index can be provided ) | ||
// | ||
// 5. `loadpkg`: | ||
// - Must be run before `gnoland start`. | ||
// - Loads a specific package from the 'examples' directory or from the working ($WORK) directory. | ||
// - Can be used to load a single package or all packages within a directory. | ||
// - If the target package has a `gno.mod`, all its dependencies (and their respective | ||
// dependencies) will also be loaded. | ||
// - The command takes either one or two arguments. The first argument is the name of the package(s), | ||
// and the second (optional) argument is the path to the package(s). | ||
// Examples: | ||
// -- # Load a package from the 'examples' directory: | ||
// -- loadpkg gno.land/p/demo/ufmt | ||
// -- # Load a package `./bar` from the testscript's working directory with the name `gno.land/r/foobar/bar`: | ||
// -- loadpkg gno.land/r/foobar/bar $WORK/bar | ||
// - If the path is not prefixed with the working directory, it is assumed to be relative to the | ||
// examples directory. | ||
// - It's important to note that the load order is significant when using multiple `loadpkg` | ||
// command; packages should be loaded in the order they are dependent upon. | ||
// | ||
// 6. `patchpkg`: | ||
// - Patches any loaded files by package by replacing all occurrences of the first argument with the second. | ||
// - This is mostly used to replace hardcoded addresses from loaded packages. | ||
// - NOTE: this command may only be temporary, as it's not best approach to | ||
// solve the above problem | ||
// | ||
// Logging: | ||
// | ||
// Gnoland logs aren't forwarded to stdout to avoid overwhelming the tests with too much | ||
// information. Instead, a log directory can be specified with `LOG_DIR`, or you | ||
// can set `TESTWORK=true` | ||
// to persist logs in the txtar working directory. In any case, the log file should be printed | ||
// on start if one of these environment variables is set. | ||
// | ||
// Accounts: | ||
// | ||
// By default, only the test1 user will be created in the default keybase directory, | ||
// with no password set. The default gnoland genesis balance file and the genesis | ||
// transaction file are also registered by default. | ||
// | ||
// Examples: | ||
// | ||
// Examples can be found in the `testdata` directory of this package. | ||
// | ||
// Environment Variables: | ||
// | ||
// Input: | ||
// | ||
// - TESTWORK: | ||
// A boolean that, when enabled, retains working directories after tests for | ||
// inspection. If enabled, gnoland logs will be persisted inside this | ||
// folder. | ||
// | ||
// - UPDATE_SCRIPTS: | ||
// A boolean that, when enabled, updates the test scripts if a `cmp` command | ||
// fails and its second argument refers to a file inside the testscript | ||
// file. The content will be quoted with txtar.Quote if needed, requiring | ||
// manual edits if it's not unquoted in the script. | ||
// | ||
// Output (available inside testscripts files): | ||
// | ||
// - WORK: | ||
// The path to the temporary work directory tree created for each script. | ||
// | ||
// - GNOROOT: | ||
// Points to the local location of the gno repository, serving as the GOROOT equivalent for gno. | ||
// | ||
// - GNOHOME: | ||
// Refers to the local directory where gnokey stores its keys. | ||
// | ||
// - GNODATA: | ||
// The path where the gnoland node stores its configuration and data. It's | ||
// set only if the node has started. | ||
// | ||
// - xxx_user_seed: | ||
// Where `xxx` is the account name; Contains the seed for the test1 account. | ||
// | ||
// - xxx_user_addr: | ||
// Where `xxx` is the account name; Contains the address for the test1 account. | ||
// | ||
// - xxx_account_num: | ||
// Where `xxx` is the account name; Contains the account number for the test1 account. | ||
// | ||
// - xxx_account_seq: | ||
// Where `xxx` is the account name; Contains the address for the test1 account. | ||
// | ||
// - RPC_ADDR: | ||
// Points to the gnoland node's remote address. It's set only if the node has started. | ||
// | ||
// For a more comprehensive guide on original behaviors, additional commands and environment | ||
// variables, refer to the original documentation of testscripts available here: | ||
// https://github.com/rogpeppe/go-internal/blob/master/testscript/doc.go | ||
package integration |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
package integration | ||
|
||
import ( | ||
"log/slog" | ||
"path/filepath" | ||
"slices" | ||
"time" | ||
|
||
"github.com/gnolang/gno/gno.land/pkg/gnoland" | ||
"github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot" | ||
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types" | ||
tmcfg "github.com/gnolang/gno/tm2/pkg/bft/config" | ||
"github.com/gnolang/gno/tm2/pkg/bft/node" | ||
bft "github.com/gnolang/gno/tm2/pkg/bft/types" | ||
"github.com/gnolang/gno/tm2/pkg/crypto" | ||
"github.com/gnolang/gno/tm2/pkg/db/memdb" | ||
"github.com/gnolang/gno/tm2/pkg/std" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
const ( | ||
DefaultAccount_Name = "test1" | ||
DefaultAccount_Address = "g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5" | ||
DefaultAccount_Seed = "source bonus chronic canvas draft south burst lottery vacant surface solve popular case indicate oppose farm nothing bullet exhibit title speed wink action roast" | ||
) | ||
|
||
// TestingInMemoryNode initializes and starts an in-memory node for testing. | ||
// It returns the node instance and its RPC remote address. | ||
func TestingInMemoryNode(t TestingTS, logger *slog.Logger, config *gnoland.InMemoryNodeConfig) (*node.Node, string) { | ||
node, err := gnoland.NewInMemoryNode(logger, config) | ||
require.NoError(t, err) | ||
|
||
err = node.Start() | ||
require.NoError(t, err) | ||
|
||
ourAddress := config.PrivValidator.GetPubKey().Address() | ||
isValidator := slices.ContainsFunc(config.Genesis.Validators, func(val bft.GenesisValidator) bool { | ||
return val.Address == ourAddress | ||
}) | ||
|
||
// Wait for first block if we are a validator. | ||
// If we are not a validator, we don't produce blocks, so node.Ready() hangs. | ||
if isValidator { | ||
select { | ||
case <-node.Ready(): | ||
case <-time.After(time.Second * 10): | ||
require.FailNow(t, "timeout while waiting for the node to start") | ||
} | ||
} | ||
|
||
return node, node.Config().RPC.ListenAddress | ||
} | ||
|
||
// TestingNodeConfig constructs an in-memory node configuration | ||
// with default packages and genesis transactions already loaded. | ||
// It will return the default creator address of the loaded packages. | ||
func TestingNodeConfig(t TestingTS, gnoroot string, additionalTxs ...gnoland.TxWithMetadata) (*gnoland.InMemoryNodeConfig, bft.Address) { | ||
cfg := TestingMinimalNodeConfig(gnoroot) | ||
cfg.SkipGenesisVerification = true | ||
|
||
creator := crypto.MustAddressFromString(DefaultAccount_Address) // test1 | ||
|
||
params := LoadDefaultGenesisParamFile(t, gnoroot) | ||
balances := LoadDefaultGenesisBalanceFile(t, gnoroot) | ||
txs := make([]gnoland.TxWithMetadata, 0) | ||
txs = append(txs, LoadDefaultPackages(t, creator, gnoroot)...) | ||
txs = append(txs, additionalTxs...) | ||
|
||
cfg.Genesis.AppState = gnoland.GnoGenesisState{ | ||
Balances: balances, | ||
Txs: txs, | ||
Params: params, | ||
} | ||
|
||
return cfg, creator | ||
} | ||
|
||
// TestingMinimalNodeConfig constructs the default minimal in-memory node configuration for testing. | ||
func TestingMinimalNodeConfig(gnoroot string) *gnoland.InMemoryNodeConfig { | ||
tmconfig := DefaultTestingTMConfig(gnoroot) | ||
|
||
// Create Mocked Identity | ||
pv := gnoland.NewMockedPrivValidator() | ||
|
||
// Generate genesis config | ||
genesis := DefaultTestingGenesisConfig(gnoroot, pv.GetPubKey(), tmconfig) | ||
|
||
return &gnoland.InMemoryNodeConfig{ | ||
PrivValidator: pv, | ||
Genesis: genesis, | ||
TMConfig: tmconfig, | ||
DB: memdb.NewMemDB(), | ||
InitChainerConfig: gnoland.InitChainerConfig{ | ||
GenesisTxResultHandler: gnoland.PanicOnFailingTxResultHandler, | ||
CacheStdlibLoad: true, | ||
}, | ||
} | ||
} | ||
|
||
func DefaultTestingGenesisConfig(gnoroot string, self crypto.PubKey, tmconfig *tmcfg.Config) *bft.GenesisDoc { | ||
return &bft.GenesisDoc{ | ||
GenesisTime: time.Now(), | ||
ChainID: tmconfig.ChainID(), | ||
ConsensusParams: abci.ConsensusParams{ | ||
Block: &abci.BlockParams{ | ||
MaxTxBytes: 1_000_000, // 1MB, | ||
MaxDataBytes: 2_000_000, // 2MB, | ||
MaxGas: 3_000_000_000, // 3B gas | ||
TimeIotaMS: 100, // 100ms | ||
}, | ||
}, | ||
Validators: []bft.GenesisValidator{ | ||
{ | ||
Address: self.Address(), | ||
PubKey: self, | ||
Power: 10, | ||
Name: "self", | ||
}, | ||
}, | ||
AppState: gnoland.GnoGenesisState{ | ||
Balances: []gnoland.Balance{ | ||
{ | ||
Address: crypto.MustAddressFromString(DefaultAccount_Address), | ||
Amount: std.MustParseCoins(ugnot.ValueString(10_000_000_000_000)), | ||
}, | ||
}, | ||
Txs: []gnoland.TxWithMetadata{}, | ||
Params: []gnoland.Param{}, | ||
}, | ||
} | ||
} | ||
|
||
// LoadDefaultPackages loads the default packages for testing using a given creator address and gnoroot directory. | ||
func LoadDefaultPackages(t TestingTS, creator bft.Address, gnoroot string) []gnoland.TxWithMetadata { | ||
examplesDir := filepath.Join(gnoroot, "examples") | ||
|
||
defaultFee := std.NewFee(50000, std.MustParseCoin(ugnot.ValueString(1000000))) | ||
txs, err := gnoland.LoadPackagesFromDir(examplesDir, creator, defaultFee) | ||
require.NoError(t, err) | ||
|
||
return txs | ||
} | ||
|
||
// LoadDefaultGenesisBalanceFile loads the default genesis balance file for testing. | ||
func LoadDefaultGenesisBalanceFile(t TestingTS, gnoroot string) []gnoland.Balance { | ||
balanceFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_balances.txt") | ||
|
||
genesisBalances, err := gnoland.LoadGenesisBalancesFile(balanceFile) | ||
require.NoError(t, err) | ||
|
||
return genesisBalances.List() | ||
} | ||
|
||
// LoadDefaultGenesisParamFile loads the default genesis balance file for testing. | ||
func LoadDefaultGenesisParamFile(t TestingTS, gnoroot string) []gnoland.Param { | ||
paramFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_params.toml") | ||
|
||
genesisParams, err := gnoland.LoadGenesisParamsFile(paramFile) | ||
require.NoError(t, err) | ||
|
||
return genesisParams | ||
} | ||
|
||
// LoadDefaultGenesisTXsFile loads the default genesis transactions file for testing. | ||
func LoadDefaultGenesisTXsFile(t TestingTS, chainid string, gnoroot string) []gnoland.TxWithMetadata { | ||
txsFile := filepath.Join(gnoroot, "gno.land", "genesis", "genesis_txs.jsonl") | ||
|
||
// NOTE: We dont care about giving a correct address here, as it's only for display | ||
// XXX: Do we care loading this TXs for testing ? | ||
genesisTXs, err := gnoland.LoadGenesisTxsFile(txsFile, chainid, "https://127.0.0.1:26657") | ||
require.NoError(t, err) | ||
|
||
return genesisTXs | ||
} | ||
|
||
// DefaultTestingTMConfig constructs the default Tendermint configuration for testing. | ||
func DefaultTestingTMConfig(gnoroot string) *tmcfg.Config { | ||
const defaultListner = "tcp://127.0.0.1:0" | ||
|
||
tmconfig := tmcfg.TestConfig().SetRootDir(gnoroot) | ||
tmconfig.Consensus.WALDisabled = true | ||
tmconfig.Consensus.SkipTimeoutCommit = true | ||
tmconfig.Consensus.CreateEmptyBlocks = true | ||
tmconfig.Consensus.CreateEmptyBlocksInterval = time.Millisecond * 100 | ||
tmconfig.RPC.ListenAddress = defaultListner | ||
tmconfig.P2P.ListenAddress = defaultListner | ||
return tmconfig | ||
} |
Oops, something went wrong.