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

feat: add thorchain support #1219

Merged
merged 40 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ffe6544
initial thorchain addition, configs setup, still need genesis update
misko9 Jul 19, 2024
9116cec
wip: thorchain genesis
misko9 Jul 23, 2024
ceba377
thorchain running
misko9 Jul 23, 2024
277335b
thorchain and bifrost working together
misko9 Jul 25, 2024
3e6981b
add savers, swaps, and saver eject example case for gaia
misko9 Jul 26, 2024
49eafc3
arb wip, all other sim tests passing
misko9 Jul 31, 2024
c0febe8
arb code in, needs testing with >1 pool
misko9 Jul 31, 2024
cbc6d2d
add ethereum to thorchain test and start cleaning up
misko9 Aug 2, 2024
50a6017
clean up savers/arb features
misko9 Aug 2, 2024
699ebf5
clean up swap feature
misko9 Aug 2, 2024
de5eb93
cleanup of saver eject and ragnarok features
misko9 Aug 2, 2024
2fcd796
fix: second+ saver eject now works
misko9 Aug 5, 2024
ac8aac9
Add back arbing and eth->gaia swap
misko9 Aug 5, 2024
cfc4091
wip, add utxo support, SendFundsWithNote() still needed
misko9 Aug 7, 2024
e1c5671
hardfork wip
agouin Aug 8, 2024
de8797a
start with genesis contents
agouin Aug 8, 2024
a166e88
progress further
agouin Aug 8, 2024
95520c5
wip: removed non-BTC chains temporarily, BTC's SendFundsWithNote succ…
misko9 Aug 8, 2024
69977a6
thorchain<->btc dual lp working
misko9 Aug 8, 2024
3fa9983
btc and bch looking good
misko9 Aug 9, 2024
ea0a2a0
ltc working, clean up logging, fix coins funded on each chain, and fi…
misko9 Aug 9, 2024
34f5287
utxo chains fully operational
misko9 Aug 10, 2024
4346aae
fix ether type
misko9 Aug 11, 2024
e39bd9a
add some protections around utxo node wallet usage
misko9 Aug 12, 2024
ad4a0a7
send utxo change back to sender instead of a change address
misko9 Aug 12, 2024
5daf638
Run tests in parallel
misko9 Aug 13, 2024
2dbbf78
clean up utxo test
misko9 Aug 13, 2024
f08f494
fmt/lint
misko9 Aug 13, 2024
7508c67
More cleanup
misko9 Aug 14, 2024
d1641df
increase time for bifrost to initialize
misko9 Aug 14, 2024
bcab349
Merge branch 'andrew/thorchain_hardfork' into steve/thorchain
misko9 Aug 14, 2024
a8b23da
Set bifrost envs at runtime
misko9 Aug 14, 2024
e8ae3a0
change wg to eg
misko9 Aug 15, 2024
7d72058
minor fmt
misko9 Aug 15, 2024
0545c5f
Merge branch 'main' into steve/thorchain
misko9 Aug 15, 2024
2a52c9c
add back mainnet-genesis.json
misko9 Aug 15, 2024
7e3f0d0
remove mainnet-genesis.json
misko9 Aug 21, 2024
70ae530
Merge branch 'main' into steve/thorchain
misko9 Aug 21, 2024
9ec32dd
lint
Reecepbcups Aug 21, 2024
ea0b733
fix: nil gRPC queries
Reecepbcups Aug 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions chain/cosmos/chain_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ type ChainNode struct {

func NewChainNode(log *zap.Logger, validator bool, chain *CosmosChain, dockerClient *dockerclient.Client, networkID string, testName string, image ibc.DockerImage, index int) *ChainNode {
tn := &ChainNode{
log: log,
log: log.With(
zap.Bool("validator", validator),
zap.Int("i", index),
),

Validator: validator,

Expand Down Expand Up @@ -144,7 +147,7 @@ func (tn *ChainNode) NewClient(addr string) error {

tn.Client = rpcClient

grpcConn, err := grpc.Dial(
grpcConn, err := grpc.NewClient(
tn.hostGRPCPort, grpc.WithTransportCredentials(insecure.NewCredentials()),
)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion chain/cosmos/cosmos_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ func (c *CosmosChain) WithPreStartNodes(preStartNodes func(*CosmosChain)) {
c.preStartNodes = preStartNodes
}


// GetCodec returns the codec for the chain.
func (c *CosmosChain) GetCodec() *codec.ProtoCodec {
return c.cdc
Expand Down Expand Up @@ -616,6 +615,9 @@ func (c *CosmosChain) UpgradeVersion(ctx context.Context, cli *client.Client, co

func (c *CosmosChain) pullImages(ctx context.Context, cli *client.Client) {
for _, image := range c.Config().Images {
if image.Version == "local" {
continue
}
rc, err := cli.ImagePull(
ctx,
image.Repository+":"+image.Version,
Expand Down
39 changes: 35 additions & 4 deletions chain/ethereum/ethererum_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ var _ ibc.Chain = &EthereumChain{}
const (
blockTime = 2 // seconds
rpcPort = "8545/tcp"
GWEI = 1_000_000_000
ETHER = 1_000_000_000 * GWEI
)

var (
GWEI = sdkmath.NewInt(1_000_000_000)
ETHER = GWEI.MulRaw(1_000_000_000)
)

var natPorts = nat.PortMap{
Expand Down Expand Up @@ -170,7 +173,8 @@ func (c *EthereumChain) pullImages(ctx context.Context, cli *dockerclient.Client

func (c *EthereumChain) Start(testName string, ctx context.Context, additionalGenesisWallets ...ibc.WalletAmount) error {
// TODO:
// * add support for different denom configuration, ether or wei, this will affect GetBalance, etc
// * add support for different denom configuration, ether, gwei or wei,
// this will affect SendFunds, SendFundsWithNote, GetBalance and anything other than wei will lose precision for GetBalance
// * add support for modifying genesis amount config, default is 10 ether
// * add support for ConfigFileOverrides
// * block time
Expand All @@ -186,6 +190,9 @@ func (c *EthereumChain) Start(testName string, ctx context.Context, additionalGe
"--block-time", "2", // 2 second block times
"--accounts", "10", // We current only use the first account for the faucet, but tests may expect the default
"--balance", "10000000", // Genesis accounts loaded with 10mil ether, change as needed
"--no-cors",
"--gas-price", "20000000000",
"--block-base-fee-per-gas", "0",
}

var mounts []mount.Mount
Expand Down Expand Up @@ -250,7 +257,11 @@ func (c *EthereumChain) HostName() string {
}

func (c *EthereumChain) Exec(ctx context.Context, cmd []string, env []string) (stdout, stderr []byte, err error) {
job := dockerutil.NewImage(c.logger(), c.DockerClient, c.NetworkID, c.testName, c.cfg.Images[0].Repository, c.cfg.Images[0].Version)
logger := zap.NewNop()
if cmd[1] != "block-number" { // too much logging, maybe switch to an rpc lib in the future
logger = c.logger()
}
job := dockerutil.NewImage(logger, c.DockerClient, c.NetworkID, c.testName, c.cfg.Images[0].Repository, c.cfg.Images[0].Version)
opts := dockerutil.ContainerOptions{
Env: env,
Binds: c.Bind(),
Expand Down Expand Up @@ -321,6 +332,26 @@ func (c *EthereumChain) CreateKey(ctx context.Context, keyName string) error {
return nil
}

// cast wallet import requires a password prompt which docker isn't properly handling. For now, we only use CreateKey().
// Can re-add/support with this commit: https://github.com/foundry-rs/foundry/pull/6671
func (c *EthereumChain) RecoverKey(ctx context.Context, keyName, mnemonic string) error {
err := c.MakeKeystoreDir(ctx) // Ensure keystore directory is created
if err != nil {
return err
}

cmd := []string{"cast", "wallet", "import", keyName, "--keystore-dir", c.KeystoreDir(), "--mnemonic", mnemonic, "--unsafe-password", ""}
_, _, err = c.Exec(ctx, cmd, nil)
if err != nil {
return err
}

// This is needed for CreateKey() since that keystore path does not use the keyname
c.keystoreMap[keyName] = path.Join(c.KeystoreDir(), keyName)

return nil
}

// Get address of account, cast to a string to use
func (c *EthereumChain) GetAddress(ctx context.Context, keyName string) ([]byte, error) {
keystore, ok := c.keystoreMap[keyName]
Expand Down
13 changes: 0 additions & 13 deletions chain/ethereum/unimplemented.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,6 @@ func (*EthereumChain) GetHostPeerAddress() string {
return ""
}

// cast wallet import requires a password prompt which docker isn't properly handling. For now, we only use CreateKey().
func (c *EthereumChain) RecoverKey(ctx context.Context, keyName, mnemonic string) error {
/*cmd := []string{"cast", "wallet", "import", keyName, "--mnemonic", mnemonic, "--password", ""}
stdout, stderr, err := c.Exec(ctx, cmd, nil)
fmt.Println("stdout: ", string(stdout))
fmt.Println("stderr: ", string(stderr))
if err != nil {
return err
}*/
PanicFunctionName()
return nil
}

func (c *EthereumChain) GetGasFeesInNativeDenom(gasPaid int64) int64 {
PanicFunctionName()
return 0
Expand Down
1 change: 0 additions & 1 deletion chain/penumbra/penumbra_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ func (c *PenumbraChain) SendFunds(ctx context.Context, keyName string, amount ib
return fn.PenumbraClientNodes[keyName].SendFunds(ctx, amount)
}


// SendFundsWithNote will initiate a local transfer from the account associated with the specified keyName,
// amount, token denom, and recipient are specified in the amount and attach a note/memo
func (c *PenumbraChain) SendFundsWithNote(ctx context.Context, keyName string, amount ibc.WalletAmount, note string) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion chain/penumbra/penumbra_client_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ func (p *PenumbraClientNode) StartContainer(ctx context.Context) error {

p.hostGRPCPort = hostPorts[0]

p.GRPCConn, err = grpc.Dial(p.hostGRPCPort, grpc.WithTransportCredentials(insecure.NewCredentials()))
p.GRPCConn, err = grpc.NewClient(p.hostGRPCPort, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return err
}
Expand Down
89 changes: 89 additions & 0 deletions chain/thorchain/account_retriever.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package thorchain

import (
"context"
"fmt"
"strconv"

authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

grpc "google.golang.org/grpc"
"google.golang.org/grpc/metadata"

"github.com/cosmos/cosmos-sdk/client"
sdk "github.com/cosmos/cosmos-sdk/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
)

var (
_ client.Account = sdk.AccountI(nil)
_ client.AccountRetriever = AccountRetriever{}
)

// AccountRetriever defines the properties of a type that can be used to
// retrieve accounts.
type AccountRetriever struct {
chain *Thorchain
}

// GetAccount queries for an account given an address and a block height. An
// error is returned if the query or decoding fails.
func (ar AccountRetriever) GetAccount(clientCtx client.Context, addr sdk.AccAddress) (client.Account, error) {
account, _, err := ar.GetAccountWithHeight(clientCtx, addr)
return account, err
}

// GetAccountWithHeight queries for an account given an address. Returns the
// height of the query with the account. An error is returned if the query
// or decoding fails.
func (ar AccountRetriever) GetAccountWithHeight(clientCtx client.Context, addr sdk.AccAddress) (client.Account, int64, error) {
var header metadata.MD

bech32Address, err := ar.chain.AccAddressToBech32(addr)
if err != nil {
return nil, 0, err
}

queryClient := authtypes.NewQueryClient(clientCtx)
res, err := queryClient.Account(context.Background(), &authtypes.QueryAccountRequest{Address: bech32Address}, grpc.Header(&header))
if err != nil {
return nil, 0, err
}

blockHeight := header.Get(grpctypes.GRPCBlockHeightHeader)
if l := len(blockHeight); l != 1 {
return nil, 0, fmt.Errorf("unexpected '%s' header length; got %d, expected: %d", grpctypes.GRPCBlockHeightHeader, l, 1)
}

nBlockHeight, err := strconv.Atoi(blockHeight[0])
if err != nil {
return nil, 0, fmt.Errorf("failed to parse block height: %w", err)
}

var acc sdk.AccountI
if err := clientCtx.InterfaceRegistry.UnpackAny(res.Account, &acc); err != nil {
return nil, 0, err
}

return acc, int64(nBlockHeight), nil
}

// EnsureExists returns an error if no account exists for the given address else nil.
func (ar AccountRetriever) EnsureExists(clientCtx client.Context, addr sdk.AccAddress) error {
if _, err := ar.GetAccount(clientCtx, addr); err != nil {
return err
}

return nil
}

// GetAccountNumberSequence returns sequence and account number for the given address.
// It returns an error if the account couldn't be retrieved from the state.
func (ar AccountRetriever) GetAccountNumberSequence(clientCtx client.Context, addr sdk.AccAddress) (uint64, uint64, error) {
acc, err := ar.GetAccount(clientCtx, addr)
if err != nil {
return 0, 0, err
}

return acc.GetAccountNumber(), acc.GetSequence(), nil
}
34 changes: 34 additions & 0 deletions chain/thorchain/address.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package thorchain

import (
"errors"
"strings"

"github.com/cosmos/cosmos-sdk/types/bech32"

sdk "github.com/cosmos/cosmos-sdk/types"
)

// AccAddressFromBech32 creates an AccAddress from a Bech32 string.
// https://github.com/cosmos/cosmos-sdk/blob/v0.50.2/types/address.go#L193-L212
func (c *Thorchain) AccAddressFromBech32(address string) (addr sdk.AccAddress, err error) {
Reecepbcups marked this conversation as resolved.
Show resolved Hide resolved
if len(strings.TrimSpace(address)) == 0 {
return sdk.AccAddress{}, errors.New("empty address string is not allowed")
}

bz, err := sdk.GetFromBech32(address, c.Config().Bech32Prefix)
if err != nil {
return nil, err
}

err = sdk.VerifyAddressFormat(bz)
if err != nil {
return nil, err
}

return sdk.AccAddress(bz), nil
}

func (c *Thorchain) AccAddressToBech32(addr sdk.AccAddress) (string, error) {
return bech32.ConvertAndEncode(c.Config().Bech32Prefix, addr)
}
Loading
Loading