255 lines
11 KiB
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.
|
|
}
|