wormhole/node/pkg/watchers/ibc/watcher_test.go

255 lines
11 KiB
Go

package ibc
import (
"encoding/base64"
"encoding/hex"
"encoding/json"
"reflect"
"strconv"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
"go.uber.org/zap"
"github.com/certusone/wormhole/node/pkg/common"
"github.com/wormhole-foundation/wormhole/sdk/vaa"
)
func TestParseIbcReceivePublishEvent(t *testing.T) {
logger := zap.NewNop()
eventJson := `{"type": "wasm","attributes": [` +
`{"key": "X2NvbnRyYWN0X2FkZHJlc3M=","value": "d29ybWhvbGUxbmM1dGF0YWZ2NmV5cTdsbGtyMmd2NTBmZjllMjJtbmY3MHFnamx2NzM3a3RtdDRlc3dycTBrZGhjag==","index": true},` +
`{"key": "YWN0aW9u", "value": "cmVjZWl2ZV9wdWJsaXNo", "index": true},` +
`{"key": "Y2hhbm5lbF9pZA==", "value": "Y2hhbm5lbC0w", "index": true},` +
`{"key": "bWVzc2FnZS5tZXNzYWdl","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNA==","index": true},` +
`{"key": "bWVzc2FnZS5zZW5kZXI=","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzU3NDMwNzQ5NTZjNzEwODAwZTgzMTk4MDExY2NiZDRkZGYxNTU2ZA==","index": true},` +
`{ "key": "bWVzc2FnZS5jaGFpbl9pZA==", "value": "MTg=", "index": true },` +
`{ "key": "bWVzc2FnZS5ub25jZQ==", "value": "MQ==", "index": true },` +
`{ "key": "bWVzc2FnZS5zZXF1ZW5jZQ==", "value": "Mg==", "index": true },` +
`{"key": "bWVzc2FnZS5ibG9ja190aW1l","value": "MTY4MDA5OTgxNA==","index": true},` +
`{"key": "bWVzc2FnZS5ibG9ja19oZWlnaHQ=","value": "MjYxMw==","index": true}` +
`]}`
require.Equal(t, true, gjson.Valid(eventJson))
event := gjson.Parse(eventJson)
contractAddress := "wormhole1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq0kdhcj"
txHash, err := vaa.StringToHash("82ea2536c5d1671830cb49120f94479e34b54596a8dd369fbc2666667a765f4b")
require.NoError(t, err)
evt, err := parseIbcReceivePublishEvent(logger, contractAddress, event, txHash)
require.NoError(t, err)
require.NotNil(t, evt)
expectedSender, err := vaa.StringToAddress("00000000000000000000000035743074956c710800e83198011ccbd4ddf1556d")
require.NoError(t, err)
expectedPayload, err := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000004")
require.NoError(t, err)
expectedResult := ibcReceivePublishEvent{
ChannelID: "channel-0",
Msg: &common.MessagePublication{
TxHash: txHash,
EmitterAddress: expectedSender,
EmitterChain: vaa.ChainIDTerra2,
Nonce: 1,
Sequence: 2,
Timestamp: time.Unix(1680099814, 0),
Payload: expectedPayload,
},
}
// Use DeepEqual() because the response contains pointers.
assert.True(t, reflect.DeepEqual(expectedResult, *evt))
}
func TestParseEventForWrongContract(t *testing.T) {
logger := zap.NewNop()
eventJson := `{"type": "wasm","attributes": [` +
`{"key": "X2NvbnRyYWN0X2FkZHJlc3M=","value": "d29ybWhvbGUxbmM1dGF0YWZ2NmV5cTdsbGtyMmd2NTBmZjllMjJtbmY3MHFnamx2NzM3a3RtdDRlc3dycTBrZGhjag==","index": true},` +
`{"key": "YWN0aW9u", "value": "cmVjZWl2ZV9wdWJsaXNo", "index": true},` +
`{"key": "Y2hhbm5lbF9pZA==", "value": "Y2hhbm5lbC0w", "index": true},` +
`{"key": "bWVzc2FnZS5tZXNzYWdl","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNA==","index": true},` +
`{"key": "bWVzc2FnZS5zZW5kZXI=","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzU3NDMwNzQ5NTZjNzEwODAwZTgzMTk4MDExY2NiZDRkZGYxNTU2ZA==","index": true},` +
`{ "key": "bWVzc2FnZS5jaGFpbl9pZA==", "value": "MTg=", "index": true },` +
`{ "key": "bWVzc2FnZS5ub25jZQ==", "value": "MQ==", "index": true },` +
`{ "key": "bWVzc2FnZS5zZXF1ZW5jZQ==", "value": "Mg==", "index": true },` +
`{"key": "bWVzc2FnZS5ibG9ja190aW1l","value": "MTY4MDA5OTgxNA==","index": true},` +
`{"key": "bWVzc2FnZS5ibG9ja19oZWlnaHQ=","value": "MjYxMw==","index": true}` +
`]}`
require.Equal(t, true, gjson.Valid(eventJson))
event := gjson.Parse(eventJson)
contractAddress := "someOtherContract"
txHash, err := vaa.StringToHash("82ea2536c5d1671830cb49120f94479e34b54596a8dd369fbc2666667a765f4b")
require.NoError(t, err)
_, err = parseIbcReceivePublishEvent(logger, contractAddress, event, txHash)
assert.Error(t, err)
}
func TestParseEventForWrongAction(t *testing.T) {
logger := zap.NewNop()
eventJson := `{"type": "wasm","attributes": [` +
`{"key": "X2NvbnRyYWN0X2FkZHJlc3M=","value": "d29ybWhvbGUxbmM1dGF0YWZ2NmV5cTdsbGtyMmd2NTBmZjllMjJtbmY3MHFnamx2NzM3a3RtdDRlc3dycTBrZGhjag==","index": true},` +
`{"key": "YWN0aW9u", "value": "cmVjZWl2ZV9wa3Q=", "index": true},` + // Changed action value to "receive_pkt"
`{"key": "Y2hhbm5lbF9pZA==", "value": "Y2hhbm5lbC0w", "index": true},` +
`{"key": "bWVzc2FnZS5tZXNzYWdl","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNA==","index": true},` +
`{"key": "bWVzc2FnZS5zZW5kZXI=","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzU3NDMwNzQ5NTZjNzEwODAwZTgzMTk4MDExY2NiZDRkZGYxNTU2ZA==","index": true},` +
`{ "key": "bWVzc2FnZS5jaGFpbl9pZA==", "value": "MTg=", "index": true },` +
`{ "key": "bWVzc2FnZS5ub25jZQ==", "value": "MQ==", "index": true },` +
`{ "key": "bWVzc2FnZS5zZXF1ZW5jZQ==", "value": "Mg==", "index": true },` +
`{"key": "bWVzc2FnZS5ibG9ja190aW1l","value": "MTY4MDA5OTgxNA==","index": true},` +
`{"key": "bWVzc2FnZS5ibG9ja19oZWlnaHQ=","value": "MjYxMw==","index": true}` +
`]}`
require.Equal(t, true, gjson.Valid(eventJson))
event := gjson.Parse(eventJson)
contractAddress := "wormhole1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq0kdhcj"
txHash, err := vaa.StringToHash("82ea2536c5d1671830cb49120f94479e34b54596a8dd369fbc2666667a765f4b")
require.NoError(t, err)
evt, err := parseIbcReceivePublishEvent(logger, contractAddress, event, txHash)
require.NoError(t, err)
assert.Nil(t, evt)
}
func TestParseEventForNoContractSpecified(t *testing.T) {
logger := zap.NewNop()
eventJson := `{"type": "wasm","attributes": [` +
// No contract specified
`{"key": "YWN0aW9u", "value": "cmVjZWl2ZV9wdWJsaXNo", "index": true},` +
`{"key": "Y2hhbm5lbF9pZA==", "value": "Y2hhbm5lbC0w", "index": true},` +
`{"key": "bWVzc2FnZS5tZXNzYWdl","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNA==","index": true},` +
`{"key": "bWVzc2FnZS5zZW5kZXI=","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzU3NDMwNzQ5NTZjNzEwODAwZTgzMTk4MDExY2NiZDRkZGYxNTU2ZA==","index": true},` +
`{ "key": "bWVzc2FnZS5jaGFpbl9pZA==", "value": "MTg=", "index": true },` +
`{ "key": "bWVzc2FnZS5ub25jZQ==", "value": "MQ==", "index": true },` +
`{ "key": "bWVzc2FnZS5zZXF1ZW5jZQ==", "value": "Mg==", "index": true },` +
`{"key": "bWVzc2FnZS5ibG9ja190aW1l","value": "MTY4MDA5OTgxNA==","index": true},` +
`{"key": "bWVzc2FnZS5ibG9ja19oZWlnaHQ=","value": "MjYxMw==","index": true}` +
`]}`
require.Equal(t, true, gjson.Valid(eventJson))
event := gjson.Parse(eventJson)
contractAddress := "wormhole1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq0kdhcj"
txHash, err := vaa.StringToHash("82ea2536c5d1671830cb49120f94479e34b54596a8dd369fbc2666667a765f4b")
require.NoError(t, err)
_, err = parseIbcReceivePublishEvent(logger, contractAddress, event, txHash)
assert.Error(t, err)
}
func TestParseEventForNoActionSpecified(t *testing.T) {
logger := zap.NewNop()
eventJson := `{"type": "wasm","attributes": [` +
`{"key": "X2NvbnRyYWN0X2FkZHJlc3M=","value": "d29ybWhvbGUxbmM1dGF0YWZ2NmV5cTdsbGtyMmd2NTBmZjllMjJtbmY3MHFnamx2NzM3a3RtdDRlc3dycTBrZGhjag==","index": true},` +
// No action specified
`{"key": "Y2hhbm5lbF9pZA==", "value": "Y2hhbm5lbC0w", "index": true},` +
`{"key": "bWVzc2FnZS5tZXNzYWdl","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwNA==","index": true},` +
`{"key": "bWVzc2FnZS5zZW5kZXI=","value": "MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzU3NDMwNzQ5NTZjNzEwODAwZTgzMTk4MDExY2NiZDRkZGYxNTU2ZA==","index": true},` +
`{ "key": "bWVzc2FnZS5jaGFpbl9pZA==", "value": "MTg=", "index": true },` +
`{ "key": "bWVzc2FnZS5ub25jZQ==", "value": "MQ==", "index": true },` +
`{ "key": "bWVzc2FnZS5zZXF1ZW5jZQ==", "value": "Mg==", "index": true },` +
`{"key": "bWVzc2FnZS5ibG9ja190aW1l","value": "MTY4MDA5OTgxNA==","index": true},` +
`{"key": "bWVzc2FnZS5ibG9ja19oZWlnaHQ=","value": "MjYxMw==","index": true}` +
`]}`
require.Equal(t, true, gjson.Valid(eventJson))
event := gjson.Parse(eventJson)
contractAddress := "wormhole1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq0kdhcj"
txHash, err := vaa.StringToHash("82ea2536c5d1671830cb49120f94479e34b54596a8dd369fbc2666667a765f4b")
require.NoError(t, err)
evt, err := parseIbcReceivePublishEvent(logger, contractAddress, event, txHash)
require.NoError(t, err)
assert.Nil(t, evt)
}
func TestParseIbcAllChannelChainsQueryResults(t *testing.T) {
respJson := []byte(`
{
"data": {
"channels_chains": [
[
"Y2hhbm5lbC0w",
18
],
[
"Y2hhbm5lbC00Mg==",
22
]
]
}
}
`)
var result ibcAllChannelChainsQueryResults
err := json.Unmarshal(respJson, &result)
require.NoError(t, err)
expectedChannStr1 := base64.StdEncoding.EncodeToString([]byte("channel-0"))
expectedChannStr2 := base64.StdEncoding.EncodeToString([]byte("channel-42"))
require.Equal(t, 2, len(result.Data.ChannelChains))
require.Equal(t, 2, len(result.Data.ChannelChains[0]))
assert.Equal(t, expectedChannStr1, result.Data.ChannelChains[0][0].(string)) //nolint:forcetypeassert
assert.Equal(t, uint16(18), uint16(result.Data.ChannelChains[0][1].(float64))) //nolint:forcetypeassert
assert.Equal(t, expectedChannStr2, result.Data.ChannelChains[1][0].(string)) //nolint:forcetypeassert
assert.Equal(t, uint16(22), uint16(result.Data.ChannelChains[1][1].(float64))) //nolint:forcetypeassert
}
func TestConvertingWsUrlToHttpUrl(t *testing.T) {
assert.Equal(t, "http://wormchain:26657", convertWsUrlToHttpUrl("ws://wormchain:26657/websocket"))
assert.Equal(t, "http://wormchain:26657", convertWsUrlToHttpUrl("ws://wormchain:26657"))
assert.Equal(t, "http://wormchain:26657", convertWsUrlToHttpUrl("wss://wormchain:26657/websocket"))
assert.Equal(t, "http://wormchain:26657", convertWsUrlToHttpUrl("wss://wormchain:26657"))
assert.Equal(t, "http://wormchain:26657", convertWsUrlToHttpUrl("wormchain:26657"))
}
func TestParseAbciInfoResults(t *testing.T) {
// This came from the following query: http://localhost:26659/abci_info
respJson := []byte(`
{
"jsonrpc": "2.0",
"id": -1,
"result": {
"response": {
"data": "wormchain",
"version": "v0.0.1",
"last_block_height": "2037",
"last_block_app_hash": "7lVJBWOpP+owbc0Gohn4htF6s2J2DrbjhdL9m79lAjU="
}
}
}
`)
var resp abciInfoResults
err := json.Unmarshal(respJson, &resp)
require.NoError(t, err)
assert.Equal(t, "v0.0.1", resp.Result.Response.Version)
assert.Equal(t, "2037", resp.Result.Response.LastBlockHeight)
blockHeight, err := strconv.ParseInt(resp.Result.Response.LastBlockHeight, 10, 64)
require.NoError(t, err)
assert.Equal(t, int64(2037), blockHeight)
assert.Equal(t, float64(2037), float64(blockHeight)) // We need it as a float to post it to Prometheus.
}