Skip to content

Commit 646694d

Browse files
authored
refactor: improve fallback latest when no version found (#13)
1 parent 15d9900 commit 646694d

File tree

3 files changed

+47
-22
lines changed

3 files changed

+47
-22
lines changed

abci/multiplexer.go

+21-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package abci
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
7+
"log"
68
"os"
79
"path/filepath"
810
"sync"
@@ -39,22 +41,30 @@ func NewMultiplexer(latestApp servertypes.ABCI, versions Versions, v *viper.Vipe
3941
versions: versions,
4042
}
4143

42-
// check height from disk
43-
wrapper.lastHeight, _ = wrapper.getLatestHeight(home, v) // if error assume genesis
44-
45-
// prepare correct version
4644
var (
4745
currentVersion Version
48-
name string
46+
err error
4947
)
5048

49+
// check height from disk
50+
wrapper.lastHeight, err = wrapper.getLatestHeight(home, v) // if error assume genesis
51+
if err != nil {
52+
log.Printf("failed to get latest height from disk, assuming genesis: %v\n", err)
53+
}
54+
55+
// prepare correct version
5156
if wrapper.lastHeight == 0 {
52-
currentVersion = versions.GenesisVersion()
57+
currentVersion, err = versions.GenesisVersion()
5358
} else {
54-
name, currentVersion = versions.GetForHeight(wrapper.lastHeight)
59+
currentVersion, err = versions.GetForHeight(wrapper.lastHeight)
60+
}
61+
if err != nil && errors.Is(err, ErrNoVersionFound) {
62+
return wrapper, nil // no version found, assume latest
63+
} else if err != nil {
64+
return nil, fmt.Errorf("failed to get app for height %d: %w", wrapper.lastHeight, err)
5565
}
5666

57-
// prepare client
67+
// prepare remote app
5868
grpcAddress := v.GetString(flagGRPCAddress)
5969
if grpcAddress == "" {
6070
grpcAddress = "localhost:9090"
@@ -74,11 +84,11 @@ func NewMultiplexer(latestApp servertypes.ABCI, versions Versions, v *viper.Vipe
7484
}
7585

7686
if err := currentVersion.Appd.Run(append(programArgs, currentVersion.StartArgs...)...); err != nil {
77-
return nil, fmt.Errorf("failed to start %s app: %w", name, err)
87+
return nil, fmt.Errorf("failed to start app: %w", err)
7888
}
7989

8090
if currentVersion.Appd.Pid() == appd.AppdStopped { // should never happen
81-
panic(fmt.Sprintf("%s app has not started", name))
91+
panic("app has not started")
8292
}
8393
}
8494

@@ -97,7 +107,7 @@ func (m *multiplexer) getLatestHeight(rootDir string, v *viper.Viper) (int64, er
97107
return height, db.Close()
98108
}
99109

100-
// Helper to get the appropriate app based on height
110+
// getAppForHeight gets the appropriate app based on height
101111
func (m *multiplexer) getAppForHeight(height int64) servertypes.ABCI {
102112
m.mu.Lock()
103113
defer m.mu.Unlock()

abci/versions.go

+22-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
package abci
22

3-
import "github.com/01builders/nova/appd"
3+
import (
4+
"errors"
5+
"fmt"
6+
7+
"github.com/01builders/nova/appd"
8+
)
9+
10+
// ErrNoVersionFound is returned when no remote version is found for a given height.
11+
var ErrNoVersionFound = errors.New("no version found")
412

513
// Version defines the configuration for remote apps.
614
type Version struct {
@@ -12,7 +20,7 @@ type Version struct {
1220
type Versions map[string]Version
1321

1422
// GenesisVersion returns the genesis version.
15-
func (v Versions) GenesisVersion() Version {
23+
func (v Versions) GenesisVersion() (Version, error) {
1624
var genesis Version
1725
var minHeight int64 = -1
1826

@@ -23,23 +31,27 @@ func (v Versions) GenesisVersion() Version {
2331
}
2432
}
2533

26-
return genesis
34+
if minHeight == -1 {
35+
return Version{}, fmt.Errorf("%w: no genesis version found", ErrNoVersionFound)
36+
}
37+
38+
return genesis, nil
2739
}
2840

2941
// GetForHeight returns the version for a given height.
30-
func (v Versions) GetForHeight(height int64) (string, Version) {
42+
func (v Versions) GetForHeight(height int64) (Version, error) {
3143
var selectedVersion Version
32-
var name string
33-
34-
for n, version := range v {
44+
for _, version := range v {
3545
if version.UntilHeight >= height {
3646
selectedVersion = version
37-
name = n
38-
break
3947
}
4048
}
4149

42-
return name, selectedVersion
50+
if selectedVersion.UntilHeight < height {
51+
return Version{}, fmt.Errorf("%w: %d", ErrNoVersionFound, height)
52+
}
53+
54+
return selectedVersion, nil
4355
}
4456

4557
// ShouldLatestApp returns true if the given height is higher than all version's UntilHeight.

passthrough.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,10 @@ Use --version to specify a named version or --height to execute on the version a
6060
return fmt.Errorf("height %d requires the latest app, use the command directly without passthrough", height)
6161
}
6262

63-
versionName, appVersion = versions.GetForHeight(height)
63+
appVersion, err = versions.GetForHeight(height)
64+
if err != nil {
65+
return fmt.Errorf("no version found for height %d: %w", height, err)
66+
}
6467
} else {
6568
return errors.New("either --version or --height must be specified")
6669
}

0 commit comments

Comments
 (0)