From bdacbdb9cb9d76c7163fc46ba1fddc8601aa94ac Mon Sep 17 00:00:00 2001 From: zale144 Date: Wed, 31 Jul 2024 22:47:06 +0200 Subject: [PATCH] fix(rpc): Fix status `CatchingUp` field updating (#971) --- block/gossip.go | 1 + block/manager.go | 14 +++++++++++++- block/manager_test.go | 35 ++++++++++++++++++++++++++++++++++- block/submit.go | 5 +++-- block/sync.go | 1 + rpc/client/client.go | 10 ++++------ 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/block/gossip.go b/block/gossip.go index 8b26a084a..11a91bcd2 100644 --- a/block/gossip.go +++ b/block/gossip.go @@ -23,6 +23,7 @@ func (m *Manager) onNewGossipedBlock(event pubsub.Message) { return } + m.UpdateTargetHeight(height) types.LastReceivedP2PHeightGauge.Set(float64(height)) m.logger.Debug("Received new block via gossip.", "block height", height, "store height", m.State.Height(), "n cachedBlocks", m.blockCache.Size()) diff --git a/block/manager.go b/block/manager.go index 5bd4c3746..edced5f02 100644 --- a/block/manager.go +++ b/block/manager.go @@ -55,7 +55,7 @@ type Manager struct { */ // The last height which was submitted to both sublayers, that we know of. When we produce new batches, we will // start at this height + 1. - // It is ALSO used by the producer, because the producer needs to check if it can prune blocks and it wont' + // It is ALSO used by the producer, because the producer needs to check if it can prune blocks and it won't // prune anything that might be submitted in the future. Therefore, it must be atomic. LastSubmittedHeight atomic.Uint64 @@ -68,6 +68,9 @@ type Manager struct { Retriever da.BatchRetriever // get the next target height to sync local state to targetSyncHeight diodes.Diode + // TargetHeight holds the value of the current highest block seen from either p2p (probably higher) or the DA + TargetHeight atomic.Uint64 + // Cached blocks and commits for applying at future heights. The blocks may not be valid, because // we can only do full validation in sequential order. blockCache *Cache @@ -227,3 +230,12 @@ func (m *Manager) syncBlockManager() error { m.logger.Info("Synced.", "current height", m.State.Height(), "last submitted height", m.LastSubmittedHeight.Load()) return nil } + +func (m *Manager) UpdateTargetHeight(h uint64) { + for { + currentHeight := m.TargetHeight.Load() + if m.TargetHeight.CompareAndSwap(currentHeight, max(currentHeight, h)) { + break + } + } +} diff --git a/block/manager_test.go b/block/manager_test.go index dcae5d160..51f7f9f3c 100644 --- a/block/manager_test.go +++ b/block/manager_test.go @@ -3,6 +3,7 @@ package block_test import ( "context" "crypto/rand" + "sync/atomic" "testing" "time" @@ -10,12 +11,13 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/dymensionxyz/dymint/block" "github.com/dymensionxyz/dymint/p2p" "github.com/dymensionxyz/dymint/settlement" "github.com/dymensionxyz/dymint/testutil" "github.com/dymensionxyz/dymint/types" - "github.com/libp2p/go-libp2p/core/crypto" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" @@ -439,3 +441,34 @@ func TestDAFetch(t *testing.T) { }) } } + +func TestManager_updateTargetHeight(t *testing.T) { + tests := []struct { + name string + TargetHeight uint64 + h uint64 + expTargetHeight uint64 + }{ + { + name: "no update target height", + TargetHeight: 100, + h: 99, + expTargetHeight: 100, + }, { + name: "update target height", + TargetHeight: 100, + h: 101, + expTargetHeight: 101, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &block.Manager{ + TargetHeight: atomic.Uint64{}, + } + m.TargetHeight.Store(tt.TargetHeight) + m.UpdateTargetHeight(tt.h) + assert.Equal(t, tt.expTargetHeight, m.TargetHeight.Load()) + }) + } +} diff --git a/block/submit.go b/block/submit.go index f4e6cbe03..fdd13d6c5 100644 --- a/block/submit.go +++ b/block/submit.go @@ -7,11 +7,12 @@ import ( "sync/atomic" "time" + "github.com/dymensionxyz/gerr-cosmos/gerrc" + "golang.org/x/sync/errgroup" + "github.com/dymensionxyz/dymint/da" "github.com/dymensionxyz/dymint/types" uchannel "github.com/dymensionxyz/dymint/utils/channel" - "github.com/dymensionxyz/gerr-cosmos/gerrc" - "golang.org/x/sync/errgroup" ) // SubmitLoop is the main loop for submitting blocks to the DA and SL layers. diff --git a/block/sync.go b/block/sync.go index 9c3e27ec1..9e37d8277 100644 --- a/block/sync.go +++ b/block/sync.go @@ -42,6 +42,7 @@ func (m *Manager) SyncToTargetHeightLoop(ctx context.Context) (err error) { continue } types.RollappHubHeightGauge.Set(float64(h)) + m.UpdateTargetHeight(h) m.targetSyncHeight.Set(diodes.GenericDataType(&h)) m.logger.Info("Set new target sync height", "height", h) case <-subscription.Cancelled(): diff --git a/rpc/client/client.go b/rpc/client/client.go index 9a6473aca..5fb78c44e 100644 --- a/rpc/client/client.go +++ b/rpc/client/client.go @@ -7,12 +7,7 @@ import ( "sort" "time" - "github.com/dymensionxyz/dymint/types" - - "github.com/dymensionxyz/dymint/version" - sdkerrors "cosmossdk.io/errors" - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/config" tmbytes "github.com/tendermint/tendermint/libs/bytes" @@ -29,6 +24,8 @@ import ( "github.com/dymensionxyz/dymint/mempool" "github.com/dymensionxyz/dymint/node" + "github.com/dymensionxyz/dymint/types" + "github.com/dymensionxyz/dymint/version" ) const ( @@ -750,13 +747,14 @@ func (c *Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) { LatestAppHash: latestAppHash[:], LatestBlockHeight: int64(latestHeight), LatestBlockTime: time.Unix(0, int64(latestBlockTimeNano)), + // CatchingUp is true if the node is not at the latest height received from p2p or da. + CatchingUp: c.node.BlockManager.TargetHeight.Load() > latestHeight, // TODO(tzdybal): add missing fields // EarliestBlockHash: earliestBlockHash, // EarliestAppHash: earliestAppHash, // EarliestBlockHeight: earliestBloc // kHeight, // EarliestBlockTime: time.Unix(0, earliestBlockTimeNano), - // CatchingUp: env.ConsensusReactor.WaitSync(), }, // TODO(ItzhakBokris): update ValidatorInfo fields ValidatorInfo: ctypes.ValidatorInfo{