|
package http_test
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/tendermint/tendermint/abci/example/kvstore"
|
|
"github.com/tendermint/tendermint/light/provider"
|
|
lighthttp "github.com/tendermint/tendermint/light/provider/http"
|
|
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
|
rpchttp "github.com/tendermint/tendermint/rpc/client/http"
|
|
rpctest "github.com/tendermint/tendermint/rpc/test"
|
|
"github.com/tendermint/tendermint/types"
|
|
)
|
|
|
|
func TestNewProvider(t *testing.T) {
|
|
c, err := lighthttp.New("chain-test", "192.168.0.1:26657")
|
|
require.NoError(t, err)
|
|
require.Equal(t, c.ID(), "http{http://192.168.0.1:26657}")
|
|
|
|
c, err = lighthttp.New("chain-test", "http://153.200.0.1:26657")
|
|
require.NoError(t, err)
|
|
require.Equal(t, c.ID(), "http{http://153.200.0.1:26657}")
|
|
|
|
c, err = lighthttp.New("chain-test", "153.200.0.1")
|
|
require.NoError(t, err)
|
|
require.Equal(t, c.ID(), "http{http://153.200.0.1}")
|
|
}
|
|
|
|
func TestProvider(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
cfg, err := rpctest.CreateConfig(t.Name())
|
|
require.NoError(t, err)
|
|
|
|
// start a tendermint node in the background to test against
|
|
app := kvstore.NewApplication()
|
|
app.RetainBlocks = 9
|
|
_, closer, err := rpctest.StartTendermint(ctx, cfg, app)
|
|
require.NoError(t, err)
|
|
|
|
rpcAddr := cfg.RPC.ListenAddress
|
|
genDoc, err := types.GenesisDocFromFile(cfg.GenesisFile())
|
|
require.NoError(t, err)
|
|
|
|
chainID := genDoc.ChainID
|
|
t.Log("chainID:", chainID)
|
|
|
|
c, err := rpchttp.New(rpcAddr)
|
|
require.NoError(t, err)
|
|
|
|
p := lighthttp.NewWithClient(chainID, c)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, p)
|
|
|
|
// let it produce some blocks
|
|
err = rpcclient.WaitForHeight(ctx, c, 10, nil)
|
|
require.NoError(t, err)
|
|
|
|
// let's get the highest block
|
|
lb, err := p.LightBlock(ctx, 0)
|
|
require.NoError(t, err)
|
|
assert.True(t, lb.Height < 9001, "height=%d", lb.Height)
|
|
|
|
// let's check this is valid somehow
|
|
assert.Nil(t, lb.ValidateBasic(chainID))
|
|
|
|
// historical queries now work :)
|
|
lower := lb.Height - 3
|
|
lb, err = p.LightBlock(ctx, lower)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, lower, lb.Height)
|
|
|
|
// fetching missing heights (both future and pruned) should return appropriate errors
|
|
lb, err = p.LightBlock(ctx, 9001)
|
|
require.Error(t, err)
|
|
require.Nil(t, lb)
|
|
assert.ErrorIs(t, err, provider.ErrHeightTooHigh)
|
|
|
|
lb, err = p.LightBlock(ctx, 1)
|
|
require.Error(t, err)
|
|
require.Nil(t, lb)
|
|
assert.ErrorIs(t, err, provider.ErrLightBlockNotFound)
|
|
|
|
// if the provider is unable to provide four more blocks then we should return
|
|
// an unreliable peer error
|
|
for i := 0; i < 4; i++ {
|
|
_, err = p.LightBlock(ctx, 1)
|
|
}
|
|
assert.IsType(t, provider.ErrUnreliableProvider{}, err)
|
|
|
|
// shut down tendermint node
|
|
require.NoError(t, closer(ctx))
|
|
cancel()
|
|
|
|
time.Sleep(10 * time.Second)
|
|
lb, err = p.LightBlock(ctx, lower+2)
|
|
// Either the connection should be refused, or the context canceled.
|
|
require.Error(t, err)
|
|
require.Nil(t, lb)
|
|
if !errors.Is(err, provider.ErrConnectionClosed) && !errors.Is(err, context.Canceled) {
|
|
assert.Fail(t, "Incorrect error", "wanted connection closed or context canceled, got %v", err)
|
|
}
|
|
}
|