Skip to content

Commit

Permalink
feat: add btcstaking
Browse files Browse the repository at this point in the history
  • Loading branch information
473n committed Apr 2, 2024
1 parent 27f0e33 commit 6f80bb4
Show file tree
Hide file tree
Showing 23 changed files with 2,791 additions and 2 deletions.
8 changes: 8 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ import (
btclightclientkeeper "github.com/Lorenzo-Protocol/lorenzo/x/btclightclient/keeper"
btclightclienttypes "github.com/Lorenzo-Protocol/lorenzo/x/btclightclient/types"

btcstakingkeeper "github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/keeper"
btcstakingtypes "github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types"

// ibc
ibctransfer "github.com/cosmos/ibc-go/v7/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/v7/modules/apps/transfer/keeper"
Expand Down Expand Up @@ -164,6 +167,8 @@ type LorenzoApp struct {

BTCLightClientKeeper btclightclientkeeper.Keeper

BTCStakingKeeper btcstakingkeeper.Keeper

// Ethermint keepers
EvmKeeper *evmkeeper.Keeper
FeeMarketKeeper feemarketkeeper.Keeper
Expand Down Expand Up @@ -242,6 +247,7 @@ func NewLorenzoApp(
evmtypes.StoreKey,
feemarkettypes.StoreKey,
btclightclienttypes.StoreKey,
btcstakingtypes.StoreKey,
)

tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey, feemarkettypes.TransientKey)
Expand Down Expand Up @@ -452,6 +458,8 @@ func NewLorenzoApp(
btclightclienttypes.NewMultiBTCLightClientHooks(),
)

app.BTCStakingKeeper = btcstakingkeeper.NewKeeper(appCodec, keys[btcstakingtypes.StoreKey], app.BTCLightClientKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String())

var transferStack ibcporttypes.IBCModule
transferStack = ibctransfer.NewIBCModule(app.TransferKeeper)

Expand Down
10 changes: 9 additions & 1 deletion app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
appparams "github.com/Lorenzo-Protocol/lorenzo/app/params"
"github.com/Lorenzo-Protocol/lorenzo/x/btclightclient"
btclightclienttypes "github.com/Lorenzo-Protocol/lorenzo/x/btclightclient/types"
"github.com/Lorenzo-Protocol/lorenzo/x/btcstaking"
btcstakingtypes "github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
Expand Down Expand Up @@ -102,6 +104,7 @@ var (
evm.AppModuleBasic{},
feemarket.AppModuleBasic{},
btclightclient.AppModuleBasic{},
btcstaking.AppModuleBasic{},
)
// module account permissions
maccPerms = map[string][]string{
Expand All @@ -114,7 +117,8 @@ var (
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
// this line is used by starport scaffolding # stargate/app/maccPerms

evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
btcstakingtypes.ModuleName: {authtypes.Minter, authtypes.Burner},
}
)

Expand Down Expand Up @@ -194,6 +198,7 @@ func appModules(

app.transferModule,
btclightclient.NewAppModule(appCodec, app.BTCLightClientKeeper),
btcstaking.NewAppModule(appCodec, app.BTCStakingKeeper),

// this line is used by starport scaffolding # stargate/app/appModule

Expand Down Expand Up @@ -237,6 +242,7 @@ func orderBeginBlockers() []string {
paramstypes.ModuleName,
vestingtypes.ModuleName,
btclightclienttypes.ModuleName,
btcstakingtypes.ModuleName,
//self module

}
Expand Down Expand Up @@ -273,6 +279,7 @@ func orderEndBlockers() []string {
upgradetypes.ModuleName,
vestingtypes.ModuleName,
btclightclienttypes.ModuleName,
btcstakingtypes.ModuleName,
//self module

}
Expand Down Expand Up @@ -312,6 +319,7 @@ func orderInitBlockers() []string {

//self module
btclightclienttypes.ModuleName,
btcstakingtypes.ModuleName,

// NOTE: crisis module must go at the end to check for invariants on each module
crisistypes.ModuleName,
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,15 @@ require (
)

require (
cosmossdk.io/core v0.5.1
github.com/btcsuite/btcd/btcec/v2 v2.3.2
github.com/btcsuite/btcd/btcutil v1.1.5
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
github.com/cosmos/cosmos-proto v1.0.0-beta.2
github.com/cosmos/gogoproto v1.4.10
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1
google.golang.org/protobuf v1.33.0
)

require (
Expand All @@ -46,7 +49,6 @@ require (
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/storage v1.30.1 // indirect
cosmossdk.io/api v0.3.1 // indirect
cosmossdk.io/core v0.5.1 // indirect
cosmossdk.io/depinject v1.0.0-alpha.3 // indirect
cosmossdk.io/tools/rosetta v0.2.1 // indirect
filippo.io/edwards25519 v1.0.0 // indirect
Expand Down
11 changes: 11 additions & 0 deletions proto/lorenzo/btcstaking/v1/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";
package lorenzo.btcstaking.v1;

import "gogoproto/gogo.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types";

// GenesisState defines the btcstaking module's genesis state.
message GenesisState {
string btc_receiving_addr = 1;
}
15 changes: 15 additions & 0 deletions proto/lorenzo/btcstaking/v1/staking_record.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
syntax = "proto3";
package lorenzo.btcstaking.v1;

import "cosmos/msg/v1/msg.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
//import "cosmos/staking/v1beta1/staking.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types";

message BTCStakingRecord {
bytes tx_hash = 1;
uint64 amount = 2;
bytes mint_to_addr = 3;
}
54 changes: 54 additions & 0 deletions proto/lorenzo/btcstaking/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
syntax = "proto3";
package lorenzo.btcstaking.v1;

import "cosmos/msg/v1/msg.proto";
import "cosmos_proto/cosmos.proto";
import "gogoproto/gogo.proto";
//import "cosmos/staking/v1beta1/staking.proto";

option go_package = "github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types";

// Msg defines the Msg service.
// TODO: handle unbonding tx with full witness
service Msg {
option (cosmos.msg.v1.service) = true;

// CreateBTCDelegation creates a new BTC delegation
rpc CreateBTCStaking(MsgCreateBTCStaking) returns (MsgCreateBTCStakingResponse);
}

message TransactionKey {
uint32 index = 1;
bytes hash = 2
[ (gogoproto.customtype) =
"github.com/Lorenzo-Protocol/lorenzo/types.BTCHeaderHashBytes" ];
}

// TransactionInfo is the info of a tx on Bitcoin,
// including
// - the position of the tx on BTC blockchain
// - the full tx content
// - the Merkle proof that this tx is on the above position
message TransactionInfo {
// key is the position (txIdx, blockHash) of this tx on BTC blockchain
// Although it is already a part of SubmissionKey, we store it here again
// to make TransactionInfo self-contained.
// For example, storing the key allows TransactionInfo to not relay on
// the fact that TransactionInfo will be ordered in the same order as
// TransactionKeys in SubmissionKey.
TransactionKey key = 1;
// transaction is the full transaction in bytes
bytes transaction = 2;
// proof is the Merkle proof that this tx is included in the position in `key`
// TODO: maybe it could use here better format as we already processed and
// validated the proof?
bytes proof = 3;
}

message MsgCreateBTCStaking {
option (cosmos.msg.v1.signer) = "signer";
string signer = 1;
TransactionInfo staking_tx = 2;
}

message MsgCreateBTCStakingResponse {}
43 changes: 43 additions & 0 deletions x/btcstaking/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cli

import (
//"encoding/hex"
"fmt"
//"strings"

//sdkmath "cosmossdk.io/math"
"github.com/cosmos/cosmos-sdk/client"
/*"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"*/
"github.com/spf13/cobra"

//lrz "github.com/Lorenzo-Protocol/lorenzo/types"
"github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types"
)

const (
FlagMoniker = "moniker"
FlagIdentity = "identity"
FlagWebsite = "website"
FlagSecurityContact = "security-contact"
FlagDetails = "details"
FlagCommissionRate = "commission-rate"
)

// GetTxCmd returns the transaction commands for this module
func GetTxCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName),
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

//FIXME: add command
cmd.AddCommand()

return cmd
}
49 changes: 49 additions & 0 deletions x/btcstaking/client/cli/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package cli

import (
"fmt"
"math"

sdkmath "cosmossdk.io/math"
"github.com/btcsuite/btcd/btcutil"
)

func parseLockTime(str string) (uint16, error) {
num, ok := sdkmath.NewIntFromString(str)

if !ok {
return 0, fmt.Errorf("invalid staking time: %s", str)
}

if !num.IsUint64() {
return 0, fmt.Errorf("staking time is not valid uint")
}

asUint64 := num.Uint64()

if asUint64 > math.MaxUint16 {
return 0, fmt.Errorf("staking time is too large. Max is %d", math.MaxUint16)
}

return uint16(asUint64), nil
}

func parseBtcAmount(str string) (btcutil.Amount, error) {
num, ok := sdkmath.NewIntFromString(str)

if !ok {
return 0, fmt.Errorf("invalid staking value: %s", str)
}

if num.IsNegative() {
return 0, fmt.Errorf("staking value is negative")
}

if !num.IsInt64() {
return 0, fmt.Errorf("staking value is not valid uint")
}

asInt64 := num.Int64()

return btcutil.Amount(asInt64), nil
}
25 changes: 25 additions & 0 deletions x/btcstaking/keeper/btc_receiving_addr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package keeper

import (
"github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// SetBTCReceivingAddr sets the x/btcstaking module parameters.
func (k Keeper) SetBTCReceivingAddr(ctx sdk.Context, p string) error {
store := ctx.KVStore(k.storeKey)
bz := []byte(p)
store.Set(types.BTCReceivingAddrKey, bz)
return nil
}

// GetBTCReceivingAddr returns the current x/btcstaking module parameters.
func (k Keeper) GetBTCReceivingAddr(ctx sdk.Context) (p string) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.BTCReceivingAddrKey)
if bz == nil {
return p
}
p = string(bz)
return p
}
31 changes: 31 additions & 0 deletions x/btcstaking/keeper/btc_staking_record.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package keeper

import (
"github.com/Lorenzo-Protocol/lorenzo/x/btcstaking/types"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
)

func (k Keeper) addBTCStakingRecord(ctx sdk.Context, btcStk *types.BTCStakingRecord) error {
store := k.btcStakingRecordStore(ctx)
var btcStkKey = btcStk.TxHash
store.Set(btcStkKey, k.cdc.MustMarshal(btcStk))
return nil
}

func (k Keeper) getBTCStakingRecord(ctx sdk.Context, txHash chainhash.Hash) *types.BTCStakingRecord {
store := k.btcStakingRecordStore(ctx)
btcStakingRecordBytes := store.Get(txHash[:])
if len(btcStakingRecordBytes) == 0 {
return nil
}
var btcStkRecord types.BTCStakingRecord
k.cdc.MustUnmarshal(btcStakingRecordBytes, &btcStkRecord)
return &btcStkRecord
}

func (k Keeper) btcStakingRecordStore(ctx sdk.Context) prefix.Store {
kvStore := ctx.KVStore(k.storeKey)
return prefix.NewStore(kvStore, types.BTCStakingRecordKey)
}
Loading

0 comments on commit 6f80bb4

Please sign in to comment.