Skip to content

Commit

Permalink
Add host client introspection tests
Browse files Browse the repository at this point in the history
  • Loading branch information
h5law committed Jul 24, 2023
1 parent 8cfd9af commit f61c97a
Show file tree
Hide file tree
Showing 3 changed files with 273 additions and 2 deletions.
3 changes: 2 additions & 1 deletion ibc/client/introspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/pokt-network/pocket/shared/codec"
"github.com/pokt-network/pocket/shared/modules"
util_types "github.com/pokt-network/pocket/utility/types"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/durationpb"
)

Expand Down Expand Up @@ -119,7 +120,7 @@ func (c *clientManager) VerifyHostClientState(counterparty modules.ClientState)
poktCounter.TrustLevel.GT(&light_client_types.Fraction{Numerator: 1, Denominator: 1}) {
return errors.New("counterparty client state trust level is not in the accepted range")
}
if !poktCounter.ProofSpec.ConvertToIcs23ProofSpec().SpecEquals(poktHost.ProofSpec.ConvertToIcs23ProofSpec()) {
if !proto.Equal(poktCounter.ProofSpec, poktHost.ProofSpec) {
return errors.New("counterparty client state has different proof spec")
}
if poktCounter.UnbondingPeriod != poktHost.UnbondingPeriod {
Expand Down
271 changes: 271 additions & 0 deletions ibc/host_introspection_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
package ibc

import (
"errors"
"testing"
"time"

ics23 "github.com/cosmos/ics23/go"
light_client_types "github.com/pokt-network/pocket/ibc/client/light_clients/types"
client_types "github.com/pokt-network/pocket/ibc/client/types"
"github.com/pokt-network/pocket/ibc/types"
"github.com/pokt-network/pocket/shared/codec"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/durationpb"
)

func TestHost_GetCurrentHeight(t *testing.T) {
_, _, _, _, ibcMod := prepareEnvironment(t, 1, 0, 0, 0)
cm := ibcMod.GetBus().GetClientManager()

// get the current height
height, err := cm.GetCurrentHeight()
require.NoError(t, err)
require.Equal(t, uint64(1), height.GetRevisionNumber())
require.Equal(t, uint64(0), height.GetRevisionHeight())

// increment the height
publishNewHeightEvent(t, ibcMod.GetBus(), 1)

height, err = cm.GetCurrentHeight()
require.NoError(t, err)
require.Equal(t, uint64(1), height.GetRevisionNumber())
require.Equal(t, uint64(1), height.GetRevisionHeight())
}

func TestHost_GetHostConsensusState(t *testing.T) {
_, _, _, _, ibcMod := prepareEnvironment(t, 1, 0, 0, 0)
cm := ibcMod.GetBus().GetClientManager()

consState, err := cm.GetHostConsensusState(&client_types.Height{RevisionNumber: 1, RevisionHeight: 0})
require.NoError(t, err)

require.Equal(t, "08-wasm", consState.ClientType())
require.NoError(t, consState.ValidateBasic())
require.Less(t, consState.GetTimestamp(), uint64(time.Now().UnixNano()))

pocketConState := new(light_client_types.PocketConsensusState)
err = codec.GetCodec().Unmarshal(consState.GetData(), pocketConState)
require.NoError(t, err)

blockstore := ibcMod.GetBus().GetPersistenceModule().GetBlockStore()
block, err := blockstore.GetBlock(0)
require.NoError(t, err)

require.Equal(t, block.BlockHeader.Timestamp, pocketConState.Timestamp)
require.Equal(t, block.BlockHeader.StateHash, pocketConState.StateHash)
require.Equal(t, block.BlockHeader.StateTreeHashes, pocketConState.StateTreeHashes)
require.Equal(t, block.BlockHeader.NextValSetHash, pocketConState.NextValSetHash)
}

func TestHost_GetHostClientState(t *testing.T) {
_, _, _, _, ibcMod := prepareEnvironment(t, 1, 0, 0, 0)
cm := ibcMod.GetBus().GetClientManager()

clientState, err := cm.GetHostClientState(&client_types.Height{RevisionNumber: 1, RevisionHeight: 0})
require.NoError(t, err)
require.Equal(t, "08-wasm", clientState.ClientType())

pocketClientState := new(light_client_types.PocketClientState)
err = codec.GetCodec().Unmarshal(clientState.GetData(), pocketClientState)
require.NoError(t, err)

blockstore := ibcMod.GetBus().GetPersistenceModule().GetBlockStore()
block, err := blockstore.GetBlock(0)
require.NoError(t, err)

require.Equal(t, pocketClientState.NetworkId, block.BlockHeader.NetworkId)
require.Equal(t, pocketClientState.TrustLevel, &light_client_types.Fraction{Numerator: 2, Denominator: 3})
require.Equal(t, pocketClientState.TrustingPeriod.AsDuration().Nanoseconds(), int64(1814400000000000))
require.Equal(t, pocketClientState.UnbondingPeriod.AsDuration().Nanoseconds(), int64(1814400000000000))
require.Equal(t, pocketClientState.MaxClockDrift.AsDuration().Nanoseconds(), int64(900000000000))
require.Equal(t, pocketClientState.LatestHeight, &client_types.Height{RevisionNumber: 1, RevisionHeight: 0})
require.True(t, pocketClientState.ProofSpec.ConvertToIcs23ProofSpec().SpecEquals(ics23.SmtSpec))
}

func TestHost_VerifyHostClientState(t *testing.T) {
_, _, _, persistenceMod, ibcMod := prepareEnvironment(t, 1, 0, 0, 0)
cm := ibcMod.GetBus().GetClientManager()

approxTime := time.Minute * 15
unbondingPeriod := time.Duration(1814400000000000) * approxTime
blockstore := ibcMod.GetBus().GetPersistenceModule().GetBlockStore()
block, err := blockstore.GetBlock(0)
require.NoError(t, err)

publishNewHeightEvent(t, ibcMod.GetBus(), 1)

rwCtx, err := persistenceMod.NewRWContext(1)
require.NoError(t, err)
defer rwCtx.Release()
err = rwCtx.Commit(nil, nil)
require.NoError(t, err)

testCases := []struct {
name string
pcs *light_client_types.PocketClientState
expectedErr error
}{
{
name: "invalid: frozen client",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
ProofSpec: types.SmtSpec,
FrozenHeight: 1,
},
expectedErr: errors.New("counterparty client state is frozen"),
},
{
name: "invalid: different network id",
pcs: &light_client_types.PocketClientState{
NetworkId: "not correct",
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
ProofSpec: types.SmtSpec,
},
expectedErr: errors.New("counterparty client state has a different network id"),
},
{
name: "invalid: different revision number",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 0,
RevisionHeight: 0,
},
ProofSpec: types.SmtSpec,
},
expectedErr: errors.New("counterparty client state has a different revision number"),
},
{
name: "invalid: equal height",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 1,
},
ProofSpec: types.SmtSpec,
},
expectedErr: errors.New("counterparty client state has a height greater than or equal to the host client state"),
},
{
name: "invalid: wrong trust level",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 1, Denominator: 4},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
ProofSpec: types.SmtSpec,
},
expectedErr: errors.New("counterparty client state trust level is not in the accepted range"),
},
{
name: "invalid: different proof spec",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
ProofSpec: types.ConvertFromIcs23ProofSpec(ics23.IavlSpec),
},
expectedErr: errors.New("counterparty client state has different proof spec"),
},
{
name: "invalid: different unbonding period",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod + 1),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
ProofSpec: types.SmtSpec,
},
expectedErr: errors.New("counterparty client state has different unbonding period"),
},
{
name: "invalid: unbonding period less than trusting period",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod - 1),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
ProofSpec: types.SmtSpec,
},
expectedErr: errors.New("counterparty client state unbonding period is less than trusting period"),
},
{
name: "valid client state",
pcs: &light_client_types.PocketClientState{
NetworkId: block.BlockHeader.NetworkId,
TrustLevel: &light_client_types.Fraction{Numerator: 2, Denominator: 3},
TrustingPeriod: durationpb.New(unbondingPeriod),
UnbondingPeriod: durationpb.New(unbondingPeriod),
MaxClockDrift: durationpb.New(approxTime),
LatestHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
ProofSpec: types.SmtSpec,
},
expectedErr: nil,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
bz, err := codec.GetCodec().Marshal(tc.pcs)
require.NoError(t, err)
clientState := &client_types.ClientState{
Data: bz,
RecentHeight: &client_types.Height{
RevisionNumber: 1,
RevisionHeight: 0,
},
}
err = cm.VerifyHostClientState(clientState)
require.ErrorAs(t, err, &tc.expectedErr)
})
}
}
1 change: 0 additions & 1 deletion ibc/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ func newTestP2PModule(t *testing.T, bus modules.Bus) modules.P2PModule {
AnyTimes()
p2pMock.EXPECT().GetModuleName().Return(modules.P2PModuleName).AnyTimes()
p2pMock.EXPECT().HandleEvent(gomock.Any()).Return(nil).AnyTimes()
bus.RegisterModule(p2pMock)

return p2pMock
}
Expand Down

0 comments on commit f61c97a

Please sign in to comment.