Skip to content

Commit

Permalink
Merge branch 'main' into assert
Browse files Browse the repository at this point in the history
  • Loading branch information
Manav-Aggarwal authored Nov 23, 2023
2 parents 8280d3b + 2437b3d commit 138604f
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 85 deletions.
8 changes: 4 additions & 4 deletions block/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ type Manager struct {

// getInitialState tries to load lastState from Store, and if it's not available it reads GenesisDoc.
func getInitialState(store store.Store, genesis *cmtypes.GenesisDoc) (types.State, error) {
s, err := store.LoadState()
s, err := store.GetState()
if err != nil {
s, err = types.NewFromGenesisDoc(genesis)
}
Expand Down Expand Up @@ -598,11 +598,11 @@ func (m *Manager) publishBlock(ctx context.Context) error {
if newHeight == uint64(m.genesis.InitialHeight) {
lastCommit = &types.Commit{}
} else {
lastCommit, err = m.store.LoadCommit(height)
lastCommit, err = m.store.GetCommit(height)
if err != nil {
return fmt.Errorf("error while loading last commit: %w", err)
}
lastBlock, err := m.store.LoadBlock(height)
lastBlock, err := m.store.GetBlock(height)
if err != nil {
return fmt.Errorf("error while loading last block: %w", err)
}
Expand All @@ -614,7 +614,7 @@ func (m *Manager) publishBlock(ctx context.Context) error {

// Check if there's an already stored block at a newer height
// If there is use that instead of creating a new block
pendingBlock, err := m.store.LoadBlock(newHeight)
pendingBlock, err := m.store.GetBlock(newHeight)
if err == nil {
m.logger.Info("Using pending block", "height", newHeight)
block = pendingBlock
Expand Down
8 changes: 8 additions & 0 deletions node/full.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/cometbft/cometbft/libs/service"
corep2p "github.com/cometbft/cometbft/p2p"
proxy "github.com/cometbft/cometbft/proxy"
rpcclient "github.com/cometbft/cometbft/rpc/client"
cmtypes "github.com/cometbft/cometbft/types"

"github.com/rollkit/rollkit/block"
Expand Down Expand Up @@ -71,6 +72,7 @@ type FullNode struct {
mempoolIDs *mempoolIDs
Store store.Store
blockManager *block.Manager
client rpcclient.Client

// Preserves cometBFT compatibility
TxIndexer txindex.TxIndexer
Expand Down Expand Up @@ -168,6 +170,7 @@ func newFullNode(

node.BaseService = *service.NewBaseService(logger, "Node", node)
node.p2pClient.SetTxValidator(node.newTxValidator())
node.client = NewFullClient(node)

return node, nil
}
Expand Down Expand Up @@ -302,6 +305,11 @@ func (n *FullNode) blockPublishLoop(ctx context.Context) {
}
}

// GetClient returns the RPC client for the full node.
func (n *FullNode) GetClient() rpcclient.Client {
return n.client
}

// Cancel calls the underlying context's cancel function.
func (n *FullNode) Cancel() {
n.cancel()
Expand Down
43 changes: 17 additions & 26 deletions node/full_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ var _ rpcclient.Client = &FullClient{}
type FullClient struct {
*cmtypes.EventBus
config *config.RPCConfig

node *FullNode
node *FullNode
}

// NewFullClient returns Client working with given node.
Expand All @@ -60,14 +59,6 @@ func NewFullClient(node *FullNode) *FullClient {
}
}

// GetClient returns a new RPC client for the full node.
//
// TODO: should this be NewRPPCClient? Or should we add the client as a field of
// the FullNode so that it is just created once?
func (n *FullNode) GetClient() rpcclient.Client {
return NewFullClient(n)
}

// ABCIInfo returns basic information about application state.
func (c *FullClient) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
resInfo, err := c.appClient().Query().InfoSync(proxy.RequestInfo)
Expand Down Expand Up @@ -327,7 +318,7 @@ func (c *FullClient) BlockchainInfo(ctx context.Context, minHeight, maxHeight in

blocks := make([]*cmtypes.BlockMeta, 0, maxHeight-minHeight+1)
for height := maxHeight; height >= minHeight; height-- {
block, err := c.node.Store.LoadBlock(uint64(height))
block, err := c.node.Store.GetBlock(uint64(height))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -417,7 +408,7 @@ func (c *FullClient) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
// If height is nil, it returns information about last known block.
func (c *FullClient) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
heightValue := c.normalizeHeight(height)
block, err := c.node.Store.LoadBlock(heightValue)
block, err := c.node.Store.GetBlock(heightValue)
if err != nil {
return nil, err
}
Expand All @@ -440,7 +431,7 @@ func (c *FullClient) Block(ctx context.Context, height *int64) (*ctypes.ResultBl

// BlockByHash returns BlockID and block itself for given hash.
func (c *FullClient) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
block, err := c.node.Store.LoadBlockByHash(hash)
block, err := c.node.Store.GetBlockByHash(hash)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -469,7 +460,7 @@ func (c *FullClient) BlockResults(ctx context.Context, height *int64) (*ctypes.R
} else {
h = uint64(*height)
}
resp, err := c.node.Store.LoadBlockResponses(h)
resp, err := c.node.Store.GetBlockResponses(h)
if err != nil {
return nil, err
}
Expand All @@ -487,11 +478,11 @@ func (c *FullClient) BlockResults(ctx context.Context, height *int64) (*ctypes.R
// Commit returns signed header (aka commit) at given height.
func (c *FullClient) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
heightValue := c.normalizeHeight(height)
com, err := c.node.Store.LoadCommit(heightValue)
com, err := c.node.Store.GetCommit(heightValue)
if err != nil {
return nil, err
}
b, err := c.node.Store.LoadBlock(heightValue)
b, err := c.node.Store.GetBlock(heightValue)
if err != nil {
return nil, err
}
Expand All @@ -507,7 +498,7 @@ func (c *FullClient) Commit(ctx context.Context, height *int64) (*ctypes.ResultC
// Validators returns paginated list of validators at given height.
func (c *FullClient) Validators(ctx context.Context, heightPtr *int64, pagePtr, perPagePtr *int) (*ctypes.ResultValidators, error) {
height := c.normalizeHeight(heightPtr)
validators, err := c.node.Store.LoadValidators(height)
validators, err := c.node.Store.GetValidators(height)
if err != nil {
return nil, fmt.Errorf("failed to load validators for height %d: %w", height, err)
}
Expand Down Expand Up @@ -545,7 +536,7 @@ func (c *FullClient) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.R

var proof cmtypes.TxProof
if prove {
block, _ := c.node.Store.LoadBlock(uint64(height))
block, _ := c.node.Store.GetBlock(uint64(height))
blockProof := block.Data.Txs.Proof(int(index)) // XXX: overflow on 32-bit machines
proof = cmtypes.TxProof{
RootHash: blockProof.RootHash,
Expand Down Expand Up @@ -614,7 +605,7 @@ func (c *FullClient) TxSearch(ctx context.Context, query string, prove bool, pag

var proof cmtypes.TxProof
/*if prove {
block := nil //env.BlockStore.LoadBlock(r.Height)
block := nil //env.BlockStore.GetBlock(r.Height)
proof = block.Data.Txs.Proof(int(r.Index)) // XXX: overflow on 32-bit machines
}*/

Expand Down Expand Up @@ -674,7 +665,7 @@ func (c *FullClient) BlockSearch(ctx context.Context, query string, page, perPag
// Fetch the blocks
blocks := make([]*ctypes.ResultBlock, 0, pageSize)
for i := skipCount; i < skipCount+pageSize; i++ {
b, err := c.node.Store.LoadBlock(uint64(results[i]))
b, err := c.node.Store.GetBlock(uint64(results[i]))
if err != nil {
return nil, err
}
Expand All @@ -695,23 +686,23 @@ func (c *FullClient) BlockSearch(ctx context.Context, query string, page, perPag

// Status returns detailed information about current status of the node.
func (c *FullClient) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
latest, err := c.node.Store.LoadBlock(c.node.Store.Height())
latest, err := c.node.Store.GetBlock(c.node.Store.Height())
if err != nil {
return nil, fmt.Errorf("failed to find latest block: %w", err)
}

initial, err := c.node.Store.LoadBlock(uint64(c.node.GetGenesis().InitialHeight))
initial, err := c.node.Store.GetBlock(uint64(c.node.GetGenesis().InitialHeight))
if err != nil {
return nil, fmt.Errorf("failed to find earliest block: %w", err)
}

validators, err := c.node.Store.LoadValidators(latest.Height())
validators, err := c.node.Store.GetValidators(latest.Height())
if err != nil {
return nil, fmt.Errorf("failed to fetch the validator info at latest block: %w", err)
}
_, validator := validators.GetByAddress(latest.SignedHeader.ProposerAddress)

state, err := c.node.Store.LoadState()
state, err := c.node.Store.GetState()
if err != nil {
return nil, fmt.Errorf("failed to load the last saved state: %w", err)
}
Expand Down Expand Up @@ -815,7 +806,7 @@ func (c *FullClient) HeaderByHash(ctx context.Context, hash cmbytes.HexBytes) (*
// decoding logic in the HTTP service will correctly translate from JSON.
// See https://github.com/cometbft/cometbft/issues/6802 for context.

block, err := c.node.Store.LoadBlockByHash(types.Hash(hash))
block, err := c.node.Store.GetBlockByHash(types.Hash(hash))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -899,7 +890,7 @@ func (c *FullClient) normalizeHeight(height *int64) uint64 {
}

func (rpc *FullClient) getBlockMeta(n int64) *cmtypes.BlockMeta {
b, err := rpc.node.Store.LoadBlock(uint64(n))
b, err := rpc.node.Store.GetBlock(uint64(n))
if err != nil {
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion node/full_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func getRandomBlockWithProposer(height uint64, nTxs int, proposerAddr []byte) *t
}

func getBlockMeta(rpc *FullClient, n int64) *cmtypes.BlockMeta {
b, err := rpc.node.Store.LoadBlock(uint64(n))
b, err := rpc.node.Store.GetBlock(uint64(n))
if err != nil {
return nil
}
Expand Down
7 changes: 3 additions & 4 deletions node/full_node_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ func TestTxGossipingAndAggregation(t *testing.T) {

// assert that all blocks known to node are same as produced by aggregator
for h := uint64(1); h <= nodes[i].Store.Height(); h++ {
aggBlock, err := nodes[0].Store.LoadBlock(h)
aggBlock, err := nodes[0].Store.GetBlock(h)
require.NoError(t, err)
nodeBlock, err := nodes[i].Store.LoadBlock(h)
nodeBlock, err := nodes[i].Store.GetBlock(h)
require.NoError(t, err)
assert.Equal(t, aggBlock, nodeBlock, fmt.Sprintf("height: %d", h))
}
Expand Down Expand Up @@ -266,8 +266,7 @@ func TestFastDASync(t *testing.T) {
// Verify that the block we synced to is DA included. This is to
// ensure that the test is passing due to the DA syncing, since the P2P
// block sync will sync quickly but the block won't be DA included.
block, err := node2.Store.LoadBlock(numberOfBlocksToSyncTill)

block, err := node2.Store.GetBlock(numberOfBlocksToSyncTill)
require.NoError(t, err)
require.True(t, node2.blockManager.IsDAIncluded(block.Hash()))
}
Expand Down
8 changes: 5 additions & 3 deletions node/light.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ type LightNode struct {

hSyncService *block.HeaderSyncService

client rpcclient.Client

ctx context.Context
cancel context.CancelFunc
}

// GetClient returns a new rpcclient for the light node
// TODO: this should be renamed to NewRPCClient or some New variant since it is
// creating a new item
func (ln *LightNode) GetClient() rpcclient.Client {
return NewLightClient(ln)
return ln.client
}

func newLightNode(
Expand Down Expand Up @@ -85,6 +85,8 @@ func newLightNode(

node.BaseService = *service.NewBaseService(logger, "LightNode", node)

node.client = NewLightClient(node)

return node, nil
}

Expand Down
32 changes: 16 additions & 16 deletions store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,20 @@ func (s *DefaultStore) SaveBlock(block *types.Block, commit *types.Commit) error
return nil
}

// LoadBlock returns block at given height, or error if it's not found in Store.
// GetBlock returns block at given height, or error if it's not found in Store.
// TODO(tzdybal): what is more common access pattern? by height or by hash?
// currently, we're indexing height->hash, and store blocks by hash, but we might as well store by height
// and index hash->height
func (s *DefaultStore) LoadBlock(height uint64) (*types.Block, error) {
func (s *DefaultStore) GetBlock(height uint64) (*types.Block, error) {
h, err := s.loadHashFromIndex(height)
if err != nil {
return nil, fmt.Errorf("failed to load hash from index: %w", err)
}
return s.LoadBlockByHash(h)
return s.GetBlockByHash(h)
}

// LoadBlockByHash returns block with given block header hash, or error if it's not found in Store.
func (s *DefaultStore) LoadBlockByHash(hash types.Hash) (*types.Block, error) {
// GetBlockByHash returns block with given block header hash, or error if it's not found in Store.
func (s *DefaultStore) GetBlockByHash(hash types.Hash) (*types.Block, error) {
blockData, err := s.db.Get(s.ctx, ds.NewKey(getBlockKey(hash)))
if err != nil {
return nil, fmt.Errorf("failed to load block data: %w", err)
Expand All @@ -130,8 +130,8 @@ func (s *DefaultStore) SaveBlockResponses(height uint64, responses *cmstate.ABCI
return s.db.Put(s.ctx, ds.NewKey(getResponsesKey(height)), data)
}

// LoadBlockResponses returns block results at given height, or error if it's not found in Store.
func (s *DefaultStore) LoadBlockResponses(height uint64) (*cmstate.ABCIResponses, error) {
// GetBlockResponses returns block results at given height, or error if it's not found in Store.
func (s *DefaultStore) GetBlockResponses(height uint64) (*cmstate.ABCIResponses, error) {
data, err := s.db.Get(s.ctx, ds.NewKey(getResponsesKey(height)))
if err != nil {
return nil, fmt.Errorf("failed to retrieve block results from height %v: %w", height, err)
Expand All @@ -144,17 +144,17 @@ func (s *DefaultStore) LoadBlockResponses(height uint64) (*cmstate.ABCIResponses
return &responses, nil
}

// LoadCommit returns commit for a block at given height, or error if it's not found in Store.
func (s *DefaultStore) LoadCommit(height uint64) (*types.Commit, error) {
// GetCommit returns commit for a block at given height, or error if it's not found in Store.
func (s *DefaultStore) GetCommit(height uint64) (*types.Commit, error) {
hash, err := s.loadHashFromIndex(height)
if err != nil {
return nil, fmt.Errorf("failed to load hash from index: %w", err)
}
return s.LoadCommitByHash(hash)
return s.GetCommitByHash(hash)
}

// LoadCommitByHash returns commit for a block with given block header hash, or error if it's not found in Store.
func (s *DefaultStore) LoadCommitByHash(hash types.Hash) (*types.Commit, error) {
// GetCommitByHash returns commit for a block with given block header hash, or error if it's not found in Store.
func (s *DefaultStore) GetCommitByHash(hash types.Hash) (*types.Commit, error) {
commitData, err := s.db.Get(s.ctx, ds.NewKey(getCommitKey(hash)))
if err != nil {
return nil, fmt.Errorf("failed to retrieve commit from hash %v: %w", hash, err)
Expand All @@ -181,8 +181,8 @@ func (s *DefaultStore) UpdateState(state types.State) error {
return s.db.Put(s.ctx, ds.NewKey(getStateKey()), data)
}

// LoadState returns last state saved with UpdateState.
func (s *DefaultStore) LoadState() (types.State, error) {
// GetState returns last state saved with UpdateState.
func (s *DefaultStore) GetState() (types.State, error) {
blob, err := s.db.Get(s.ctx, ds.NewKey(getStateKey()))
if err != nil {
return types.State{}, fmt.Errorf("failed to retrieve state: %w", err)
Expand Down Expand Up @@ -213,8 +213,8 @@ func (s *DefaultStore) SaveValidators(height uint64, validatorSet *cmtypes.Valid
return s.db.Put(s.ctx, ds.NewKey(getValidatorsKey(height)), blob)
}

// LoadValidators loads validator set at given block height from store.
func (s *DefaultStore) LoadValidators(height uint64) (*cmtypes.ValidatorSet, error) {
// GetValidators loads validator set at given block height from store.
func (s *DefaultStore) GetValidators(height uint64) (*cmtypes.ValidatorSet, error) {
blob, err := s.db.Get(s.ctx, ds.NewKey(getValidatorsKey(height)))
if err != nil {
return nil, fmt.Errorf("failed to load Validators for height %v: %w", height, err)
Expand Down
16 changes: 8 additions & 8 deletions store/store.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ The Store interface defines the following methods:
- `Height`: Returns the height of the highest block in the store.
- `SetHeight`: Sets given height in the store if it's higher than the existing height in the store.
- `SaveBlock`: Saves a block along with its seen commit.
- `LoadBlock`: Returns a block at a given height.
- `LoadBlockByHash`: Returns a block with a given block header hash.
- `GetBlock`: Returns a block at a given height.
- `GetBlockByHash`: Returns a block with a given block header hash.
- `SaveBlockResponses`: Saves block responses in the Store.
- `LoadBlockResponses`: Returns block results at a given height.
- `LoadCommit`: Returns a commit for a block at a given height.
- `LoadCommitByHash`: Returns a commit for a block with a given block header hash.
- `GetBlockResponses`: Returns block results at a given height.
- `GetCommit`: Returns a commit for a block at a given height.
- `GetCommitByHash`: Returns a commit for a block with a given block header hash.
- `UpdateState`: Updates the state saved in the Store. Only one State is stored.
- `LoadState`: Returns the last state saved with UpdateState.
- `GetState`: Returns the last state saved with UpdateState.
- `SaveValidators`: Saves the validator set at a given height.
- `LoadValidators`: Returns the validator set at a given height.
- `GetValidators`: Returns the validator set at a given height.

The `TxnDatastore` interface inside [go-datastore] is used for constructing different key-value stores for the underlying storage of a full node. The are two different implementations of `TxnDatastore` in [kv.go]:

Expand All @@ -39,7 +39,7 @@ For the main node data, `DefaultStore` struct, an implementation of the Store in
- `responsesPrefix` with value "r": Used to store responses related to the blocks.
- `validatorsPrefix` with value "v": Used to store validator sets at a given height.

For example, in a call to `LoadBlockByHash` for some block hash `<block_hash>`, the key used in the full node's base key-value store will be `/0/b/<block_hash>` where `0` is the main store prefix and `b` is the block prefix. Similarly, in a call to `LoadValidators` for some height `<height>`, the key used in the full node's base key-value store will be `/0/v/<height>` where `0` is the main store prefix and `v` is the validator set prefix.
For example, in a call to `GetBlockByHash` for some block hash `<block_hash>`, the key used in the full node's base key-value store will be `/0/b/<block_hash>` where `0` is the main store prefix and `b` is the block prefix. Similarly, in a call to `GetValidators` for some height `<height>`, the key used in the full node's base key-value store will be `/0/v/<height>` where `0` is the main store prefix and `v` is the validator set prefix.

Inside the key-value store, the value of these various types of data like `Block`, `Commit`, etc is stored as a byte array which is encoded and decoded using the corresponding Protobuf [marshal and unmarshal methods][serialization].

Expand Down
Loading

0 comments on commit 138604f

Please sign in to comment.