Skip to content

Commit

Permalink
Outgoing Contract Calls (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
mvid authored Aug 2, 2021
1 parent 5990cc8 commit 9aa15e8
Show file tree
Hide file tree
Showing 14 changed files with 260 additions and 208 deletions.
10 changes: 5 additions & 5 deletions module/proto/gravity/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ option go_package = "github.com/peggyjv/gravity-bridge/module/x/gravity/types";
// when the attestation is created, but only allows for slashing once the event
// has passed
//
// target_batch_timeout:
// target_eth_tx_timeout:
//
// This is the 'target' value for when batches time out, this is a target
// because Ethereum is a probabalistic chain and you can't say for sure what the
// This is the 'target' value for when ethereum transactions time out, this is a target
// because Ethereum is a probabilistic chain and you can't say for sure what the
// block frequency is ahead of time.
//
// average_block_time
// average_ethereum_block_time
//
// These values are the average Cosmos block time and Ethereum block time
// repsectively and they are used to copute what the target batch timeout is. It
// respectively and they are used to compute what the target batch timeout is. It
// is important that governance updates these in case of any major, prolonged
// change in the time it takes to produce a block
//
Expand All @@ -79,7 +79,7 @@ message Params {
uint64 signed_signer_set_txs_window = 6;
uint64 signed_batches_window = 7;
uint64 ethereum_signatures_window = 8;
uint64 target_batch_timeout = 10;
uint64 target_eth_tx_timeout = 10;
uint64 average_block_time = 11;
uint64 average_ethereum_block_time = 12;
// TODO: slash fraction for contract call txs too
Expand Down
2 changes: 1 addition & 1 deletion module/proto/gravity/v1/gravity.proto
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ message SendToEthereum {
ERC20Token erc20_fee = 5 [ (gogoproto.nullable) = false ];
}

// ContractCallTx represents an individual arbitratry logic call transaction
// ContractCallTx represents an individual arbitrary logic call transaction
// from Cosmos to Ethereum.
message ContractCallTx {
uint64 invalidation_nonce = 1;
Expand Down
2 changes: 1 addition & 1 deletion module/proto/gravity/v1/msgs.proto
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ message BatchExecutedEvent {
// investigate?
message ContractCallExecutedEvent {
uint64 event_nonce = 1;
bytes invalidation_id = 2
bytes invalidation_scope = 2
[ (gogoproto.casttype) =
"github.com/tendermint/tendermint/libs/bytes.HexBytes" ];
uint64 invalidation_nonce = 3;
Expand Down
2 changes: 1 addition & 1 deletion module/x/gravity/keeper/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (k Keeper) getBatchTimeoutHeight(ctx sdk.Context) uint64 {
projectedCurrentEthereumHeight := (projectedMillis / params.AverageEthereumBlockTime) + heights.EthereumHeight
// we convert our target time for block timeouts (lets say 12 hours) into a number of blocks to
// place on top of our projection of the current Ethereum block height.
blocksToAdd := params.TargetBatchTimeout / params.AverageEthereumBlockTime
blocksToAdd := params.TargetEthTxTimeout / params.AverageEthereumBlockTime
return projectedCurrentEthereumHeight + blocksToAdd
}

Expand Down
70 changes: 60 additions & 10 deletions module/x/gravity/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"math"
"sort"
"strconv"
"strings"

"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
Expand All @@ -16,6 +17,7 @@ import (
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/ethereum/go-ethereum/common"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/libs/log"

"github.com/peggyjv/gravity-bridge/module/x/gravity/types"
Expand Down Expand Up @@ -83,9 +85,9 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger {
// incrementLatestSignerSetTxNonce sets the latest valset nonce
func (k Keeper) incrementLatestSignerSetTxNonce(ctx sdk.Context) uint64 {
current := k.GetLatestSignerSetTxNonce(ctx)
new := current + 1
ctx.KVStore(k.storeKey).Set([]byte{types.LatestSignerSetTxNonceKey}, sdk.Uint64ToBigEndian(new))
return new
next := current + 1
ctx.KVStore(k.storeKey).Set([]byte{types.LatestSignerSetTxNonceKey}, sdk.Uint64ToBigEndian(next))
return next
}

// GetLatestSignerSetTxNonce returns the latest valset nonce
Expand Down Expand Up @@ -180,7 +182,7 @@ func (k Keeper) GetOrchestratorValidatorAddress(ctx sdk.Context, orchAddr sdk.Ac
store := ctx.KVStore(k.storeKey)
key := types.MakeOrchestratorValidatorAddressKey(orchAddr)

return sdk.ValAddress(store.Get(key))
return store.Get(key)
}

////////////////////////
Expand Down Expand Up @@ -234,7 +236,7 @@ func (k Keeper) GetEthereumOrchestratorAddress(ctx sdk.Context, ethAddr common.A
store := ctx.KVStore(k.storeKey)
key := types.MakeEthereumOrchestratorAddressKey(ethAddr)

return sdk.AccAddress(store.Get(key))
return store.Get(key)
}

func (k Keeper) getEthereumAddressesByOrchestrator(ctx sdk.Context, orch sdk.AccAddress) (ethAddrs []common.Address) {
Expand Down Expand Up @@ -308,7 +310,7 @@ func (k Keeper) CurrentSignerSet(ctx sdk.Context) types.EthereumSigners {
ethereumSigners[i].Power = sdk.NewUint(ethereumSigners[i].Power).MulUint64(math.MaxUint32).QuoUint64(totalPower).Uint64()
}

return (types.EthereumSigners)(ethereumSigners)
return ethereumSigners
}

// GetSignerSetTxs returns all the signer set txs from the store
Expand Down Expand Up @@ -388,7 +390,7 @@ func (k Keeper) getDelegateKeys(ctx sdk.Context) (out []*types.MsgDelegateKeys)
iter.Close()

for _, msg := range out {
msg.OrchestratorAddress = sdk.AccAddress(k.GetEthereumOrchestratorAddress(ctx, common.HexToAddress(msg.EthereumAddress))).String()
msg.OrchestratorAddress = k.GetEthereumOrchestratorAddress(ctx, common.HexToAddress(msg.EthereumAddress)).String()
}

// we iterated over a map, so now we have to sort to ensure the
Expand All @@ -413,16 +415,14 @@ func (k Keeper) GetUnbondingvalidators(unbondingVals []byte) stakingtypes.ValAdd
// OUTGOING TX //
/////////////////

// todo: outgoingTx prefix byte
// GetOutgoingTx
// GetOutgoingTx todo: outgoingTx prefix byte
func (k Keeper) GetOutgoingTx(ctx sdk.Context, storeIndex []byte) (out types.OutgoingTx) {
if err := k.cdc.UnmarshalInterface(ctx.KVStore(k.storeKey).Get(types.MakeOutgoingTxKey(storeIndex)), &out); err != nil {
panic(err)
}
return out
}

// SetOutgoingTx
func (k Keeper) SetOutgoingTx(ctx sdk.Context, outgoing types.OutgoingTx) {
any, err := types.PackOutgoingTx(outgoing)
if err != nil {
Expand Down Expand Up @@ -513,3 +513,53 @@ func (k Keeper) setLastObservedSignerSetTx(ctx sdk.Context, signerSet types.Sign
key := []byte{types.LastObservedSignerSetKey}
ctx.KVStore(k.storeKey).Set(key, k.cdc.MustMarshal(&signerSet))
}

// CreateContractCallTx xxx
func (k Keeper) CreateContractCallTx(ctx sdk.Context, invalidationNonce uint64, invalidationScope tmbytes.HexBytes,
payload []byte, tokens []types.ERC20Token, fees []types.ERC20Token) *types.ContractCallTx {
params := k.GetParams(ctx)

newContractCallTx := &types.ContractCallTx{
InvalidationNonce: invalidationNonce,
InvalidationScope: invalidationScope,
Address: k.getBridgeContractAddress(ctx),
Payload: payload,
Timeout: params.TargetEthTxTimeout,
Tokens: tokens,
Fees: fees,
Height: uint64(ctx.BlockHeight()),
}

var tokenString []string
for _, token := range tokens {
tokenString = append(tokenString, token.String())
}

var feeString []string
for _, fee := range fees {
feeString = append(feeString, fee.String())
}

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeMultisigUpdateRequest,
sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName),
sdk.NewAttribute(types.AttributeKeyContract, k.getBridgeContractAddress(ctx)),
sdk.NewAttribute(types.AttributeKeyBridgeChainID, strconv.Itoa(int(k.getBridgeChainID(ctx)))),
sdk.NewAttribute(types.AttributeKeyContractCallInvalidationNonce, fmt.Sprint(invalidationNonce)),
sdk.NewAttribute(types.AttributeKeyContractCallInvalidationScope, fmt.Sprint(invalidationScope)),
sdk.NewAttribute(types.AttributeKeyContractCallPayload, string(payload)),
sdk.NewAttribute(types.AttributeKeyContractCallTokens, strings.Join(tokenString, "|")),
sdk.NewAttribute(types.AttributeKeyContractCallFees, strings.Join(feeString, "|")),
sdk.NewAttribute(types.AttributeKeyEthTxTimeout, strconv.FormatUint(params.TargetEthTxTimeout, 10)),
),
)
k.SetOutgoingTx(ctx, newContractCallTx)
k.Logger(ctx).Info(
"ContractCallTx created",
"invalidation_nonce", newContractCallTx.InvalidationNonce,
"invalidation_scope", newContractCallTx.InvalidationScope,
// todo: fill out all fields
)
return newContractCallTx
}
6 changes: 3 additions & 3 deletions module/x/gravity/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestCurrentValsetNormalization(t *testing.T) {
}
input.GravityKeeper.StakingKeeper = NewStakingKeeperWeightedMock(operators...)
r := input.GravityKeeper.CreateSignerSetTx(ctx)
assert.Equal(t, spec.expPowers, types.EthereumSigners(r.Signers).GetPowers())
assert.Equal(t, spec.expPowers, r.Signers.GetPowers())
})
}
}
Expand Down Expand Up @@ -78,7 +78,7 @@ func TestAttestationIterator(t *testing.T) {
input.GravityKeeper.setEthereumEventVoteRecord(ctx, dep1.EventNonce, dep1.Hash(), att1)
input.GravityKeeper.setEthereumEventVoteRecord(ctx, dep2.EventNonce, dep2.Hash(), att2)

atts := []*types.EthereumEventVoteRecord{}
var atts []*types.EthereumEventVoteRecord
input.GravityKeeper.iterateEthereumEventVoteRecords(ctx, func(_ []byte, att *types.EthereumEventVoteRecord) bool {
atts = append(atts, att)
return false
Expand Down Expand Up @@ -158,7 +158,7 @@ func TestStoreEventVoteRecord(t *testing.T) {

cctxe := &types.ContractCallExecutedEvent{
EventNonce: 2,
InvalidationId: []byte{0x1, 0x2},
InvalidationScope: []byte{0x1, 0x2},
InvalidationNonce: 1,
EthereumHeight: 11,
}
Expand Down
2 changes: 1 addition & 1 deletion module/x/gravity/keeper/test_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ var (
SignedSignerSetTxsWindow: 10,
UnbondSlashingSignerSetTxsWindow: 15,
EthereumSignaturesWindow: 10,
TargetBatchTimeout: 60001,
TargetEthTxTimeout: 60001,
AverageBlockTime: 5000,
AverageEthereumBlockTime: 15000,
SlashFractionSignerSetTx: sdk.NewDecWithPrec(1, 2),
Expand Down
2 changes: 1 addition & 1 deletion module/x/gravity/spec/07_params.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The gravity module contains the following parameters:
| SignedValsetsWindow | uint64 | 10_000 |
| SignedBatchesWindow | uint64 | 10_000 |
| SignedClaimsWindow | uint64 | 10_000 |
| TargetBatchTimeout | uint64 | 43_200_000 |
| TargetEthTxTimeout | uint64 | 43_200_000 |
| AverageBlockTime | uint64 | 5_000 |
| AverageEthereumBlockTime | uint64 | 15_000 |
| SlashFractionValset | sdkTypes.Dec | - |
Expand Down
2 changes: 1 addition & 1 deletion module/x/gravity/types/ethereum_event.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func (ccee *ContractCallExecutedEvent) Hash() tmbytes.HexBytes {
path := bytes.Join(
[][]byte{
sdk.Uint64ToBigEndian(ccee.EventNonce),
ccee.InvalidationId,
ccee.InvalidationScope,
sdk.Uint64ToBigEndian(ccee.InvalidationNonce),
sdk.Uint64ToBigEndian(ccee.EthereumHeight),
},
Expand Down
29 changes: 16 additions & 13 deletions module/x/gravity/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,21 @@ const (
AttributeKeyEthereumEventVoteRecordID = "ethereum_event_vote_record_id"
AttributeKeyBatchConfirmKey = "batch_confirm_key"
AttributeKeyEthereumSignatureKey = "ethereum_signature_key"
AttributeKeyMultisigID = "multisig_id"
AttributeKeyOutgoingBatchID = "batch_id"
AttributeKeyOutgoingTXID = "outgoing_tx_id"
AttributeKeyEthereumEventType = "ethereum_event_type"
AttributeKeyContract = "bridge_contract"
AttributeKeyNonce = "nonce"
AttributeKeySignerSetNonce = "signerset_nonce"
AttributeKeyBatchNonce = "batch_nonce"
AttributeKeyBridgeChainID = "bridge_chain_id"
AttributeKeySetOrchestratorAddr = "set_orchestrator_address"
AttributeKeySetEthereumAddr = "set_ethereum_address"
AttributeKeyValidatorAddr = "validator_address"
AttributeKeyInvalidationID = "logic_call_invalidation_id"
AttributeKeyInvalidationNonce = "logic_call_invalidation_nonce"
AttributeKeyOutgoingTXID = "outgoing_tx_id"
AttributeKeyEthereumEventType = "ethereum_event_type"
AttributeKeyContract = "bridge_contract"
AttributeKeyNonce = "nonce"
AttributeKeySignerSetNonce = "signerset_nonce"
AttributeKeyBatchNonce = "batch_nonce"
AttributeKeyBridgeChainID = "bridge_chain_id"
AttributeKeySetOrchestratorAddr = "set_orchestrator_address"
AttributeKeySetEthereumAddr = "set_ethereum_address"
AttributeKeyValidatorAddr = "validator_address"
AttributeKeyContractCallInvalidationScope = "contract_call_invalidation_scope"
AttributeKeyContractCallInvalidationNonce = "contract_call_invalidation_nonce"
AttributeKeyContractCallPayload = "contract_call_payload"
AttributeKeyContractCallTokens = "contract_call_tokens"
AttributeKeyContractCallFees = "contract_call_fees"
AttributeKeyEthTxTimeout = "eth_tx_timeout"
)
12 changes: 6 additions & 6 deletions module/x/gravity/types/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ var (
// ParamsStoreKeyEthereumSignaturesWindow stores the signed blocks window
ParamsStoreKeyEthereumSignaturesWindow = []byte("EthereumSignaturesWindow")

// ParamsStoreKeyTargetBatchTimeout stores the signed blocks window
ParamsStoreKeyTargetBatchTimeout = []byte("TargetBatchTimeout")
// ParamsStoreKeyTargetEthTxTimeout stores the target ethereum transaction timeout
ParamsStoreKeyTargetEthTxTimeout = []byte("TargetEthTxTimeout")

// ParamsStoreKeyAverageBlockTime stores the signed blocks window
ParamsStoreKeyAverageBlockTime = []byte("AverageBlockTime")
Expand Down Expand Up @@ -119,7 +119,7 @@ func DefaultParams() *Params {
SignedSignerSetTxsWindow: 10000,
SignedBatchesWindow: 10000,
EthereumSignaturesWindow: 10000,
TargetBatchTimeout: 43200000,
TargetEthTxTimeout: 43200000,
AverageBlockTime: 5000,
AverageEthereumBlockTime: 15000,
SlashFractionSignerSetTx: sdk.NewDec(1).Quo(sdk.NewDec(1000)),
Expand All @@ -144,7 +144,7 @@ func (p Params) ValidateBasic() error {
if err := validateBridgeChainID(p.BridgeChainId); err != nil {
return sdkerrors.Wrap(err, "bridge chain id")
}
if err := validateTargetBatchTimeout(p.TargetBatchTimeout); err != nil {
if err := validateTargetEthTxTimeout(p.TargetEthTxTimeout); err != nil {
return sdkerrors.Wrap(err, "Batch timeout")
}
if err := validateAverageBlockTime(p.AverageBlockTime); err != nil {
Expand Down Expand Up @@ -198,7 +198,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
paramtypes.NewParamSetPair(ParamsStoreKeySignedBatchesWindow, &p.SignedBatchesWindow, validateSignedBatchesWindow),
paramtypes.NewParamSetPair(ParamsStoreKeyEthereumSignaturesWindow, &p.EthereumSignaturesWindow, validateEthereumSignaturesWindow),
paramtypes.NewParamSetPair(ParamsStoreKeyAverageBlockTime, &p.AverageBlockTime, validateAverageBlockTime),
paramtypes.NewParamSetPair(ParamsStoreKeyTargetBatchTimeout, &p.TargetBatchTimeout, validateTargetBatchTimeout),
paramtypes.NewParamSetPair(ParamsStoreKeyTargetEthTxTimeout, &p.TargetEthTxTimeout, validateTargetEthTxTimeout),
paramtypes.NewParamSetPair(ParamsStoreKeyAverageEthereumBlockTime, &p.AverageEthereumBlockTime, validateAverageEthereumBlockTime),
paramtypes.NewParamSetPair(ParamsStoreSlashFractionSignerSetTx, &p.SlashFractionSignerSetTx, validateSlashFractionSignerSetTx),
paramtypes.NewParamSetPair(ParamsStoreSlashFractionBatch, &p.SlashFractionBatch, validateSlashFractionBatch),
Expand Down Expand Up @@ -248,7 +248,7 @@ func validateBridgeChainID(i interface{}) error {
return nil
}

func validateTargetBatchTimeout(i interface{}) error {
func validateTargetEthTxTimeout(i interface{}) error {
val, ok := i.(uint64)
if !ok {
return fmt.Errorf("invalid parameter type: %T", i)
Expand Down
Loading

0 comments on commit 9aa15e8

Please sign in to comment.