Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci(tests): historacle e2e #1687

Merged
merged 19 commits into from
Jan 6, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ dist/

# OSX
*.DS_Store

# e2e test keychain folder
tests/e2e/keyring-test
24 changes: 22 additions & 2 deletions tests/e2e/e2e_setup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
appparams "github.com/umee-network/umee/v3/app/params"
"github.com/umee-network/umee/v3/x/leverage/fixtures"
leveragetypes "github.com/umee-network/umee/v3/x/leverage/types"
oracletypes "github.com/umee-network/umee/v3/x/oracle/types"
)

const (
Expand Down Expand Up @@ -230,6 +231,7 @@ func (s *IntegrationTestSuite) initGenesis() {
appGenState, genDoc, err := genutiltypes.GenesisStateFromGenFile(genFilePath)
s.Require().NoError(err)

// Gravity Bridge
var gravityGenState gravitytypes.GenesisState
s.Require().NoError(cdc.UnmarshalJSON(appGenState[gravitytypes.ModuleName], &gravityGenState))

Expand All @@ -242,12 +244,14 @@ func (s *IntegrationTestSuite) initGenesis() {
var bech32GenState bech32ibctypes.GenesisState
s.Require().NoError(cdc.UnmarshalJSON(appGenState[bech32ibctypes.ModuleName], &bech32GenState))

// bech32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why adding these comments? it's "purple prose"

bech32GenState.NativeHRP = sdk.GetConfig().GetBech32AccountAddrPrefix()

bz, err = cdc.MarshalJSON(&bech32GenState)
s.Require().NoError(err)
appGenState[bech32ibctypes.ModuleName] = bz

// Leverage
var leverageGenState leveragetypes.GenesisState
s.Require().NoError(cdc.UnmarshalJSON(appGenState[leveragetypes.ModuleName], &leverageGenState))

Expand All @@ -259,6 +263,19 @@ func (s *IntegrationTestSuite) initGenesis() {
s.Require().NoError(err)
appGenState[leveragetypes.ModuleName] = bz

// Oracle
var oracleGenState oracletypes.GenesisState
s.Require().NoError(cdc.UnmarshalJSON(appGenState[oracletypes.ModuleName], &oracleGenState))

oracleGenState.Params.HistoricStampPeriod = 5
oracleGenState.Params.MaximumPriceStamps = 4
oracleGenState.Params.MedianStampPeriod = 20

bz, err = cdc.MarshalJSON(&oracleGenState)
s.Require().NoError(err)
appGenState[oracletypes.ModuleName] = bz

// Bank
var bankGenState banktypes.GenesisState
s.Require().NoError(cdc.UnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState))

Expand Down Expand Up @@ -657,7 +674,9 @@ func (s *IntegrationTestSuite) runIBCRelayer() {
s.tmpDirs = append(s.tmpDirs, tmpDir)

gaiaVal := s.chain.gaiaValidators[0]
umeeVal := s.chain.validators[0]
// umeeVal for the relayer needs to be a different account
// than what we use for runPriceFeeder.
umeeVal := s.chain.validators[1]
hermesCfgPath := path.Join(tmpDir, "hermes")

s.Require().NoError(os.MkdirAll(hermesCfgPath, 0o755))
Expand Down Expand Up @@ -685,7 +704,7 @@ func (s *IntegrationTestSuite) runIBCRelayer() {
fmt.Sprintf("UMEE_E2E_GAIA_VAL_MNEMONIC=%s", gaiaVal.mnemonic),
fmt.Sprintf("UMEE_E2E_UMEE_VAL_MNEMONIC=%s", umeeVal.mnemonic),
fmt.Sprintf("UMEE_E2E_GAIA_VAL_HOST=%s", s.gaiaResource.Container.Name[1:]),
fmt.Sprintf("UMEE_E2E_UMEE_VAL_HOST=%s", s.valResources[0].Container.Name[1:]),
fmt.Sprintf("UMEE_E2E_UMEE_VAL_HOST=%s", s.valResources[1].Container.Name[1:]),
},
Entrypoint: []string{
"sh",
Expand Down Expand Up @@ -942,6 +961,7 @@ func (s *IntegrationTestSuite) runPriceFeeder() {
fmt.Sprintf("UMEE_E2E_PRICE_FEEDER_ADDRESS=%s", umeeValAddr),
fmt.Sprintf("UMEE_E2E_PRICE_FEEDER_VALIDATOR=%s", sdk.ValAddress(umeeValAddr)),
fmt.Sprintf("UMEE_E2E_UMEE_VAL_HOST=%s", s.valResources[0].Container.Name[1:]),
fmt.Sprintf("UMEE_E2E_CHAIN_ID=%s", s.chain.id),
},
Entrypoint: []string{
"sh",
Expand Down
11 changes: 11 additions & 0 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"

appparams "github.com/umee-network/umee/v3/app/params"
"github.com/umee-network/umee/v3/tests/gRPC"
)

func (s *IntegrationTestSuite) TestIBCTokenTransfer() {
Expand Down Expand Up @@ -139,3 +140,13 @@ func (s *IntegrationTestSuite) TestUmeeTokenTransfers() {
s.sendFromEthToUmeeCheck(orchestratorIdxSender, umeeValIdxReceiver, umeeERC20Addr, appparams.BondDenom, amount)
})
}

func (s *IntegrationTestSuite) TestHistorical() {
err := gRPC.MedianCheck(
s.chain.id,
"tcp://localhost:26657",
"tcp://localhost:9090",
s.chain.validators[0].mnemonic,
)
s.Require().NoError(err)
}
102 changes: 94 additions & 8 deletions tests/e2e/scripts/price_feeder_bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ touch /root/.price-feeder/config.toml

# setup price-feeder configuration
tee /root/.price-feeder/config.toml <<EOF
gas_adjustment = 1.2
gas_adjustment = 1
provider_timeout = "5000ms"

[server]
Expand All @@ -17,37 +17,123 @@ read_timeout = "20s"
verbose_cors = true
write_timeout = "20s"

[[deviation_thresholds]]
base = "USDT"
threshold = "1.5"

[[deviation_thresholds]]
base = "UMEE"
threshold = "1.5"

[[deviation_thresholds]]
base = "ATOM"
threshold = "1.5"

[[deviation_thresholds]]
base = "USDC"
threshold = "1.5"

[[deviation_thresholds]]
base = "CRO"
threshold = "1.5"

[[deviation_thresholds]]
base = "DAI"
threshold = "2"

[[deviation_thresholds]]
base = "ETH"
threshold = "2"

[[deviation_thresholds]]
base = "WBTC"
threshold = "1.5"

[[currency_pairs]]
base = "UMEE"
providers = [
"mock",
"okx",
"gate",
"mexc",
]
quote = "USDT"

[[currency_pairs]]
base = "USDT"
providers = [
"kraken",
"coinbase",
"binanceus",
]
quote = "USD"

[[currency_pairs]]
base = "ATOM"
providers = [
"okx",
"bitget",
]
quote = "USDT"

[[currency_pairs]]
base = "ATOM"
providers = [
"mock",
"kraken",
]
quote = "USDC"
quote = "USD"

[[currency_pairs]]
base = "USDC"
providers = [
"mock",
"okx",
"bitget",
"kraken",
]
quote = "USDT"

[[currency_pairs]]
base = "DAI"
providers = [
"okx",
"bitget",
"huobi",
]
quote = "USDT"

[[currency_pairs]]
base = "DAI"
providers = [
"kraken",
]
quote = "USD"

[[currency_pairs]]
base = "USDT"
base = "ETH"
providers = [
"okx",
"bitget",
]
quote = "USDT"

[[currency_pairs]]
base = "ETH"
providers = [
"mock",
"kraken",
]
quote = "USD"

[[currency_pairs]]
base = "WBTC"
providers = [
"okx",
"bitget",
"crypto",
]
quote = "USDT"

[account]
address = '$UMEE_E2E_PRICE_FEEDER_ADDRESS'
chain_id = "umee-local-testnet"
chain_id = '$UMEE_E2E_CHAIN_ID'
validator = '$UMEE_E2E_PRICE_FEEDER_VALIDATOR'

[keyring]
Expand Down
112 changes: 112 additions & 0 deletions tests/gRPC/chain_height.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package gRPC

import (
"context"
"errors"
"sync"

"github.com/rs/zerolog"
tmrpcclient "github.com/tendermint/tendermint/rpc/client"
tmctypes "github.com/tendermint/tendermint/rpc/core/types"
tmtypes "github.com/tendermint/tendermint/types"
)

var (
errParseEventDataNewBlockHeader = errors.New("error parsing EventDataNewBlockHeader")
queryEventNewBlockHeader = tmtypes.QueryForEvent(tmtypes.EventNewBlockHeader)
)

// ChainHeight is used to cache the chain height of the
// current node which is being updated each time the
// node sends an event of EventNewBlockHeader.
// It starts a goroutine to subscribe to blockchain new block event and update the cached height.
type ChainHeight struct {
Logger zerolog.Logger

mtx sync.RWMutex
errGetChainHeight error
lastChainHeight int64
HeightChanged chan (int64)
}

// NewChainHeight returns a new ChainHeight struct that
// starts a new goroutine subscribed to EventNewBlockHeader.
func NewChainHeight(
ctx context.Context,
rpcClient tmrpcclient.Client,
logger zerolog.Logger,
) (*ChainHeight, error) {
if !rpcClient.IsRunning() {
if err := rpcClient.Start(); err != nil {
return nil, err
}
}

newBlockHeaderSubscription, err := rpcClient.Subscribe(
ctx, tmtypes.EventNewBlockHeader, queryEventNewBlockHeader.String())
if err != nil {
return nil, err
}

chainHeight := &ChainHeight{
Logger: logger.With().Str("oracle_client", "chain_height").Logger(),
}
chainHeight.HeightChanged = make(chan int64)

go chainHeight.subscribe(ctx, rpcClient, newBlockHeaderSubscription)
Fixed Show fixed Hide fixed

return chainHeight, nil
}

// updateChainHeight receives the data to be updated thread safe.
func (chainHeight *ChainHeight) updateChainHeight(blockHeight int64, err error) {
chainHeight.mtx.Lock()
defer chainHeight.mtx.Unlock()

if chainHeight.lastChainHeight != blockHeight {
select {
case chainHeight.HeightChanged <- blockHeight:
default:
}
}
chainHeight.lastChainHeight = blockHeight
chainHeight.errGetChainHeight = err
}

// subscribe listens to new blocks being made
// and updates the chain height.
func (chainHeight *ChainHeight) subscribe(
ctx context.Context,
eventsClient tmrpcclient.EventsClient,
newBlockHeaderSubscription <-chan tmctypes.ResultEvent,
) {
for {
select {
case <-ctx.Done():
err := eventsClient.Unsubscribe(ctx, tmtypes.EventNewBlockHeader, queryEventNewBlockHeader.String())
if err != nil {
chainHeight.Logger.Err(err)
chainHeight.updateChainHeight(chainHeight.lastChainHeight, err)
}
chainHeight.Logger.Info().Msg("closing the ChainHeight subscription")
return

case resultEvent := <-newBlockHeaderSubscription:
eventDataNewBlockHeader, ok := resultEvent.Data.(tmtypes.EventDataNewBlockHeader)
if !ok {
chainHeight.Logger.Err(errParseEventDataNewBlockHeader)
chainHeight.updateChainHeight(chainHeight.lastChainHeight, errParseEventDataNewBlockHeader)
continue
}
chainHeight.updateChainHeight(eventDataNewBlockHeader.Header.Height, nil)
}
}
}

// GetChainHeight returns the last chain height available.
func (chainHeight *ChainHeight) GetChainHeight() (int64, error) {
chainHeight.mtx.RLock()
defer chainHeight.mtx.RUnlock()

return chainHeight.lastChainHeight, chainHeight.errGetChainHeight
}
34 changes: 34 additions & 0 deletions tests/gRPC/grpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package gRPC

import (
"context"
"net"
"strings"
)

func dialerFunc(_ context.Context, addr string) (net.Conn, error) {
return Connect(addr)
}

// Connect dials the given address and returns a net.Conn. The protoAddr
// argument should be prefixed with the protocol,
// eg. "tcp://127.0.0.1:8080" or "unix:///tmp/test.sock".
func Connect(protoAddr string) (net.Conn, error) {
proto, address := ProtocolAndAddress(protoAddr)
conn, err := net.Dial(proto, address)
return conn, err
}

// ProtocolAndAddress splits an address into the protocol and address components.
// For instance, "tcp://127.0.0.1:8080" will be split into "tcp" and "127.0.0.1:8080".
// If the address has no protocol prefix, the default is "tcp".
func ProtocolAndAddress(listenAddr string) (string, string) {
protocol, address := "tcp", listenAddr

parts := strings.SplitN(address, "://", 2)
if len(parts) == 2 {
protocol, address = parts[0], parts[1]
}

return protocol, address
}