Skip to content

Commit

Permalink
Feature(cli): Commands that utilize BroadcastTx now have synchronous …
Browse files Browse the repository at this point in the history
…and asynchronous submission options (#134)

* add sync vs async broadcast tx

* add async flag to relevant commands

* rename internal async vars to isAsync, move defer Stop

* typo fix

Co-authored-by: jesse snyder <[email protected]>

* typo fix

Co-authored-by: jesse snyder <[email protected]>

* debug bytes

* proto amount as string. fix typos.

* check tx result.Code since error may be nil. fix integration tests.

* run integration tests in ci/cd

* verbose integration tests for debugging

* run the cli for ci tests

* wait for startup before running tests

* debug logs for ci debugging

* need error output

* comments in code updated to start with lowercase

* screen the dev runner. use combined output.

* use Output, leave FIXME

* test sync first

* does testing order matter?

* tests almost passing

* fix tests

* increase ctx timeout. check for tx on loop. fix tests.

* rename unused variable

* reorder logic

* remove comment cruft

---------

Co-authored-by: jesse snyder <[email protected]>
  • Loading branch information
sambukowski and steezeburger authored Jul 19, 2024
1 parent 628c2db commit 9c858af
Show file tree
Hide file tree
Showing 25 changed files with 350 additions and 162 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/lint-and-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Install just
uses: taiki-e/install-action@just
- uses: actions/setup-go@v4
with:
go-version: 1.22.0
Expand Down Expand Up @@ -38,6 +40,14 @@ jobs:
# no solutions have worked so far https://github.com/actions/runner/issues/241
run: go test ./... -skip TestProcessPane
working-directory: modules/cli
- name: Integration Test Go
run: |
# run dev runner and test-integration
just run dev init
screen -d -m just run dev run
sleep 5
just test-integration
# FIXME - sequencer client tests are empty
# - name: Test Go (go-sequencer-client)
# run: go test ./...
# working-directory: modules/go-sequencer-client
2 changes: 1 addition & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ alias ti := test-integration
# run integrations tests. requires running geth + cometbft + astria core.
test-integration-cli:
just build-cli astria-go-testy
cd modules/cli/integration_tests && go test ./... -tags=integration_tests -count=1
cd modules/cli/integration_tests && go test -v ./... -tags=integration_tests -count=1
rm ./bin/astria-go-testy

# run integration tests for go-sequencer-client. requires running geth + cometbft + astria core.
Expand Down
36 changes: 18 additions & 18 deletions modules/cli/cmd/devrunner/config/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,29 +56,29 @@ var embeddedDevPrivKey embed.FS

// CreateComposerDevPrivKeyFile creates a new composer_dev_priv_key file in the specified directory.
func CreateComposerDevPrivKeyFile(dir string) {
// Read the content from the embedded file
// read the content from the embedded file
devPrivKeyData, err := fs.ReadFile(embeddedDevPrivKey, "composer_dev_priv_key")
if err != nil {
log.Fatalf("failed to read embedded file: %v", err)
panic(err)
}

// Specify the path for the new file
// specify the path for the new file
newDevPrivKeyPath := filepath.Join(dir, "composer_dev_priv_key")

_, err = os.Stat(newDevPrivKeyPath)
if err == nil {
log.Infof("%s already exists. Skipping initialization.\n", newDevPrivKeyPath)
} else {
// Create a new file
// create a new file
newDevPrivKeyFile, err := os.Create(newDevPrivKeyPath)
if err != nil {
log.Fatalf("failed to create new file: %v", err)
panic(err)
}
defer newDevPrivKeyFile.Close()

// Write the data to the new file
// write the data to the new file
_, err = newDevPrivKeyFile.Write(devPrivKeyData)
if err != nil {
log.Fatalf("failed to write data to new file: %v", err)
Expand All @@ -99,13 +99,13 @@ var embeddedCometbftValidatorFile embed.FS
// network name and local default denomination to update the chain id and
// default denom for the local sequencer network.
func RecreateCometbftAndSequencerGenesisData(path, localNetworkName, localNativeDenom string) {
// Read the content from the embedded file
// read the content from the embedded file
genesisData, err := fs.ReadFile(embeddedCometbftGenesisFile, "genesis.json")
if err != nil {
log.Fatalf("failed to read embedded file: %v", err)
panic(err)
}
// Unmarshal JSON into a map to update sequencer chain id
// unmarshal JSON into a map to update sequencer chain id
var data map[string]interface{}
if err := json.Unmarshal(genesisData, &data); err != nil {
log.Fatalf("Error unmarshaling JSON: %s", err)
Expand All @@ -124,30 +124,30 @@ func RecreateCometbftAndSequencerGenesisData(path, localNetworkName, localNative
log.Fatalf("Error marshaling updated data to JSON: %s", err)
}

// Read the content from the embedded file
// read the content from the embedded file
validatorData, err := fs.ReadFile(embeddedCometbftValidatorFile, "priv_validator_key.json")
if err != nil {
log.Fatalf("failed to read embedded file: %v", err)
panic(err)
}

// Specify the path for the new file
// specify the path for the new file
newGenesisPath := filepath.Join(path, "genesis.json")
newValidatorPath := filepath.Join(path, "priv_validator_key.json")

_, err = os.Stat(newGenesisPath)
if err == nil {
log.Infof("%s already exists. Skipping initialization.\n", newGenesisPath)
} else {
// Create a new file
// create a new file
newGenesisFile, err := os.Create(newGenesisPath)
if err != nil {
log.Fatalf("failed to create new file: %v", err)
panic(err)
}
defer newGenesisFile.Close()

// Write the data to the new file
// write the data to the new file
_, err = newGenesisFile.Write(genesisData)
if err != nil {
log.Fatalf("failed to write data to new file: %v", err)
Expand Down Expand Up @@ -240,30 +240,30 @@ func InitCometbft(defaultDir string, dataDirName string, binDirName string, conf
// replaceInFile replaces oldValue with newValue in the file at filename.
// it is used here to update the block time in the cometbft config.toml file.
func replaceInFile(filename, oldValue, newValue string) error {
// Read the original file.
// read the original file.
content, err := os.ReadFile(filename)
if err != nil {
return fmt.Errorf("failed to read the file: %w", err)
}

// Perform the replacement.
// perform the replacement.
modifiedContent := strings.ReplaceAll(string(content), oldValue, newValue)

// Write the modified content to a new temporary file.
// write the modified content to a new temporary file.
tmpFilename := filename + ".tmp"
if err := os.WriteFile(tmpFilename, []byte(modifiedContent), 0666); err != nil {
return fmt.Errorf("failed to write to temporary file: %w", err)
}

// Rename the original file to filename.bak.
// rename the original file to filename.bak.
backupFilename := filename + ".bak"
if err := os.Rename(filename, backupFilename); err != nil {
return fmt.Errorf("failed to rename original file to backup: %w", err)
}

// Rename the temporary file to the original file name.
// rename the temporary file to the original file name.
if err := os.Rename(tmpFilename, filename); err != nil {
// Attempt to restore the original file if renaming fails.
// attempt to restore the original file if renaming fails.
err := os.Rename(backupFilename, filename)
if err != nil {
return err
Expand All @@ -279,7 +279,7 @@ func replaceInFile(filename, oldValue, newValue string) error {
func MergeConfigs(configs ...[]string) []string {
mergedMap := make(map[string]string)

// Helper function to add slices to the map
// helper function to add slices to the map
addSliceToMap := func(slice []string) {
for _, item := range slice {
keyVal := strings.SplitN(item, "=", 2)
Expand All @@ -295,7 +295,7 @@ func MergeConfigs(configs ...[]string) []string {
addSliceToMap(config)
}

// Convert the map back to a slice
// convert the map back to a slice
var result []string
for key, value := range mergedMap {
result = append(result, key+"="+value)
Expand Down
14 changes: 7 additions & 7 deletions modules/cli/cmd/devrunner/config/networks.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,19 +221,19 @@ func CreateNetworksConfig(path, localSequencerChainId, localNativeDenom string)
log.Infof("%s already exists. Skipping initialization.\n", path)
return
}
// Create an instance of the Config struct with some data
// create an instance of the Config struct with some data
config := DefaultNetworksConfigs()
config.Local.NativeDenom = localNativeDenom
config.Local.SequencerChainId = localSequencerChainId

// Open a file for writing
// open a file for writing
file, err := os.Create(path)
if err != nil {
panic(err)
}
defer file.Close()

// Encode the struct to TOML and write to the file
// encode the struct to TOML and write to the file
if err := toml.NewEncoder(file).Encode(config); err != nil {
panic(err)
}
Expand All @@ -251,17 +251,17 @@ func CreateBaseConfig(path, instance string) {
log.Infof("%s already exists. Skipping initialization.\n", path)
return
}
// Create an instance of the Config struct with some data
// create an instance of the Config struct with some data
config := NewBaseConfig(instance)

// Open a file for writing
// open a file for writing
file, err := os.Create(path)
if err != nil {
panic(err)
}
defer file.Close()

// Encode the struct to TOML and write to the file
// encode the struct to TOML and write to the file
if err := toml.NewEncoder(file).Encode(config); err != nil {
panic(err)
}
Expand Down Expand Up @@ -295,7 +295,7 @@ func (b BaseConfig) ToSlice() []string {
typ := reflect.TypeOf(b)

var output []string
// Ensure the provided variable is a struct
// ensure the provided variable is a struct
for i := 0; i < val.NumField(); i++ {
field := typ.Field(i)
value := val.Field(i)
Expand Down
18 changes: 9 additions & 9 deletions modules/cli/cmd/devrunner/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,21 +87,21 @@ func runInitialization(c *cobra.Command, args []string) {

// downloadFile downloads a file from the specified URL to the given local path.
func downloadFile(url, filepath string) error {
// Get the data
// get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()

// Create the file
// create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()

// Write the body to file
// write downloaded data to a file
_, err = io.Copy(out, resp.Body)
return err
}
Expand Down Expand Up @@ -153,32 +153,32 @@ func extractTarGz(dest string, gzipStream io.Reader) error {
}

func downloadAndUnpack(url string, packageName string, placePath string) {
// Check if the file already exists
// check if the file already exists
if _, err := os.Stat(filepath.Join(placePath, packageName)); err == nil {
log.Infof("%s already exists. Skipping download.\n", packageName)
return
}
log.Infof("Downloading: (%s, %s)\n", packageName, url)

// Download the file
// download the file
dest := filepath.Join(placePath, packageName+".tar.gz")
if err := downloadFile(url, dest); err != nil {
panic(err)
}
// Open the downloaded .tar.gz file
// open the downloaded .tar.gz file
file, err := os.Open(dest)
if err != nil {
panic(err)
}
defer file.Close()

// Extract the contents
// extract the contents
if err := extractTarGz(placePath, file); err != nil {
panic(err)
}

// Delete the .tar.gz file
// TODO: should this be configuratble?
// delete the .tar.gz file
// TODO: should this be configurable?
err = os.Remove(dest)
if err != nil {
log.Fatalf("Failed to delete downloaded %s.tar.gz file: %v", packageName, err)
Expand Down
4 changes: 2 additions & 2 deletions modules/cli/cmd/devrunner/purge.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func purgeBinariesCmdHandler(c *cobra.Command, _ []string) {

log.Infof("Deleting binaries for instance '%s'", instance)

// Remove the state files for sequencer and Cometbft
// remove the state files for sequencer and Cometbft
err = os.RemoveAll(binDir)
if err != nil {
fmt.Println("Error removing file:", err)
Expand Down Expand Up @@ -76,7 +76,7 @@ func purgeAllCmdHandler(c *cobra.Command, _ []string) {

log.Infof("Deleting instance '%s'", instance)

// Remove the state files for sequencer and Cometbft
// remove the state files for sequencer and Cometbft
err = os.RemoveAll(instanceDir)
if err != nil {
fmt.Println("Error removing file:", err)
Expand Down
4 changes: 2 additions & 2 deletions modules/cli/cmd/devrunner/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func resetConfigCmdHandler(c *cobra.Command, _ []string) {

log.Infof("Resetting config for instance '%s'", instance)

// Remove the config files
// remove the config files
err = os.Remove(filepath.Join(localConfigDir, config.DefaultCometbftGenesisFilename))
if err != nil {
fmt.Println("Error removing file:", err)
Expand Down Expand Up @@ -129,7 +129,7 @@ func resetStateCmdHandler(c *cobra.Command, _ []string) {

log.Infof("Resetting state for instance '%s'", instance)

// Remove the state files for sequencer and Cometbft
// remove the state files for sequencer and Cometbft
err = os.RemoveAll(dataDir)
if err != nil {
fmt.Println("Error removing file:", err)
Expand Down
16 changes: 8 additions & 8 deletions modules/cli/cmd/devrunner/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ func getFlagPath(c *cobra.Command, flag string, serviceName string, defaultValue
// endpoint. Being able to connect to the gRPC server is a requirement for both
// the Conductor and Composer services.
func getSequencerOKCallback(config []string) func() bool {
// Get the sequencer gRPC address from the environment
// get the sequencer gRPC address from the environment
var seqGRPCAddr string
for _, envVar := range config {
if strings.HasPrefix(envVar, "ASTRIA_SEQUENCER_GRPC_ADDR") {
Expand All @@ -267,17 +267,17 @@ func getSequencerOKCallback(config []string) func() bool {
}
seqGRPCHealthURL := "http://" + seqGRPCAddr + "/health"

// Return the anonymous callback function
// return the anonymous callback function
return func() bool {
// Make the HTTP request
// make the HTTP request
seqResp, err := http.Get(seqGRPCHealthURL)
if err != nil {
log.WithError(err).Debug("Startup callback check to sequencer gRPC /health did not succeed")
return false
}
defer seqResp.Body.Close()

// Check status code
// check status code
if seqResp.StatusCode == 200 {
log.Debug("Sequencer gRPC server started")
return true
Expand All @@ -294,7 +294,7 @@ func getSequencerOKCallback(config []string) func() bool {
// endpoint. Being able to connect to the rpc server is a requirement for both
// the Conductor and Composer services.
func getCometbftOKCallback(config []string) func() bool {
// Get the CometBFT rpc address from the environment
// get the CometBFT rpc address from the environment
var seqRPCAddr string
for _, envVar := range config {
if strings.HasPrefix(envVar, "ASTRIA_CONDUCTOR_SEQUENCER_COMETBFT_URL") {
Expand All @@ -304,17 +304,17 @@ func getCometbftOKCallback(config []string) func() bool {
}
cometbftRPCHealthURL := seqRPCAddr + "/health"

// Return the anonymous callback function
// return the anonymous callback function
return func() bool {
// Make the HTTP request
// make the HTTP request
cometbftResp, err := http.Get(cometbftRPCHealthURL)
if err != nil {
log.WithError(err).Debug("Startup callback check to CometBFT rpc /health did not succeed")
return false
}
defer cometbftResp.Body.Close()

// Check status code
// check status code
if cometbftResp.StatusCode == 200 {
log.Debug("CometBFT rpc server started")
return true
Expand Down
Loading

0 comments on commit 9c858af

Please sign in to comment.