mirror of
https://github.com/tendermint/tendermint.git
synced 2026-07-24 09:02:43 +00:00
Merge branch 'master' into wb/message-delay-metrics
This commit is contained in:
@@ -24,7 +24,7 @@ jobs:
|
||||
with:
|
||||
go-version: "1.17"
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
with:
|
||||
go-version: "1.17"
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
@@ -67,7 +67,7 @@ jobs:
|
||||
with:
|
||||
go-version: "1.17"
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
with:
|
||||
go-version: '1.17'
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
timeout-minutes: 8
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
with:
|
||||
go-version: "1.17"
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
needs: tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- uses: technote-space/get-diff-action@v5
|
||||
- uses: technote-space/get-diff-action@v6.0.1
|
||||
with:
|
||||
PATTERNS: |
|
||||
**/**.go
|
||||
|
||||
@@ -51,6 +51,7 @@ Special thanks to external contributors on this release:
|
||||
- [internal/protoio] \#7325 Optimized `MarshalDelimited` by inlining the common case and using a `sync.Pool` in the worst case. (@odeke-em)
|
||||
|
||||
- [pubsub] \#7319 Performance improvements for the event query API (@creachadair)
|
||||
- [node] \#7521 Define concrete type for seed node implementation (@spacech1mp)
|
||||
|
||||
### BUG FIXES
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ var RootCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
if logger == nil {
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo)
|
||||
}
|
||||
|
||||
if client == nil {
|
||||
@@ -575,15 +575,14 @@ func cmdQuery(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
func cmdKVStore(cmd *cobra.Command, args []string) error {
|
||||
logger := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
|
||||
logger := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo)
|
||||
|
||||
// Create the application - in memory or persisted to disk
|
||||
var app types.Application
|
||||
if flagPersist == "" {
|
||||
app = kvstore.NewApplication()
|
||||
} else {
|
||||
app = kvstore.NewPersistentKVStoreApplication(flagPersist)
|
||||
app.(*kvstore.PersistentKVStoreApplication).SetLogger(logger.With("module", "kvstore"))
|
||||
app = kvstore.NewPersistentKVStoreApplication(logger, flagPersist)
|
||||
}
|
||||
|
||||
// Start the listener
|
||||
|
||||
@@ -76,7 +76,9 @@ func TestPersistentKVStoreKV(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kvstore := NewPersistentKVStoreApplication(dir)
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
kvstore := NewPersistentKVStoreApplication(logger, dir)
|
||||
key := testKey
|
||||
value := key
|
||||
tx := []byte(key)
|
||||
@@ -92,7 +94,9 @@ func TestPersistentKVStoreInfo(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kvstore := NewPersistentKVStoreApplication(dir)
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
kvstore := NewPersistentKVStoreApplication(logger, dir)
|
||||
InitKVStore(kvstore)
|
||||
height := int64(0)
|
||||
|
||||
@@ -124,7 +128,9 @@ func TestValUpdates(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kvstore := NewPersistentKVStoreApplication(dir)
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
kvstore := NewPersistentKVStoreApplication(logger, dir)
|
||||
|
||||
// init with some validators
|
||||
total := 10
|
||||
|
||||
@@ -35,7 +35,7 @@ type PersistentKVStoreApplication struct {
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication {
|
||||
func NewPersistentKVStoreApplication(logger log.Logger, dbDir string) *PersistentKVStoreApplication {
|
||||
name := "kvstore"
|
||||
db, err := dbm.NewGoLevelDB(name, dbDir)
|
||||
if err != nil {
|
||||
@@ -47,7 +47,7 @@ func NewPersistentKVStoreApplication(dbDir string) *PersistentKVStoreApplication
|
||||
return &PersistentKVStoreApplication{
|
||||
app: &Application{state: state},
|
||||
valAddrToPubKeyMap: make(map[string]cryptoproto.PublicKey),
|
||||
logger: log.NewNopLogger(),
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,10 +55,6 @@ func (app *PersistentKVStoreApplication) Close() error {
|
||||
return app.app.state.db.Close()
|
||||
}
|
||||
|
||||
func (app *PersistentKVStoreApplication) SetLogger(l log.Logger) {
|
||||
app.logger = l
|
||||
}
|
||||
|
||||
func (app *PersistentKVStoreApplication) Info(req types.RequestInfo) types.ResponseInfo {
|
||||
res := app.app.Info(req)
|
||||
res.LastBlockHeight = app.app.state.Height
|
||||
|
||||
@@ -259,14 +259,26 @@ func (s *SocketServer) handleResponses(
|
||||
responses <-chan *types.Response,
|
||||
) {
|
||||
bw := bufio.NewWriter(conn)
|
||||
for res := range responses {
|
||||
if err := types.WriteMessage(res, bw); err != nil {
|
||||
closeConn <- fmt.Errorf("error writing message: %w", err)
|
||||
return
|
||||
}
|
||||
if err := bw.Flush(); err != nil {
|
||||
closeConn <- fmt.Errorf("error flushing write buffer: %w", err)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case res := <-responses:
|
||||
if err := types.WriteMessage(res, bw); err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case closeConn <- fmt.Errorf("error writing message: %w", err):
|
||||
}
|
||||
return
|
||||
}
|
||||
if err := bw.Flush(); err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case closeConn <- fmt.Errorf("error flushing write buffer: %w", err):
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/fortytw2/leaktest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
abciclientent "github.com/tendermint/tendermint/abci/client"
|
||||
@@ -13,6 +14,8 @@ import (
|
||||
)
|
||||
|
||||
func TestClientServerNoAddrPrefix(t *testing.T) {
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@@ -27,9 +30,11 @@ func TestClientServerNoAddrPrefix(t *testing.T) {
|
||||
assert.NoError(t, err, "expected no error on NewServer")
|
||||
err = server.Start(ctx)
|
||||
assert.NoError(t, err, "expected no error on server.Start")
|
||||
t.Cleanup(server.Wait)
|
||||
|
||||
client, err := abciclientent.NewClient(logger, addr, transport, true)
|
||||
assert.NoError(t, err, "expected no error on NewClient")
|
||||
err = client.Start(ctx)
|
||||
assert.NoError(t, err, "expected no error on client.Start")
|
||||
t.Cleanup(client.Wait)
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func main() {
|
||||
rootCA = flag.String("rootcafile", "", "absolute path to root CA")
|
||||
prometheusAddr = flag.String("prometheus-addr", "", "address for prometheus endpoint (host:port)")
|
||||
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false).
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo).
|
||||
With("module", "priv_val")
|
||||
)
|
||||
flag.Parse()
|
||||
@@ -138,7 +138,6 @@ func main() {
|
||||
defer opcancel()
|
||||
go func() {
|
||||
<-opctx.Done()
|
||||
logger.Debug("SignerServer: calling Close")
|
||||
if *prometheusAddr != "" {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||||
defer cancel()
|
||||
|
||||
@@ -15,7 +15,7 @@ var (
|
||||
flagProfAddr = "pprof-laddr"
|
||||
flagFrequency = "frequency"
|
||||
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo)
|
||||
)
|
||||
|
||||
// DebugCmd defines the root command containing subcommands that assist in
|
||||
|
||||
@@ -102,7 +102,7 @@ func init() {
|
||||
}
|
||||
|
||||
func runProxy(cmd *cobra.Command, args []string) error {
|
||||
logger, err := log.NewDefaultLogger(logFormat, logLevel, false)
|
||||
logger, err := log.NewDefaultLogger(logFormat, logLevel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/rpc/client/local"
|
||||
rpctest "github.com/tendermint/tendermint/rpc/test"
|
||||
e2e "github.com/tendermint/tendermint/test/e2e/app"
|
||||
@@ -49,7 +50,9 @@ func TestRollbackIntegration(t *testing.T) {
|
||||
node2, _, err2 := rpctest.StartTendermint(ctx, cfg, app, rpctest.SuppressStdout)
|
||||
require.NoError(t, err2)
|
||||
|
||||
client, err := local.New(node2.(local.NodeService))
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
client, err := local.New(logger, node2.(local.NodeService))
|
||||
require.NoError(t, err)
|
||||
|
||||
ticker := time.NewTicker(200 * time.Millisecond)
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
var (
|
||||
config = cfg.DefaultConfig()
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
|
||||
logger = log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo)
|
||||
ctxTimeout = 4 * time.Second
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@ var RootCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
logger, err = log.NewDefaultLogger(config.LogFormat, config.LogLevel, false)
|
||||
logger, err = log.NewDefaultLogger(config.LogFormat, config.LogLevel)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -683,7 +683,6 @@ func TestP2PConfig() *P2PConfig {
|
||||
cfg.ListenAddress = "tcp://127.0.0.1:36656"
|
||||
cfg.AllowDuplicateIP = true
|
||||
cfg.FlushThrottleTimeout = 10 * time.Millisecond
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"text/template"
|
||||
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
)
|
||||
|
||||
// DefaultDirPerm is the default permissions used when creating directories.
|
||||
@@ -549,6 +550,7 @@ func ResetTestRootWithChainID(testName string, chainID string) (*Config, error)
|
||||
}
|
||||
|
||||
config := TestConfig().SetRoot(rootDir)
|
||||
config.Instrumentation.Namespace = fmt.Sprintf("%s_%s_%s", testName, chainID, tmrand.Str(16))
|
||||
return config, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ module github.com/tendermint/tendermint
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.4.1
|
||||
github.com/BurntSushi/toml v1.0.0
|
||||
github.com/adlio/schema v1.2.3
|
||||
github.com/btcsuite/btcd v0.22.0-beta
|
||||
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
|
||||
|
||||
@@ -63,8 +63,9 @@ github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H2
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.0.0 h1:dtDWrepsVPfW9H/4y7dDgFc2MBUSeJhlaDtK13CxFlU=
|
||||
github.com/BurntSushi/toml v1.0.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/internal/consensus"
|
||||
"github.com/tendermint/tendermint/internal/eventbus"
|
||||
"github.com/tendermint/tendermint/internal/p2p"
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
"github.com/tendermint/tendermint/internal/store"
|
||||
@@ -96,7 +97,8 @@ type Reactor struct {
|
||||
// stopping the p2p Channel(s).
|
||||
poolWG sync.WaitGroup
|
||||
|
||||
metrics *consensus.Metrics
|
||||
metrics *consensus.Metrics
|
||||
eventBus *eventbus.EventBus
|
||||
|
||||
syncStartTime time.Time
|
||||
}
|
||||
@@ -113,6 +115,7 @@ func NewReactor(
|
||||
peerUpdates *p2p.PeerUpdates,
|
||||
blockSync bool,
|
||||
metrics *consensus.Metrics,
|
||||
eventBus *eventbus.EventBus,
|
||||
) (*Reactor, error) {
|
||||
|
||||
if state.LastBlockHeight != store.Height() {
|
||||
@@ -146,6 +149,7 @@ func NewReactor(
|
||||
blockSyncOutBridgeCh: make(chan p2p.Envelope),
|
||||
peerUpdates: peerUpdates,
|
||||
metrics: metrics,
|
||||
eventBus: eventBus,
|
||||
syncStartTime: time.Time{},
|
||||
}
|
||||
|
||||
@@ -354,7 +358,6 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
r.logger.Debug("stopped listening on peer updates channel; closing...")
|
||||
return
|
||||
case peerUpdate := <-r.peerUpdates.Updates():
|
||||
r.processPeerUpdate(peerUpdate)
|
||||
@@ -639,6 +642,13 @@ func (r *Reactor) GetRemainingSyncTime() time.Duration {
|
||||
return time.Duration(int64(remain * float64(time.Second)))
|
||||
}
|
||||
|
||||
func (r *Reactor) PublishStatus(ctx context.Context, event types.EventDataBlockSyncStatus) error {
|
||||
if r.eventBus == nil {
|
||||
return errors.New("event bus is not configured")
|
||||
}
|
||||
return r.eventBus.PublishEventBlockSyncStatus(ctx, event)
|
||||
}
|
||||
|
||||
// atomicBool is an atomic Boolean, safe for concurrent use by multiple
|
||||
// goroutines.
|
||||
type atomicBool int32
|
||||
|
||||
@@ -144,7 +144,6 @@ func (rts *reactorTestSuite) addNode(
|
||||
time.Now(),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
lastCommit = types.NewCommit(
|
||||
vote.Height,
|
||||
vote.Round,
|
||||
@@ -182,7 +181,9 @@ func (rts *reactorTestSuite) addNode(
|
||||
chCreator,
|
||||
rts.peerUpdates[nodeID],
|
||||
rts.blockSync,
|
||||
consensus.NopMetrics())
|
||||
consensus.NopMetrics(),
|
||||
nil, // eventbus, can be nil
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, rts.reactors[nodeID].Start(ctx))
|
||||
@@ -206,7 +207,7 @@ func TestReactor_AbruptDisconnect(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(cfg.RootDir)
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, 1, false, 30)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, cfg, 1, false, 30)
|
||||
maxBlockHeight := int64(64)
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
|
||||
@@ -245,7 +246,7 @@ func TestReactor_SyncTime(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(cfg.RootDir)
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, 1, false, 30)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, cfg, 1, false, 30)
|
||||
maxBlockHeight := int64(101)
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
|
||||
@@ -273,7 +274,7 @@ func TestReactor_NoBlockResponse(t *testing.T) {
|
||||
|
||||
defer os.RemoveAll(cfg.RootDir)
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, 1, false, 30)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, cfg, 1, false, 30)
|
||||
maxBlockHeight := int64(65)
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
|
||||
@@ -325,7 +326,7 @@ func TestReactor_BadBlockStopsPeer(t *testing.T) {
|
||||
defer os.RemoveAll(cfg.RootDir)
|
||||
|
||||
maxBlockHeight := int64(48)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, 1, false, 30)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, cfg, 1, false, 30)
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0, 0, 0, 0}, 1000)
|
||||
|
||||
@@ -359,7 +360,7 @@ func TestReactor_BadBlockStopsPeer(t *testing.T) {
|
||||
//
|
||||
// XXX: This causes a potential race condition.
|
||||
// See: https://github.com/tendermint/tendermint/issues/6005
|
||||
otherGenDoc, otherPrivVals := factory.RandGenesisDoc(ctx, cfg, 1, false, 30)
|
||||
otherGenDoc, otherPrivVals := factory.RandGenesisDoc(ctx, t, cfg, 1, false, 30)
|
||||
newNode := rts.network.MakeNode(ctx, t, p2ptest.NodeOptions{
|
||||
MaxPeers: uint16(len(rts.nodes) + 1),
|
||||
MaxConnected: uint16(len(rts.nodes) + 1),
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
tickerFunc := newMockTickerFunc(true)
|
||||
appFunc := newKVStore
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, config, nValidators, false, 30)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, config, nValidators, false, 30)
|
||||
states := make([]*State, nValidators)
|
||||
|
||||
for i := 0; i < nValidators; i++ {
|
||||
@@ -59,7 +59,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
defer os.RemoveAll(thisConfig.RootDir)
|
||||
|
||||
ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
|
||||
app := appFunc(t)
|
||||
app := appFunc(t, logger)
|
||||
vals := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
|
||||
@@ -139,7 +139,6 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
i := 0
|
||||
for _, ps := range bzReactor.peers {
|
||||
if i < len(bzReactor.peers)/2 {
|
||||
bzNodeState.logger.Info("signed and pushed vote", "vote", prevote1, "peer", ps.peerID)
|
||||
require.NoError(t, bzReactor.voteCh.Send(ctx,
|
||||
p2p.Envelope{
|
||||
To: ps.peerID,
|
||||
@@ -148,7 +147,6 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
},
|
||||
}))
|
||||
} else {
|
||||
bzNodeState.logger.Info("signed and pushed vote", "vote", prevote2, "peer", ps.peerID)
|
||||
require.NoError(t, bzReactor.voteCh.Send(ctx,
|
||||
p2p.Envelope{
|
||||
To: ps.peerID,
|
||||
@@ -161,7 +159,6 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
i++
|
||||
}
|
||||
} else {
|
||||
bzNodeState.logger.Info("behaving normally")
|
||||
bzNodeState.defaultDoPrevote(ctx, height, round)
|
||||
}
|
||||
}
|
||||
@@ -173,7 +170,6 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
lazyNodeState := states[1]
|
||||
|
||||
lazyNodeState.decideProposal = func(ctx context.Context, height int64, round int32) {
|
||||
lazyNodeState.logger.Info("Lazy Proposer proposing condensed commit")
|
||||
require.NotNil(t, lazyNodeState.privValidator)
|
||||
|
||||
var commit *types.Commit
|
||||
@@ -227,8 +223,6 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
lazyNodeState.Height, lazyNodeState.Round, part,
|
||||
}, ""})
|
||||
}
|
||||
lazyNodeState.logger.Info("Signed proposal", "height", height, "round", round, "proposal", proposal)
|
||||
lazyNodeState.logger.Debug(fmt.Sprintf("Signed proposal block: %v", block))
|
||||
} else if !lazyNodeState.replayMode {
|
||||
lazyNodeState.logger.Error("enterPropose: Error signing proposal", "height", height, "round", round, "err", err)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"sync"
|
||||
@@ -737,11 +736,11 @@ func randConsensusState(
|
||||
nValidators int,
|
||||
testName string,
|
||||
tickerFunc func() TimeoutTicker,
|
||||
appFunc func(t *testing.T) abci.Application,
|
||||
appFunc func(t *testing.T, logger log.Logger) abci.Application,
|
||||
configOpts ...func(*config.Config),
|
||||
) ([]*State, cleanupFunc) {
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, nValidators, false, 30)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, cfg, nValidators, false, 30)
|
||||
css := make([]*State, nValidators)
|
||||
logger := consensusLogger()
|
||||
|
||||
@@ -764,7 +763,7 @@ func randConsensusState(
|
||||
|
||||
ensureDir(t, filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
|
||||
|
||||
app := appFunc(t)
|
||||
app := appFunc(t, logger)
|
||||
|
||||
if appCloser, ok := app.(io.Closer); ok {
|
||||
closeFuncs = append(closeFuncs, appCloser.Close)
|
||||
@@ -797,11 +796,11 @@ func randConsensusNetWithPeers(
|
||||
nPeers int,
|
||||
testName string,
|
||||
tickerFunc func() TimeoutTicker,
|
||||
appFunc func(string) abci.Application,
|
||||
appFunc func(log.Logger, string) abci.Application,
|
||||
) ([]*State, *types.GenesisDoc, *config.Config, cleanupFunc) {
|
||||
t.Helper()
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, nValidators, false, testMinPower)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, cfg, nValidators, false, testMinPower)
|
||||
css := make([]*State, nPeers)
|
||||
logger := consensusLogger()
|
||||
|
||||
@@ -831,7 +830,7 @@ func randConsensusNetWithPeers(
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
app := appFunc(path.Join(cfg.DBDir(), fmt.Sprintf("%s_%d", testName, i)))
|
||||
app := appFunc(logger, filepath.Join(cfg.DBDir(), fmt.Sprintf("%s_%d", testName, i)))
|
||||
vals := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
if _, ok := app.(*kvstore.PersistentKVStoreApplication); ok {
|
||||
// simulate handshake, receive app version. If don't do this, replay test will fail
|
||||
@@ -859,7 +858,7 @@ func randGenesisState(
|
||||
minPower int64,
|
||||
) (sm.State, []types.PrivValidator) {
|
||||
|
||||
genDoc, privValidators := factory.RandGenesisDoc(ctx, cfg, numValidators, randPower, minPower)
|
||||
genDoc, privValidators := factory.RandGenesisDoc(ctx, t, cfg, numValidators, randPower, minPower)
|
||||
s0, err := sm.MakeGenesisState(genDoc)
|
||||
require.NoError(t, err)
|
||||
return s0, privValidators
|
||||
@@ -912,21 +911,21 @@ func (m *mockTicker) Chan() <-chan timeoutInfo {
|
||||
|
||||
func (*mockTicker) SetLogger(log.Logger) {}
|
||||
|
||||
func newPersistentKVStore(t *testing.T) abci.Application {
|
||||
func newPersistentKVStore(t *testing.T, logger log.Logger) abci.Application {
|
||||
t.Helper()
|
||||
|
||||
dir, err := os.MkdirTemp("", "persistent-kvstore")
|
||||
require.NoError(t, err)
|
||||
|
||||
return kvstore.NewPersistentKVStoreApplication(dir)
|
||||
return kvstore.NewPersistentKVStoreApplication(logger, dir)
|
||||
}
|
||||
|
||||
func newKVStore(_ *testing.T) abci.Application {
|
||||
func newKVStore(_ *testing.T, _ log.Logger) abci.Application {
|
||||
return kvstore.NewApplication()
|
||||
}
|
||||
|
||||
func newPersistentKVStoreWithPath(dbDir string) abci.Application {
|
||||
return kvstore.NewPersistentKVStoreApplication(dbDir)
|
||||
func newPersistentKVStoreWithPath(logger log.Logger, dbDir string) abci.Application {
|
||||
return kvstore.NewPersistentKVStoreApplication(logger, dbDir)
|
||||
}
|
||||
|
||||
func signDataIsEqual(v1 *types.Vote, v2 *tmproto.Vote) bool {
|
||||
|
||||
@@ -123,7 +123,6 @@ func invalidDoPrevoteFunc(
|
||||
cs.mtx.Unlock()
|
||||
|
||||
for _, ps := range r.peers {
|
||||
cs.logger.Info("sending bad vote", "block", blockHash, "peer", ps.peerID)
|
||||
require.NoError(t, r.voteCh.Send(ctx, p2p.Envelope{
|
||||
To: ps.peerID,
|
||||
Message: &tmcons.Vote{
|
||||
|
||||
@@ -99,7 +99,6 @@ func TestMempoolProgressInHigherRound(t *testing.T) {
|
||||
if cs.Height == 2 && cs.Round == 0 {
|
||||
// dont set the proposal in round 0 so we timeout and
|
||||
// go to next round
|
||||
cs.logger.Info("Ignoring set proposal at height 2, round 0")
|
||||
return nil
|
||||
}
|
||||
return cs.defaultSetProposal(proposal)
|
||||
|
||||
@@ -23,8 +23,8 @@ var (
|
||||
|
||||
// peerStateStats holds internal statistics for a peer.
|
||||
type peerStateStats struct {
|
||||
Votes int `json:"votes"`
|
||||
BlockParts int `json:"block_parts"`
|
||||
Votes int `json:"votes,string"`
|
||||
BlockParts int `json:"block_parts,string"`
|
||||
}
|
||||
|
||||
func (pss peerStateStats) String() string {
|
||||
|
||||
@@ -1455,7 +1455,6 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
r.logger.Debug("stopped listening on peer updates channel; closing...")
|
||||
return
|
||||
case peerUpdate := <-r.peerUpdates.Updates():
|
||||
r.processPeerUpdate(ctx, peerUpdate)
|
||||
|
||||
@@ -383,7 +383,7 @@ func TestReactorWithEvidence(t *testing.T) {
|
||||
tickerFunc := newMockTickerFunc(true)
|
||||
appFunc := newKVStore
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, n, false, 30)
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, t, cfg, n, false, 30)
|
||||
states := make([]*State, n)
|
||||
logger := consensusLogger()
|
||||
|
||||
@@ -398,7 +398,7 @@ func TestReactorWithEvidence(t *testing.T) {
|
||||
defer os.RemoveAll(thisConfig.RootDir)
|
||||
|
||||
ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
|
||||
app := appFunc(t)
|
||||
app := appFunc(t, logger)
|
||||
vals := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
|
||||
|
||||
@@ -696,7 +696,6 @@ func TestMockProxyApp(t *testing.T) {
|
||||
if txRes.Code == abci.CodeTypeOK {
|
||||
validTxs++
|
||||
} else {
|
||||
logger.Debug("Invalid tx", "code", txRes.Code, "log", txRes.Log)
|
||||
invalidTxs++
|
||||
}
|
||||
abciRes.DeliverTxs[txIndex] = txRes
|
||||
@@ -764,7 +763,7 @@ func testHandshakeReplay(
|
||||
testConfig, err := ResetConfig(fmt.Sprintf("%s_%v_s", t.Name(), mode))
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = os.RemoveAll(testConfig.RootDir) }()
|
||||
walBody, err := WALWithNBlocks(ctx, t, numBlocks)
|
||||
walBody, err := WALWithNBlocks(ctx, t, logger, numBlocks)
|
||||
require.NoError(t, err)
|
||||
walFile := tempWALWithData(t, walBody)
|
||||
cfg.Consensus.SetWalFile(walFile)
|
||||
@@ -806,7 +805,7 @@ func testHandshakeReplay(
|
||||
latestAppHash := state.AppHash
|
||||
|
||||
// make a new client creator
|
||||
kvstoreApp := kvstore.NewPersistentKVStoreApplication(
|
||||
kvstoreApp := kvstore.NewPersistentKVStoreApplication(logger,
|
||||
filepath.Join(cfg.DBDir(), fmt.Sprintf("replay_test_%d_%d_a_r%d", nBlocks, mode, rand.Int())))
|
||||
t.Cleanup(func() { require.NoError(t, kvstoreApp.Close()) })
|
||||
|
||||
@@ -960,7 +959,7 @@ func buildTMStateFromChain(
|
||||
t.Helper()
|
||||
|
||||
// run the whole chain against this client to build up the tendermint state
|
||||
kvstoreApp := kvstore.NewPersistentKVStoreApplication(
|
||||
kvstoreApp := kvstore.NewPersistentKVStoreApplication(logger,
|
||||
filepath.Join(cfg.DBDir(), fmt.Sprintf("replay_test_%d_%d_t", nBlocks, mode)))
|
||||
defer kvstoreApp.Close()
|
||||
clientCreator := abciclient.NewLocalCreator(kvstoreApp)
|
||||
@@ -1023,8 +1022,7 @@ func TestHandshakePanicsIfAppReturnsWrongAppHash(t *testing.T) {
|
||||
genDoc, _ := sm.MakeGenesisDocFromFile(cfg.GenesisFile())
|
||||
state.LastValidators = state.Validators.Copy()
|
||||
// mode = 0 for committing all the blocks
|
||||
blocks, err := sf.MakeBlocks(ctx, 3, &state, privVal)
|
||||
require.NoError(t, err)
|
||||
blocks := sf.MakeBlocks(ctx, t, 3, &state, privVal)
|
||||
|
||||
store.chain = blocks
|
||||
|
||||
@@ -1287,7 +1285,8 @@ func TestHandshakeUpdatesValidators(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
val, _ := factory.RandValidator(ctx, true, 10)
|
||||
val, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
vals := types.NewValidatorSet([]*types.Validator{val})
|
||||
app := &initChainApp{vals: types.TM2PB.ValidatorUpdates(vals)}
|
||||
clientCreator := abciclient.NewLocalCreator(app)
|
||||
|
||||
@@ -3,6 +3,7 @@ package consensus
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -18,10 +19,8 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cstypes "github.com/tendermint/tendermint/internal/consensus/types"
|
||||
"github.com/tendermint/tendermint/internal/eventbus"
|
||||
"github.com/tendermint/tendermint/internal/libs/fail"
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
tmevents "github.com/tendermint/tendermint/libs/events"
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmmath "github.com/tendermint/tendermint/libs/math"
|
||||
tmos "github.com/tendermint/tendermint/libs/os"
|
||||
@@ -254,14 +253,14 @@ func (cs *State) GetRoundState() *cstypes.RoundState {
|
||||
func (cs *State) GetRoundStateJSON() ([]byte, error) {
|
||||
cs.mtx.RLock()
|
||||
defer cs.mtx.RUnlock()
|
||||
return tmjson.Marshal(cs.RoundState)
|
||||
return json.Marshal(cs.RoundState)
|
||||
}
|
||||
|
||||
// GetRoundStateSimpleJSON returns a json of RoundStateSimple
|
||||
func (cs *State) GetRoundStateSimpleJSON() ([]byte, error) {
|
||||
cs.mtx.RLock()
|
||||
defer cs.mtx.RUnlock()
|
||||
return tmjson.Marshal(cs.RoundState.RoundStateSimple())
|
||||
return json.Marshal(cs.RoundState.RoundStateSimple())
|
||||
}
|
||||
|
||||
// GetValidators returns a copy of the current validators.
|
||||
@@ -867,14 +866,6 @@ func (cs *State) receiveRoutine(ctx context.Context, maxSteps int) {
|
||||
))
|
||||
}
|
||||
|
||||
if _, ok := mi.Msg.(*VoteMessage); ok {
|
||||
// we actually want to simulate failing during
|
||||
// the previous WriteSync, but this isn't easy to do.
|
||||
// Equivalent would be to fail here and manually remove
|
||||
// some bytes from the end of the wal.
|
||||
fail.Fail() // XXX
|
||||
}
|
||||
|
||||
// handles proposals, block parts, votes
|
||||
cs.handleMsg(ctx, mi)
|
||||
|
||||
@@ -1708,8 +1699,6 @@ func (cs *State) finalizeCommit(ctx context.Context, height int64) {
|
||||
)
|
||||
logger.Debug(fmt.Sprintf("%v", block))
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Save to blockStore.
|
||||
if cs.blockStore.Height() < block.Height {
|
||||
// NOTE: the seenCommit is local justification to commit this block,
|
||||
@@ -1722,8 +1711,6 @@ func (cs *State) finalizeCommit(ctx context.Context, height int64) {
|
||||
logger.Debug("calling finalizeCommit on already stored block", "height", block.Height)
|
||||
}
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Write EndHeightMessage{} for this height, implying that the blockstore
|
||||
// has saved the block.
|
||||
//
|
||||
@@ -1745,8 +1732,6 @@ func (cs *State) finalizeCommit(ctx context.Context, height int64) {
|
||||
))
|
||||
}
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Create a copy of the state for staging and an event cache for txs.
|
||||
stateCopy := cs.state.Copy()
|
||||
|
||||
@@ -1765,16 +1750,12 @@ func (cs *State) finalizeCommit(ctx context.Context, height int64) {
|
||||
return
|
||||
}
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// must be called before we update state
|
||||
cs.RecordMetrics(height, block)
|
||||
|
||||
// NewHeightStep!
|
||||
cs.updateToState(ctx, stateCopy)
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Private validator might have changed it's key pair => refetch pubkey.
|
||||
if err := cs.updatePrivValidatorPubKey(ctx); err != nil {
|
||||
logger.Error("failed to get private validator pubkey", "err", err)
|
||||
|
||||
@@ -81,7 +81,6 @@ func (t *timeoutTicker) stopTimer() {
|
||||
select {
|
||||
case <-t.timer.C:
|
||||
default:
|
||||
t.logger.Debug("Timer already stopped")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,7 +89,6 @@ func (t *timeoutTicker) stopTimer() {
|
||||
// timers are interupted and replaced by new ticks from later steps
|
||||
// timeouts of 0 on the tickChan will be immediately relayed to the tockChan
|
||||
func (t *timeoutTicker) timeoutRoutine(ctx context.Context) {
|
||||
t.logger.Debug("Starting timeout routine")
|
||||
var ti timeoutInfo
|
||||
for {
|
||||
select {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
tmjson "github.com/tendermint/tendermint/libs/json"
|
||||
tmmath "github.com/tendermint/tendermint/libs/math"
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -237,7 +237,7 @@ func (hvs *HeightVoteSet) StringIndented(indent string) string {
|
||||
func (hvs *HeightVoteSet) MarshalJSON() ([]byte, error) {
|
||||
hvs.mtx.Lock()
|
||||
defer hvs.mtx.Unlock()
|
||||
return tmjson.Marshal(hvs.toAllRoundVotes())
|
||||
return json.Marshal(hvs.toAllRoundVotes())
|
||||
}
|
||||
|
||||
func (hvs *HeightVoteSet) toAllRoundVotes() []roundVotes {
|
||||
|
||||
@@ -33,7 +33,7 @@ func TestPeerCatchupRounds(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
valSet, privVals := factory.RandValidatorSet(ctx, 10, 1)
|
||||
valSet, privVals := factory.RandValidatorSet(ctx, t, 10, 1)
|
||||
|
||||
hvs := NewHeightVoteSet(cfg.ChainID(), 1, valSet)
|
||||
|
||||
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
// PeerRoundState contains the known state of a peer.
|
||||
// NOTE: Read-only when returned by PeerState.GetRoundState().
|
||||
type PeerRoundState struct {
|
||||
Height int64 `json:"height"` // Height peer is at
|
||||
Round int32 `json:"round"` // Round peer is at, -1 if unknown.
|
||||
Step RoundStepType `json:"step"` // Step peer is at
|
||||
Height int64 `json:"height,string"` // Height peer is at
|
||||
Round int32 `json:"round"` // Round peer is at, -1 if unknown.
|
||||
Step RoundStepType `json:"step"` // Step peer is at
|
||||
|
||||
// Estimated start of round 0 at this height
|
||||
StartTime time.Time `json:"start_time"`
|
||||
|
||||
@@ -31,13 +31,12 @@ import (
|
||||
// persistent kvstore application and special consensus wal instance
|
||||
// (byteBufferWAL) and waits until numBlocks are created.
|
||||
// If the node fails to produce given numBlocks, it returns an error.
|
||||
func WALGenerateNBlocks(ctx context.Context, t *testing.T, wr io.Writer, numBlocks int) (err error) {
|
||||
func WALGenerateNBlocks(ctx context.Context, t *testing.T, logger log.Logger, wr io.Writer, numBlocks int) (err error) {
|
||||
cfg := getConfig(t)
|
||||
|
||||
app := kvstore.NewPersistentKVStoreApplication(filepath.Join(cfg.DBDir(), "wal_generator"))
|
||||
app := kvstore.NewPersistentKVStoreApplication(logger, filepath.Join(cfg.DBDir(), "wal_generator"))
|
||||
t.Cleanup(func() { require.NoError(t, app.Close()) })
|
||||
|
||||
logger := log.TestingLogger().With("wal_generator", "wal_generator")
|
||||
logger.Info("generating WAL (last height msg excluded)", "numBlocks", numBlocks)
|
||||
|
||||
// COPY PASTE FROM node.go WITH A FEW MODIFICATIONS
|
||||
@@ -116,11 +115,11 @@ func WALGenerateNBlocks(ctx context.Context, t *testing.T, wr io.Writer, numBloc
|
||||
}
|
||||
|
||||
// WALWithNBlocks returns a WAL content with numBlocks.
|
||||
func WALWithNBlocks(ctx context.Context, t *testing.T, numBlocks int) (data []byte, err error) {
|
||||
func WALWithNBlocks(ctx context.Context, t *testing.T, logger log.Logger, numBlocks int) (data []byte, err error) {
|
||||
var b bytes.Buffer
|
||||
wr := bufio.NewWriter(&b)
|
||||
|
||||
if err := WALGenerateNBlocks(ctx, t, wr, numBlocks); err != nil {
|
||||
if err := WALGenerateNBlocks(ctx, t, logger, wr, numBlocks); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ func TestWALTruncate(t *testing.T) {
|
||||
// 60 block's size nearly 70K, greater than group's headBuf size(4096 * 10),
|
||||
// when headBuf is full, truncate content will Flush to the file. at this
|
||||
// time, RotateFile is called, truncate content exist in each file.
|
||||
err = WALGenerateNBlocks(ctx, t, wal.Group(), 60)
|
||||
err = WALGenerateNBlocks(ctx, t, logger, wal.Group(), 60)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(1 * time.Millisecond) // wait groupCheckDuration, make sure RotateFile run
|
||||
@@ -136,13 +136,15 @@ func TestWALSearchForEndHeight(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
walBody, err := WALWithNBlocks(ctx, t, 6)
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
walBody, err := WALWithNBlocks(ctx, t, logger, 6)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
walFile := tempWALWithData(t, walBody)
|
||||
|
||||
wal, err := NewWAL(log.TestingLogger(), walFile)
|
||||
wal, err := NewWAL(logger, walFile)
|
||||
require.NoError(t, err)
|
||||
|
||||
h := int64(3)
|
||||
@@ -171,9 +173,10 @@ func TestWALPeriodicSync(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
wal.SetFlushInterval(walTestFlushInterval)
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
// Generate some data
|
||||
err = WALGenerateNBlocks(ctx, t, wal.Group(), 5)
|
||||
err = WALGenerateNBlocks(ctx, t, logger, wal.Group(), 5)
|
||||
require.NoError(t, err)
|
||||
|
||||
// We should have data in the buffer now
|
||||
|
||||
@@ -41,7 +41,7 @@ func TestEvidencePoolBasic(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
valSet, privVals := factory.RandValidatorSet(ctx, 1, 10)
|
||||
valSet, privVals := factory.RandValidatorSet(ctx, t, 1, 10)
|
||||
|
||||
blockStore.On("LoadBlockMeta", mock.AnythingOfType("int64")).Return(
|
||||
&types.BlockMeta{Header: types.Header{Time: defaultEvidenceTime}},
|
||||
|
||||
@@ -255,7 +255,6 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) {
|
||||
case peerUpdate := <-r.peerUpdates.Updates():
|
||||
r.processPeerUpdate(ctx, peerUpdate)
|
||||
case <-ctx.Done():
|
||||
r.logger.Debug("stopped listening on peer updates channel; closing...")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,17 +201,16 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
conflictingVals, conflictingPrivVals := factory.RandValidatorSet(ctx, 5, 10)
|
||||
conflictingVals, conflictingPrivVals := factory.RandValidatorSet(ctx, t, 5, 10)
|
||||
|
||||
conflictingHeader, err := factory.MakeHeader(&types.Header{
|
||||
conflictingHeader := factory.MakeHeader(t, &types.Header{
|
||||
ChainID: evidenceChainID,
|
||||
Height: 10,
|
||||
Time: defaultEvidenceTime,
|
||||
ValidatorsHash: conflictingVals.Hash(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
trustedHeader, _ := factory.MakeHeader(&types.Header{
|
||||
trustedHeader := factory.MakeHeader(t, &types.Header{
|
||||
ChainID: evidenceChainID,
|
||||
Height: 10,
|
||||
Time: defaultEvidenceTime,
|
||||
@@ -228,6 +227,7 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) {
|
||||
voteSet := types.NewVoteSet(evidenceChainID, 10, 1, tmproto.SignedMsgType(2), conflictingVals)
|
||||
commit, err := factory.MakeCommit(ctx, blockID, 10, 1, voteSet, conflictingPrivVals[:4], defaultEvidenceTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
ev := &types.LightClientAttackEvidence{
|
||||
ConflictingBlock: &types.LightBlock{
|
||||
SignedHeader: &types.SignedHeader{
|
||||
@@ -247,27 +247,26 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) {
|
||||
trustedCommit, err := factory.MakeCommit(ctx, trustedBlockID, 10, 1,
|
||||
trustedVoteSet, conflictingPrivVals, defaultEvidenceTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
trustedSignedHeader := &types.SignedHeader{
|
||||
Header: trustedHeader,
|
||||
Commit: trustedCommit,
|
||||
}
|
||||
|
||||
// good pass -> no error
|
||||
err = evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour))
|
||||
|
||||
// trusted and conflicting hashes are the same -> an error should be returned
|
||||
err = evidence.VerifyLightClientAttack(ev, trustedSignedHeader, ev.ConflictingBlock.SignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour)
|
||||
assert.Error(t, err)
|
||||
assert.Error(t, evidence.VerifyLightClientAttack(ev, trustedSignedHeader, ev.ConflictingBlock.SignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour))
|
||||
|
||||
// conflicting header has different next validators hash which should have been correctly derived from
|
||||
// the previous round
|
||||
ev.ConflictingBlock.Header.NextValidatorsHash = crypto.CRandBytes(tmhash.Size)
|
||||
err = evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, nil,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour)
|
||||
assert.Error(t, err)
|
||||
assert.Error(t, evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, nil,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour))
|
||||
|
||||
// revert next validators hash
|
||||
ev.ConflictingBlock.Header.NextValidatorsHash = trustedHeader.NextValidatorsHash
|
||||
|
||||
@@ -300,17 +299,16 @@ func TestVerifyLightClientAttack_Amnesia(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
conflictingVals, conflictingPrivVals := factory.RandValidatorSet(ctx, 5, 10)
|
||||
conflictingVals, conflictingPrivVals := factory.RandValidatorSet(ctx, t, 5, 10)
|
||||
|
||||
conflictingHeader, err := factory.MakeHeader(&types.Header{
|
||||
conflictingHeader := factory.MakeHeader(t, &types.Header{
|
||||
ChainID: evidenceChainID,
|
||||
Height: height,
|
||||
Time: defaultEvidenceTime,
|
||||
ValidatorsHash: conflictingVals.Hash(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
trustedHeader, _ := factory.MakeHeader(&types.Header{
|
||||
trustedHeader := factory.MakeHeader(t, &types.Header{
|
||||
ChainID: evidenceChainID,
|
||||
Height: height,
|
||||
Time: defaultEvidenceTime,
|
||||
@@ -327,6 +325,7 @@ func TestVerifyLightClientAttack_Amnesia(t *testing.T) {
|
||||
voteSet := types.NewVoteSet(evidenceChainID, height, 0, tmproto.SignedMsgType(2), conflictingVals)
|
||||
commit, err := factory.MakeCommit(ctx, blockID, height, 0, voteSet, conflictingPrivVals, defaultEvidenceTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
ev := &types.LightClientAttackEvidence{
|
||||
ConflictingBlock: &types.LightBlock{
|
||||
SignedHeader: &types.SignedHeader{
|
||||
@@ -346,20 +345,19 @@ func TestVerifyLightClientAttack_Amnesia(t *testing.T) {
|
||||
trustedCommit, err := factory.MakeCommit(ctx, trustedBlockID, height, 1,
|
||||
trustedVoteSet, conflictingPrivVals, defaultEvidenceTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
trustedSignedHeader := &types.SignedHeader{
|
||||
Header: trustedHeader,
|
||||
Commit: trustedCommit,
|
||||
}
|
||||
|
||||
// good pass -> no error
|
||||
err = evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, evidence.VerifyLightClientAttack(ev, trustedSignedHeader, trustedSignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour))
|
||||
|
||||
// trusted and conflicting hashes are the same -> an error should be returned
|
||||
err = evidence.VerifyLightClientAttack(ev, trustedSignedHeader, ev.ConflictingBlock.SignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour)
|
||||
assert.Error(t, err)
|
||||
assert.Error(t, evidence.VerifyLightClientAttack(ev, trustedSignedHeader, ev.ConflictingBlock.SignedHeader, conflictingVals,
|
||||
defaultEvidenceTime.Add(1*time.Minute), 2*time.Hour))
|
||||
|
||||
state := sm.State{
|
||||
LastBlockTime: defaultEvidenceTime.Add(1 * time.Minute),
|
||||
@@ -496,14 +494,16 @@ func makeLunaticEvidence(
|
||||
totalVals, byzVals, phantomVals int,
|
||||
commonTime, attackTime time.Time,
|
||||
) (ev *types.LightClientAttackEvidence, trusted *types.LightBlock, common *types.LightBlock) {
|
||||
commonValSet, commonPrivVals := factory.RandValidatorSet(ctx, totalVals, defaultVotingPower)
|
||||
t.Helper()
|
||||
|
||||
commonValSet, commonPrivVals := factory.RandValidatorSet(ctx, t, totalVals, defaultVotingPower)
|
||||
|
||||
require.Greater(t, totalVals, byzVals)
|
||||
|
||||
// extract out the subset of byzantine validators in the common validator set
|
||||
byzValSet, byzPrivVals := commonValSet.Validators[:byzVals], commonPrivVals[:byzVals]
|
||||
|
||||
phantomValSet, phantomPrivVals := factory.RandValidatorSet(ctx, phantomVals, defaultVotingPower)
|
||||
phantomValSet, phantomPrivVals := factory.RandValidatorSet(ctx, t, phantomVals, defaultVotingPower)
|
||||
|
||||
conflictingVals := phantomValSet.Copy()
|
||||
require.NoError(t, conflictingVals.UpdateWithChangeSet(byzValSet))
|
||||
@@ -511,31 +511,30 @@ func makeLunaticEvidence(
|
||||
|
||||
conflictingPrivVals = orderPrivValsByValSet(ctx, t, conflictingVals, conflictingPrivVals)
|
||||
|
||||
commonHeader, err := factory.MakeHeader(&types.Header{
|
||||
commonHeader := factory.MakeHeader(t, &types.Header{
|
||||
ChainID: evidenceChainID,
|
||||
Height: commonHeight,
|
||||
Time: commonTime,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
trustedHeader, err := factory.MakeHeader(&types.Header{
|
||||
|
||||
trustedHeader := factory.MakeHeader(t, &types.Header{
|
||||
ChainID: evidenceChainID,
|
||||
Height: height,
|
||||
Time: defaultEvidenceTime,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
conflictingHeader, err := factory.MakeHeader(&types.Header{
|
||||
conflictingHeader := factory.MakeHeader(t, &types.Header{
|
||||
ChainID: evidenceChainID,
|
||||
Height: height,
|
||||
Time: attackTime,
|
||||
ValidatorsHash: conflictingVals.Hash(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
blockID := factory.MakeBlockIDWithHash(conflictingHeader.Hash())
|
||||
voteSet := types.NewVoteSet(evidenceChainID, height, 1, tmproto.SignedMsgType(2), conflictingVals)
|
||||
commit, err := factory.MakeCommit(ctx, blockID, height, 1, voteSet, conflictingPrivVals, defaultEvidenceTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
ev = &types.LightClientAttackEvidence{
|
||||
ConflictingBlock: &types.LightBlock{
|
||||
SignedHeader: &types.SignedHeader{
|
||||
@@ -559,10 +558,11 @@ func makeLunaticEvidence(
|
||||
ValidatorSet: commonValSet,
|
||||
}
|
||||
trustedBlockID := factory.MakeBlockIDWithHash(trustedHeader.Hash())
|
||||
trustedVals, privVals := factory.RandValidatorSet(ctx, totalVals, defaultVotingPower)
|
||||
trustedVals, privVals := factory.RandValidatorSet(ctx, t, totalVals, defaultVotingPower)
|
||||
trustedVoteSet := types.NewVoteSet(evidenceChainID, height, 1, tmproto.SignedMsgType(2), trustedVals)
|
||||
trustedCommit, err := factory.MakeCommit(ctx, trustedBlockID, height, 1, trustedVoteSet, privVals, defaultEvidenceTime)
|
||||
require.NoError(t, err)
|
||||
|
||||
trusted = &types.LightBlock{
|
||||
SignedHeader: &types.SignedHeader{
|
||||
Header: trustedHeader,
|
||||
|
||||
+16
-30
@@ -8,14 +8,12 @@ import (
|
||||
"github.com/rs/cors"
|
||||
|
||||
"github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/internal/consensus"
|
||||
"github.com/tendermint/tendermint/internal/pubsub"
|
||||
"github.com/tendermint/tendermint/internal/rpc/core"
|
||||
"github.com/tendermint/tendermint/internal/state"
|
||||
"github.com/tendermint/tendermint/internal/state/indexer"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/rpc/jsonrpc/server"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// Server defines parameters for running an Inspector rpc server.
|
||||
@@ -33,24 +31,23 @@ type eventBusUnsubscriber interface {
|
||||
// Routes returns the set of routes used by the Inspector server.
|
||||
func Routes(cfg config.RPCConfig, s state.Store, bs state.BlockStore, es []indexer.EventSink, logger log.Logger) core.RoutesMap {
|
||||
env := &core.Environment{
|
||||
Config: cfg,
|
||||
EventSinks: es,
|
||||
StateStore: s,
|
||||
BlockStore: bs,
|
||||
ConsensusReactor: waitSyncCheckerImpl{},
|
||||
Logger: logger,
|
||||
Config: cfg,
|
||||
EventSinks: es,
|
||||
StateStore: s,
|
||||
BlockStore: bs,
|
||||
Logger: logger,
|
||||
}
|
||||
return core.RoutesMap{
|
||||
"blockchain": server.NewRPCFunc(env.BlockchainInfo, "minHeight,maxHeight", true),
|
||||
"consensus_params": server.NewRPCFunc(env.ConsensusParams, "height", true),
|
||||
"block": server.NewRPCFunc(env.Block, "height", true),
|
||||
"block_by_hash": server.NewRPCFunc(env.BlockByHash, "hash", true),
|
||||
"block_results": server.NewRPCFunc(env.BlockResults, "height", true),
|
||||
"commit": server.NewRPCFunc(env.Commit, "height", true),
|
||||
"validators": server.NewRPCFunc(env.Validators, "height,page,per_page", true),
|
||||
"tx": server.NewRPCFunc(env.Tx, "hash,prove", true),
|
||||
"tx_search": server.NewRPCFunc(env.TxSearch, "query,prove,page,per_page,order_by", false),
|
||||
"block_search": server.NewRPCFunc(env.BlockSearch, "query,page,per_page,order_by", false),
|
||||
"blockchain": server.NewRPCFunc(env.BlockchainInfo, "minHeight,maxHeight"),
|
||||
"consensus_params": server.NewRPCFunc(env.ConsensusParams, "height"),
|
||||
"block": server.NewRPCFunc(env.Block, "height"),
|
||||
"block_by_hash": server.NewRPCFunc(env.BlockByHash, "hash"),
|
||||
"block_results": server.NewRPCFunc(env.BlockResults, "height"),
|
||||
"commit": server.NewRPCFunc(env.Commit, "height"),
|
||||
"validators": server.NewRPCFunc(env.Validators, "height,page,per_page"),
|
||||
"tx": server.NewRPCFunc(env.Tx, "hash,prove"),
|
||||
"tx_search": server.NewRPCFunc(env.TxSearch, "query,prove,page,per_page,order_by"),
|
||||
"block_search": server.NewRPCFunc(env.BlockSearch, "query,page,per_page,order_by"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,10 +66,9 @@ func Handler(rpcConfig *config.RPCConfig, routes core.RoutesMap, logger log.Logg
|
||||
wmLogger.Error("Failed to unsubscribe addr from events", "addr", remoteAddr, "err", err)
|
||||
}
|
||||
}
|
||||
wm := server.NewWebsocketManager(routes,
|
||||
wm := server.NewWebsocketManager(logger, routes,
|
||||
server.OnDisconnect(websocketDisconnectFn),
|
||||
server.ReadLimit(rpcConfig.MaxBodyBytes))
|
||||
wm.SetLogger(wmLogger)
|
||||
mux.HandleFunc("/websocket", wm.WebsocketHandler)
|
||||
|
||||
server.RegisterRPCFuncs(mux, routes, logger)
|
||||
@@ -93,16 +89,6 @@ func addCORSHandler(rpcConfig *config.RPCConfig, h http.Handler) http.Handler {
|
||||
return h
|
||||
}
|
||||
|
||||
type waitSyncCheckerImpl struct{}
|
||||
|
||||
func (waitSyncCheckerImpl) WaitSync() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (waitSyncCheckerImpl) GetPeerState(peerID types.NodeID) (*consensus.PeerState, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// ListenAndServe listens on the address specified in srv.Addr and handles any
|
||||
// incoming requests over HTTP using the Inspector rpc handler specified on the server.
|
||||
func (srv *Server) ListenAndServe(ctx context.Context) error {
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package fail
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func envSet() int {
|
||||
callIndexToFailS := os.Getenv("FAIL_TEST_INDEX")
|
||||
|
||||
if callIndexToFailS == "" {
|
||||
return -1
|
||||
}
|
||||
|
||||
var err error
|
||||
callIndexToFail, err := strconv.Atoi(callIndexToFailS)
|
||||
if err != nil {
|
||||
return -1
|
||||
}
|
||||
|
||||
return callIndexToFail
|
||||
}
|
||||
|
||||
// Fail when FAIL_TEST_INDEX == callIndex
|
||||
var callIndex int // indexes Fail calls
|
||||
|
||||
func Fail() {
|
||||
callIndexToFail := envSet()
|
||||
if callIndexToFail < 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if callIndex == callIndexToFail {
|
||||
fmt.Printf("*** fail-test %d ***\n", callIndex)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
callIndex++
|
||||
}
|
||||
@@ -55,13 +55,6 @@ func (t *ThrottleTimer) Set() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *ThrottleTimer) Unset() {
|
||||
t.mtx.Lock()
|
||||
defer t.mtx.Unlock()
|
||||
t.isSet = false
|
||||
t.timer.Stop()
|
||||
}
|
||||
|
||||
// For ease of .Stop()'ing services before .Start()'ing them,
|
||||
// we ignore .Stop()'s on nil ThrottleTimers
|
||||
func (t *ThrottleTimer) Stop() bool {
|
||||
|
||||
@@ -281,7 +281,6 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
r.logger.Debug("stopped listening on peer updates channel; closing...")
|
||||
return
|
||||
case peerUpdate := <-r.peerUpdates.Updates():
|
||||
r.processPeerUpdate(ctx, peerUpdate)
|
||||
|
||||
@@ -353,7 +353,6 @@ FOR_LOOP:
|
||||
channel.updateStats()
|
||||
}
|
||||
case <-c.pingTimer.C:
|
||||
c.logger.Debug("Send Ping")
|
||||
_n, err = protoWriter.WriteMsg(mustWrapPacket(&tmp2p.PacketPing{}))
|
||||
if err != nil {
|
||||
c.logger.Error("Failed to send PacketPing", "err", err)
|
||||
@@ -370,13 +369,11 @@ FOR_LOOP:
|
||||
c.flush()
|
||||
case timeout := <-c.pongTimeoutCh:
|
||||
if timeout {
|
||||
c.logger.Debug("Pong timeout")
|
||||
err = errors.New("pong timeout")
|
||||
} else {
|
||||
c.stopPongTimer()
|
||||
}
|
||||
case <-c.pong:
|
||||
c.logger.Debug("Send Pong")
|
||||
_n, err = protoWriter.WriteMsg(mustWrapPacket(&tmp2p.PacketPong{}))
|
||||
if err != nil {
|
||||
c.logger.Error("Failed to send PacketPong", "err", err)
|
||||
@@ -528,14 +525,12 @@ FOR_LOOP:
|
||||
case *tmp2p.Packet_PacketPing:
|
||||
// TODO: prevent abuse, as they cause flush()'s.
|
||||
// https://github.com/tendermint/tendermint/issues/1190
|
||||
c.logger.Debug("Receive Ping")
|
||||
select {
|
||||
case c.pong <- struct{}{}:
|
||||
default:
|
||||
// never block
|
||||
}
|
||||
case *tmp2p.Packet_PacketPong:
|
||||
c.logger.Debug("Receive Pong")
|
||||
select {
|
||||
case c.pongTimeoutCh <- false:
|
||||
default:
|
||||
|
||||
@@ -181,7 +181,6 @@ func (r *Reactor) processPexCh(ctx context.Context) {
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
r.logger.Debug("stopped listening on PEX channel; closing...")
|
||||
return
|
||||
|
||||
// outbound requests for new peers
|
||||
@@ -215,7 +214,6 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
r.logger.Debug("stopped listening on peer updates channel; closing...")
|
||||
return
|
||||
case peerUpdate := <-r.peerUpdates.Updates():
|
||||
r.processPeerUpdate(peerUpdate)
|
||||
|
||||
@@ -487,7 +487,6 @@ func (r *reactorTestSuite) listenFor(
|
||||
}
|
||||
|
||||
func (r *reactorTestSuite) listenForRequest(ctx context.Context, t *testing.T, fromNode, toNode int, waitPeriod time.Duration) {
|
||||
r.logger.Info("Listening for request", "from", fromNode, "to", toNode)
|
||||
to, from := r.checkNodePair(t, toNode, fromNode)
|
||||
conditional := func(msg *p2p.Envelope) bool {
|
||||
_, ok := msg.Message.(*p2pproto.PexRequest)
|
||||
@@ -508,7 +507,7 @@ func (r *reactorTestSuite) pingAndlistenForNAddresses(
|
||||
addresses int,
|
||||
) {
|
||||
t.Helper()
|
||||
r.logger.Info("Listening for addresses", "from", fromNode, "to", toNode)
|
||||
|
||||
to, from := r.checkNodePair(t, toNode, fromNode)
|
||||
conditional := func(msg *p2p.Envelope) bool {
|
||||
_, ok := msg.Message.(*p2pproto.PexResponse)
|
||||
@@ -541,11 +540,9 @@ func (r *reactorTestSuite) listenForResponse(
|
||||
waitPeriod time.Duration,
|
||||
addresses []p2pproto.PexAddress,
|
||||
) {
|
||||
r.logger.Info("Listening for response", "from", fromNode, "to", toNode)
|
||||
to, from := r.checkNodePair(t, toNode, fromNode)
|
||||
conditional := func(msg *p2p.Envelope) bool {
|
||||
_, ok := msg.Message.(*p2pproto.PexResponse)
|
||||
r.logger.Info("message", msg, "ok", ok)
|
||||
return ok && msg.From == from
|
||||
}
|
||||
assertion := func(t *testing.T, msg *p2p.Envelope) bool {
|
||||
@@ -658,7 +655,6 @@ func (r *reactorTestSuite) connectN(ctx context.Context, t *testing.T, n int) {
|
||||
func (r *reactorTestSuite) connectPeers(ctx context.Context, t *testing.T, sourceNode, targetNode int) {
|
||||
t.Helper()
|
||||
node1, node2 := r.checkNodePair(t, sourceNode, targetNode)
|
||||
r.logger.Info("connecting peers", "sourceNode", sourceNode, "targetNode", targetNode)
|
||||
|
||||
n1 := r.network.Nodes[node1]
|
||||
if n1 == nil {
|
||||
@@ -676,16 +672,12 @@ func (r *reactorTestSuite) connectPeers(ctx context.Context, t *testing.T, sourc
|
||||
targetSub := n2.PeerManager.Subscribe(ctx)
|
||||
|
||||
sourceAddress := n1.NodeAddress
|
||||
r.logger.Debug("source address", "address", sourceAddress)
|
||||
targetAddress := n2.NodeAddress
|
||||
r.logger.Debug("target address", "address", targetAddress)
|
||||
|
||||
added, err := n1.PeerManager.Add(targetAddress)
|
||||
require.NoError(t, err)
|
||||
|
||||
if !added {
|
||||
r.logger.Debug("nodes already know about one another",
|
||||
"sourceNode", sourceNode, "targetNode", targetNode)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -695,19 +687,16 @@ func (r *reactorTestSuite) connectPeers(ctx context.Context, t *testing.T, sourc
|
||||
NodeID: node1,
|
||||
Status: p2p.PeerStatusUp,
|
||||
}, peerUpdate)
|
||||
r.logger.Debug("target connected with source")
|
||||
case <-time.After(2 * time.Second):
|
||||
require.Fail(t, "timed out waiting for peer", "%v accepting %v",
|
||||
targetNode, sourceNode)
|
||||
}
|
||||
|
||||
select {
|
||||
case peerUpdate := <-sourceSub.Updates():
|
||||
require.Equal(t, p2p.PeerUpdate{
|
||||
NodeID: node2,
|
||||
Status: p2p.PeerStatusUp,
|
||||
}, peerUpdate)
|
||||
r.logger.Debug("source connected with target")
|
||||
case <-time.After(2 * time.Second):
|
||||
require.Fail(t, "timed out waiting for peer", "%v dialing %v",
|
||||
sourceNode, targetNode)
|
||||
|
||||
@@ -472,8 +472,6 @@ func (r *Router) dialSleep(ctx context.Context) {
|
||||
// acceptPeers accepts inbound connections from peers on the given transport,
|
||||
// and spawns goroutines that route messages to/from them.
|
||||
func (r *Router) acceptPeers(ctx context.Context, transport Transport) {
|
||||
r.logger.Debug("starting accept routine", "transport", transport)
|
||||
|
||||
for {
|
||||
conn, err := transport.Accept(ctx)
|
||||
switch err {
|
||||
@@ -555,8 +553,6 @@ func (r *Router) openConnection(ctx context.Context, conn Connection) {
|
||||
|
||||
// dialPeers maintains outbound connections to peers by dialing them.
|
||||
func (r *Router) dialPeers(ctx context.Context) {
|
||||
r.logger.Debug("starting dial routine")
|
||||
|
||||
addresses := make(chan NodeAddress)
|
||||
wg := &sync.WaitGroup{}
|
||||
|
||||
@@ -587,7 +583,6 @@ LOOP:
|
||||
address, err := r.peerManager.DialNext(ctx)
|
||||
switch {
|
||||
case errors.Is(err, context.Canceled):
|
||||
r.logger.Debug("stopping dial routine")
|
||||
break LOOP
|
||||
case err != nil:
|
||||
r.logger.Error("failed to find next peer to dial", "err", err)
|
||||
@@ -917,16 +912,12 @@ func (r *Router) sendPeer(ctx context.Context, peerID types.NodeID, conn Connect
|
||||
|
||||
// evictPeers evicts connected peers as requested by the peer manager.
|
||||
func (r *Router) evictPeers(ctx context.Context) {
|
||||
r.logger.Debug("starting evict routine")
|
||||
|
||||
for {
|
||||
peerID, err := r.peerManager.EvictNext(ctx)
|
||||
|
||||
switch {
|
||||
case errors.Is(err, context.Canceled):
|
||||
r.logger.Debug("stopping evict routine")
|
||||
return
|
||||
|
||||
case err != nil:
|
||||
r.logger.Error("failed to find next peer to evict", "err", err)
|
||||
return
|
||||
|
||||
@@ -21,7 +21,7 @@ func DefaultClientCreator(logger log.Logger, addr, transport, dbDir string) (abc
|
||||
case "kvstore":
|
||||
return abciclient.NewLocalCreator(kvstore.NewApplication()), noopCloser{}
|
||||
case "persistent_kvstore":
|
||||
app := kvstore.NewPersistentKVStoreApplication(dbDir)
|
||||
app := kvstore.NewPersistentKVStoreApplication(logger, dbDir)
|
||||
return abciclient.NewLocalCreator(app), app
|
||||
case "e2e":
|
||||
app, err := e2e.NewApplication(e2e.DefaultConfig(dbDir))
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/internal/proxy"
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
// ABCIQuery queries the application for some information.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_query
|
||||
func (env *Environment) ABCIQuery(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
height int64,
|
||||
prove bool,
|
||||
) (*coretypes.ResultABCIQuery, error) {
|
||||
resQuery, err := env.ProxyAppQuery.QuerySync(ctx.Context(), abci.RequestQuery{
|
||||
resQuery, err := env.ProxyAppQuery.QuerySync(ctx, abci.RequestQuery{
|
||||
Path: path,
|
||||
Data: data,
|
||||
Height: height,
|
||||
@@ -32,8 +33,8 @@ func (env *Environment) ABCIQuery(
|
||||
|
||||
// ABCIInfo gets some info about the application.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info
|
||||
func (env *Environment) ABCIInfo(ctx *rpctypes.Context) (*coretypes.ResultABCIInfo, error) {
|
||||
resInfo, err := env.ProxyAppQuery.InfoSync(ctx.Context(), proxy.RequestInfo)
|
||||
func (env *Environment) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) {
|
||||
resInfo, err := env.ProxyAppQuery.InfoSync(ctx, proxy.RequestInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+10
-10
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
@@ -9,7 +10,6 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
tmmath "github.com/tendermint/tendermint/libs/math"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
//
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/blockchain
|
||||
func (env *Environment) BlockchainInfo(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
|
||||
|
||||
const limit int64 = 20
|
||||
@@ -92,7 +92,7 @@ func filterMinMax(base, height, min, max, limit int64) (int64, int64, error) {
|
||||
// Block gets block at a given height.
|
||||
// If no height is provided, it will fetch the latest block.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/block
|
||||
func (env *Environment) Block(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultBlock, error) {
|
||||
func (env *Environment) Block(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlock, error) {
|
||||
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -109,7 +109,7 @@ func (env *Environment) Block(ctx *rpctypes.Context, heightPtr *int64) (*coretyp
|
||||
|
||||
// BlockByHash gets block by hash.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/block_by_hash
|
||||
func (env *Environment) BlockByHash(ctx *rpctypes.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) {
|
||||
func (env *Environment) BlockByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultBlock, error) {
|
||||
// N.B. The hash parameter is HexBytes so that the reflective parameter
|
||||
// decoding logic in the HTTP service will correctly translate from JSON.
|
||||
// See https://github.com/tendermint/tendermint/issues/6802 for context.
|
||||
@@ -126,7 +126,7 @@ func (env *Environment) BlockByHash(ctx *rpctypes.Context, hash bytes.HexBytes)
|
||||
// Header gets block header at a given height.
|
||||
// If no height is provided, it will fetch the latest header.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/header
|
||||
func (env *Environment) Header(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultHeader, error) {
|
||||
func (env *Environment) Header(ctx context.Context, heightPtr *int64) (*coretypes.ResultHeader, error) {
|
||||
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -142,7 +142,7 @@ func (env *Environment) Header(ctx *rpctypes.Context, heightPtr *int64) (*corety
|
||||
|
||||
// HeaderByHash gets header by hash.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/header_by_hash
|
||||
func (env *Environment) HeaderByHash(ctx *rpctypes.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) {
|
||||
func (env *Environment) HeaderByHash(ctx context.Context, hash bytes.HexBytes) (*coretypes.ResultHeader, error) {
|
||||
// N.B. The hash parameter is HexBytes so that the reflective parameter
|
||||
// decoding logic in the HTTP service will correctly translate from JSON.
|
||||
// See https://github.com/tendermint/tendermint/issues/6802 for context.
|
||||
@@ -158,7 +158,7 @@ func (env *Environment) HeaderByHash(ctx *rpctypes.Context, hash bytes.HexBytes)
|
||||
// Commit gets block commit at a given height.
|
||||
// If no height is provided, it will fetch the commit for the latest block.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/commit
|
||||
func (env *Environment) Commit(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultCommit, error) {
|
||||
func (env *Environment) Commit(ctx context.Context, heightPtr *int64) (*coretypes.ResultCommit, error) {
|
||||
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -196,7 +196,7 @@ func (env *Environment) Commit(ctx *rpctypes.Context, heightPtr *int64) (*corety
|
||||
// Thus response.results.deliver_tx[5] is the results of executing
|
||||
// getBlock(h).Txs[5]
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/block_results
|
||||
func (env *Environment) BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*coretypes.ResultBlockResults, error) {
|
||||
func (env *Environment) BlockResults(ctx context.Context, heightPtr *int64) (*coretypes.ResultBlockResults, error) {
|
||||
height, err := env.getHeight(env.BlockStore.Height(), heightPtr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -226,7 +226,7 @@ func (env *Environment) BlockResults(ctx *rpctypes.Context, heightPtr *int64) (*
|
||||
// BlockSearch searches for a paginated set of blocks matching BeginBlock and
|
||||
// EndBlock event search criteria.
|
||||
func (env *Environment) BlockSearch(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
query string,
|
||||
pagePtr, perPagePtr *int,
|
||||
orderBy string,
|
||||
@@ -248,7 +248,7 @@ func (env *Environment) BlockSearch(
|
||||
}
|
||||
}
|
||||
|
||||
results, err := kvsink.SearchBlockEvents(ctx.Context(), q)
|
||||
results, err := kvsink.SearchBlockEvents(ctx, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
@@ -14,7 +15,6 @@ import (
|
||||
"github.com/tendermint/tendermint/internal/state/mocks"
|
||||
tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
func TestBlockchainInfo(t *testing.T) {
|
||||
@@ -108,8 +108,9 @@ func TestBlockResults(t *testing.T) {
|
||||
}},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
for _, tc := range testCases {
|
||||
res, err := env.BlockResults(&rpctypes.Context{}, &tc.height)
|
||||
res, err := env.BlockResults(ctx, &tc.height)
|
||||
if tc.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
tmmath "github.com/tendermint/tendermint/libs/math"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
// Validators gets the validator set at the given block height.
|
||||
@@ -14,7 +15,7 @@ import (
|
||||
//
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/validators
|
||||
func (env *Environment) Validators(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
heightPtr *int64,
|
||||
pagePtr, perPagePtr *int) (*coretypes.ResultValidators, error) {
|
||||
|
||||
@@ -50,7 +51,7 @@ func (env *Environment) Validators(
|
||||
// DumpConsensusState dumps consensus state.
|
||||
// UNSTABLE
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/dump_consensus_state
|
||||
func (env *Environment) DumpConsensusState(ctx *rpctypes.Context) (*coretypes.ResultDumpConsensusState, error) {
|
||||
func (env *Environment) DumpConsensusState(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) {
|
||||
// Get Peer consensus states.
|
||||
|
||||
var peerStates []coretypes.PeerStateInfo
|
||||
@@ -91,7 +92,7 @@ func (env *Environment) DumpConsensusState(ctx *rpctypes.Context) (*coretypes.Re
|
||||
// ConsensusState returns a concise summary of the consensus state.
|
||||
// UNSTABLE
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_state
|
||||
func (env *Environment) GetConsensusState(ctx *rpctypes.Context) (*coretypes.ResultConsensusState, error) {
|
||||
func (env *Environment) GetConsensusState(ctx context.Context) (*coretypes.ResultConsensusState, error) {
|
||||
// Get self round state.
|
||||
bz, err := env.ConsensusState.GetRoundStateSimpleJSON()
|
||||
return &coretypes.ResultConsensusState{RoundState: bz}, err
|
||||
@@ -100,9 +101,7 @@ func (env *Environment) GetConsensusState(ctx *rpctypes.Context) (*coretypes.Res
|
||||
// ConsensusParams gets the consensus parameters at the given block height.
|
||||
// If no height is provided, it will fetch the latest consensus params.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/consensus_params
|
||||
func (env *Environment) ConsensusParams(
|
||||
ctx *rpctypes.Context,
|
||||
heightPtr *int64) (*coretypes.ResultConsensusParams, error) {
|
||||
func (env *Environment) ConsensusParams(ctx context.Context, heightPtr *int64) (*coretypes.ResultConsensusParams, error) {
|
||||
|
||||
// The latest consensus params that we know is the consensus params after the
|
||||
// last block.
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
// UnsafeFlushMempool removes all transactions from the mempool.
|
||||
func (env *Environment) UnsafeFlushMempool(ctx *rpctypes.Context) (*coretypes.ResultUnsafeFlushMempool, error) {
|
||||
func (env *Environment) UnsafeFlushMempool(ctx context.Context) (*coretypes.ResultUnsafeFlushMempool, error) {
|
||||
env.Mempool.Flush()
|
||||
return &coretypes.ResultUnsafeFlushMempool{}, nil
|
||||
}
|
||||
|
||||
+10
-10
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/internal/blocksync"
|
||||
"github.com/tendermint/tendermint/internal/consensus"
|
||||
"github.com/tendermint/tendermint/internal/eventbus"
|
||||
"github.com/tendermint/tendermint/internal/mempool"
|
||||
@@ -52,11 +53,6 @@ type transport interface {
|
||||
NodeInfo() types.NodeInfo
|
||||
}
|
||||
|
||||
type consensusReactor interface {
|
||||
WaitSync() bool
|
||||
GetPeerState(peerID types.NodeID) (*consensus.PeerState, bool)
|
||||
}
|
||||
|
||||
type peerManager interface {
|
||||
Peers() []types.NodeID
|
||||
Addresses(types.NodeID) []p2p.NodeAddress
|
||||
@@ -75,7 +71,8 @@ type Environment struct {
|
||||
BlockStore sm.BlockStore
|
||||
EvidencePool sm.EvidencePool
|
||||
ConsensusState consensusState
|
||||
ConsensusReactor consensusReactor
|
||||
ConsensusReactor *consensus.Reactor
|
||||
BlockSyncReactor *blocksync.Reactor
|
||||
|
||||
// Legacy p2p stack
|
||||
P2PTransport transport
|
||||
@@ -89,7 +86,6 @@ type Environment struct {
|
||||
EventSinks []indexer.EventSink
|
||||
EventBus *eventbus.EventBus // thread safe
|
||||
Mempool mempool.Mempool
|
||||
BlockSyncReactor consensus.BlockSyncReactor
|
||||
StateSyncMetricer statesync.Metricer
|
||||
|
||||
Logger log.Logger
|
||||
@@ -199,9 +195,13 @@ func (env *Environment) getHeight(latestHeight int64, heightPtr *int64) (int64,
|
||||
}
|
||||
|
||||
func (env *Environment) latestUncommittedHeight() int64 {
|
||||
nodeIsSyncing := env.ConsensusReactor.WaitSync()
|
||||
if nodeIsSyncing {
|
||||
return env.BlockStore.Height()
|
||||
if env.ConsensusReactor != nil {
|
||||
// consensus reactor can be nil in inspect mode.
|
||||
|
||||
nodeIsSyncing := env.ConsensusReactor.WaitSync()
|
||||
if nodeIsSyncing {
|
||||
return env.BlockStore.Height()
|
||||
}
|
||||
}
|
||||
return env.BlockStore.Height() + 1
|
||||
}
|
||||
|
||||
+13
-12
@@ -23,8 +23,9 @@ const (
|
||||
|
||||
// Subscribe for events via WebSocket.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Websocket/subscribe
|
||||
func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretypes.ResultSubscribe, error) {
|
||||
addr := ctx.RemoteAddr()
|
||||
func (env *Environment) Subscribe(ctx context.Context, query string) (*coretypes.ResultSubscribe, error) {
|
||||
callInfo := rpctypes.GetCallInfo(ctx)
|
||||
addr := callInfo.RemoteAddr()
|
||||
|
||||
if env.EventBus.NumClients() >= env.Config.MaxSubscriptionClients {
|
||||
return nil, fmt.Errorf("max_subscription_clients %d reached", env.Config.MaxSubscriptionClients)
|
||||
@@ -41,7 +42,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
|
||||
return nil, fmt.Errorf("failed to parse query: %w", err)
|
||||
}
|
||||
|
||||
subCtx, cancel := context.WithTimeout(ctx.Context(), SubscribeTimeout)
|
||||
subCtx, cancel := context.WithTimeout(ctx, SubscribeTimeout)
|
||||
defer cancel()
|
||||
|
||||
sub, err := env.EventBus.SubscribeWithArgs(subCtx, tmpubsub.SubscribeArgs{
|
||||
@@ -54,7 +55,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
|
||||
}
|
||||
|
||||
// Capture the current ID, since it can change in the future.
|
||||
subscriptionID := ctx.JSONReq.ID
|
||||
subscriptionID := callInfo.RPCRequest.ID
|
||||
go func() {
|
||||
opctx, opcancel := context.WithCancel(context.Background())
|
||||
defer opcancel()
|
||||
@@ -67,7 +68,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
|
||||
} else if errors.Is(err, tmpubsub.ErrTerminated) {
|
||||
// The subscription was terminated by the publisher.
|
||||
resp := rpctypes.RPCServerError(subscriptionID, err)
|
||||
ok := ctx.WSConn.TryWriteRPCResponse(opctx, resp)
|
||||
ok := callInfo.WSConn.TryWriteRPCResponse(opctx, resp)
|
||||
if !ok {
|
||||
env.Logger.Info("Unable to write response (slow client)",
|
||||
"to", addr, "subscriptionID", subscriptionID, "err", err)
|
||||
@@ -82,7 +83,7 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
|
||||
Events: msg.Events(),
|
||||
})
|
||||
wctx, cancel := context.WithTimeout(opctx, 10*time.Second)
|
||||
err = ctx.WSConn.WriteRPCResponse(wctx, resp)
|
||||
err = callInfo.WSConn.WriteRPCResponse(wctx, resp)
|
||||
cancel()
|
||||
if err != nil {
|
||||
env.Logger.Info("Unable to write response (slow client)",
|
||||
@@ -96,8 +97,8 @@ func (env *Environment) Subscribe(ctx *rpctypes.Context, query string) (*coretyp
|
||||
|
||||
// Unsubscribe from events via WebSocket.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe
|
||||
func (env *Environment) Unsubscribe(ctx *rpctypes.Context, query string) (*coretypes.ResultUnsubscribe, error) {
|
||||
args := tmpubsub.UnsubscribeArgs{Subscriber: ctx.RemoteAddr()}
|
||||
func (env *Environment) Unsubscribe(ctx context.Context, query string) (*coretypes.ResultUnsubscribe, error) {
|
||||
args := tmpubsub.UnsubscribeArgs{Subscriber: rpctypes.GetCallInfo(ctx).RemoteAddr()}
|
||||
env.Logger.Info("Unsubscribe from query", "remote", args.Subscriber, "subscription", query)
|
||||
|
||||
var err error
|
||||
@@ -107,7 +108,7 @@ func (env *Environment) Unsubscribe(ctx *rpctypes.Context, query string) (*coret
|
||||
args.ID = query
|
||||
}
|
||||
|
||||
err = env.EventBus.Unsubscribe(ctx.Context(), args)
|
||||
err = env.EventBus.Unsubscribe(ctx, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -116,10 +117,10 @@ func (env *Environment) Unsubscribe(ctx *rpctypes.Context, query string) (*coret
|
||||
|
||||
// UnsubscribeAll from all events via WebSocket.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Websocket/unsubscribe_all
|
||||
func (env *Environment) UnsubscribeAll(ctx *rpctypes.Context) (*coretypes.ResultUnsubscribe, error) {
|
||||
addr := ctx.RemoteAddr()
|
||||
func (env *Environment) UnsubscribeAll(ctx context.Context) (*coretypes.ResultUnsubscribe, error) {
|
||||
addr := rpctypes.GetCallInfo(ctx).RemoteAddr()
|
||||
env.Logger.Info("Unsubscribe from all", "remote", addr)
|
||||
err := env.EventBus.UnsubscribeAll(ctx.Context(), addr)
|
||||
err := env.EventBus.UnsubscribeAll(ctx, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// BroadcastEvidence broadcasts evidence of the misbehavior.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Evidence/broadcast_evidence
|
||||
func (env *Environment) BroadcastEvidence(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
|
||||
if ev == nil {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
// Health gets node health. Returns empty result (200 OK) on success, no
|
||||
// response - in case of an error.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/health
|
||||
func (env *Environment) Health(ctx *rpctypes.Context) (*coretypes.ResultHealth, error) {
|
||||
func (env *Environment) Health(ctx context.Context) (*coretypes.ResultHealth, error) {
|
||||
return &coretypes.ResultHealth{}, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"github.com/tendermint/tendermint/internal/mempool"
|
||||
"github.com/tendermint/tendermint/internal/state/indexer"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -20,8 +20,8 @@ import (
|
||||
// BroadcastTxAsync returns right away, with no response. Does not wait for
|
||||
// CheckTx nor DeliverTx results.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_async
|
||||
func (env *Environment) BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
err := env.Mempool.CheckTx(ctx.Context(), tx, nil, mempool.TxInfo{})
|
||||
func (env *Environment) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
err := env.Mempool.CheckTx(ctx, tx, nil, mempool.TxInfo{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -32,10 +32,10 @@ func (env *Environment) BroadcastTxAsync(ctx *rpctypes.Context, tx types.Tx) (*c
|
||||
// BroadcastTxSync returns with the response from CheckTx. Does not wait for
|
||||
// DeliverTx result.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_sync
|
||||
func (env *Environment) BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
func (env *Environment) BroadcastTxSync(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
resCh := make(chan *abci.Response, 1)
|
||||
err := env.Mempool.CheckTx(
|
||||
ctx.Context(),
|
||||
ctx,
|
||||
tx,
|
||||
func(res *abci.Response) { resCh <- res },
|
||||
mempool.TxInfo{},
|
||||
@@ -59,10 +59,10 @@ func (env *Environment) BroadcastTxSync(ctx *rpctypes.Context, tx types.Tx) (*co
|
||||
|
||||
// BroadcastTxCommit returns with the responses from CheckTx and DeliverTx.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Tx/broadcast_tx_commit
|
||||
func (env *Environment) BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
|
||||
func (env *Environment) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
|
||||
resCh := make(chan *abci.Response, 1)
|
||||
err := env.Mempool.CheckTx(
|
||||
ctx.Context(),
|
||||
ctx,
|
||||
tx,
|
||||
func(res *abci.Response) { resCh <- res },
|
||||
mempool.TxInfo{},
|
||||
@@ -89,7 +89,7 @@ func (env *Environment) BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*
|
||||
for {
|
||||
count++
|
||||
select {
|
||||
case <-ctx.Context().Done():
|
||||
case <-ctx.Done():
|
||||
env.Logger.Error("error on broadcastTxCommit",
|
||||
"duration", time.Since(startAt),
|
||||
"err", err)
|
||||
@@ -120,7 +120,7 @@ func (env *Environment) BroadcastTxCommit(ctx *rpctypes.Context, tx types.Tx) (*
|
||||
// UnconfirmedTxs gets unconfirmed transactions (maximum ?limit entries)
|
||||
// including their number.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/unconfirmed_txs
|
||||
func (env *Environment) UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
func (env *Environment) UnconfirmedTxs(ctx context.Context, limitPtr *int) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
// reuse per_page validator
|
||||
limit := env.validatePerPage(limitPtr)
|
||||
|
||||
@@ -134,7 +134,7 @@ func (env *Environment) UnconfirmedTxs(ctx *rpctypes.Context, limitPtr *int) (*c
|
||||
|
||||
// NumUnconfirmedTxs gets number of unconfirmed transactions.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/num_unconfirmed_txs
|
||||
func (env *Environment) NumUnconfirmedTxs(ctx *rpctypes.Context) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
func (env *Environment) NumUnconfirmedTxs(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
return &coretypes.ResultUnconfirmedTxs{
|
||||
Count: env.Mempool.Size(),
|
||||
Total: env.Mempool.Size(),
|
||||
@@ -144,14 +144,14 @@ func (env *Environment) NumUnconfirmedTxs(ctx *rpctypes.Context) (*coretypes.Res
|
||||
// CheckTx checks the transaction without executing it. The transaction won't
|
||||
// be added to the mempool either.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx
|
||||
func (env *Environment) CheckTx(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) {
|
||||
res, err := env.ProxyAppMempool.CheckTxSync(ctx.Context(), abci.RequestCheckTx{Tx: tx})
|
||||
func (env *Environment) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) {
|
||||
res, err := env.ProxyAppMempool.CheckTxSync(ctx, abci.RequestCheckTx{Tx: tx})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &coretypes.ResultCheckTx{ResponseCheckTx: *res}, nil
|
||||
}
|
||||
|
||||
func (env *Environment) RemoveTx(ctx *rpctypes.Context, txkey types.TxKey) error {
|
||||
func (env *Environment) RemoveTx(ctx context.Context, txkey types.TxKey) error {
|
||||
return env.Mempool.RemoveTxByKey(txkey)
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
|
||||
// NetInfo returns network info.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/net_info
|
||||
func (env *Environment) NetInfo(ctx *rpctypes.Context) (*coretypes.ResultNetInfo, error) {
|
||||
func (env *Environment) NetInfo(ctx context.Context) (*coretypes.ResultNetInfo, error) {
|
||||
peerList := env.PeerManager.Peers()
|
||||
|
||||
peers := make([]coretypes.Peer, 0, len(peerList))
|
||||
@@ -36,7 +36,7 @@ func (env *Environment) NetInfo(ctx *rpctypes.Context) (*coretypes.ResultNetInfo
|
||||
|
||||
// Genesis returns genesis file.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/genesis
|
||||
func (env *Environment) Genesis(ctx *rpctypes.Context) (*coretypes.ResultGenesis, error) {
|
||||
func (env *Environment) Genesis(ctx context.Context) (*coretypes.ResultGenesis, error) {
|
||||
if len(env.genChunks) > 1 {
|
||||
return nil, errors.New("genesis response is large, please use the genesis_chunked API instead")
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func (env *Environment) Genesis(ctx *rpctypes.Context) (*coretypes.ResultGenesis
|
||||
return &coretypes.ResultGenesis{Genesis: env.GenDoc}, nil
|
||||
}
|
||||
|
||||
func (env *Environment) GenesisChunked(ctx *rpctypes.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
|
||||
func (env *Environment) GenesisChunked(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
|
||||
if env.genChunks == nil {
|
||||
return nil, fmt.Errorf("service configuration error, genesis chunks are not initialized")
|
||||
}
|
||||
|
||||
+30
-30
@@ -17,46 +17,46 @@ func (env *Environment) GetRoutes() RoutesMap {
|
||||
"unsubscribe_all": rpc.NewWSRPCFunc(env.UnsubscribeAll, ""),
|
||||
|
||||
// info API
|
||||
"health": rpc.NewRPCFunc(env.Health, "", false),
|
||||
"status": rpc.NewRPCFunc(env.Status, "", false),
|
||||
"net_info": rpc.NewRPCFunc(env.NetInfo, "", false),
|
||||
"blockchain": rpc.NewRPCFunc(env.BlockchainInfo, "minHeight,maxHeight", true),
|
||||
"genesis": rpc.NewRPCFunc(env.Genesis, "", true),
|
||||
"genesis_chunked": rpc.NewRPCFunc(env.GenesisChunked, "chunk", true),
|
||||
"header": rpc.NewRPCFunc(env.Header, "height", true),
|
||||
"header_by_hash": rpc.NewRPCFunc(env.HeaderByHash, "hash", true),
|
||||
"block": rpc.NewRPCFunc(env.Block, "height", true),
|
||||
"block_by_hash": rpc.NewRPCFunc(env.BlockByHash, "hash", true),
|
||||
"block_results": rpc.NewRPCFunc(env.BlockResults, "height", true),
|
||||
"commit": rpc.NewRPCFunc(env.Commit, "height", true),
|
||||
"check_tx": rpc.NewRPCFunc(env.CheckTx, "tx", true),
|
||||
"remove_tx": rpc.NewRPCFunc(env.RemoveTx, "txkey", false),
|
||||
"tx": rpc.NewRPCFunc(env.Tx, "hash,prove", true),
|
||||
"tx_search": rpc.NewRPCFunc(env.TxSearch, "query,prove,page,per_page,order_by", false),
|
||||
"block_search": rpc.NewRPCFunc(env.BlockSearch, "query,page,per_page,order_by", false),
|
||||
"validators": rpc.NewRPCFunc(env.Validators, "height,page,per_page", true),
|
||||
"dump_consensus_state": rpc.NewRPCFunc(env.DumpConsensusState, "", false),
|
||||
"consensus_state": rpc.NewRPCFunc(env.GetConsensusState, "", false),
|
||||
"consensus_params": rpc.NewRPCFunc(env.ConsensusParams, "height", true),
|
||||
"unconfirmed_txs": rpc.NewRPCFunc(env.UnconfirmedTxs, "limit", false),
|
||||
"num_unconfirmed_txs": rpc.NewRPCFunc(env.NumUnconfirmedTxs, "", false),
|
||||
"health": rpc.NewRPCFunc(env.Health, ""),
|
||||
"status": rpc.NewRPCFunc(env.Status, ""),
|
||||
"net_info": rpc.NewRPCFunc(env.NetInfo, ""),
|
||||
"blockchain": rpc.NewRPCFunc(env.BlockchainInfo, "minHeight,maxHeight"),
|
||||
"genesis": rpc.NewRPCFunc(env.Genesis, ""),
|
||||
"genesis_chunked": rpc.NewRPCFunc(env.GenesisChunked, "chunk"),
|
||||
"header": rpc.NewRPCFunc(env.Header, "height"),
|
||||
"header_by_hash": rpc.NewRPCFunc(env.HeaderByHash, "hash"),
|
||||
"block": rpc.NewRPCFunc(env.Block, "height"),
|
||||
"block_by_hash": rpc.NewRPCFunc(env.BlockByHash, "hash"),
|
||||
"block_results": rpc.NewRPCFunc(env.BlockResults, "height"),
|
||||
"commit": rpc.NewRPCFunc(env.Commit, "height"),
|
||||
"check_tx": rpc.NewRPCFunc(env.CheckTx, "tx"),
|
||||
"remove_tx": rpc.NewRPCFunc(env.RemoveTx, "txkey"),
|
||||
"tx": rpc.NewRPCFunc(env.Tx, "hash,prove"),
|
||||
"tx_search": rpc.NewRPCFunc(env.TxSearch, "query,prove,page,per_page,order_by"),
|
||||
"block_search": rpc.NewRPCFunc(env.BlockSearch, "query,page,per_page,order_by"),
|
||||
"validators": rpc.NewRPCFunc(env.Validators, "height,page,per_page"),
|
||||
"dump_consensus_state": rpc.NewRPCFunc(env.DumpConsensusState, ""),
|
||||
"consensus_state": rpc.NewRPCFunc(env.GetConsensusState, ""),
|
||||
"consensus_params": rpc.NewRPCFunc(env.ConsensusParams, "height"),
|
||||
"unconfirmed_txs": rpc.NewRPCFunc(env.UnconfirmedTxs, "limit"),
|
||||
"num_unconfirmed_txs": rpc.NewRPCFunc(env.NumUnconfirmedTxs, ""),
|
||||
|
||||
// tx broadcast API
|
||||
"broadcast_tx_commit": rpc.NewRPCFunc(env.BroadcastTxCommit, "tx", false),
|
||||
"broadcast_tx_sync": rpc.NewRPCFunc(env.BroadcastTxSync, "tx", false),
|
||||
"broadcast_tx_async": rpc.NewRPCFunc(env.BroadcastTxAsync, "tx", false),
|
||||
"broadcast_tx_commit": rpc.NewRPCFunc(env.BroadcastTxCommit, "tx"),
|
||||
"broadcast_tx_sync": rpc.NewRPCFunc(env.BroadcastTxSync, "tx"),
|
||||
"broadcast_tx_async": rpc.NewRPCFunc(env.BroadcastTxAsync, "tx"),
|
||||
|
||||
// abci API
|
||||
"abci_query": rpc.NewRPCFunc(env.ABCIQuery, "path,data,height,prove", false),
|
||||
"abci_info": rpc.NewRPCFunc(env.ABCIInfo, "", true),
|
||||
"abci_query": rpc.NewRPCFunc(env.ABCIQuery, "path,data,height,prove"),
|
||||
"abci_info": rpc.NewRPCFunc(env.ABCIInfo, ""),
|
||||
|
||||
// evidence API
|
||||
"broadcast_evidence": rpc.NewRPCFunc(env.BroadcastEvidence, "evidence", false),
|
||||
"broadcast_evidence": rpc.NewRPCFunc(env.BroadcastEvidence, "evidence"),
|
||||
}
|
||||
}
|
||||
|
||||
// AddUnsafeRoutes adds unsafe routes.
|
||||
func (env *Environment) AddUnsafe(routes RoutesMap) {
|
||||
// control API
|
||||
routes["unsafe_flush_mempool"] = rpc.NewRPCFunc(env.UnsafeFlushMempool, "", false)
|
||||
routes["unsafe_flush_mempool"] = rpc.NewRPCFunc(env.UnsafeFlushMempool, "")
|
||||
}
|
||||
|
||||
@@ -2,18 +2,18 @@ package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
tmbytes "github.com/tendermint/tendermint/libs/bytes"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// Status returns Tendermint status including node info, pubkey, latest block
|
||||
// hash, app hash, block height, current max peer block height, and time.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/status
|
||||
func (env *Environment) Status(ctx *rpctypes.Context) (*coretypes.ResultStatus, error) {
|
||||
func (env *Environment) Status(ctx context.Context) (*coretypes.ResultStatus, error) {
|
||||
var (
|
||||
earliestBlockHeight int64
|
||||
earliestBlockHash tmbytes.HexBytes
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
@@ -10,7 +11,6 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
tmmath "github.com/tendermint/tendermint/libs/math"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
// transaction is in the mempool, invalidated, or was not sent in the first
|
||||
// place.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/tx
|
||||
func (env *Environment) Tx(ctx *rpctypes.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) {
|
||||
func (env *Environment) Tx(ctx context.Context, hash bytes.HexBytes, prove bool) (*coretypes.ResultTx, error) {
|
||||
// if index is disabled, return error
|
||||
|
||||
// N.B. The hash parameter is HexBytes so that the reflective parameter
|
||||
@@ -63,7 +63,7 @@ func (env *Environment) Tx(ctx *rpctypes.Context, hash bytes.HexBytes, prove boo
|
||||
// list of transactions (maximum ?per_page entries) and the total count.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Info/tx_search
|
||||
func (env *Environment) TxSearch(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
query string,
|
||||
prove bool,
|
||||
pagePtr, perPagePtr *int,
|
||||
@@ -83,7 +83,7 @@ func (env *Environment) TxSearch(
|
||||
|
||||
for _, sink := range env.EventSinks {
|
||||
if sink.Type() == indexer.KV {
|
||||
results, err := sink.SearchTxEvents(ctx.Context(), q)
|
||||
results, err := sink.SearchTxEvents(ctx, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto/encoding"
|
||||
"github.com/tendermint/tendermint/internal/eventbus"
|
||||
"github.com/tendermint/tendermint/internal/libs/fail"
|
||||
"github.com/tendermint/tendermint/internal/mempool"
|
||||
"github.com/tendermint/tendermint/internal/proxy"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
@@ -171,15 +170,11 @@ func (blockExec *BlockExecutor) ApplyBlock(
|
||||
return state, ErrProxyAppConn(err)
|
||||
}
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Save the results before we commit.
|
||||
if err := blockExec.store.SaveABCIResponses(block.Height, abciResponses); err != nil {
|
||||
return state, err
|
||||
}
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// validate the validator updates and convert to tendermint types
|
||||
abciValUpdates := abciResponses.EndBlock.ValidatorUpdates
|
||||
err = validateValidatorUpdates(abciValUpdates, state.ConsensusParams.Validator)
|
||||
@@ -210,16 +205,12 @@ func (blockExec *BlockExecutor) ApplyBlock(
|
||||
// Update evpool with the latest state.
|
||||
blockExec.evpool.Update(state, block.Evidence.Evidence)
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Update the app hash and save the state.
|
||||
state.AppHash = appHash
|
||||
if err := blockExec.store.Save(state); err != nil {
|
||||
return state, err
|
||||
}
|
||||
|
||||
fail.Fail() // XXX
|
||||
|
||||
// Prune old heights, if requested by ABCI app.
|
||||
if retainHeight > 0 {
|
||||
pruned, err := blockExec.pruneBlocks(retainHeight)
|
||||
|
||||
@@ -40,6 +40,7 @@ func newTestApp() proxy.AppConns {
|
||||
|
||||
func makeAndCommitGoodBlock(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
state sm.State,
|
||||
height int64,
|
||||
lastCommit *types.Commit,
|
||||
@@ -47,64 +48,59 @@ func makeAndCommitGoodBlock(
|
||||
blockExec *sm.BlockExecutor,
|
||||
privVals map[string]types.PrivValidator,
|
||||
evidence []types.Evidence,
|
||||
) (sm.State, types.BlockID, *types.Commit, error) {
|
||||
) (sm.State, types.BlockID, *types.Commit) {
|
||||
t.Helper()
|
||||
|
||||
// A good block passes
|
||||
state, blockID, err := makeAndApplyGoodBlock(ctx, state, height, lastCommit, proposerAddr, blockExec, evidence)
|
||||
if err != nil {
|
||||
return state, types.BlockID{}, nil, err
|
||||
}
|
||||
state, blockID := makeAndApplyGoodBlock(ctx, t, state, height, lastCommit, proposerAddr, blockExec, evidence)
|
||||
|
||||
// Simulate a lastCommit for this block from all validators for the next height
|
||||
commit, err := makeValidCommit(ctx, height, blockID, state.Validators, privVals)
|
||||
if err != nil {
|
||||
return state, types.BlockID{}, nil, err
|
||||
}
|
||||
return state, blockID, commit, nil
|
||||
commit := makeValidCommit(ctx, t, height, blockID, state.Validators, privVals)
|
||||
|
||||
return state, blockID, commit
|
||||
}
|
||||
|
||||
func makeAndApplyGoodBlock(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
state sm.State,
|
||||
height int64,
|
||||
lastCommit *types.Commit,
|
||||
proposerAddr []byte,
|
||||
blockExec *sm.BlockExecutor,
|
||||
evidence []types.Evidence,
|
||||
) (sm.State, types.BlockID, error) {
|
||||
) (sm.State, types.BlockID) {
|
||||
t.Helper()
|
||||
block, _, err := state.MakeBlock(height, factory.MakeTenTxs(height), lastCommit, evidence, proposerAddr)
|
||||
if err != nil {
|
||||
return state, types.BlockID{}, err
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
if err := blockExec.ValidateBlock(state, block); err != nil {
|
||||
return state, types.BlockID{}, err
|
||||
}
|
||||
require.NoError(t, blockExec.ValidateBlock(state, block))
|
||||
blockID := types.BlockID{Hash: block.Hash(),
|
||||
PartSetHeader: types.PartSetHeader{Total: 3, Hash: tmrand.Bytes(32)}}
|
||||
state, err = blockExec.ApplyBlock(ctx, state, blockID, block)
|
||||
if err != nil {
|
||||
return state, types.BlockID{}, err
|
||||
}
|
||||
return state, blockID, nil
|
||||
require.NoError(t, err)
|
||||
|
||||
return state, blockID
|
||||
}
|
||||
|
||||
func makeValidCommit(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
height int64,
|
||||
blockID types.BlockID,
|
||||
vals *types.ValidatorSet,
|
||||
privVals map[string]types.PrivValidator,
|
||||
) (*types.Commit, error) {
|
||||
) *types.Commit {
|
||||
t.Helper()
|
||||
sigs := make([]types.CommitSig, 0)
|
||||
for i := 0; i < vals.Size(); i++ {
|
||||
_, val := vals.GetByIndex(int32(i))
|
||||
vote, err := factory.MakeVote(ctx, privVals[val.Address.String()], chainID, int32(i), height, 0, 2, blockID, time.Now())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
require.NoError(t, err)
|
||||
sigs = append(sigs, vote.CommitSig())
|
||||
}
|
||||
return types.NewCommit(height, 0, blockID, sigs), nil
|
||||
|
||||
return types.NewCommit(height, 0, blockID, sigs)
|
||||
}
|
||||
|
||||
func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) {
|
||||
@@ -263,9 +259,16 @@ func makeRandomStateFromValidatorSet(
|
||||
}
|
||||
}
|
||||
|
||||
func makeRandomStateFromConsensusParams(ctx context.Context, consensusParams *types.ConsensusParams,
|
||||
height, lastHeightConsensusParamsChanged int64) sm.State {
|
||||
val, _ := factory.RandValidator(ctx, true, 10)
|
||||
func makeRandomStateFromConsensusParams(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
consensusParams *types.ConsensusParams,
|
||||
height,
|
||||
lastHeightConsensusParamsChanged int64,
|
||||
) sm.State {
|
||||
t.Helper()
|
||||
val, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
valSet := types.NewValidatorSet([]*types.Validator{val})
|
||||
return sm.State{
|
||||
LastBlockHeight: height - 1,
|
||||
|
||||
@@ -113,7 +113,7 @@ func TestRollbackDifferentStateHeight(t *testing.T) {
|
||||
|
||||
func setupStateStore(ctx context.Context, t *testing.T, height int64) state.Store {
|
||||
stateStore := state.NewStore(dbm.NewMemDB())
|
||||
valSet, _ := factory.RandValidatorSet(ctx, 5, 10)
|
||||
valSet, _ := factory.RandValidatorSet(ctx, t, 5, 10)
|
||||
|
||||
params := types.DefaultConsensusParams()
|
||||
params.Version.AppVersion = 10
|
||||
|
||||
@@ -32,13 +32,15 @@ func TestStoreBootstrap(t *testing.T) {
|
||||
|
||||
stateDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
val, _ := factory.RandValidator(ctx, true, 10)
|
||||
val2, _ := factory.RandValidator(ctx, true, 10)
|
||||
val3, _ := factory.RandValidator(ctx, true, 10)
|
||||
val, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
val2, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
val3, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
vals := types.NewValidatorSet([]*types.Validator{val, val2, val3})
|
||||
bootstrapState := makeRandomStateFromValidatorSet(vals, 100, 100)
|
||||
err := stateStore.Bootstrap(bootstrapState)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, stateStore.Bootstrap(bootstrapState))
|
||||
|
||||
// bootstrap should also save the previous validator
|
||||
_, err = stateStore.LoadValidators(99)
|
||||
@@ -61,17 +63,18 @@ func TestStoreLoadValidators(t *testing.T) {
|
||||
|
||||
stateDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
val, _ := factory.RandValidator(ctx, true, 10)
|
||||
val2, _ := factory.RandValidator(ctx, true, 10)
|
||||
val3, _ := factory.RandValidator(ctx, true, 10)
|
||||
val, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
val2, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
val3, _, err := factory.RandValidator(ctx, true, 10)
|
||||
require.NoError(t, err)
|
||||
vals := types.NewValidatorSet([]*types.Validator{val, val2, val3})
|
||||
|
||||
// 1) LoadValidators loads validators using a height where they were last changed
|
||||
// Note that only the next validators at height h + 1 are saved
|
||||
err := stateStore.Save(makeRandomStateFromValidatorSet(vals, 1, 1))
|
||||
require.NoError(t, err)
|
||||
err = stateStore.Save(makeRandomStateFromValidatorSet(vals.CopyIncrementProposerPriority(1), 2, 1))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, stateStore.Save(makeRandomStateFromValidatorSet(vals, 1, 1)))
|
||||
require.NoError(t, stateStore.Save(makeRandomStateFromValidatorSet(vals.CopyIncrementProposerPriority(1), 2, 1)))
|
||||
loadedVals, err := stateStore.LoadValidators(3)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, vals.CopyIncrementProposerPriority(3), loadedVals)
|
||||
@@ -153,7 +156,7 @@ func TestStoreLoadConsensusParams(t *testing.T) {
|
||||
|
||||
stateDB := dbm.NewMemDB()
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
err := stateStore.Save(makeRandomStateFromConsensusParams(ctx, types.DefaultConsensusParams(), 1, 1))
|
||||
err := stateStore.Save(makeRandomStateFromConsensusParams(ctx, t, types.DefaultConsensusParams(), 1, 1))
|
||||
require.NoError(t, err)
|
||||
params, err := stateStore.LoadConsensusParams(1)
|
||||
require.NoError(t, err)
|
||||
@@ -163,7 +166,7 @@ func TestStoreLoadConsensusParams(t *testing.T) {
|
||||
// it should save a pointer to the params at height 1
|
||||
differentParams := types.DefaultConsensusParams()
|
||||
differentParams.Block.MaxBytes = 20000
|
||||
err = stateStore.Save(makeRandomStateFromConsensusParams(ctx, differentParams, 10, 1))
|
||||
err = stateStore.Save(makeRandomStateFromConsensusParams(ctx, t, differentParams, 10, 1))
|
||||
require.NoError(t, err)
|
||||
res, err := stateStore.LoadConsensusParams(10)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -2,14 +2,18 @@ package factory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
"github.com/tendermint/tendermint/internal/test/factory"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
func MakeBlocks(ctx context.Context, n int, state *sm.State, privVal types.PrivValidator) ([]*types.Block, error) {
|
||||
func MakeBlocks(ctx context.Context, t *testing.T, n int, state *sm.State, privVal types.PrivValidator) []*types.Block {
|
||||
t.Helper()
|
||||
|
||||
blocks := make([]*types.Block, n)
|
||||
|
||||
var (
|
||||
@@ -21,10 +25,7 @@ func MakeBlocks(ctx context.Context, n int, state *sm.State, privVal types.PrivV
|
||||
for i := 0; i < n; i++ {
|
||||
height := int64(i + 1)
|
||||
|
||||
block, parts, err := makeBlockAndPartSet(ctx, *state, prevBlock, prevBlockMeta, privVal, height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
block, parts := makeBlockAndPartSet(ctx, t, *state, prevBlock, prevBlockMeta, privVal, height)
|
||||
|
||||
blocks[i] = block
|
||||
|
||||
@@ -37,7 +38,7 @@ func MakeBlocks(ctx context.Context, n int, state *sm.State, privVal types.PrivV
|
||||
state.LastBlockHeight = height
|
||||
}
|
||||
|
||||
return blocks, nil
|
||||
return blocks
|
||||
}
|
||||
|
||||
func MakeBlock(state sm.State, height int64, c *types.Commit) (*types.Block, error) {
|
||||
@@ -57,24 +58,31 @@ func MakeBlock(state sm.State, height int64, c *types.Commit) (*types.Block, err
|
||||
|
||||
func makeBlockAndPartSet(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
state sm.State,
|
||||
lastBlock *types.Block,
|
||||
lastBlockMeta *types.BlockMeta,
|
||||
privVal types.PrivValidator,
|
||||
height int64,
|
||||
) (*types.Block, *types.PartSet, error) {
|
||||
) (*types.Block, *types.PartSet) {
|
||||
t.Helper()
|
||||
|
||||
lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
|
||||
if height > 1 {
|
||||
vote, _ := factory.MakeVote(
|
||||
vote, err := factory.MakeVote(
|
||||
ctx,
|
||||
privVal,
|
||||
lastBlock.Header.ChainID,
|
||||
1, lastBlock.Header.Height, 0, 2,
|
||||
lastBlockMeta.BlockID,
|
||||
time.Now())
|
||||
require.NoError(t, err)
|
||||
lastCommit = types.NewCommit(vote.Height, vote.Round,
|
||||
lastBlockMeta.BlockID, []types.CommitSig{vote.CommitSig()})
|
||||
}
|
||||
|
||||
return state.MakeBlock(height, []types.Tx{}, lastCommit, nil, state.Validators.GetProposer().Address)
|
||||
block, partSet, err := state.MakeBlock(height, []types.Tx{}, lastCommit, nil, state.Validators.GetProposer().Address)
|
||||
require.NoError(t, err)
|
||||
|
||||
return block, partSet
|
||||
}
|
||||
|
||||
@@ -103,10 +103,8 @@ func TestValidateBlockHeader(t *testing.T) {
|
||||
/*
|
||||
A good block passes
|
||||
*/
|
||||
var err error
|
||||
state, _, lastCommit, err = makeAndCommitGoodBlock(ctx,
|
||||
state, _, lastCommit = makeAndCommitGoodBlock(ctx, t,
|
||||
state, height, lastCommit, state.Validators.GetProposer().Address, blockExec, privVals, nil)
|
||||
require.NoError(t, err, "height %d", height)
|
||||
}
|
||||
|
||||
nextHeight := validationTestsStopHeight
|
||||
@@ -158,7 +156,7 @@ func TestValidateBlockCommit(t *testing.T) {
|
||||
state.LastBlockID,
|
||||
time.Now(),
|
||||
)
|
||||
require.NoError(t, err, "height %d", height)
|
||||
require.NoError(t, err)
|
||||
wrongHeightCommit := types.NewCommit(
|
||||
wrongHeightVote.Height,
|
||||
wrongHeightVote.Round,
|
||||
@@ -188,10 +186,10 @@ func TestValidateBlockCommit(t *testing.T) {
|
||||
/*
|
||||
A good block passes
|
||||
*/
|
||||
var err error
|
||||
var blockID types.BlockID
|
||||
state, blockID, lastCommit, err = makeAndCommitGoodBlock(
|
||||
state, blockID, lastCommit = makeAndCommitGoodBlock(
|
||||
ctx,
|
||||
t,
|
||||
state,
|
||||
height,
|
||||
lastCommit,
|
||||
@@ -200,7 +198,6 @@ func TestValidateBlockCommit(t *testing.T) {
|
||||
privVals,
|
||||
nil,
|
||||
)
|
||||
require.NoError(t, err, "height %d", height)
|
||||
|
||||
/*
|
||||
wrongSigsCommit is fine except for the extra bad precommit
|
||||
@@ -216,8 +213,7 @@ func TestValidateBlockCommit(t *testing.T) {
|
||||
blockID,
|
||||
time.Now(),
|
||||
)
|
||||
require.NoError(t, err, "height %d", height)
|
||||
|
||||
require.NoError(t, err)
|
||||
bpvPubKey, err := badPrivVal.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -319,9 +315,9 @@ func TestValidateBlockEvidence(t *testing.T) {
|
||||
evidence = append(evidence, newEv)
|
||||
}
|
||||
|
||||
var err error
|
||||
state, _, lastCommit, err = makeAndCommitGoodBlock(
|
||||
state, _, lastCommit = makeAndCommitGoodBlock(
|
||||
ctx,
|
||||
t,
|
||||
state,
|
||||
height,
|
||||
lastCommit,
|
||||
@@ -330,6 +326,6 @@ func TestValidateBlockEvidence(t *testing.T) {
|
||||
privVals,
|
||||
evidence,
|
||||
)
|
||||
require.NoError(t, err, "height %d", height)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ loop:
|
||||
|
||||
func mockLBResp(ctx context.Context, t *testing.T, peer types.NodeID, height int64, time time.Time) lightBlockResponse {
|
||||
t.Helper()
|
||||
vals, pv := factory.RandValidatorSet(ctx, 3, 10)
|
||||
vals, pv := factory.RandValidatorSet(ctx, t, 3, 10)
|
||||
_, _, lb := mockLB(ctx, t, height, time, factory.MakeBlockID(), vals, pv)
|
||||
return lightBlockResponse{
|
||||
block: lb,
|
||||
|
||||
@@ -76,7 +76,7 @@ func TestDispatcherReturnsNoBlock(t *testing.T) {
|
||||
|
||||
d := NewDispatcher(ch)
|
||||
|
||||
peer := factory.NodeID("a")
|
||||
peer := factory.NodeID(t, "a")
|
||||
|
||||
go func() {
|
||||
<-chans.Out
|
||||
@@ -99,7 +99,7 @@ func TestDispatcherTimeOutWaitingOnLightBlock(t *testing.T) {
|
||||
|
||||
_, ch := testChannel(100)
|
||||
d := NewDispatcher(ch)
|
||||
peer := factory.NodeID("a")
|
||||
peer := factory.NodeID(t, "a")
|
||||
|
||||
ctx, cancelFunc := context.WithTimeout(ctx, 10*time.Millisecond)
|
||||
defer cancelFunc()
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/internal/eventbus"
|
||||
"github.com/tendermint/tendermint/internal/p2p"
|
||||
"github.com/tendermint/tendermint/internal/proxy"
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
@@ -156,6 +157,7 @@ type Reactor struct {
|
||||
providers map[types.NodeID]*BlockProvider
|
||||
stateProvider StateProvider
|
||||
|
||||
eventBus *eventbus.EventBus
|
||||
metrics *Metrics
|
||||
backfillBlockTotal int64
|
||||
backfilledBlocks int64
|
||||
@@ -179,6 +181,7 @@ func NewReactor(
|
||||
blockStore *store.BlockStore,
|
||||
tempDir string,
|
||||
ssMetrics *Metrics,
|
||||
eventBus *eventbus.EventBus,
|
||||
) (*Reactor, error) {
|
||||
|
||||
chDesc := getChannelDescriptors()
|
||||
@@ -219,6 +222,7 @@ func NewReactor(
|
||||
dispatcher: NewDispatcher(blockCh),
|
||||
providers: make(map[types.NodeID]*BlockProvider),
|
||||
metrics: ssMetrics,
|
||||
eventBus: eventBus,
|
||||
}
|
||||
|
||||
r.BaseService = *service.NewBaseService(logger, "StateSync", r)
|
||||
@@ -248,6 +252,14 @@ func (r *Reactor) OnStop() {
|
||||
r.dispatcher.Close()
|
||||
}
|
||||
|
||||
func (r *Reactor) PublishStatus(ctx context.Context, event types.EventDataStateSyncStatus) error {
|
||||
if r.eventBus == nil {
|
||||
return errors.New("event system is not configured")
|
||||
}
|
||||
|
||||
return r.eventBus.PublishEventStateSyncStatus(ctx, event)
|
||||
}
|
||||
|
||||
// Sync runs a state sync, fetching snapshots and providing chunks to the
|
||||
// application. At the close of the operation, Sync will bootstrap the state
|
||||
// store and persist the commit at that height so that either consensus or
|
||||
@@ -887,7 +899,6 @@ func (r *Reactor) processPeerUpdates(ctx context.Context) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
r.logger.Debug("stopped listening on peer updates channel; closing...")
|
||||
return
|
||||
case peerUpdate := <-r.peerUpdates.Updates():
|
||||
r.processPeerUpdate(ctx, peerUpdate)
|
||||
|
||||
@@ -161,13 +161,15 @@ func setup(
|
||||
}
|
||||
}
|
||||
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
var err error
|
||||
rts.reactor, err = NewReactor(
|
||||
ctx,
|
||||
factory.DefaultTestChainID,
|
||||
1,
|
||||
*cfg,
|
||||
log.TestingLogger(),
|
||||
logger.With("component", "reactor"),
|
||||
conn,
|
||||
connQuery,
|
||||
chCreator,
|
||||
@@ -176,12 +178,13 @@ func setup(
|
||||
rts.blockStore,
|
||||
"",
|
||||
m,
|
||||
nil, // eventbus can be nil
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
rts.syncer = newSyncer(
|
||||
*cfg,
|
||||
log.NewNopLogger(),
|
||||
logger.With("component", "syncer"),
|
||||
conn,
|
||||
connQuery,
|
||||
stateProvider,
|
||||
@@ -191,13 +194,14 @@ func setup(
|
||||
rts.reactor.metrics,
|
||||
)
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
||||
require.NoError(t, rts.reactor.Start(ctx))
|
||||
require.True(t, rts.reactor.IsRunning())
|
||||
|
||||
t.Cleanup(func() {
|
||||
rts.reactor.Wait()
|
||||
require.False(t, rts.reactor.IsRunning())
|
||||
})
|
||||
t.Cleanup(cancel)
|
||||
t.Cleanup(rts.reactor.Wait)
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
|
||||
return rts
|
||||
}
|
||||
@@ -233,7 +237,7 @@ func TestReactor_Sync(t *testing.T) {
|
||||
defer close(closeCh)
|
||||
go handleLightBlockRequests(ctx, t, chain, rts.blockOutCh,
|
||||
rts.blockInCh, closeCh, 0)
|
||||
go graduallyAddPeers(rts.peerUpdateCh, closeCh, 1*time.Second)
|
||||
go graduallyAddPeers(t, rts.peerUpdateCh, closeCh, 1*time.Second)
|
||||
go handleSnapshotRequests(t, rts.snapshotOutCh, rts.snapshotInCh, closeCh, []snapshot{
|
||||
{
|
||||
Height: uint64(snapshotHeight),
|
||||
@@ -434,10 +438,11 @@ func TestReactor_LightBlockResponse(t *testing.T) {
|
||||
rts := setup(ctx, t, nil, nil, nil, 2)
|
||||
|
||||
var height int64 = 10
|
||||
h := factory.MakeRandomHeader()
|
||||
// generates a random header
|
||||
h := factory.MakeHeader(t, &types.Header{})
|
||||
h.Height = height
|
||||
blockID := factory.MakeBlockIDWithHash(h.Hash())
|
||||
vals, pv := factory.RandValidatorSet(ctx, 1, 10)
|
||||
vals, pv := factory.RandValidatorSet(ctx, t, 1, 10)
|
||||
vote, err := factory.MakeVote(ctx, pv[0], h.ChainID, 0, h.Height, 0, 2,
|
||||
blockID, factory.DefaultTestTime)
|
||||
require.NoError(t, err)
|
||||
@@ -728,7 +733,7 @@ func handleLightBlockRequests(
|
||||
} else {
|
||||
switch errorCount % 3 {
|
||||
case 0: // send a different block
|
||||
vals, pv := factory.RandValidatorSet(ctx, 3, 10)
|
||||
vals, pv := factory.RandValidatorSet(ctx, t, 3, 10)
|
||||
_, _, lb := mockLB(ctx, t, int64(msg.Height), factory.DefaultTestTime, factory.MakeBlockID(), vals, pv)
|
||||
differntLB, err := lb.ToProto()
|
||||
require.NoError(t, err)
|
||||
@@ -797,7 +802,7 @@ func buildLightBlockChain(ctx context.Context, t *testing.T, fromHeight, toHeigh
|
||||
chain := make(map[int64]*types.LightBlock, toHeight-fromHeight)
|
||||
lastBlockID := factory.MakeBlockID()
|
||||
blockTime := startTime.Add(time.Duration(fromHeight-toHeight) * time.Minute)
|
||||
vals, pv := factory.RandValidatorSet(ctx, 3, 10)
|
||||
vals, pv := factory.RandValidatorSet(ctx, t, 3, 10)
|
||||
for height := fromHeight; height < toHeight; height++ {
|
||||
vals, pv, chain[height] = mockLB(ctx, t, height, blockTime, lastBlockID, vals, pv)
|
||||
lastBlockID = factory.MakeBlockIDWithHash(chain[height].Header.Hash())
|
||||
@@ -810,14 +815,14 @@ func mockLB(ctx context.Context, t *testing.T, height int64, time time.Time, las
|
||||
currentVals *types.ValidatorSet, currentPrivVals []types.PrivValidator,
|
||||
) (*types.ValidatorSet, []types.PrivValidator, *types.LightBlock) {
|
||||
t.Helper()
|
||||
header, err := factory.MakeHeader(&types.Header{
|
||||
header := factory.MakeHeader(t, &types.Header{
|
||||
Height: height,
|
||||
LastBlockID: lastBlockID,
|
||||
Time: time,
|
||||
})
|
||||
header.Version.App = testAppVersion
|
||||
require.NoError(t, err)
|
||||
nextVals, nextPrivVals := factory.RandValidatorSet(ctx, 3, 10)
|
||||
|
||||
nextVals, nextPrivVals := factory.RandValidatorSet(ctx, t, 3, 10)
|
||||
header.ValidatorsHash = currentVals.Hash()
|
||||
header.NextValidatorsHash = nextVals.Hash()
|
||||
header.ConsensusHash = types.DefaultConsensusParams().HashConsensusParams()
|
||||
@@ -837,6 +842,7 @@ func mockLB(ctx context.Context, t *testing.T, height int64, time time.Time, las
|
||||
// graduallyAddPeers delivers a new randomly-generated peer update on peerUpdateCh once
|
||||
// per interval, until closeCh is closed. Each peer update is assigned a random node ID.
|
||||
func graduallyAddPeers(
|
||||
t *testing.T,
|
||||
peerUpdateCh chan p2p.PeerUpdate,
|
||||
closeCh chan struct{},
|
||||
interval time.Duration,
|
||||
@@ -846,7 +852,7 @@ func graduallyAddPeers(
|
||||
select {
|
||||
case <-ticker.C:
|
||||
peerUpdateCh <- p2p.PeerUpdate{
|
||||
NodeID: factory.RandomNodeID(),
|
||||
NodeID: factory.RandomNodeID(t),
|
||||
Status: p2p.PeerStatusUp,
|
||||
}
|
||||
case <-closeCh:
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
peerAID := types.NodeID("aa")
|
||||
peerBID := types.NodeID("bb")
|
||||
peerCID := types.NodeID("cc")
|
||||
rts := setup(ctx, t, connSnapshot, connQuery, stateProvider, 3)
|
||||
rts := setup(ctx, t, connSnapshot, connQuery, stateProvider, 4)
|
||||
|
||||
rts.reactor.syncer = rts.syncer
|
||||
|
||||
@@ -133,27 +133,38 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
chunkRequests := make(map[uint32]int)
|
||||
chunkRequestsMtx := sync.Mutex{}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(4)
|
||||
chunkProcessDone := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
for e := range rts.chunkOutCh {
|
||||
msg, ok := e.Message.(*ssproto.ChunkRequest)
|
||||
assert.True(t, ok)
|
||||
defer close(chunkProcessDone)
|
||||
var seen int
|
||||
for {
|
||||
if seen >= 4 {
|
||||
return
|
||||
}
|
||||
|
||||
assert.EqualValues(t, 1, msg.Height)
|
||||
assert.EqualValues(t, 1, msg.Format)
|
||||
assert.LessOrEqual(t, msg.Index, uint32(len(chunks)))
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
t.Logf("sent %d chunks", seen)
|
||||
return
|
||||
case e := <-rts.chunkOutCh:
|
||||
msg, ok := e.Message.(*ssproto.ChunkRequest)
|
||||
assert.True(t, ok)
|
||||
|
||||
added, err := rts.syncer.AddChunk(chunks[msg.Index])
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, added)
|
||||
assert.EqualValues(t, 1, msg.Height)
|
||||
assert.EqualValues(t, 1, msg.Format)
|
||||
assert.LessOrEqual(t, msg.Index, uint32(len(chunks)))
|
||||
|
||||
chunkRequestsMtx.Lock()
|
||||
chunkRequests[msg.Index]++
|
||||
chunkRequestsMtx.Unlock()
|
||||
added, err := rts.syncer.AddChunk(chunks[msg.Index])
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, added)
|
||||
|
||||
wg.Done()
|
||||
chunkRequestsMtx.Lock()
|
||||
chunkRequests[msg.Index]++
|
||||
chunkRequestsMtx.Unlock()
|
||||
seen++
|
||||
t.Logf("added chunk (%d of 4): %d", seen, msg.Index)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -186,7 +197,7 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
newState, lastCommit, err := rts.syncer.SyncAny(ctx, 0, func() error { return nil })
|
||||
require.NoError(t, err)
|
||||
|
||||
wg.Wait()
|
||||
<-chunkProcessDone
|
||||
|
||||
chunkRequestsMtx.Lock()
|
||||
require.Equal(t, map[uint32]int{0: 1, 1: 2, 2: 1}, chunkRequests)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package factory
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/tmhash"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -17,13 +19,6 @@ var (
|
||||
DefaultTestTime = time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
)
|
||||
|
||||
func MakeVersion() version.Consensus {
|
||||
return version.Consensus{
|
||||
Block: version.BlockProtocol,
|
||||
App: 1,
|
||||
}
|
||||
}
|
||||
|
||||
func RandomAddress() []byte {
|
||||
return crypto.CRandBytes(crypto.AddressSize)
|
||||
}
|
||||
@@ -48,7 +43,8 @@ func MakeBlockIDWithHash(hash []byte) types.BlockID {
|
||||
|
||||
// MakeHeader fills the rest of the contents of the header such that it passes
|
||||
// validate basic
|
||||
func MakeHeader(h *types.Header) (*types.Header, error) {
|
||||
func MakeHeader(t *testing.T, h *types.Header) *types.Header {
|
||||
t.Helper()
|
||||
if h.Version.Block == 0 {
|
||||
h.Version.Block = version.BlockProtocol
|
||||
}
|
||||
@@ -89,13 +85,7 @@ func MakeHeader(h *types.Header) (*types.Header, error) {
|
||||
h.ProposerAddress = RandomAddress()
|
||||
}
|
||||
|
||||
return h, h.ValidateBasic()
|
||||
}
|
||||
require.NoError(t, h.ValidateBasic())
|
||||
|
||||
func MakeRandomHeader() *types.Header {
|
||||
h, err := MakeHeader(&types.Header{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package factory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
|
||||
@@ -10,12 +9,11 @@ import (
|
||||
)
|
||||
|
||||
func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round int32, voteSet *types.VoteSet, validators []types.PrivValidator, now time.Time) (*types.Commit, error) {
|
||||
|
||||
// all sign
|
||||
for i := 0; i < len(validators); i++ {
|
||||
pubKey, err := validators[i].GetPubKey(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get pubkey: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
vote := &types.Vote{
|
||||
ValidatorAddress: pubKey.Address(),
|
||||
@@ -27,21 +25,16 @@ func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round
|
||||
Timestamp: now,
|
||||
}
|
||||
|
||||
_, err = signAddVote(ctx, validators[i], vote, voteSet)
|
||||
if err != nil {
|
||||
v := vote.ToProto()
|
||||
|
||||
if err := validators[i].SignVote(ctx, voteSet.ChainID(), v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vote.Signature = v.Signature
|
||||
if _, err := voteSet.AddVote(vote); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return voteSet.MakeCommit(), nil
|
||||
}
|
||||
|
||||
func signAddVote(ctx context.Context, privVal types.PrivValidator, vote *types.Vote, voteSet *types.VoteSet) (signed bool, err error) {
|
||||
v := vote.ToProto()
|
||||
err = privVal.SignVote(ctx, voteSet.ChainID(), v)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
vote.Signature = v.Signature
|
||||
return voteSet.AddVote(vote)
|
||||
}
|
||||
|
||||
@@ -3,16 +3,13 @@ package factory
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
func TestMakeHeader(t *testing.T) {
|
||||
_, err := MakeHeader(&types.Header{})
|
||||
assert.NoError(t, err)
|
||||
MakeHeader(t, &types.Header{})
|
||||
}
|
||||
|
||||
func TestRandomNodeID(t *testing.T) {
|
||||
assert.NotPanics(t, func() { RandomNodeID() })
|
||||
RandomNodeID(t)
|
||||
}
|
||||
|
||||
@@ -3,24 +3,22 @@ package factory
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/config"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
func RandGenesisDoc(
|
||||
ctx context.Context,
|
||||
cfg *config.Config,
|
||||
numValidators int,
|
||||
randPower bool,
|
||||
minPower int64,
|
||||
) (*types.GenesisDoc, []types.PrivValidator) {
|
||||
func RandGenesisDoc(ctx context.Context, t *testing.T, cfg *config.Config, numValidators int, randPower bool, minPower int64) (*types.GenesisDoc, []types.PrivValidator) {
|
||||
t.Helper()
|
||||
|
||||
validators := make([]types.GenesisValidator, numValidators)
|
||||
privValidators := make([]types.PrivValidator, numValidators)
|
||||
for i := 0; i < numValidators; i++ {
|
||||
val, privVal := RandValidator(ctx, randPower, minPower)
|
||||
val, privVal, err := RandValidator(ctx, randPower, minPower)
|
||||
require.NoError(t, err)
|
||||
validators[i] = types.GenesisValidator{
|
||||
PubKey: val.PubKey,
|
||||
Power: val.VotingPower,
|
||||
|
||||
@@ -3,25 +3,29 @@ package factory
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/libs/rand"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// NodeID returns a valid NodeID based on an inputted string
|
||||
func NodeID(str string) types.NodeID {
|
||||
func NodeID(t *testing.T, str string) types.NodeID {
|
||||
t.Helper()
|
||||
|
||||
id, err := types.NewNodeID(strings.Repeat(str, 2*types.NodeIDByteLength))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
// RandomNodeID returns a randomly generated valid NodeID
|
||||
func RandomNodeID() types.NodeID {
|
||||
func RandomNodeID(t *testing.T) types.NodeID {
|
||||
t.Helper()
|
||||
|
||||
id, err := types.NewNodeID(hex.EncodeToString(rand.Bytes(types.NodeIDByteLength)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
@@ -2,15 +2,10 @@ package factory
|
||||
|
||||
import "github.com/tendermint/tendermint/types"
|
||||
|
||||
// MakeTxs is a helper function to generate mock transactions by given the block height
|
||||
// and the transaction numbers.
|
||||
func MakeTxs(height int64, num int) (txs []types.Tx) {
|
||||
for i := 0; i < num; i++ {
|
||||
txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
|
||||
func MakeTenTxs(height int64) []types.Tx {
|
||||
txs := make([]types.Tx, 10)
|
||||
for i := range txs {
|
||||
txs[i] = types.Tx([]byte{byte(height), byte(i)})
|
||||
}
|
||||
return txs
|
||||
}
|
||||
|
||||
func MakeTenTxs(height int64) (txs []types.Tx) {
|
||||
return MakeTxs(height, 10)
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
func RandValidator(ctx context.Context, randPower bool, minPower int64) (*types.Validator, types.PrivValidator) {
|
||||
func RandValidator(ctx context.Context, randPower bool, minPower int64) (*types.Validator, types.PrivValidator, error) {
|
||||
privVal := types.NewMockPV()
|
||||
votePower := minPower
|
||||
if randPower {
|
||||
@@ -18,20 +20,23 @@ func RandValidator(ctx context.Context, randPower bool, minPower int64) (*types.
|
||||
}
|
||||
pubKey, err := privVal.GetPubKey(ctx)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("could not retrieve pubkey %w", err))
|
||||
return nil, nil, fmt.Errorf("could not retrieve public key: %w", err)
|
||||
}
|
||||
|
||||
val := types.NewValidator(pubKey, votePower)
|
||||
return val, privVal
|
||||
return val, privVal, err
|
||||
}
|
||||
|
||||
func RandValidatorSet(ctx context.Context, numValidators int, votingPower int64) (*types.ValidatorSet, []types.PrivValidator) {
|
||||
func RandValidatorSet(ctx context.Context, t *testing.T, numValidators int, votingPower int64) (*types.ValidatorSet, []types.PrivValidator) {
|
||||
var (
|
||||
valz = make([]*types.Validator, numValidators)
|
||||
privValidators = make([]types.PrivValidator, numValidators)
|
||||
)
|
||||
t.Helper()
|
||||
|
||||
for i := 0; i < numValidators; i++ {
|
||||
val, privValidator := RandValidator(ctx, false, votingPower)
|
||||
val, privValidator, err := RandValidator(ctx, false, votingPower)
|
||||
require.NoError(t, err)
|
||||
valz[i] = val
|
||||
privValidators[i] = privValidator
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ func MakeVote(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v := &types.Vote{
|
||||
ValidatorAddress: pubKey.Address(),
|
||||
ValidatorIndex: valIndex,
|
||||
@@ -34,10 +35,10 @@ func MakeVote(
|
||||
}
|
||||
|
||||
vpb := v.ToProto()
|
||||
err = val.SignVote(ctx, chainID, vpb)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if err := val.SignVote(ctx, chainID, vpb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v.Signature = vpb.Signature
|
||||
return v, nil
|
||||
}
|
||||
|
||||
+3
-10
@@ -14,8 +14,6 @@ var _ Logger = (*defaultLogger)(nil)
|
||||
|
||||
type defaultLogger struct {
|
||||
zerolog.Logger
|
||||
|
||||
trace bool
|
||||
}
|
||||
|
||||
// NewDefaultLogger returns a default logger that can be used within Tendermint
|
||||
@@ -26,7 +24,7 @@ type defaultLogger struct {
|
||||
// Since zerolog supports typed structured logging and it is difficult to reflect
|
||||
// that in a generic interface, all logging methods accept a series of key/value
|
||||
// pair tuples, where the key must be a string.
|
||||
func NewDefaultLogger(format, level string, trace bool) (Logger, error) {
|
||||
func NewDefaultLogger(format, level string) (Logger, error) {
|
||||
var logWriter io.Writer
|
||||
switch strings.ToLower(format) {
|
||||
case LogFormatPlain, LogFormatText:
|
||||
@@ -59,14 +57,13 @@ func NewDefaultLogger(format, level string, trace bool) (Logger, error) {
|
||||
|
||||
return defaultLogger{
|
||||
Logger: zerolog.New(logWriter).Level(logLevel).With().Timestamp().Logger(),
|
||||
trace: trace,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MustNewDefaultLogger delegates a call NewDefaultLogger where it panics on
|
||||
// error.
|
||||
func MustNewDefaultLogger(format, level string, trace bool) Logger {
|
||||
logger, err := NewDefaultLogger(format, level, trace)
|
||||
func MustNewDefaultLogger(format, level string) Logger {
|
||||
logger, err := NewDefaultLogger(format, level)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -80,9 +77,6 @@ func (l defaultLogger) Info(msg string, keyVals ...interface{}) {
|
||||
|
||||
func (l defaultLogger) Error(msg string, keyVals ...interface{}) {
|
||||
e := l.Logger.Error()
|
||||
if l.trace {
|
||||
e = e.Stack()
|
||||
}
|
||||
|
||||
e.Fields(getLogFields(keyVals...)).Msg(msg)
|
||||
}
|
||||
@@ -94,7 +88,6 @@ func (l defaultLogger) Debug(msg string, keyVals ...interface{}) {
|
||||
func (l defaultLogger) With(keyVals ...interface{}) Logger {
|
||||
return defaultLogger{
|
||||
Logger: l.Logger.With().Fields(getLogFields(keyVals...)).Logger(),
|
||||
trace: l.trace,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,11 +34,11 @@ func TestNewDefaultLogger(t *testing.T) {
|
||||
tc := tc
|
||||
|
||||
t.Run(name, func(t *testing.T) {
|
||||
_, err := log.NewDefaultLogger(tc.format, tc.level, false)
|
||||
_, err := log.NewDefaultLogger(tc.format, tc.level)
|
||||
if tc.expectErr {
|
||||
require.Error(t, err)
|
||||
require.Panics(t, func() {
|
||||
_ = log.MustNewDefaultLogger(tc.format, tc.level, false)
|
||||
_ = log.MustNewDefaultLogger(tc.format, tc.level)
|
||||
})
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -7,6 +7,5 @@ import (
|
||||
func NewNopLogger() Logger {
|
||||
return defaultLogger{
|
||||
Logger: zerolog.Nop(),
|
||||
trace: false,
|
||||
}
|
||||
}
|
||||
|
||||
+1
-6
@@ -32,7 +32,7 @@ func TestingLogger() Logger {
|
||||
}
|
||||
|
||||
if testing.Verbose() {
|
||||
testingLogger = MustNewDefaultLogger(LogFormatText, LogLevelDebug, true)
|
||||
testingLogger = MustNewDefaultLogger(LogFormatText, LogLevelDebug)
|
||||
} else {
|
||||
testingLogger = NewNopLogger()
|
||||
}
|
||||
@@ -73,13 +73,8 @@ func NewTestingLoggerWithLevel(t testing.TB, level string) Logger {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse log level (%s): %v", level, err)
|
||||
}
|
||||
trace := false
|
||||
if testing.Verbose() {
|
||||
trace = true
|
||||
}
|
||||
|
||||
return defaultLogger{
|
||||
Logger: zerolog.New(newSyncWriter(testingWriter{t})).Level(logLevel),
|
||||
trace: trace,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +162,6 @@ func (bs *BaseService) Start(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
bs.logger.Debug("not starting service; already started", "service", bs.name, "impl", bs.impl.String())
|
||||
return ErrAlreadyStarted
|
||||
}
|
||||
|
||||
@@ -183,7 +182,6 @@ func (bs *BaseService) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
bs.logger.Debug("not stopping service; already stopped", "service", bs.name, "impl", bs.impl.String())
|
||||
return ErrAlreadyStopped
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ func TestClient_SequentialVerification(t *testing.T) {
|
||||
|
||||
newKeys := genPrivKeys(4)
|
||||
newVals := newKeys.ToValidators(10, 1)
|
||||
differentVals, _ := factory.RandValidatorSet(ctx, 10, 100)
|
||||
differentVals, _ := factory.RandValidatorSet(ctx, t, 10, 100)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -942,7 +942,7 @@ func TestClient_TrustedValidatorSet(t *testing.T) {
|
||||
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
differentVals, _ := factory.RandValidatorSet(ctx, 10, 100)
|
||||
differentVals, _ := factory.RandValidatorSet(ctx, t, 10, 100)
|
||||
mockBadValSetNode := mockNodeFromHeadersAndVals(
|
||||
map[int64]*types.SignedHeader{
|
||||
1: h1,
|
||||
|
||||
@@ -26,7 +26,7 @@ func ExampleClient() {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
|
||||
logger, err := log.NewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
|
||||
logger, err := log.NewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo)
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func (p *Proxy) listen(ctx context.Context) (net.Listener, *http.ServeMux, error
|
||||
|
||||
// 2) Allow websocket connections.
|
||||
wmLogger := p.Logger.With("protocol", "websocket")
|
||||
wm := rpcserver.NewWebsocketManager(r,
|
||||
wm := rpcserver.NewWebsocketManager(wmLogger, r,
|
||||
rpcserver.OnDisconnect(func(remoteAddr string) {
|
||||
err := p.Client.UnsubscribeAll(context.Background(), remoteAddr)
|
||||
if err != nil && err != tmpubsub.ErrSubscriptionNotFound {
|
||||
@@ -104,7 +104,7 @@ func (p *Proxy) listen(ctx context.Context) (net.Listener, *http.ServeMux, error
|
||||
}),
|
||||
rpcserver.ReadLimit(p.Config.MaxBodyBytes),
|
||||
)
|
||||
wm.SetLogger(wmLogger)
|
||||
|
||||
mux.HandleFunc("/websocket", wm.WebsocketHandler)
|
||||
|
||||
// 3) Start a client.
|
||||
|
||||
+110
-109
@@ -1,12 +1,13 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
lrpc "github.com/tendermint/tendermint/light/rpc"
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||
"github.com/tendermint/tendermint/rpc/coretypes"
|
||||
rpcserver "github.com/tendermint/tendermint/rpc/jsonrpc/server"
|
||||
rpctypes "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -18,149 +19,149 @@ func RPCRoutes(c *lrpc.Client) map[string]*rpcserver.RPCFunc {
|
||||
"unsubscribe_all": rpcserver.NewWSRPCFunc(c.UnsubscribeAllWS, ""),
|
||||
|
||||
// info API
|
||||
"health": rpcserver.NewRPCFunc(makeHealthFunc(c), "", false),
|
||||
"status": rpcserver.NewRPCFunc(makeStatusFunc(c), "", false),
|
||||
"net_info": rpcserver.NewRPCFunc(makeNetInfoFunc(c), "", false),
|
||||
"blockchain": rpcserver.NewRPCFunc(makeBlockchainInfoFunc(c), "minHeight,maxHeight", true),
|
||||
"genesis": rpcserver.NewRPCFunc(makeGenesisFunc(c), "", true),
|
||||
"genesis_chunked": rpcserver.NewRPCFunc(makeGenesisChunkedFunc(c), "", true),
|
||||
"header": rpcserver.NewRPCFunc(makeHeaderFunc(c), "height", true),
|
||||
"header_by_hash": rpcserver.NewRPCFunc(makeHeaderByHashFunc(c), "hash", true),
|
||||
"block": rpcserver.NewRPCFunc(makeBlockFunc(c), "height", true),
|
||||
"block_by_hash": rpcserver.NewRPCFunc(makeBlockByHashFunc(c), "hash", true),
|
||||
"block_results": rpcserver.NewRPCFunc(makeBlockResultsFunc(c), "height", true),
|
||||
"commit": rpcserver.NewRPCFunc(makeCommitFunc(c), "height", true),
|
||||
"tx": rpcserver.NewRPCFunc(makeTxFunc(c), "hash,prove", true),
|
||||
"tx_search": rpcserver.NewRPCFunc(makeTxSearchFunc(c), "query,prove,page,per_page,order_by", false),
|
||||
"block_search": rpcserver.NewRPCFunc(makeBlockSearchFunc(c), "query,page,per_page,order_by", false),
|
||||
"validators": rpcserver.NewRPCFunc(makeValidatorsFunc(c), "height,page,per_page", true),
|
||||
"dump_consensus_state": rpcserver.NewRPCFunc(makeDumpConsensusStateFunc(c), "", false),
|
||||
"consensus_state": rpcserver.NewRPCFunc(makeConsensusStateFunc(c), "", false),
|
||||
"consensus_params": rpcserver.NewRPCFunc(makeConsensusParamsFunc(c), "height", true),
|
||||
"unconfirmed_txs": rpcserver.NewRPCFunc(makeUnconfirmedTxsFunc(c), "limit", false),
|
||||
"num_unconfirmed_txs": rpcserver.NewRPCFunc(makeNumUnconfirmedTxsFunc(c), "", false),
|
||||
"health": rpcserver.NewRPCFunc(makeHealthFunc(c), ""),
|
||||
"status": rpcserver.NewRPCFunc(makeStatusFunc(c), ""),
|
||||
"net_info": rpcserver.NewRPCFunc(makeNetInfoFunc(c), ""),
|
||||
"blockchain": rpcserver.NewRPCFunc(makeBlockchainInfoFunc(c), "minHeight,maxHeight"),
|
||||
"genesis": rpcserver.NewRPCFunc(makeGenesisFunc(c), ""),
|
||||
"genesis_chunked": rpcserver.NewRPCFunc(makeGenesisChunkedFunc(c), ""),
|
||||
"header": rpcserver.NewRPCFunc(makeHeaderFunc(c), "height"),
|
||||
"header_by_hash": rpcserver.NewRPCFunc(makeHeaderByHashFunc(c), "hash"),
|
||||
"block": rpcserver.NewRPCFunc(makeBlockFunc(c), "height"),
|
||||
"block_by_hash": rpcserver.NewRPCFunc(makeBlockByHashFunc(c), "hash"),
|
||||
"block_results": rpcserver.NewRPCFunc(makeBlockResultsFunc(c), "height"),
|
||||
"commit": rpcserver.NewRPCFunc(makeCommitFunc(c), "height"),
|
||||
"tx": rpcserver.NewRPCFunc(makeTxFunc(c), "hash,prove"),
|
||||
"tx_search": rpcserver.NewRPCFunc(makeTxSearchFunc(c), "query,prove,page,per_page,order_by"),
|
||||
"block_search": rpcserver.NewRPCFunc(makeBlockSearchFunc(c), "query,page,per_page,order_by"),
|
||||
"validators": rpcserver.NewRPCFunc(makeValidatorsFunc(c), "height,page,per_page"),
|
||||
"dump_consensus_state": rpcserver.NewRPCFunc(makeDumpConsensusStateFunc(c), ""),
|
||||
"consensus_state": rpcserver.NewRPCFunc(makeConsensusStateFunc(c), ""),
|
||||
"consensus_params": rpcserver.NewRPCFunc(makeConsensusParamsFunc(c), "height"),
|
||||
"unconfirmed_txs": rpcserver.NewRPCFunc(makeUnconfirmedTxsFunc(c), "limit"),
|
||||
"num_unconfirmed_txs": rpcserver.NewRPCFunc(makeNumUnconfirmedTxsFunc(c), ""),
|
||||
|
||||
// tx broadcast API
|
||||
"broadcast_tx_commit": rpcserver.NewRPCFunc(makeBroadcastTxCommitFunc(c), "tx", false),
|
||||
"broadcast_tx_sync": rpcserver.NewRPCFunc(makeBroadcastTxSyncFunc(c), "tx", false),
|
||||
"broadcast_tx_async": rpcserver.NewRPCFunc(makeBroadcastTxAsyncFunc(c), "tx", false),
|
||||
"broadcast_tx_commit": rpcserver.NewRPCFunc(makeBroadcastTxCommitFunc(c), "tx"),
|
||||
"broadcast_tx_sync": rpcserver.NewRPCFunc(makeBroadcastTxSyncFunc(c), "tx"),
|
||||
"broadcast_tx_async": rpcserver.NewRPCFunc(makeBroadcastTxAsyncFunc(c), "tx"),
|
||||
|
||||
// abci API
|
||||
"abci_query": rpcserver.NewRPCFunc(makeABCIQueryFunc(c), "path,data,height,prove", false),
|
||||
"abci_info": rpcserver.NewRPCFunc(makeABCIInfoFunc(c), "", true),
|
||||
"abci_query": rpcserver.NewRPCFunc(makeABCIQueryFunc(c), "path,data,height,prove"),
|
||||
"abci_info": rpcserver.NewRPCFunc(makeABCIInfoFunc(c), ""),
|
||||
|
||||
// evidence API
|
||||
"broadcast_evidence": rpcserver.NewRPCFunc(makeBroadcastEvidenceFunc(c), "evidence", false),
|
||||
"broadcast_evidence": rpcserver.NewRPCFunc(makeBroadcastEvidenceFunc(c), "evidence"),
|
||||
}
|
||||
}
|
||||
|
||||
type rpcHealthFunc func(ctx *rpctypes.Context) (*coretypes.ResultHealth, error)
|
||||
type rpcHealthFunc func(ctx context.Context) (*coretypes.ResultHealth, error)
|
||||
|
||||
func makeHealthFunc(c *lrpc.Client) rpcHealthFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultHealth, error) {
|
||||
return c.Health(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultHealth, error) {
|
||||
return c.Health(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcStatusFunc func(ctx *rpctypes.Context) (*coretypes.ResultStatus, error)
|
||||
type rpcStatusFunc func(ctx context.Context) (*coretypes.ResultStatus, error)
|
||||
|
||||
// nolint: interfacer
|
||||
func makeStatusFunc(c *lrpc.Client) rpcStatusFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultStatus, error) {
|
||||
return c.Status(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultStatus, error) {
|
||||
return c.Status(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcNetInfoFunc func(ctx *rpctypes.Context) (*coretypes.ResultNetInfo, error)
|
||||
type rpcNetInfoFunc func(ctx context.Context) (*coretypes.ResultNetInfo, error)
|
||||
|
||||
func makeNetInfoFunc(c *lrpc.Client) rpcNetInfoFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultNetInfo, error) {
|
||||
return c.NetInfo(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultNetInfo, error) {
|
||||
return c.NetInfo(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBlockchainInfoFunc func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error)
|
||||
type rpcBlockchainInfoFunc func(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error)
|
||||
|
||||
func makeBlockchainInfoFunc(c *lrpc.Client) rpcBlockchainInfoFunc {
|
||||
return func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
|
||||
return c.BlockchainInfo(ctx.Context(), minHeight, maxHeight)
|
||||
return func(ctx context.Context, minHeight, maxHeight int64) (*coretypes.ResultBlockchainInfo, error) {
|
||||
return c.BlockchainInfo(ctx, minHeight, maxHeight)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcGenesisFunc func(ctx *rpctypes.Context) (*coretypes.ResultGenesis, error)
|
||||
type rpcGenesisFunc func(ctx context.Context) (*coretypes.ResultGenesis, error)
|
||||
|
||||
func makeGenesisFunc(c *lrpc.Client) rpcGenesisFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultGenesis, error) {
|
||||
return c.Genesis(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultGenesis, error) {
|
||||
return c.Genesis(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcGenesisChunkedFunc func(ctx *rpctypes.Context, chunk uint) (*coretypes.ResultGenesisChunk, error)
|
||||
type rpcGenesisChunkedFunc func(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error)
|
||||
|
||||
func makeGenesisChunkedFunc(c *lrpc.Client) rpcGenesisChunkedFunc {
|
||||
return func(ctx *rpctypes.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
|
||||
return c.GenesisChunked(ctx.Context(), chunk)
|
||||
return func(ctx context.Context, chunk uint) (*coretypes.ResultGenesisChunk, error) {
|
||||
return c.GenesisChunked(ctx, chunk)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcHeaderFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultHeader, error)
|
||||
type rpcHeaderFunc func(ctx context.Context, height *int64) (*coretypes.ResultHeader, error)
|
||||
|
||||
func makeHeaderFunc(c *lrpc.Client) rpcHeaderFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultHeader, error) {
|
||||
return c.Header(ctx.Context(), height)
|
||||
return func(ctx context.Context, height *int64) (*coretypes.ResultHeader, error) {
|
||||
return c.Header(ctx, height)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcHeaderByHashFunc func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultHeader, error)
|
||||
type rpcHeaderByHashFunc func(ctx context.Context, hash []byte) (*coretypes.ResultHeader, error)
|
||||
|
||||
func makeHeaderByHashFunc(c *lrpc.Client) rpcHeaderByHashFunc {
|
||||
return func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultHeader, error) {
|
||||
return c.HeaderByHash(ctx.Context(), hash)
|
||||
return func(ctx context.Context, hash []byte) (*coretypes.ResultHeader, error) {
|
||||
return c.HeaderByHash(ctx, hash)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBlockFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlock, error)
|
||||
type rpcBlockFunc func(ctx context.Context, height *int64) (*coretypes.ResultBlock, error)
|
||||
|
||||
func makeBlockFunc(c *lrpc.Client) rpcBlockFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlock, error) {
|
||||
return c.Block(ctx.Context(), height)
|
||||
return func(ctx context.Context, height *int64) (*coretypes.ResultBlock, error) {
|
||||
return c.Block(ctx, height)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBlockByHashFunc func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultBlock, error)
|
||||
type rpcBlockByHashFunc func(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error)
|
||||
|
||||
func makeBlockByHashFunc(c *lrpc.Client) rpcBlockByHashFunc {
|
||||
return func(ctx *rpctypes.Context, hash []byte) (*coretypes.ResultBlock, error) {
|
||||
return c.BlockByHash(ctx.Context(), hash)
|
||||
return func(ctx context.Context, hash []byte) (*coretypes.ResultBlock, error) {
|
||||
return c.BlockByHash(ctx, hash)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBlockResultsFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlockResults, error)
|
||||
type rpcBlockResultsFunc func(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error)
|
||||
|
||||
func makeBlockResultsFunc(c *lrpc.Client) rpcBlockResultsFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultBlockResults, error) {
|
||||
return c.BlockResults(ctx.Context(), height)
|
||||
return func(ctx context.Context, height *int64) (*coretypes.ResultBlockResults, error) {
|
||||
return c.BlockResults(ctx, height)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcCommitFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultCommit, error)
|
||||
type rpcCommitFunc func(ctx context.Context, height *int64) (*coretypes.ResultCommit, error)
|
||||
|
||||
func makeCommitFunc(c *lrpc.Client) rpcCommitFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultCommit, error) {
|
||||
return c.Commit(ctx.Context(), height)
|
||||
return func(ctx context.Context, height *int64) (*coretypes.ResultCommit, error) {
|
||||
return c.Commit(ctx, height)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcTxFunc func(ctx *rpctypes.Context, hash []byte, prove bool) (*coretypes.ResultTx, error)
|
||||
type rpcTxFunc func(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error)
|
||||
|
||||
func makeTxFunc(c *lrpc.Client) rpcTxFunc {
|
||||
return func(ctx *rpctypes.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) {
|
||||
return c.Tx(ctx.Context(), hash, prove)
|
||||
return func(ctx context.Context, hash []byte, prove bool) (*coretypes.ResultTx, error) {
|
||||
return c.Tx(ctx, hash, prove)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcTxSearchFunc func(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
query string,
|
||||
prove bool,
|
||||
page, perPage *int,
|
||||
@@ -169,18 +170,18 @@ type rpcTxSearchFunc func(
|
||||
|
||||
func makeTxSearchFunc(c *lrpc.Client) rpcTxSearchFunc {
|
||||
return func(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
query string,
|
||||
prove bool,
|
||||
page, perPage *int,
|
||||
orderBy string,
|
||||
) (*coretypes.ResultTxSearch, error) {
|
||||
return c.TxSearch(ctx.Context(), query, prove, page, perPage, orderBy)
|
||||
return c.TxSearch(ctx, query, prove, page, perPage, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBlockSearchFunc func(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
query string,
|
||||
prove bool,
|
||||
page, perPage *int,
|
||||
@@ -189,116 +190,116 @@ type rpcBlockSearchFunc func(
|
||||
|
||||
func makeBlockSearchFunc(c *lrpc.Client) rpcBlockSearchFunc {
|
||||
return func(
|
||||
ctx *rpctypes.Context,
|
||||
ctx context.Context,
|
||||
query string,
|
||||
prove bool,
|
||||
page, perPage *int,
|
||||
orderBy string,
|
||||
) (*coretypes.ResultBlockSearch, error) {
|
||||
return c.BlockSearch(ctx.Context(), query, page, perPage, orderBy)
|
||||
return c.BlockSearch(ctx, query, page, perPage, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcValidatorsFunc func(ctx *rpctypes.Context, height *int64,
|
||||
type rpcValidatorsFunc func(ctx context.Context, height *int64,
|
||||
page, perPage *int) (*coretypes.ResultValidators, error)
|
||||
|
||||
func makeValidatorsFunc(c *lrpc.Client) rpcValidatorsFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) {
|
||||
return c.Validators(ctx.Context(), height, page, perPage)
|
||||
return func(ctx context.Context, height *int64, page, perPage *int) (*coretypes.ResultValidators, error) {
|
||||
return c.Validators(ctx, height, page, perPage)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcDumpConsensusStateFunc func(ctx *rpctypes.Context) (*coretypes.ResultDumpConsensusState, error)
|
||||
type rpcDumpConsensusStateFunc func(ctx context.Context) (*coretypes.ResultDumpConsensusState, error)
|
||||
|
||||
func makeDumpConsensusStateFunc(c *lrpc.Client) rpcDumpConsensusStateFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultDumpConsensusState, error) {
|
||||
return c.DumpConsensusState(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultDumpConsensusState, error) {
|
||||
return c.DumpConsensusState(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcConsensusStateFunc func(ctx *rpctypes.Context) (*coretypes.ResultConsensusState, error)
|
||||
type rpcConsensusStateFunc func(ctx context.Context) (*coretypes.ResultConsensusState, error)
|
||||
|
||||
func makeConsensusStateFunc(c *lrpc.Client) rpcConsensusStateFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultConsensusState, error) {
|
||||
return c.ConsensusState(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultConsensusState, error) {
|
||||
return c.ConsensusState(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcConsensusParamsFunc func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultConsensusParams, error)
|
||||
type rpcConsensusParamsFunc func(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error)
|
||||
|
||||
func makeConsensusParamsFunc(c *lrpc.Client) rpcConsensusParamsFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*coretypes.ResultConsensusParams, error) {
|
||||
return c.ConsensusParams(ctx.Context(), height)
|
||||
return func(ctx context.Context, height *int64) (*coretypes.ResultConsensusParams, error) {
|
||||
return c.ConsensusParams(ctx, height)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcUnconfirmedTxsFunc func(ctx *rpctypes.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error)
|
||||
type rpcUnconfirmedTxsFunc func(ctx context.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error)
|
||||
|
||||
func makeUnconfirmedTxsFunc(c *lrpc.Client) rpcUnconfirmedTxsFunc {
|
||||
return func(ctx *rpctypes.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
return c.UnconfirmedTxs(ctx.Context(), limit)
|
||||
return func(ctx context.Context, limit *int) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
return c.UnconfirmedTxs(ctx, limit)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcNumUnconfirmedTxsFunc func(ctx *rpctypes.Context) (*coretypes.ResultUnconfirmedTxs, error)
|
||||
type rpcNumUnconfirmedTxsFunc func(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error)
|
||||
|
||||
func makeNumUnconfirmedTxsFunc(c *lrpc.Client) rpcNumUnconfirmedTxsFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
return c.NumUnconfirmedTxs(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultUnconfirmedTxs, error) {
|
||||
return c.NumUnconfirmedTxs(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBroadcastTxCommitFunc func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error)
|
||||
type rpcBroadcastTxCommitFunc func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error)
|
||||
|
||||
func makeBroadcastTxCommitFunc(c *lrpc.Client) rpcBroadcastTxCommitFunc {
|
||||
return func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
|
||||
return c.BroadcastTxCommit(ctx.Context(), tx)
|
||||
return func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTxCommit, error) {
|
||||
return c.BroadcastTxCommit(ctx, tx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBroadcastTxSyncFunc func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
|
||||
type rpcBroadcastTxSyncFunc func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
|
||||
|
||||
func makeBroadcastTxSyncFunc(c *lrpc.Client) rpcBroadcastTxSyncFunc {
|
||||
return func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
return c.BroadcastTxSync(ctx.Context(), tx)
|
||||
return func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
return c.BroadcastTxSync(ctx, tx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBroadcastTxAsyncFunc func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
|
||||
type rpcBroadcastTxAsyncFunc func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error)
|
||||
|
||||
func makeBroadcastTxAsyncFunc(c *lrpc.Client) rpcBroadcastTxAsyncFunc {
|
||||
return func(ctx *rpctypes.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
return c.BroadcastTxAsync(ctx.Context(), tx)
|
||||
return func(ctx context.Context, tx types.Tx) (*coretypes.ResultBroadcastTx, error) {
|
||||
return c.BroadcastTxAsync(ctx, tx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcABCIQueryFunc func(ctx *rpctypes.Context, path string,
|
||||
type rpcABCIQueryFunc func(ctx context.Context, path string,
|
||||
data bytes.HexBytes, height int64, prove bool) (*coretypes.ResultABCIQuery, error)
|
||||
|
||||
func makeABCIQueryFunc(c *lrpc.Client) rpcABCIQueryFunc {
|
||||
return func(ctx *rpctypes.Context, path string, data bytes.HexBytes,
|
||||
return func(ctx context.Context, path string, data bytes.HexBytes,
|
||||
height int64, prove bool) (*coretypes.ResultABCIQuery, error) {
|
||||
|
||||
return c.ABCIQueryWithOptions(ctx.Context(), path, data, rpcclient.ABCIQueryOptions{
|
||||
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.ABCIQueryOptions{
|
||||
Height: height,
|
||||
Prove: prove,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type rpcABCIInfoFunc func(ctx *rpctypes.Context) (*coretypes.ResultABCIInfo, error)
|
||||
type rpcABCIInfoFunc func(ctx context.Context) (*coretypes.ResultABCIInfo, error)
|
||||
|
||||
func makeABCIInfoFunc(c *lrpc.Client) rpcABCIInfoFunc {
|
||||
return func(ctx *rpctypes.Context) (*coretypes.ResultABCIInfo, error) {
|
||||
return c.ABCIInfo(ctx.Context())
|
||||
return func(ctx context.Context) (*coretypes.ResultABCIInfo, error) {
|
||||
return c.ABCIInfo(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
type rpcBroadcastEvidenceFunc func(ctx *rpctypes.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error)
|
||||
type rpcBroadcastEvidenceFunc func(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error)
|
||||
|
||||
// nolint: interfacer
|
||||
func makeBroadcastEvidenceFunc(c *lrpc.Client) rpcBroadcastEvidenceFunc {
|
||||
return func(ctx *rpctypes.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
return c.BroadcastEvidence(ctx.Context(), ev)
|
||||
return func(ctx context.Context, ev types.Evidence) (*coretypes.ResultBroadcastEvidence, error) {
|
||||
return c.BroadcastEvidence(ctx, ev)
|
||||
}
|
||||
}
|
||||
|
||||
+9
-8
@@ -615,11 +615,12 @@ func (c *Client) RegisterOpDecoder(typ string, dec merkle.OpDecoder) {
|
||||
// SubscribeWS subscribes for events using the given query and remote address as
|
||||
// a subscriber, but does not verify responses (UNSAFE)!
|
||||
// TODO: verify data
|
||||
func (c *Client) SubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.ResultSubscribe, error) {
|
||||
func (c *Client) SubscribeWS(ctx context.Context, query string) (*coretypes.ResultSubscribe, error) {
|
||||
bctx, bcancel := context.WithCancel(context.Background())
|
||||
c.closers = append(c.closers, bcancel)
|
||||
|
||||
out, err := c.next.Subscribe(bctx, ctx.RemoteAddr(), query)
|
||||
callInfo := rpctypes.GetCallInfo(ctx)
|
||||
out, err := c.next.Subscribe(bctx, callInfo.RemoteAddr(), query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -630,9 +631,9 @@ func (c *Client) SubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.Re
|
||||
case resultEvent := <-out:
|
||||
// We should have a switch here that performs a validation
|
||||
// depending on the event's type.
|
||||
ctx.WSConn.TryWriteRPCResponse(bctx,
|
||||
callInfo.WSConn.TryWriteRPCResponse(bctx,
|
||||
rpctypes.NewRPCSuccessResponse(
|
||||
rpctypes.JSONRPCStringID(fmt.Sprintf("%v#event", ctx.JSONReq.ID)),
|
||||
rpctypes.JSONRPCStringID(fmt.Sprintf("%v#event", callInfo.RPCRequest.ID)),
|
||||
resultEvent,
|
||||
))
|
||||
case <-bctx.Done():
|
||||
@@ -646,8 +647,8 @@ func (c *Client) SubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.Re
|
||||
|
||||
// UnsubscribeWS calls original client's Unsubscribe using remote address as a
|
||||
// subscriber.
|
||||
func (c *Client) UnsubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.ResultUnsubscribe, error) {
|
||||
err := c.next.Unsubscribe(context.Background(), ctx.RemoteAddr(), query)
|
||||
func (c *Client) UnsubscribeWS(ctx context.Context, query string) (*coretypes.ResultUnsubscribe, error) {
|
||||
err := c.next.Unsubscribe(context.Background(), rpctypes.GetCallInfo(ctx).RemoteAddr(), query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -656,8 +657,8 @@ func (c *Client) UnsubscribeWS(ctx *rpctypes.Context, query string) (*coretypes.
|
||||
|
||||
// UnsubscribeAllWS calls original client's UnsubscribeAll using remote address
|
||||
// as a subscriber.
|
||||
func (c *Client) UnsubscribeAllWS(ctx *rpctypes.Context) (*coretypes.ResultUnsubscribe, error) {
|
||||
err := c.next.UnsubscribeAll(context.Background(), ctx.RemoteAddr())
|
||||
func (c *Client) UnsubscribeAllWS(ctx context.Context) (*coretypes.ResultUnsubscribe, error) {
|
||||
err := c.next.UnsubscribeAll(context.Background(), rpctypes.GetCallInfo(ctx).RemoteAddr())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ func TestLast_FirstLightBlockHeight(t *testing.T) {
|
||||
assert.EqualValues(t, -1, height)
|
||||
|
||||
// 1 key
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, int64(1)))
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, t, int64(1)))
|
||||
require.NoError(t, err)
|
||||
|
||||
height, err = dbStore.LastLightBlockHeight()
|
||||
@@ -58,7 +58,7 @@ func Test_SaveLightBlock(t *testing.T) {
|
||||
assert.Nil(t, h)
|
||||
|
||||
// 1 key
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, 1))
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, t, 1))
|
||||
require.NoError(t, err)
|
||||
|
||||
size := dbStore.Size()
|
||||
@@ -90,7 +90,7 @@ func Test_LightBlockBefore(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
err := dbStore.SaveLightBlock(randLightBlock(ctx, int64(2)))
|
||||
err := dbStore.SaveLightBlock(randLightBlock(ctx, t, int64(2)))
|
||||
require.NoError(t, err)
|
||||
|
||||
h, err := dbStore.LightBlockBefore(3)
|
||||
@@ -115,7 +115,7 @@ func Test_Prune(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// One header
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, 2))
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, t, 2))
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.EqualValues(t, 1, dbStore.Size())
|
||||
@@ -130,7 +130,7 @@ func Test_Prune(t *testing.T) {
|
||||
|
||||
// Multiple headers
|
||||
for i := 1; i <= 10; i++ {
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, int64(i)))
|
||||
err = dbStore.SaveLightBlock(randLightBlock(ctx, t, int64(i)))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ func Test_Concurrency(t *testing.T) {
|
||||
go func(i int64) {
|
||||
defer wg.Done()
|
||||
|
||||
err := dbStore.SaveLightBlock(randLightBlock(ctx, i))
|
||||
err := dbStore.SaveLightBlock(randLightBlock(ctx, t, i))
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = dbStore.LightBlock(i)
|
||||
@@ -198,8 +198,9 @@ func Test_Concurrency(t *testing.T) {
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func randLightBlock(ctx context.Context, height int64) *types.LightBlock {
|
||||
vals, _ := factory.RandValidatorSet(ctx, 2, 1)
|
||||
func randLightBlock(ctx context.Context, t *testing.T, height int64) *types.LightBlock {
|
||||
t.Helper()
|
||||
vals, _ := factory.RandValidatorSet(ctx, t, 2, 1)
|
||||
return &types.LightBlock{
|
||||
SignedHeader: &types.SignedHeader{
|
||||
Header: &types.Header{
|
||||
|
||||
+43
-157
@@ -63,23 +63,17 @@ type nodeImpl struct {
|
||||
isListening bool
|
||||
|
||||
// services
|
||||
eventBus *eventbus.EventBus // pub/sub for services
|
||||
eventSinks []indexer.EventSink
|
||||
stateStore sm.Store
|
||||
blockStore *store.BlockStore // store the blockchain to disk
|
||||
bcReactor service.Service // for block-syncing
|
||||
mempoolReactor service.Service // for gossipping transactions
|
||||
mempool mempool.Mempool
|
||||
blockStore *store.BlockStore // store the blockchain to disk
|
||||
stateSync bool // whether the node should state sync on startup
|
||||
stateSyncReactor *statesync.Reactor // for hosting and restoring state sync snapshots
|
||||
consensusReactor *consensus.Reactor // for participating in the consensus
|
||||
pexReactor service.Service // for exchanging peer addresses
|
||||
evidenceReactor service.Service
|
||||
rpcListeners []net.Listener // rpc servers
|
||||
shutdownOps closer
|
||||
indexerService service.Service
|
||||
rpcEnv *rpccore.Environment
|
||||
prometheusSrv *http.Server
|
||||
|
||||
services []service.Service
|
||||
rpcListeners []net.Listener // rpc servers
|
||||
shutdownOps closer
|
||||
rpcEnv *rpccore.Environment
|
||||
prometheusSrv *http.Server
|
||||
}
|
||||
|
||||
// newDefaultNode returns a Tendermint node with default settings for the
|
||||
@@ -339,6 +333,7 @@ func makeNode(
|
||||
peerManager.Subscribe(ctx),
|
||||
blockSync && !stateSync,
|
||||
nodeMetrics.consensus,
|
||||
eventBus,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, combineCloseError(
|
||||
@@ -372,6 +367,7 @@ func makeNode(
|
||||
blockStore,
|
||||
cfg.StateSync.TempDir,
|
||||
nodeMetrics.statesync,
|
||||
eventBus,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, combineCloseError(err, makeCloser(closers))
|
||||
@@ -384,7 +380,6 @@ func makeNode(
|
||||
return nil, combineCloseError(err, makeCloser(closers))
|
||||
}
|
||||
}
|
||||
|
||||
node := &nodeImpl{
|
||||
config: cfg,
|
||||
logger: logger,
|
||||
@@ -396,19 +391,22 @@ func makeNode(
|
||||
nodeInfo: nodeInfo,
|
||||
nodeKey: nodeKey,
|
||||
|
||||
eventSinks: eventSinks,
|
||||
|
||||
services: []service.Service{
|
||||
eventBus,
|
||||
indexerService,
|
||||
evReactor,
|
||||
mpReactor,
|
||||
csReactor,
|
||||
bcReactor,
|
||||
pexReactor,
|
||||
},
|
||||
|
||||
stateStore: stateStore,
|
||||
blockStore: blockStore,
|
||||
bcReactor: bcReactor,
|
||||
mempoolReactor: mpReactor,
|
||||
mempool: mp,
|
||||
consensusReactor: csReactor,
|
||||
stateSyncReactor: stateSyncReactor,
|
||||
stateSync: stateSync,
|
||||
pexReactor: pexReactor,
|
||||
evidenceReactor: evReactor,
|
||||
indexerService: indexerService,
|
||||
eventBus: eventBus,
|
||||
eventSinks: eventSinks,
|
||||
|
||||
shutdownOps: makeCloser(closers),
|
||||
|
||||
@@ -442,76 +440,6 @@ func makeNode(
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// makeSeedNode returns a new seed node, containing only p2p, pex reactor
|
||||
func makeSeedNode(
|
||||
ctx context.Context,
|
||||
cfg *config.Config,
|
||||
dbProvider config.DBProvider,
|
||||
nodeKey types.NodeKey,
|
||||
genesisDocProvider genesisDocProvider,
|
||||
logger log.Logger,
|
||||
) (service.Service, error) {
|
||||
if !cfg.P2P.PexReactor {
|
||||
return nil, errors.New("cannot run seed nodes with PEX disabled")
|
||||
}
|
||||
|
||||
genDoc, err := genesisDocProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
state, err := sm.MakeGenesisState(genDoc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeInfo, err := makeSeedNodeInfo(cfg, nodeKey, genDoc, state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Setup Transport and Switch.
|
||||
p2pMetrics := p2p.PrometheusMetrics(cfg.Instrumentation.Namespace, "chain_id", genDoc.ChainID)
|
||||
|
||||
peerManager, closer, err := createPeerManager(cfg, dbProvider, nodeKey.ID)
|
||||
if err != nil {
|
||||
return nil, combineCloseError(
|
||||
fmt.Errorf("failed to create peer manager: %w", err),
|
||||
closer)
|
||||
}
|
||||
|
||||
router, err := createRouter(ctx, logger, p2pMetrics, nodeInfo, nodeKey,
|
||||
peerManager, cfg, nil)
|
||||
if err != nil {
|
||||
return nil, combineCloseError(
|
||||
fmt.Errorf("failed to create router: %w", err),
|
||||
closer)
|
||||
}
|
||||
|
||||
pexReactor, err := pex.NewReactor(ctx, logger, peerManager, router.OpenChannel, peerManager.Subscribe(ctx))
|
||||
if err != nil {
|
||||
return nil, combineCloseError(err, closer)
|
||||
}
|
||||
|
||||
node := &nodeImpl{
|
||||
config: cfg,
|
||||
logger: logger,
|
||||
genesisDoc: genDoc,
|
||||
|
||||
nodeInfo: nodeInfo,
|
||||
nodeKey: nodeKey,
|
||||
peerManager: peerManager,
|
||||
router: router,
|
||||
|
||||
shutdownOps: closer,
|
||||
|
||||
pexReactor: pexReactor,
|
||||
}
|
||||
node.BaseService = *service.NewBaseService(logger, "SeedNode", node)
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// OnStart starts the Node. It implements service.Service.
|
||||
func (n *nodeImpl) OnStart(ctx context.Context) error {
|
||||
if n.config.RPC.PprofListenAddress != "" {
|
||||
@@ -546,7 +474,7 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
|
||||
|
||||
// Start the RPC server before the P2P server
|
||||
// so we can eg. receive txs for the first block
|
||||
if n.config.RPC.ListenAddress != "" && n.config.Mode != config.ModeSeed {
|
||||
if n.config.RPC.ListenAddress != "" {
|
||||
listeners, err := n.startRPC(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -564,46 +492,25 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
|
||||
}
|
||||
n.isListening = true
|
||||
|
||||
if n.config.Mode != config.ModeSeed {
|
||||
if err := n.bcReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, reactor := range n.services {
|
||||
if err := reactor.Start(ctx); err != nil {
|
||||
if errors.Is(err, service.ErrAlreadyStarted) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Start the real consensus reactor separately since the switch uses the shim.
|
||||
if err := n.consensusReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the real state sync reactor separately since the switch uses the shim.
|
||||
if err := n.stateSyncReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the real mempool reactor separately since the switch uses the shim.
|
||||
if err := n.mempoolReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Start the real evidence reactor separately since the switch uses the shim.
|
||||
if err := n.evidenceReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("problem starting service '%T': %w ", reactor, err)
|
||||
}
|
||||
}
|
||||
|
||||
if n.config.P2P.PexReactor {
|
||||
if err := n.pexReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := n.stateSyncReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run state sync
|
||||
// TODO: We shouldn't run state sync if we already have state that has a
|
||||
// LastBlockHeight that is not InitialHeight
|
||||
if n.stateSync {
|
||||
bcR, ok := n.bcReactor.(consensus.BlockSyncReactor)
|
||||
if !ok {
|
||||
return fmt.Errorf("this blockchain reactor does not support switching from state sync")
|
||||
}
|
||||
bcR := n.rpcEnv.BlockSyncReactor
|
||||
|
||||
// we need to get the genesis state to get parameters such as
|
||||
state, err := sm.MakeGenesisState(n.genesisDoc)
|
||||
@@ -616,7 +523,7 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
|
||||
// At the beginning of the statesync start, we use the initialHeight as the event height
|
||||
// because of the statesync doesn't have the concreate state height before fetched the snapshot.
|
||||
d := types.EventDataStateSyncStatus{Complete: false, Height: state.InitialHeight}
|
||||
if err := n.eventBus.PublishEventStateSyncStatus(ctx, d); err != nil {
|
||||
if err := n.stateSyncReactor.PublishStatus(ctx, d); err != nil {
|
||||
n.logger.Error("failed to emit the statesync start event", "err", err)
|
||||
}
|
||||
|
||||
@@ -635,9 +542,9 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
n.consensusReactor.SetStateSyncingMetrics(0)
|
||||
n.rpcEnv.ConsensusReactor.SetStateSyncingMetrics(0)
|
||||
|
||||
if err := n.eventBus.PublishEventStateSyncStatus(ctx,
|
||||
if err := n.stateSyncReactor.PublishStatus(ctx,
|
||||
types.EventDataStateSyncStatus{
|
||||
Complete: true,
|
||||
Height: ssState.LastBlockHeight,
|
||||
@@ -650,13 +557,13 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
|
||||
// advancing reactors to be able to control which one of the three
|
||||
// is running
|
||||
// FIXME Very ugly to have these metrics bleed through here.
|
||||
n.consensusReactor.SetBlockSyncingMetrics(1)
|
||||
n.rpcEnv.ConsensusReactor.SetBlockSyncingMetrics(1)
|
||||
if err := bcR.SwitchToBlockSync(ctx, ssState); err != nil {
|
||||
n.logger.Error("failed to switch to block sync", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := n.eventBus.PublishEventBlockSyncStatus(ctx,
|
||||
if err := bcR.PublishStatus(ctx,
|
||||
types.EventDataBlockSyncStatus{
|
||||
Complete: false,
|
||||
Height: ssState.LastBlockHeight,
|
||||
@@ -673,27 +580,17 @@ func (n *nodeImpl) OnStart(ctx context.Context) error {
|
||||
func (n *nodeImpl) OnStop() {
|
||||
n.logger.Info("Stopping Node")
|
||||
|
||||
if n.eventBus != nil {
|
||||
n.eventBus.Wait()
|
||||
}
|
||||
if n.indexerService != nil {
|
||||
n.indexerService.Wait()
|
||||
}
|
||||
|
||||
for _, es := range n.eventSinks {
|
||||
if err := es.Stop(); err != nil {
|
||||
n.logger.Error("failed to stop event sink", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
if n.config.Mode != config.ModeSeed {
|
||||
n.bcReactor.Wait()
|
||||
n.consensusReactor.Wait()
|
||||
n.stateSyncReactor.Wait()
|
||||
n.mempoolReactor.Wait()
|
||||
n.evidenceReactor.Wait()
|
||||
for _, reactor := range n.services {
|
||||
reactor.Wait()
|
||||
}
|
||||
n.pexReactor.Wait()
|
||||
|
||||
n.stateSyncReactor.Wait()
|
||||
n.router.Wait()
|
||||
n.isListening = false
|
||||
|
||||
@@ -769,16 +666,15 @@ func (n *nodeImpl) startRPC(ctx context.Context) ([]net.Listener, error) {
|
||||
mux := http.NewServeMux()
|
||||
rpcLogger := n.logger.With("module", "rpc-server")
|
||||
wmLogger := rpcLogger.With("protocol", "websocket")
|
||||
wm := rpcserver.NewWebsocketManager(routes,
|
||||
wm := rpcserver.NewWebsocketManager(wmLogger, routes,
|
||||
rpcserver.OnDisconnect(func(remoteAddr string) {
|
||||
err := n.eventBus.UnsubscribeAll(context.Background(), remoteAddr)
|
||||
err := n.rpcEnv.EventBus.UnsubscribeAll(context.Background(), remoteAddr)
|
||||
if err != nil && err != tmpubsub.ErrSubscriptionNotFound {
|
||||
wmLogger.Error("Failed to unsubscribe addr from events", "addr", remoteAddr, "err", err)
|
||||
}
|
||||
}),
|
||||
rpcserver.ReadLimit(cfg.MaxBodyBytes),
|
||||
)
|
||||
wm.SetLogger(wmLogger)
|
||||
mux.HandleFunc("/websocket", wm.WebsocketHandler)
|
||||
rpcserver.RegisterRPCFuncs(mux, routes, rpcLogger)
|
||||
listener, err := rpcserver.Listen(
|
||||
@@ -866,19 +762,9 @@ func (n *nodeImpl) startPrometheusServer(ctx context.Context, addr string) *http
|
||||
return srv
|
||||
}
|
||||
|
||||
// ConsensusReactor returns the Node's ConsensusReactor.
|
||||
func (n *nodeImpl) ConsensusReactor() *consensus.Reactor {
|
||||
return n.consensusReactor
|
||||
}
|
||||
|
||||
// Mempool returns the Node's mempool.
|
||||
func (n *nodeImpl) Mempool() mempool.Mempool {
|
||||
return n.mempool
|
||||
}
|
||||
|
||||
// EventBus returns the Node's EventBus.
|
||||
func (n *nodeImpl) EventBus() *eventbus.EventBus {
|
||||
return n.eventBus
|
||||
return n.rpcEnv.EventBus
|
||||
}
|
||||
|
||||
// PrivValidator returns the Node's PrivValidator.
|
||||
|
||||
+2
-2
@@ -556,7 +556,7 @@ func TestNodeNewSeedNode(t *testing.T) {
|
||||
t.Cleanup(ns.Wait)
|
||||
|
||||
require.NoError(t, err)
|
||||
n, ok := ns.(*nodeImpl)
|
||||
n, ok := ns.(*seedNodeImpl)
|
||||
require.True(t, ok)
|
||||
|
||||
err = n.Start(ctx)
|
||||
@@ -717,7 +717,7 @@ func loadStatefromGenesis(ctx context.Context, t *testing.T) sm.State {
|
||||
require.NoError(t, err)
|
||||
require.True(t, loadedState.IsEmpty())
|
||||
|
||||
genDoc, _ := factory.RandGenesisDoc(ctx, cfg, 0, false, 10)
|
||||
genDoc, _ := factory.RandGenesisDoc(ctx, t, cfg, 0, false, 10)
|
||||
|
||||
state, err := loadStateFromDBOrGenesisDocProvider(
|
||||
stateStore,
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/internal/p2p"
|
||||
"github.com/tendermint/tendermint/internal/p2p/pex"
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
"github.com/tendermint/tendermint/libs/service"
|
||||
"github.com/tendermint/tendermint/libs/strings"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
type seedNodeImpl struct {
|
||||
service.BaseService
|
||||
logger log.Logger
|
||||
|
||||
// config
|
||||
config *config.Config
|
||||
genesisDoc *types.GenesisDoc // initial validator set
|
||||
|
||||
// network
|
||||
peerManager *p2p.PeerManager
|
||||
router *p2p.Router
|
||||
nodeInfo types.NodeInfo
|
||||
nodeKey types.NodeKey // our node privkey
|
||||
isListening bool
|
||||
|
||||
// services
|
||||
pexReactor service.Service // for exchanging peer addresses
|
||||
shutdownOps closer
|
||||
}
|
||||
|
||||
// makeSeedNode returns a new seed node, containing only p2p, pex reactor
|
||||
func makeSeedNode(
|
||||
ctx context.Context,
|
||||
cfg *config.Config,
|
||||
dbProvider config.DBProvider,
|
||||
nodeKey types.NodeKey,
|
||||
genesisDocProvider genesisDocProvider,
|
||||
logger log.Logger,
|
||||
) (service.Service, error) {
|
||||
if !cfg.P2P.PexReactor {
|
||||
return nil, errors.New("cannot run seed nodes with PEX disabled")
|
||||
}
|
||||
|
||||
genDoc, err := genesisDocProvider()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
state, err := sm.MakeGenesisState(genDoc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nodeInfo, err := makeSeedNodeInfo(cfg, nodeKey, genDoc, state)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Setup Transport and Switch.
|
||||
p2pMetrics := p2p.PrometheusMetrics(cfg.Instrumentation.Namespace, "chain_id", genDoc.ChainID)
|
||||
|
||||
peerManager, closer, err := createPeerManager(cfg, dbProvider, nodeKey.ID)
|
||||
if err != nil {
|
||||
return nil, combineCloseError(
|
||||
fmt.Errorf("failed to create peer manager: %w", err),
|
||||
closer)
|
||||
}
|
||||
|
||||
router, err := createRouter(ctx, logger, p2pMetrics, nodeInfo, nodeKey,
|
||||
peerManager, cfg, nil)
|
||||
if err != nil {
|
||||
return nil, combineCloseError(
|
||||
fmt.Errorf("failed to create router: %w", err),
|
||||
closer)
|
||||
}
|
||||
|
||||
pexReactor, err := pex.NewReactor(ctx, logger, peerManager, router.OpenChannel, peerManager.Subscribe(ctx))
|
||||
if err != nil {
|
||||
return nil, combineCloseError(err, closer)
|
||||
}
|
||||
|
||||
node := &seedNodeImpl{
|
||||
config: cfg,
|
||||
logger: logger,
|
||||
genesisDoc: genDoc,
|
||||
|
||||
nodeInfo: nodeInfo,
|
||||
nodeKey: nodeKey,
|
||||
peerManager: peerManager,
|
||||
router: router,
|
||||
|
||||
shutdownOps: closer,
|
||||
|
||||
pexReactor: pexReactor,
|
||||
}
|
||||
node.BaseService = *service.NewBaseService(logger, "SeedNode", node)
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// OnStart starts the Seed Node. It implements service.Service.
|
||||
func (n *seedNodeImpl) OnStart(ctx context.Context) error {
|
||||
if n.config.RPC.PprofListenAddress != "" {
|
||||
rpcCtx, rpcCancel := context.WithCancel(ctx)
|
||||
srv := &http.Server{Addr: n.config.RPC.PprofListenAddress, Handler: nil}
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
sctx, scancel := context.WithTimeout(context.Background(), time.Second)
|
||||
defer scancel()
|
||||
_ = srv.Shutdown(sctx)
|
||||
case <-rpcCtx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
n.logger.Info("Starting pprof server", "laddr", n.config.RPC.PprofListenAddress)
|
||||
|
||||
if err := srv.ListenAndServe(); err != nil {
|
||||
n.logger.Error("pprof server error", "err", err)
|
||||
rpcCancel()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
now := tmtime.Now()
|
||||
genTime := n.genesisDoc.GenesisTime
|
||||
if genTime.After(now) {
|
||||
n.logger.Info("Genesis time is in the future. Sleeping until then...", "genTime", genTime)
|
||||
time.Sleep(genTime.Sub(now))
|
||||
}
|
||||
|
||||
// Start the transport.
|
||||
if err := n.router.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
n.isListening = true
|
||||
|
||||
if n.config.P2P.PexReactor {
|
||||
if err := n.pexReactor.Start(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnStop stops the Seed Node. It implements service.Service.
|
||||
func (n *seedNodeImpl) OnStop() {
|
||||
n.logger.Info("Stopping Node")
|
||||
|
||||
n.pexReactor.Wait()
|
||||
n.router.Wait()
|
||||
n.isListening = false
|
||||
|
||||
if err := n.shutdownOps(); err != nil {
|
||||
if strings.TrimSpace(err.Error()) != "" {
|
||||
n.logger.Error("problem shutting down additional services", "err", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -3,6 +3,7 @@ package privval
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -72,7 +73,7 @@ func (pvKey FilePVKey) Save() error {
|
||||
|
||||
// FilePVLastSignState stores the mutable part of PrivValidator.
|
||||
type FilePVLastSignState struct {
|
||||
Height int64 `json:"height"`
|
||||
Height int64 `json:"height,string"`
|
||||
Round int32 `json:"round"`
|
||||
Step int8 `json:"step"`
|
||||
Signature []byte `json:"signature,omitempty"`
|
||||
@@ -128,7 +129,7 @@ func (lss *FilePVLastSignState) Save() error {
|
||||
if outFile == "" {
|
||||
return errors.New("cannot save FilePVLastSignState: filePath not set")
|
||||
}
|
||||
jsonBytes, err := tmjson.MarshalIndent(lss, "", " ")
|
||||
jsonBytes, err := json.MarshalIndent(lss, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -215,7 +216,7 @@ func loadFilePV(keyFilePath, stateFilePath string, loadState bool) (*FilePV, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tmjson.Unmarshal(stateJSONBytes, &pvState)
|
||||
err = json.Unmarshal(stateJSONBytes, &pvState)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading PrivValidator state from %v: %w", stateFilePath, err)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package privval
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
@@ -105,7 +106,7 @@ func TestUnmarshalValidatorState(t *testing.T) {
|
||||
}`
|
||||
|
||||
val := FilePVLastSignState{}
|
||||
err := tmjson.Unmarshal([]byte(serialized), &val)
|
||||
err := json.Unmarshal([]byte(serialized), &val)
|
||||
require.NoError(t, err)
|
||||
|
||||
// make sure the values match
|
||||
@@ -114,7 +115,7 @@ func TestUnmarshalValidatorState(t *testing.T) {
|
||||
assert.EqualValues(t, val.Step, 1)
|
||||
|
||||
// export it and make sure it is the same
|
||||
out, err := tmjson.Marshal(val)
|
||||
out, err := json.Marshal(val)
|
||||
require.NoError(t, err)
|
||||
assert.JSONEq(t, serialized, string(out))
|
||||
}
|
||||
|
||||
@@ -34,15 +34,15 @@ func (sc *RetrySignerClient) IsConnected() bool {
|
||||
return sc.next.IsConnected()
|
||||
}
|
||||
|
||||
func (sc *RetrySignerClient) WaitForConnection(maxWait time.Duration) error {
|
||||
return sc.next.WaitForConnection(maxWait)
|
||||
func (sc *RetrySignerClient) WaitForConnection(ctx context.Context, maxWait time.Duration) error {
|
||||
return sc.next.WaitForConnection(ctx, maxWait)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Implement PrivValidator
|
||||
|
||||
func (sc *RetrySignerClient) Ping() error {
|
||||
return sc.next.Ping()
|
||||
func (sc *RetrySignerClient) Ping(ctx context.Context) error {
|
||||
return sc.next.Ping(ctx)
|
||||
}
|
||||
|
||||
func (sc *RetrySignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, error) {
|
||||
|
||||
@@ -41,7 +41,12 @@ func NewSignerClient(ctx context.Context, endpoint *SignerListenerEndpoint, chai
|
||||
|
||||
// Close closes the underlying connection
|
||||
func (sc *SignerClient) Close() error {
|
||||
return sc.endpoint.Close()
|
||||
err := sc.endpoint.Stop()
|
||||
cerr := sc.endpoint.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cerr
|
||||
}
|
||||
|
||||
// IsConnected indicates with the signer is connected to a remote signing service
|
||||
@@ -50,16 +55,16 @@ func (sc *SignerClient) IsConnected() bool {
|
||||
}
|
||||
|
||||
// WaitForConnection waits maxWait for a connection or returns a timeout error
|
||||
func (sc *SignerClient) WaitForConnection(maxWait time.Duration) error {
|
||||
return sc.endpoint.WaitForConnection(maxWait)
|
||||
func (sc *SignerClient) WaitForConnection(ctx context.Context, maxWait time.Duration) error {
|
||||
return sc.endpoint.WaitForConnection(ctx, maxWait)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Implement PrivValidator
|
||||
|
||||
// Ping sends a ping request to the remote signer
|
||||
func (sc *SignerClient) Ping() error {
|
||||
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.PingRequest{}))
|
||||
func (sc *SignerClient) Ping(ctx context.Context) error {
|
||||
response, err := sc.endpoint.SendRequest(ctx, mustWrapMsg(&privvalproto.PingRequest{}))
|
||||
if err != nil {
|
||||
sc.logger.Error("SignerClient::Ping", "err", err)
|
||||
return nil
|
||||
@@ -76,7 +81,7 @@ func (sc *SignerClient) Ping() error {
|
||||
// GetPubKey retrieves a public key from a remote signer
|
||||
// returns an error if client is not able to provide the key
|
||||
func (sc *SignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, error) {
|
||||
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.PubKeyRequest{ChainId: sc.chainID}))
|
||||
response, err := sc.endpoint.SendRequest(ctx, mustWrapMsg(&privvalproto.PubKeyRequest{ChainId: sc.chainID}))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("send: %w", err)
|
||||
}
|
||||
@@ -99,7 +104,7 @@ func (sc *SignerClient) GetPubKey(ctx context.Context) (crypto.PubKey, error) {
|
||||
|
||||
// SignVote requests a remote signer to sign a vote
|
||||
func (sc *SignerClient) SignVote(ctx context.Context, chainID string, vote *tmproto.Vote) error {
|
||||
response, err := sc.endpoint.SendRequest(mustWrapMsg(&privvalproto.SignVoteRequest{Vote: vote, ChainId: chainID}))
|
||||
response, err := sc.endpoint.SendRequest(ctx, mustWrapMsg(&privvalproto.SignVoteRequest{Vote: vote, ChainId: chainID}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -119,7 +124,7 @@ func (sc *SignerClient) SignVote(ctx context.Context, chainID string, vote *tmpr
|
||||
|
||||
// SignProposal requests a remote signer to sign a proposal
|
||||
func (sc *SignerClient) SignProposal(ctx context.Context, chainID string, proposal *tmproto.Proposal) error {
|
||||
response, err := sc.endpoint.SendRequest(mustWrapMsg(
|
||||
response, err := sc.endpoint.SendRequest(ctx, mustWrapMsg(
|
||||
&privvalproto.SignProposalRequest{Proposal: proposal, ChainId: chainID},
|
||||
))
|
||||
if err != nil {
|
||||
|
||||
@@ -57,6 +57,7 @@ func getSignerTestCases(ctx context.Context, t *testing.T, logger log.Logger) []
|
||||
signerServer: ss,
|
||||
})
|
||||
t.Cleanup(ss.Wait)
|
||||
t.Cleanup(sc.endpoint.Wait)
|
||||
}
|
||||
|
||||
return testCases
|
||||
@@ -72,10 +73,14 @@ func TestSignerClose(t *testing.T) {
|
||||
|
||||
for _, tc := range getSignerTestCases(bctx, t, logger) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
|
||||
defer tc.closer()
|
||||
|
||||
assert.NoError(t, tc.signerClient.Close())
|
||||
assert.NoError(t, tc.signerServer.Stop())
|
||||
t.Cleanup(tc.signerClient.endpoint.Wait)
|
||||
t.Cleanup(tc.signerServer.Wait)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -89,7 +94,7 @@ func TestSignerPing(t *testing.T) {
|
||||
logger := log.NewTestingLogger(t)
|
||||
|
||||
for _, tc := range getSignerTestCases(ctx, t, logger) {
|
||||
err := tc.signerClient.Ping()
|
||||
err := tc.signerClient.Ping(ctx)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}
|
||||
@@ -298,9 +303,7 @@ func TestSignerVoteKeepAlive(t *testing.T) {
|
||||
|
||||
// in this particular case, we use the dialer logger to ensure that
|
||||
// test messages are properly interleaved in the test logs
|
||||
tc.signerServer.endpoint.logger.Debug("TEST: Forced Wait -------------------------------------------------")
|
||||
time.Sleep(testTimeoutReadWrite * 3)
|
||||
tc.signerServer.endpoint.logger.Debug("TEST: Forced Wait DONE---------------------------------------------")
|
||||
|
||||
require.NoError(t, tc.mockPV.SignVote(ctx, tc.chainID, want.ToProto()))
|
||||
require.NoError(t, tc.signerClient.SignVote(ctx, tc.chainID, have.ToProto()))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user