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

Problem: no command to enable/disable bridge #775

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [cronos#742](https://github.com/crypto-org-chain/cronos/pull/742) Add upgrade handler for v0.8.0-gravity-alpha2.
- [cronos#750](https://github.com/crypto-org-chain/cronos/pull/750) Add upgrade handler for v0.8.0-gravity-alpha3.
- [cronos#769](https://github.com/crypto-org-chain/cronos/pull/769) Prevent cancellation function to be called outside the scope of the contract that manage it.
- [cronos#775](https://github.com/crypto-org-chain/cronos/pull/775) Support turnbridge transaction.

### Improvements

Expand Down
26 changes: 26 additions & 0 deletions integration_tests/cosmoscli.py
Original file line number Diff line number Diff line change
Expand Up @@ -1404,3 +1404,29 @@ def query_grant(self, granter, grantee):
home=self.data_dir,
)
)

def query_batches(self):
"query all gravity batches"
return json.loads(
self.raw(
"query",
"gravity",
"batch-txs",
home=self.data_dir,
)
)

def turn_bridge(self, enable, **kwargs):
kwargs.setdefault("gas_prices", DEFAULT_GAS_PRICE)
kwargs.setdefault("gas", DEFAULT_GAS)
return json.loads(
self.raw(
"tx",
"cronos",
"turn-bridge",
enable,
"-y",
home=self.data_dir,
**kwargs,
)
)
71 changes: 71 additions & 0 deletions integration_tests/test_gravity.py
Original file line number Diff line number Diff line change
Expand Up @@ -795,3 +795,74 @@ def check():
gravity.contract.functions.redeemVoucher(
old_nonce, ADDRS["signer2"]
).build_transaction({"from": ADDRS["signer1"]})


def test_gravity_turn_bridge(gravity):
geth = gravity.geth
cli = gravity.cronos.cosmos_cli()
cronos_w3 = gravity.cronos.w3

# deploy test erc20 contract
erc20 = deploy_contract(
geth,
CONTRACTS["TestERC20A"],
)

balance = erc20.caller.balanceOf(ADDRS["validator"])
assert balance == 100000000000000000000000000
amount = 1000

print("send to cronos crc20")
recipient = HexBytes(ADDRS["community"])
txreceipt = send_to_cosmos(
gravity.contract, erc20, geth, recipient, amount, KEYS["validator"]
)
assert txreceipt.status == 1, "should success"
assert erc20.caller.balanceOf(ADDRS["validator"]) == balance - amount

denom = f"gravity{erc20.address}"

def check_gravity_native_tokens():
"check the balance of gravity native token"
return cli.balance(eth_to_bech32(recipient), denom=denom) == amount

if gravity.cronos.enable_auto_deployment:
crc21_contract = None

def local_check_auto_deployment():
nonlocal crc21_contract
crc21_contract = check_auto_deployment(
cli, denom, cronos_w3, recipient, amount
)
return crc21_contract

wait_for_fn("send-to-crc21", local_check_auto_deployment)
else:
wait_for_fn("send-to-gravity-native", check_gravity_native_tokens)

# turn off bridge
rsp = cli.turn_bridge("false", from_="community")
assert rsp["code"] != 0, "should not have the permission"

rsp = cli.turn_bridge("false", from_="validator")
assert rsp["code"] == 0, rsp["raw_log"]
wait_for_new_blocks(cli, 1)

if gravity.cronos.enable_auto_deployment:
# send it back to erc20, should fail
tx = crc21_contract.functions.send_to_evm_chain(
ADDRS["validator"], amount, 1, 0, b""
).build_transaction({"from": ADDRS["community"]})
txreceipt = send_transaction(cronos_w3, tx, KEYS["community"])
assert txreceipt.status == 0, "should fail"
else:
# send back the gravity native tokens, should fail
rsp = cli.send_to_ethereum(
ADDRS["validator"], f"{amount}{denom}", f"0{denom}", from_="community"
)
assert rsp["code"] == 3, rsp["raw_log"]

wait_for_new_blocks(cli, 10)
# check no new batch is created
rsp = cli.query_batches()
assert len(rsp["batches"]) == 0
66 changes: 43 additions & 23 deletions proto/cronos/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,43 @@ option go_package = "github.com/crypto-org-chain/cronos/x/cronos/types";

// Msg defines the Cronos Msg service
service Msg {
// this line is used by starport scaffolding # proto/tx/rpc
// this line is used by starport scaffolding # proto/tx/rpc

// ConvertVouchers defines a method for converting ibc voucher to cronos evm coins.
rpc ConvertVouchers(MsgConvertVouchers) returns (MsgConvertVouchersResponse);
// ConvertVouchers defines a method for converting ibc voucher to cronos evm
// coins.
rpc ConvertVouchers(MsgConvertVouchers) returns (MsgConvertVouchersResponse);

// TransferTokens defines a method to transfer cronos evm coins to another chain through IBC
rpc TransferTokens(MsgTransferTokens) returns (MsgTransferTokensResponse);
// TransferTokens defines a method to transfer cronos evm coins to another
// chain through IBC
rpc TransferTokens(MsgTransferTokens) returns (MsgTransferTokensResponse);

// UpdateTokenMapping defines a method to update token mapping
rpc UpdateTokenMapping(MsgUpdateTokenMapping) returns (MsgUpdateTokenMappingResponse);
// UpdateTokenMapping defines a method to update token mapping
rpc UpdateTokenMapping(MsgUpdateTokenMapping)
returns (MsgUpdateTokenMappingResponse);

// TurnBridge defines a method to disable or enable the gravity bridge
rpc TurnBridge(MsgTurnBridge) returns (MsgTurnBridgeResponse);
}

// MsgConvertVouchers represents a message to convert ibc voucher coins to cronos evm coins.
// MsgConvertVouchers represents a message to convert ibc voucher coins to
// cronos evm coins.
message MsgConvertVouchers {
string address = 1;
repeated cosmos.base.v1beta1.Coin coins = 2
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
string address = 1;
repeated cosmos.base.v1beta1.Coin coins = 2 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

// MsgTransferTokens represents a message to transfer cronos evm coins through ibc.
// MsgTransferTokens represents a message to transfer cronos evm coins through
// ibc.
message MsgTransferTokens {
string from = 1;
string to = 2;
repeated cosmos.base.v1beta1.Coin coins = 3
[(gogoproto.nullable) = false, (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"];
string from = 1;
string to = 2;
repeated cosmos.base.v1beta1.Coin coins = 3 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

// MsgConvertVouchersResponse defines the ConvertVouchers response type.
Expand All @@ -45,16 +57,24 @@ message MsgTransferTokensResponse {}

// MsgUpdateTokenMapping defines the request type
message MsgUpdateTokenMapping {
string sender = 1;
string denom = 2;
string contract = 3;
// only when updating cronos (source) tokens
string symbol = 4;
uint32 decimal = 5;
string sender = 1;
string denom = 2;
string contract = 3;
// only when updating cronos (source) tokens
string symbol = 4;
uint32 decimal = 5;
}

// MsgUpdateTokenMappingResponse defines the response type
message MsgUpdateTokenMappingResponse {
message MsgUpdateTokenMappingResponse {}

// MsgTurnBridge defines the request type
message MsgTurnBridge {
string sender = 1;
bool enable = 2;
}

// MsgTurnBridgegResponse defines the response type
message MsgTurnBridgeResponse {}

// this line is used by starport scaffolding # proto/tx/message
30 changes: 30 additions & 0 deletions x/cronos/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cli

import (
"fmt"
"strconv"
"strings"

"github.com/cosmos/cosmos-sdk/client/flags"
Expand Down Expand Up @@ -34,6 +35,7 @@ func GetTxCmd() *cobra.Command {
cmd.AddCommand(CmdConvertTokens())
cmd.AddCommand(CmdSendToCryptoOrg())
cmd.AddCommand(CmdUpdateTokenMapping())
cmd.AddCommand(CmdTurnBridge())

return cmd
}
Expand Down Expand Up @@ -249,3 +251,31 @@ func CmdUpdateTokenMapping() *cobra.Command {

return cmd
}

// CmdTurnBridge returns a CLI command handler for enable or disable the bridge
func CmdTurnBridge() *cobra.Command {
cmd := &cobra.Command{
Use: "turn-bridge [true/false]",
Short: "Turn Bridge",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

enable, err := strconv.ParseBool(args[0])
if err != nil {
return err
}
msg := types.NewMsgTurnBridge(clientCtx.GetFromAddress().String(), enable)
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)
return cmd
}
4 changes: 3 additions & 1 deletion x/cronos/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
case *types.MsgConvertVouchers:
res, err := msgServer.ConvertVouchers(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)

case *types.MsgTransferTokens:
res, err := msgServer.TransferTokens(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgUpdateTokenMapping:
res, err := msgServer.UpdateTokenMapping(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
case *types.MsgTurnBridge:
res, err := msgServer.TurnBridge(sdk.WrapSDKContext(ctx), msg)
return sdk.WrapServiceResult(ctx, res, err)
default:
errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg)
return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg)
Expand Down
16 changes: 16 additions & 0 deletions x/cronos/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,19 @@ func (k msgServer) UpdateTokenMapping(goCtx context.Context, msg *types.MsgUpdat
}
return &types.MsgUpdateTokenMappingResponse{}, nil
}

// TurnBridge implements the grpc method
func (k msgServer) TurnBridge(goCtx context.Context, msg *types.MsgTurnBridge) (*types.MsgTurnBridgeResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
admin := k.Keeper.GetParams(ctx).CronosAdmin
// if admin is empty, no sender could be equal to it
if admin != msg.Sender {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "msg sender is authorized")
}

gravityParams := k.gravityKeeper.GetParams(ctx)
gravityParams.BridgeActive = msg.Enable
k.gravityKeeper.SetParams(ctx, gravityParams)

return &types.MsgTurnBridgeResponse{}, nil
}
2 changes: 1 addition & 1 deletion x/cronos/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
)

// NewConvertVouchersEvent constructs a new voucher convert sdk.Event
//nolint: interfacer
// nolint: interfacer
func NewConvertVouchersEvent(sender string, amount fmt.Stringer) sdk.Event {
return sdk.NewEvent(
EventTypeConvertVouchers,
Expand Down
1 change: 1 addition & 0 deletions x/cronos/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type GravityKeeper interface {
ERC20ToDenomLookup(ctx sdk.Context, tokenContract common.Address) (bool, string)
IterateUnbatchedSendToEthereums(ctx sdk.Context, cb func(*gravitytypes.SendToEthereum) bool)
GetParams(ctx sdk.Context) (params gravitytypes.Params)
SetParams(ctx sdk.Context, params gravitytypes.Params)
}

// EvmLogHandler defines the interface for evm log handler
Expand Down
46 changes: 46 additions & 0 deletions x/cronos/types/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const (
TypeMsgConvertVouchers = "ConvertVouchers"
TypeMsgTransferTokens = "TransferTokens"
TypeMsgUpdateTokenMapping = "UpdateTokenMapping"
TypeTurnBridge = "TurnBridge"
)

var _ sdk.Msg = &MsgConvertVouchers{}
Expand Down Expand Up @@ -171,3 +172,48 @@ func (msg *MsgUpdateTokenMapping) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}

var _ sdk.Msg = &MsgTurnBridge{}

// NewMsgTurnBridge ...
func NewMsgTurnBridge(admin string, enable bool) *MsgTurnBridge {
return &MsgTurnBridge{
Sender: admin,
Enable: enable,
}
}

// GetSigners ...
func (msg *MsgTurnBridge) GetSigners() []sdk.AccAddress {
sender, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
panic(err)
}
return []sdk.AccAddress{sender}
}

// ValidateBasic ...
func (msg *MsgTurnBridge) ValidateBasic() error {
_, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid sender address (%s)", err)
}

return nil
}

// Route ...
func (msg MsgTurnBridge) Route() string {
return RouterKey
}

// Type ...
func (msg MsgTurnBridge) Type() string {
return TypeTurnBridge
}

// GetSignBytes ...
func (msg *MsgTurnBridge) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}
Loading