Skip to content

Commit

Permalink
Tests for compass communication (#254)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vizualni authored Jun 21, 2022
1 parent 984ff68 commit 6f634c3
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 101 deletions.
1 change: 0 additions & 1 deletion testutil/keeper/valset.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ func ValsetKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
memStoreKey,
paramsSubspace,
nil,
nil,
)

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())
Expand Down
11 changes: 11 additions & 0 deletions util/slice/filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package slice

func Filter[V any](slice []V, filterIn func(val V) bool) []V {
var filtered []V
for _, item := range slice {
if filterIn(item) {
filtered = append(filtered, item)
}
}
return filtered
}
3 changes: 2 additions & 1 deletion x/consensus/keeper/consensus/consensus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ func TestConsensusQueueAllMethods(t *testing.T) {
sig := &types.SignData{
ValAddress: sdk.ValAddress("bob"),
Signature: []byte(`custom signature`),
PublicKey: []byte("it does not matter"),
}

cq.AddSignature(ctx, msgs[0].GetId(), []byte("does not matter"), sig)
cq.AddSignature(ctx, msgs[0].GetId(), sig)

t.Run("getting all messages should still return one", func(t *testing.T) {
var err error
Expand Down
10 changes: 5 additions & 5 deletions x/consensus/keeper/consensus/mocks/Queuer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 21 additions & 10 deletions x/evm/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import (
valsettypes "github.com/palomachain/paloma/x/valset/types"
)

const (
maxPower = 1 << 32
)
const (
ConsensusArbitraryContractCall = consensustypes.ConsensusQueueType("evm-arbitrary-smart-contract-call")
ConsensusTurnstoneMessage = consensustypes.ConsensusQueueType("evm-turnstone-message")
Expand All @@ -28,9 +31,13 @@ type evmChainTemp struct {
turnstoneID string
}

func (e evmChainTemp) ChainID() string {
return e.chainID
}

var zero32Byte [32]byte

var supportedChainIDs = []evmChainTemp{
var SupportedChainIDs = []evmChainTemp{
{"eth-main", string(zero32Byte[:])},
{"ropsten", string(zero32Byte[:])},
}
Expand Down Expand Up @@ -72,16 +79,24 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger {

func (k Keeper) AddSmartContractExecutionToConsensus(
ctx sdk.Context,
msg *types.Message,
chainID,
turnstoneID string,
logicCall *types.SubmitLogicCall,
) error {
return k.ConsensusKeeper.PutMessageForSigning(
ctx,
consensustypes.Queue(
ConsensusTurnstoneMessage,
consensustypes.ChainTypeEVM,
msg.ChainID,
chainID,
),
msg,
&types.Message{
ChainID: chainID,
TurnstoneID: turnstoneID,
Action: &types.Message_SubmitLogicCall{
SubmitLogicCall: logicCall,
},
},
)
}

Expand Down Expand Up @@ -122,7 +137,7 @@ func (k Keeper) RegisterConsensusQueues(adder consensus.RegistryAdder) {
return receivedAddr.Hex() == recoveredAddr.Hex()
}

for _, chain := range supportedChainIDs {
for _, chain := range SupportedChainIDs {
adder.AddConcencusQueueType(
false,
consensus.WithChainInfo(consensustypes.ChainTypeEVM, chain.chainID),
Expand Down Expand Up @@ -152,12 +167,8 @@ func (k Keeper) RegisterConsensusQueues(adder consensus.RegistryAdder) {

}

const (
maxPower = 1 << 32
)

func (k Keeper) OnSnapshotBuilt(ctx sdk.Context, snapshot *valsettypes.Snapshot) {
for _, chain := range supportedChainIDs {
for _, chain := range SupportedChainIDs {
valset := transformSnapshotToTurnstoneValset(snapshot, chain.chainID)

k.ConsensusKeeper.PutMessageForSigning(
Expand Down
179 changes: 116 additions & 63 deletions x/evm/keeper/keeper_integration_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
package keeper_test

import (
"math/big"
"strings"
"testing"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/palomachain/paloma/app"
"github.com/palomachain/paloma/testutil/rand"
"github.com/palomachain/paloma/testutil/sample"
"github.com/palomachain/paloma/util/slice"
consensustypes "github.com/palomachain/paloma/x/consensus/types"
"github.com/palomachain/paloma/x/evm/keeper"
"github.com/palomachain/paloma/x/evm/types"
valsettypes "github.com/palomachain/paloma/x/valset/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
"github.com/vizualni/whoops"
)

func genValidators(t *testing.T, numValidators, totalConsPower int) []stakingtypes.Validator {
Expand Down Expand Up @@ -43,66 +58,104 @@ func genValidators(t *testing.T, numValidators, totalConsPower int) []stakingtyp
return validators
}

// func TestEndToEndForEvmArbitraryCall(t *testing.T) {
// chainType, chainID := consensustypes.ChainTypeEVM, "eth-main"
// a := app.NewTestApp(t, false)
// ctx := a.NewContext(false, tmproto.Header{
// Height: 5,
// })

// validators := genValidators(t, 25, 25000)
// for _, val := range validators {
// a.StakingKeeper.SetValidator(ctx, val)
// }

// smartContractAddr := common.BytesToAddress(rand.Bytes(5))
// err := a.EvmKeeper.AddSmartContractExecutionToConsensus(
// ctx,
// &types.ArbitrarySmartContractCall{
// Payload: func() []byte {
// evm := whoops.Must(abi.JSON(strings.NewReader(sample.SimpleABI)))
// return whoops.Must(evm.Pack("store", big.NewInt(1337)))
// }(),
// HexAddress: smartContractAddr.Hex(),
// Abi: []byte(sample.SimpleABI),
// },
// )

// require.NoError(t, err)

// private, err := crypto.GenerateKey()
// require.NoError(t, err)

// accAddr := crypto.PubkeyToAddress(private.PublicKey)
// err = a.ValsetKeeper.AddExternalChainInfo(ctx, validators[0].GetOperator(), []*valsettypes.ExternalChainInfo{
// {
// ChainType: chainType,
// ChainID: chainID,
// Address: accAddr.Hex(),
// Pubkey: accAddr[:],
// },
// })

// require.NoError(t, err)
// queue := consensustypes.Queue(keeper.ConsensusArbitraryContractCall, chainType, chainID)
// msgs, err := a.ConsensusKeeper.GetMessagesForSigning(ctx, queue, validators[0].GetOperator())

// for _, msg := range msgs {
// sigbz, err := crypto.Sign(msg.GetBytesToSign(), private)
// require.NoError(t, err)
// err = a.ConsensusKeeper.AddMessageSignature(
// ctx,
// validators[0].GetOperator(),
// []*consensustypes.MsgAddMessagesSignatures_MsgSignedMessage{
// {
// Id: msg.GetId(),
// QueueTypeName: queue,
// Signature: sigbz,
// SignedByAddress: accAddr.Hex(),
// },
// },
// )
// require.NoError(t, err)
// }

// }
func TestEndToEndForEvmArbitraryCall(t *testing.T) {
chainType, chainID := consensustypes.ChainTypeEVM, "eth-main"
a := app.NewTestApp(t, false)
ctx := a.NewContext(false, tmproto.Header{
Height: 5,
})

validators := genValidators(t, 25, 25000)
for _, val := range validators {
a.StakingKeeper.SetValidator(ctx, val)
}

smartContractAddr := common.BytesToAddress(rand.Bytes(5))
err := a.EvmKeeper.AddSmartContractExecutionToConsensus(
ctx,
chainID,
"",
&types.SubmitLogicCall{
Payload: func() []byte {
evm := whoops.Must(abi.JSON(strings.NewReader(sample.SimpleABI)))
return whoops.Must(evm.Pack("store", big.NewInt(1337)))
}(),
HexContractAddress: smartContractAddr.Hex(),
Abi: []byte(sample.SimpleABI),
Deadline: 1337,
},
)

require.NoError(t, err)

private, err := crypto.GenerateKey()
require.NoError(t, err)

accAddr := crypto.PubkeyToAddress(private.PublicKey)
err = a.ValsetKeeper.AddExternalChainInfo(ctx, validators[0].GetOperator(), []*valsettypes.ExternalChainInfo{
{
ChainType: chainType,
ChainID: chainID,
Address: accAddr.Hex(),
Pubkey: accAddr[:],
},
})

require.NoError(t, err)
queue := consensustypes.Queue(keeper.ConsensusArbitraryContractCall, chainType, chainID)
msgs, err := a.ConsensusKeeper.GetMessagesForSigning(ctx, queue, validators[0].GetOperator())

for _, msg := range msgs {
sigbz, err := crypto.Sign(msg.GetBytesToSign(), private)
require.NoError(t, err)
err = a.ConsensusKeeper.AddMessageSignature(
ctx,
validators[0].GetOperator(),
[]*consensustypes.MsgAddMessagesSignatures_MsgSignedMessage{
{
Id: msg.GetId(),
QueueTypeName: queue,
Signature: sigbz,
SignedByAddress: accAddr.Hex(),
},
},
)
require.NoError(t, err)
}

}

func TestOnSnapshotBuilt(t *testing.T) {
a := app.NewTestApp(t, false)
ctx := a.NewContext(false, tmproto.Header{
Height: 5,
})

validators := genValidators(t, 25, 25000)
for _, val := range validators {
a.StakingKeeper.SetValidator(ctx, val)
}

var supportedChainIDs []string
for _, c := range keeper.SupportedChainIDs {
supportedChainIDs = append(supportedChainIDs, c.ChainID())
}

require.Empty(t, slice.Filter(supportedChainIDs, func(chainID string) bool {
queue := consensustypes.Queue(keeper.ConsensusTurnstoneMessage, consensustypes.ChainTypeEVM, chainID)
msgs, err := a.ConsensusKeeper.GetMessagesFromQueue(ctx, queue, 1)
require.NoError(t, err)
return len(msgs) > 0
}))

snapshot, err := a.ValsetKeeper.TriggerSnapshotBuild(ctx)
require.NoError(t, err)
a.EvmKeeper.OnSnapshotBuilt(ctx, snapshot)

require.Len(t, slice.Filter(supportedChainIDs, func(chainID string) bool {
queue := consensustypes.Queue(keeper.ConsensusTurnstoneMessage, consensustypes.ChainTypeEVM, chainID)
msgs, err := a.ConsensusKeeper.GetMessagesFromQueue(ctx, queue, 1)
require.NoError(t, err)
return len(msgs) > 0
}), 2)
}
18 changes: 7 additions & 11 deletions x/evm/keeper/msg_server_submit_new_job.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,13 @@ func (k msgServer) SubmitNewJob(goCtx context.Context, msg *types.MsgSubmitNewJo

err := k.AddSmartContractExecutionToConsensus(
ctx,
&types.Message{
ChainID: msg.ChainID,
TurnstoneID: string(zero32Byte[:]),
Action: &types.Message_SubmitLogicCall{
SubmitLogicCall: &types.SubmitLogicCall{
HexContractAddress: msg.GetHexSmartContractAddress(),
Payload: common.Hex2Bytes(msg.GetHexPayload()),
Abi: []byte(msg.GetAbi()),
Deadline: ctx.BlockTime().UTC().Add(5 * time.Minute).Unix(),
},
},
msg.GetChainID(),
string(zero32Byte[:]),
&types.SubmitLogicCall{
HexContractAddress: msg.GetHexSmartContractAddress(),
Payload: common.Hex2Bytes(msg.GetHexPayload()),
Abi: []byte(msg.GetAbi()),
Deadline: ctx.BlockTime().UTC().Add(5 * time.Minute).Unix(),
},
)

Expand Down
22 changes: 15 additions & 7 deletions x/evm/types/turnstone_abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,31 +66,39 @@ func (_m *Message_SubmitLogicCall) keccak256(orig *Message, nonce uint64) []byte
arguments := abi.Arguments{
// arguments
{Type: whoops.Must(abi.NewType("tuple", "", []abi.ArgumentMarshaling{
{Type: "address"},
{Type: "bytes"},
{Name: "address", Type: "address"},
{Name: "payload", Type: "bytes"},
}))},
// message id
{Type: whoops.Must(abi.NewType("uint256", "", nil))},
// turnstone id
{Type: whoops.Must(abi.NewType("bytes", "", nil))},
{Type: whoops.Must(abi.NewType("bytes32", "", nil))},
// deadline
{Type: whoops.Must(abi.NewType("uint256", "", nil))},
}

method := abi.NewMethod("logic_call", "logic_call", abi.Function, "", false, false, arguments, abi.Arguments{})
var bytes32 [32]byte

copy(bytes32[:], orig.GetTurnstoneID())

bytes, err := arguments.Pack(
[]any{
struct {
Address common.Address
Payload []byte
}{
common.HexToAddress(m.GetHexContractAddress()),
m.GetPayload(),
},
new(big.Int).SetInt64(int64(nonce)).Bytes(),
orig.GetTurnstoneID(),
m.GetDeadline(),
new(big.Int).SetInt64(int64(nonce)),
bytes32,
big.NewInt(m.GetDeadline()),
)

if err != nil {
panic(err)
}

bytes = append(method.ID[:], bytes...)

return crypto.Keccak256(bytes)
Expand Down
Loading

0 comments on commit 6f634c3

Please sign in to comment.