Skip to content

Commit

Permalink
tests(e2e): Osmosis e2e tests (#2029)
Browse files Browse the repository at this point in the history
* cosmoswasm artifacts

* first pass

* run make format

* add comments

* run make format

* fix lint

* fix wrong params

* lint code

* lint code

* refactor utils func

* update osmosis ver

* update compile contracts script

* enable osmosis outpost

* update bins & add contract patch

* remove unnecessary dump to file

* update app.go with bank keeper in availablePrecompiles

* refactor

* update test setup for contract v1

* remove unnecessary changes

* make format

* fix lint issues

* fix lint issues

* add channel patch

* update comment

* fix lint issues

* fix lint issues

* Apply suggestions from code review

Co-authored-by: stepit <48993133+0xstepit@users.noreply.github.com>

* address review comments

* fix onFailDelivery unit test

* fix gosec issues

* Update precompiles/outposts/osmosis/types.go

---------

Co-authored-by: facs95 <facs95@users.noreply.github.com>
Co-authored-by: tom <tomasguerraalda@hotmail.com>
Co-authored-by: Tom <54514587+GAtom22@users.noreply.github.com>
Co-authored-by: stepit <48993133+0xstepit@users.noreply.github.com>
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
  • Loading branch information
6 people committed Dec 4, 2023
1 parent cfad1ee commit 8a890e2
Show file tree
Hide file tree
Showing 17 changed files with 672 additions and 129 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (p256-precompile) [#2110](https://github.com/evmos/evmos/pull/2110) Adjust `p256` precompile address.
- (upgrade) [#2117](https://github.com/evmos/evmos/pull/2117) Enable Stride and Osmosis outposts in v16 upgrade handler.
- (osmosis-outpost) [#2109](https://github.com/evmos/evmos/pull/2109) Add Osmosis outpost to available EVM extensions.
- (osmosis-outpost) [#2029](https://github.com/evmos/evmos/pull/2029) Add Osmosis outpost end-to-end tests.
- (upgrade) [#2131](https://github.com/evmos/evmos/pull/2131) Remove incentives pool burning logic from upgrade handler.

### Bug Fixes
Expand Down
6 changes: 3 additions & 3 deletions nix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ import sources.nixpkgs {
# cause it is faster than building from source
osmosisd = pkgs.callPackage ./bin.nix {
appName = "osmosisd";
version = "v19.2.0";
binUrl = "https://github.com/osmosis-labs/osmosis/releases/download/v19.2.0/osmosisd-19.2.0-linux-amd64";
sha256 = "sha256-cj/xxTSes8A5w9xfVYlbveLhSZ/nwKlpYMxvre7IFMQ=";
version = "v20.2.1";
binUrl = "https://github.com/osmosis-labs/osmosis/releases/download/v20.2.1/osmosisd-20.2.1-linux-amd64";
sha256 = "sha256-TmCocIYcoXgZ+8tJ//mBtXMewRIdfLq0OYfF8E/wmfo=";
};
# Using gaia v11 (includes the PFM) cause after this version the '--min-self-delegation' flag is removed
# from the 'gentx' cmd.
Expand Down
33 changes: 23 additions & 10 deletions precompiles/outposts/osmosis/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"encoding/json"
"fmt"
"math/big"
"strconv"

"golang.org/x/exp/slices"

Expand Down Expand Up @@ -75,7 +76,7 @@ func NewIBCChannel(
// TWAP represents a Time-Weighted Average Price configuration.
type TWAP struct {
// SlippagePercentage specifies the acceptable slippage percentage for a transaction.
SlippagePercentage uint8 `json:"slippage_percentage"`
SlippagePercentage string `json:"slippage_percentage"`
// WindowSeconds defines the duration for which the TWAP is calculated.
WindowSeconds uint64 `json:"window_seconds"`
}
Expand All @@ -98,7 +99,7 @@ type OsmosisSwap struct {
// OnFailedDelivery specifies the action to be taken in case the swap delivery fails.
// This can be "do_nothing" or the address on the Osmosis chain that can recover funds
// in case of errors.
OnFailedDelivery string `json:"on_failed_delivery"`
OnFailedDelivery interface{} `json:"on_failed_delivery"`
// NextMemo contains any additional memo information for the next operation in a PFM setting.
NextMemo string `json:"next_memo,omitempty"`
}
Expand All @@ -123,6 +124,12 @@ type RawPacketMetadata struct {
Wasm *WasmMemo `json:"wasm"`
}

// RecoveryAddress is the address to send the funds in case of failed delivery.
type RecoveryAddress struct {
// The recovery address in Osmosis chain.
Address string `json:"local_recovery_addr"`
}

// Validate performs basic validation of the IBC memo for the Osmosis outpost.
// This function assumes that memo field is parsed with ParseSwapPacketData, which
// performs data casting ensuring outputDenom cannot be an empty string.
Expand All @@ -142,7 +149,11 @@ func (r RawPacketMetadata) Validate() error {
return fmt.Errorf(ErrReceiverAddress, "not a valid evmos address")
}

if osmosisSwap.Slippage.TWAP.SlippagePercentage == 0 || osmosisSwap.Slippage.TWAP.SlippagePercentage > MaxSlippagePercentage {
slippagePercNum, err := strconv.ParseUint(osmosisSwap.Slippage.TWAP.SlippagePercentage, 10, 8)
if err != nil {
return fmt.Errorf(ErrSlippagePercentage, "not valid slippage percentage")
}
if slippagePercNum == 0 || slippagePercNum > uint64(MaxSlippagePercentage) {
return fmt.Errorf(ErrSlippagePercentage)
}

Expand All @@ -159,8 +170,10 @@ func CreatePacketWithMemo(
outputDenom, receiver, contract string,
slippagePercentage uint8,
windowSeconds uint64,
onFailedDelivery, nextMemo string,
onFailedDelivery interface{}, nextMemo string,
) *RawPacketMetadata {
// slippage percentage is a string in the memo field
slippagePercStr := strconv.FormatUint(uint64(slippagePercentage), 10)
return &RawPacketMetadata{
&WasmMemo{
Contract: contract,
Expand All @@ -169,7 +182,7 @@ func CreatePacketWithMemo(
OutputDenom: outputDenom,
Slippage: &Slippage{
&TWAP{
SlippagePercentage: slippagePercentage,
SlippagePercentage: slippagePercStr,
WindowSeconds: windowSeconds,
},
},
Expand All @@ -186,7 +199,7 @@ func CreatePacketWithMemo(
// string.
func (r RawPacketMetadata) String() string {
// Convert the struct to a JSON string
jsonBytes, err := json.MarshalIndent(r, "", " ")
jsonBytes, err := json.Marshal(r)
if err != nil {
return ""
}
Expand All @@ -196,20 +209,20 @@ func (r RawPacketMetadata) String() string {

// CreateOnFailedDeliveryField is an utility function to create the memo field
// onFailedDelivery. The returned string is the bech32 of the input or "do_nothing".
func CreateOnFailedDeliveryField(address string) string {
onFailedDelivery := address
func CreateOnFailedDeliveryField(address string) interface{} {
recoveryAddress := address
bech32Prefix, addressBytes, err := cosmosbech32.DecodeAndConvert(address)
if err != nil {
return DefaultOnFailedDelivery
}
if bech32Prefix != OsmosisPrefix {
onFailedDelivery, err = sdk.Bech32ifyAddressBytes(OsmosisPrefix, addressBytes)
recoveryAddress, err = sdk.Bech32ifyAddressBytes(OsmosisPrefix, addressBytes)
if err != nil {
return DefaultOnFailedDelivery
}
}

return onFailedDelivery
return RecoveryAddress{Address: recoveryAddress}
}

// ValidateInputOutput validates the input and output tokens used in the Osmosis swap.
Expand Down
38 changes: 22 additions & 16 deletions precompiles/outposts/osmosis/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ func TestCreatePacketWithMemo(t *testing.T) {
contract string
slippagePercentage uint8
windowSeconds uint64
onFailedDelivery string
onFailedDelivery interface{}
nextMemo string
expNextMemo bool
expMemo string
}{
{
name: "pass - correct string without memo",
Expand All @@ -40,7 +40,7 @@ func TestCreatePacketWithMemo(t *testing.T) {
windowSeconds: 30,
onFailedDelivery: doNothing,
nextMemo: "",
expNextMemo: false,
expMemo: "{\"wasm\":{\"contract\":\"evmos1vl0x3xr0zwgrllhdzxxlkal7txnnk56q3552x7\",\"msg\":{\"osmosis_swap\":{\"output_denom\":\"aevmos\",\"slippage\":{\"twap\":{\"slippage_percentage\":\"10\",\"window_seconds\":30}},\"receiver\":\"evmos1vl0x3xr0zwgrllhdzxxlkal7txnnk56q3552x7\",\"on_failed_delivery\":\"do_nothing\"}}}}",
},
{
name: "pass - correct string with memo",
Expand All @@ -51,7 +51,18 @@ func TestCreatePacketWithMemo(t *testing.T) {
windowSeconds: 30,
onFailedDelivery: doNothing,
nextMemo: "a next memo",
expNextMemo: true,
expMemo: "{\"wasm\":{\"contract\":\"evmos1vl0x3xr0zwgrllhdzxxlkal7txnnk56q3552x7\",\"msg\":{\"osmosis_swap\":{\"output_denom\":\"aevmos\",\"slippage\":{\"twap\":{\"slippage_percentage\":\"10\",\"window_seconds\":30}},\"receiver\":\"evmos1vl0x3xr0zwgrllhdzxxlkal7txnnk56q3552x7\",\"on_failed_delivery\":\"do_nothing\",\"next_memo\":\"a next memo\"}}}}",
},
{
name: "pass - correct string with memo and recovery address",
outputDenom: utils.BaseDenom,
receiver: receiver,
contract: contract,
slippagePercentage: 10,
windowSeconds: 30,
onFailedDelivery: osmosisoutpost.RecoveryAddress{"osmo1g8j7tgfam7kmj86zks5rcfxruf9lzp87u8mwdf"},
nextMemo: "a next memo",
expMemo: "{\"wasm\":{\"contract\":\"evmos1vl0x3xr0zwgrllhdzxxlkal7txnnk56q3552x7\",\"msg\":{\"osmosis_swap\":{\"output_denom\":\"aevmos\",\"slippage\":{\"twap\":{\"slippage_percentage\":\"10\",\"window_seconds\":30}},\"receiver\":\"evmos1vl0x3xr0zwgrllhdzxxlkal7txnnk56q3552x7\",\"on_failed_delivery\":{\"local_recovery_addr\":\"osmo1g8j7tgfam7kmj86zks5rcfxruf9lzp87u8mwdf\"},\"next_memo\":\"a next memo\"}}}}",
},
}

Expand All @@ -64,15 +75,10 @@ func TestCreatePacketWithMemo(t *testing.T) {
packet := osmosisoutpost.CreatePacketWithMemo(
tc.outputDenom, tc.receiver, tc.contract, tc.slippagePercentage, tc.windowSeconds, tc.onFailedDelivery, tc.nextMemo,
)
packetString := packet.String()
err := ValidateAndParseWasmRoutedMemo(packetString, tc.receiver)
memo := packet.String()
require.Equal(t, tc.expMemo, memo)
err := ValidateAndParseWasmRoutedMemo(memo, tc.receiver)
require.NoError(t, err, "memo is not a valid wasm routed JSON formatted string")

if tc.expNextMemo {
require.Contains(t, packetString, fmt.Sprintf("\"next_memo\": \"%s\"", tc.nextMemo))
} else {
require.NotContains(t, packetString, fmt.Sprintf("next_memo: %s", tc.nextMemo))
}
})

}
Expand Down Expand Up @@ -448,12 +454,12 @@ func TestCreateOnFailedDeliveryField(t *testing.T) {
testCases := []struct {
name string
address string
expRes string
expRes interface{}
}{
{
name: "receiver osmo bech32",
address: address,
expRes: address,
expRes: osmosisoutpost.RecoveryAddress{address},
},
{
name: "use default do_nothing",
Expand All @@ -463,7 +469,7 @@ func TestCreateOnFailedDeliveryField(t *testing.T) {
{
name: "convert receiver to osmo bech32",
address: "cosmos1c2m73hdt6f37w9jqpqps5t3ha3st99dcsp7lf5",
expRes: address,
expRes: osmosisoutpost.RecoveryAddress{address},
},
}

Expand All @@ -474,7 +480,7 @@ func TestCreateOnFailedDeliveryField(t *testing.T) {
t.Parallel()

onFailedDelivery := osmosisoutpost.CreateOnFailedDeliveryField(tc.address)
require.Contains(t, onFailedDelivery, tc.expRes)
require.Equal(t, onFailedDelivery, tc.expRes)
})
}
}
Expand Down
27 changes: 27 additions & 0 deletions scripts/compile-cosmwasm-contracts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env bash

echo "Compiling CosmWasm contracts"

# For the osmosis outpost we're using the v1 of the
# crosschain swap contract. This is available in v15.x
OSMOSIS_VERSION=v15.2.0
# For this script to work properly
# We need to copy the contents of the cosmwasm folder of the
# Osmosis repo (https://github.com/osmosis-labs/osmosis/tree/v20.2.1/cosmwasm)
# into the ./tests/nix_tests/cosmwasm folder

git clone -b $OSMOSIS_VERSION --single-branch https://github.com/osmosis-labs/osmosis.git /tmp/osmosis

cp -r /tmp/osmosis/cosmwasm/* ./tests/nix_tests/cosmwasm
rm -rf /tmp/osmosis

cd ./tests/nix_tests/cosmwasm || exit
# This command compiles the contracts for x86-64 (amd64) arch
docker run --rm -v "$(pwd)":/code \
--mount type=volume,source="$(basename "$(pwd)")_cache",target=/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
cosmwasm/workspace-optimizer:0.15.0

# Remove all files and subdirectories except 'artifacts'
# where the compiled contracts are located
find . -mindepth 1 -maxdepth 1 ! -name 'artifacts' -exec rm -r {} \;
16 changes: 16 additions & 0 deletions tests/nix_tests/configs/osmosis-channel.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/x/evm/keeper/precompiles.go b/x/evm/keeper/precompiles.go
index b0aa3202..39668025 100644
--- a/x/evm/keeper/precompiles.go
+++ b/x/evm/keeper/precompiles.go
@@ -88,8 +88,10 @@ func AvailablePrecompiles(
panic(fmt.Errorf("failed to instantiate stride outpost: %w", err))
}

+ // Update the channel for the corresponding one in the
+ // Nix testing setup
osmosisOutpost, err := osmosisoutpost.NewPrecompile(
- transfertypes.PortID, "channel-215",
+ transfertypes.PortID, "channel-0",
osmosisoutpost.XCSContractTestnet,
authzKeeper, bankKeeper, transferKeeper, stakingKeeper, erc20Keeper, channelKeeper,
)
79 changes: 3 additions & 76 deletions tests/nix_tests/configs/osmosis-outpost.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -10,79 +10,6 @@ config {
},
},
},
'cosmoshub-1': {
cmd: 'gaiad',
'account-prefix': 'cosmos',
'app-config': {
'minimum-gas-prices': '0.0025uatom',
},
validators: [
{
coins: '2234240000000000000uatom',
staked: '10000000000000uatom',
mnemonic: '${VALIDATOR1_MNEMONIC}',
base_port: 26800,
},
{
coins: '987870000000000000uatom',
staked: '20000000000000uatom',
mnemonic: '${VALIDATOR2_MNEMONIC}',
base_port: 26810,
},
],
accounts: [
{
name: 'community',
coins: '10000000000000uatom',
mnemonic: '${COMMUNITY_MNEMONIC}',
},
{
name: 'relayer',
coins: '10000000000000uatom',
mnemonic: '${SIGNER1_MNEMONIC}',
},
{
name: 'signer2',
coins: '10000000000000uatom',
mnemonic: '${SIGNER2_MNEMONIC}',
},
],
genesis: {
app_state: {
staking: {
params: {
unbonding_time: '1814400s',
bond_denom: 'uatom',
},
},
gov: {
voting_params: {
voting_period: '1814400s',
},
deposit_params: {
max_deposit_period: '1814400s',
min_deposit: [
{
denom: 'uatom',
amount: '10000000',
},
],
},
},
mint: {
params: {
mint_denom: 'uatom',
},
},
transfer: {
params: {
receive_enabled: true,
send_enabled: true,
},
},
},
},
},
'osmosis-1': {
cmd: 'osmosisd',
'account-prefix': 'osmo',
Expand Down Expand Up @@ -153,7 +80,7 @@ config {
denom: 'uosmo',
amount: '50000000',
},
],
],
},
},
poolincentives: {
Expand All @@ -165,7 +92,7 @@ config {
params: {
mint_denom: 'uosmo',
},
},
},
transfer: {
params: {
receive_enabled: true,
Expand All @@ -174,7 +101,7 @@ config {
},
},
},
},
},
relayer: {
mode: {
clients: {
Expand Down
15 changes: 15 additions & 0 deletions tests/nix_tests/configs/osmosis-outpost.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{ pkgs ? import ../../../nix { } }:
let evmosd = (pkgs.callPackage ../../../. { });
in
evmosd.overrideAttrs (oldAttrs: {
# Patch the evmos binary to:
# - allow to register WEVMOS token pair
# - use the CrossChainSwap contract address in the testing setup
# - update the corresponding IBC channel to match the tests setup
patches = oldAttrs.patches or [ ] ++ [
./allow-wevmos-register.patch
./xcs-osmosis-contract.patch
./osmosis-channel.patch
];
})

0 comments on commit 8a890e2

Please sign in to comment.