Implement onboarding module for testnet participants #36

Merged
ashwin merged 8 commits from testnet-onboarding into main 2024-07-16 07:45:45 +00:00
22 changed files with 199 additions and 53 deletions
Showing only changes of commit f23f691646 - Show all commits

69
.golangci.yml Normal file
View File

@ -0,0 +1,69 @@
run:
tests: false
# timeout for analysis, e.g. 30s, 5m, default is 1m
# timeout: 5m
linters:
enable:
- bodyclose
- dogsled
- errcheck
- goconst
- gocritic
# - revive # overly sensitive var-naming detection
- gosec
- gosimple
- govet
- ineffassign
- lll
- misspell
- nakedret
- prealloc
- exportloopref
- staticcheck
- stylecheck
- typecheck
- unconvert
- unparam
- unused
- asciicheck
- exportloopref
- gofumpt
- gomodguard
- whitespace
issues:
exclude-rules:
- path: _test\.go
linters:
- gosec
- linters:
- lll
source: "https://"
- linters:
- stylecheck
text: "ST1003:"
max-same-issues: 50
linters-settings:
lll:
line-length: 150
dogsled:
max-blank-identifiers: 3
golint:
min-confidence: 0
maligned:
suggest-new: true
misspell:
locale: US
gofumpt:
lang-version: "1.21"
gomodguard:
blocked:
versions: # List of blocked module version constraints
- https://github.com/etcd-io/etcd: # Blocked module with version constraint
version: ">= 3.4.10 || ~3.3.23" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons
reason: "CVE-2020-15114; CVE-2020-15136; CVE-2020-15115" # Reason why the version constraint exists. (Optional)
- https://github.com/dgrijalva/jwt-go: # Blocked module with version constraint
version: ">= 4.0.0-preview1" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons
reason: "CVE-2020-26160" # Reason why the version constraint exists. (Optional)

View File

@ -51,7 +51,7 @@ func (app *LaconicApp) ExportAppStateAndValidators(
}
// prepare for fresh start at zero height
// NOTE zero height genesis is a temporary feature, which will be deprecated in favour of export at a block height
// NOTE zero height genesis is a temporary feature, which will be deprecated in favor of export at a block height
func (app *LaconicApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
applyAllowedAddrs := false

2
go.mod
View File

@ -44,7 +44,6 @@ require (
github.com/statechannels/go-nitro v0.1.2
github.com/stretchr/testify v1.8.4
github.com/vektah/gqlparser/v2 v2.5.11
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
golang.org/x/sync v0.7.0
google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f
google.golang.org/grpc v1.60.1
@ -181,6 +180,7 @@ require (
go.etcd.io/bbolt v1.3.8 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/term v0.19.0 // indirect

View File

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"time"
"cosmossdk.io/log"
"github.com/99designs/gqlgen/graphql/handler"
@ -54,7 +55,12 @@ func Server(ctx context.Context, clientCtx client.Context, logger log.Logger) er
go func() {
logger.Info(fmt.Sprintf("Connect to GraphQL playground url: http://localhost:%s", port))
errCh <- http.ListenAndServe(":"+port, router)
server := &http.Server{
Addr: ":" + port,
Handler: router,
ReadHeaderTimeout: 3 * time.Second,
}
errCh <- server.ListenAndServe()
}()
select {

View File

@ -39,7 +39,8 @@ func getStatusInfo(client client.Context) (*NodeInfo, *SyncInfo, *ValidatorInfo,
}, nil
}
func getNetInfo(client client.Context) (string, []*PeerInfo, error) {
// nolint: all
func getNetInfo(_ client.Context) (string, []*PeerInfo, error) {
// TODO: Implement
// nodeClient, err := client.GetNode()

View File

@ -103,7 +103,14 @@ func (tf *TestFixture) Setup() error {
bondKeeper := bondkeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[bondTypes.StoreKey]), accountKeeper, bankKeeper)
registryKeeper := registrykeeper.NewKeeper(cdc, runtime.NewKVStoreService(keys[registryTypes.StoreKey]), accountKeeper, bankKeeper, bondKeeper, auctionKeeper)
registryKeeper := registrykeeper.NewKeeper(
cdc,
runtime.NewKVStoreService(keys[registryTypes.StoreKey]),
accountKeeper,
bankKeeper,
bondKeeper,
auctionKeeper,
)
authModule := auth.NewAppModule(cdc, accountKeeper, authsims.RandomGenesisAccounts, nil)
bankModule := bank.NewAppModule(cdc, bankKeeper, accountKeeper, nil)

View File

@ -146,7 +146,11 @@ func collectGenFiles(cfg Config, vals []*Validator, outputDir string) error {
}
appState, err := genutil.GenAppStateFromConfig(cfg.Codec, cfg.TxConfig,
cmtCfg, initCfg, appGenesis, banktypes.GenesisBalancesIterator{}, genutiltypes.DefaultMessageValidator, cfg.TxConfig.SigningContext().ValidatorAddressCodec())
cmtCfg, initCfg, appGenesis,
banktypes.GenesisBalancesIterator{},
genutiltypes.DefaultMessageValidator,
cfg.TxConfig.SigningContext().ValidatorAddressCodec(),
)
if err != nil {
return err
}

View File

@ -77,8 +77,12 @@ type Keeper struct {
// state management
Schema collections.Schema
Params collections.Item[auctiontypes.Params]
Auctions *collections.IndexedMap[string, auctiontypes.Auction, AuctionsIndexes] // map: auctionId -> Auction, index: owner -> Auctions
Bids *collections.IndexedMap[collections.Pair[string, string], auctiontypes.Bid, BidsIndexes] // map: (auctionId, bidder) -> Bid, index: bidder -> auctionId
Auctions *collections.IndexedMap[
string, auctiontypes.Auction, AuctionsIndexes,
] // map: auctionId -> Auction, index: owner -> Auctions
Bids *collections.IndexedMap[
collections.Pair[string, string], auctiontypes.Bid, BidsIndexes,
] // map: (auctionId, bidder) -> Bid, index: bidder -> auctionId
}
// NewKeeper creates a new Keeper instance
@ -94,9 +98,16 @@ func NewKeeper(
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
Params: collections.NewItem(sb, auctiontypes.ParamsPrefix, "params", codec.CollValue[auctiontypes.Params](cdc)),
Auctions: collections.NewIndexedMap(sb, auctiontypes.AuctionsPrefix, "auctions", collections.StringKey, codec.CollValue[auctiontypes.Auction](cdc), newAuctionIndexes(sb)),
Bids: collections.NewIndexedMap(sb, auctiontypes.BidsPrefix, "bids", collections.PairKeyCodec(collections.StringKey, collections.StringKey), codec.CollValue[auctiontypes.Bid](cdc), newBidsIndexes(sb)),
usageKeepers: nil,
Auctions: collections.NewIndexedMap(
sb, auctiontypes.AuctionsPrefix, "auctions", collections.StringKey, codec.CollValue[auctiontypes.Auction](cdc), newAuctionIndexes(sb),
),
Bids: collections.NewIndexedMap(
sb, auctiontypes.BidsPrefix, "bids",
collections.PairKeyCodec(collections.StringKey, collections.StringKey),
codec.CollValue[auctiontypes.Bid](cdc),
newBidsIndexes(sb),
),
usageKeepers: nil,
}
schema, err := sb.Build()
@ -191,10 +202,16 @@ func (k Keeper) GetBid(ctx sdk.Context, id string, bidder string) (auctiontypes.
func (k Keeper) GetBids(ctx sdk.Context, id string) ([]*auctiontypes.Bid, error) {
var bids []*auctiontypes.Bid
err := k.Bids.Walk(ctx, collections.NewPrefixedPairRange[string, string](id), func(key collections.Pair[string, string], value auctiontypes.Bid) (stop bool, err error) {
bids = append(bids, &value)
return false, nil
})
err := k.Bids.Walk(ctx,
collections.NewPrefixedPairRange[string, string](id),
func(
key collections.Pair[string, string],
value auctiontypes.Bid) (stop bool, err error,
) {
bids = append(bids, &value)
return false, nil
},
)
if err != nil {
return nil, err
}
@ -716,7 +733,12 @@ func (k Keeper) pickAuctionWinner(ctx sdk.Context, auction *auctiontypes.Auction
}
// Use auction burn module account instead of actually burning coins to better keep track of supply.
sdkErr = k.bankKeeper.SendCoinsFromModuleToModule(ctx, auctiontypes.ModuleName, auctiontypes.AuctionBurnModuleAccountName, sdk.NewCoins(amountToBurn))
sdkErr = k.bankKeeper.SendCoinsFromModuleToModule(
ctx,
auctiontypes.ModuleName,
auctiontypes.AuctionBurnModuleAccountName,
sdk.NewCoins(amountToBurn),
)
if sdkErr != nil {
k.Logger(ctx).Error(fmt.Sprintf("Auction error burning coins: %v", sdkErr))
panic(sdkErr)

View File

@ -98,7 +98,10 @@ func (qs queryServer) GetBids(c context.Context, req *auctiontypes.QueryGetBidsR
}
// AuctionsByBidder queries auctions by bidder
func (qs queryServer) AuctionsByBidder(c context.Context, req *auctiontypes.QueryAuctionsByBidderRequest) (*auctiontypes.QueryAuctionsByBidderResponse, error) {
func (qs queryServer) AuctionsByBidder(
c context.Context,
req *auctiontypes.QueryAuctionsByBidderRequest,
) (*auctiontypes.QueryAuctionsByBidderResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
if req.BidderAddress == "" {
@ -110,11 +113,18 @@ func (qs queryServer) AuctionsByBidder(c context.Context, req *auctiontypes.Quer
return nil, err
}
return &auctiontypes.QueryAuctionsByBidderResponse{Auctions: &auctiontypes.Auctions{Auctions: auctions}}, nil
return &auctiontypes.QueryAuctionsByBidderResponse{
Auctions: &auctiontypes.Auctions{
Auctions: auctions,
},
}, nil
}
// AuctionsByOwner queries auctions by owner
func (qs queryServer) AuctionsByOwner(c context.Context, req *auctiontypes.QueryAuctionsByOwnerRequest) (*auctiontypes.QueryAuctionsByOwnerResponse, error) {
func (qs queryServer) AuctionsByOwner(
c context.Context,
req *auctiontypes.QueryAuctionsByOwnerRequest,
) (*auctiontypes.QueryAuctionsByOwnerResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
if req.OwnerAddress == "" {
@ -130,7 +140,10 @@ func (qs queryServer) AuctionsByOwner(c context.Context, req *auctiontypes.Query
}
// GetAuctionModuleBalance queries the auction module account balance
func (qs queryServer) GetAuctionModuleBalance(c context.Context, req *auctiontypes.QueryGetAuctionModuleBalanceRequest) (*auctiontypes.QueryGetAuctionModuleBalanceResponse, error) {
func (qs queryServer) GetAuctionModuleBalance(
c context.Context,
req *auctiontypes.QueryGetAuctionModuleBalanceRequest,
) (*auctiontypes.QueryGetAuctionModuleBalanceResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
balances := qs.k.GetAuctionModuleBalances(ctx)

View File

@ -4,7 +4,6 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/store"
"cosmossdk.io/depinject"
"golang.org/x/exp/maps"
"github.com/cosmos/cosmos-sdk/codec"
auth "github.com/cosmos/cosmos-sdk/x/auth/keeper"
@ -64,15 +63,14 @@ func InvokeSetAuctionHooks(
keeper *keeper.Keeper,
auctionHooks map[string]auction.AuctionHooksWrapper,
) error {
// all arguments to invokers are optional
// All arguments to invokers are optional
if keeper == nil || config == nil {
return nil
}
var usageKeepers []auction.AuctionUsageKeeper
usageKeepers := make([]auction.AuctionUsageKeeper, 0, len(auctionHooks))
for _, modName := range maps.Keys(auctionHooks) {
hook := auctionHooks[modName]
for _, hook := range auctionHooks {
usageKeepers = append(usageKeepers, hook)
}

View File

@ -71,8 +71,10 @@ func NewKeeper(
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
Params: collections.NewItem(sb, bondtypes.ParamsPrefix, "params", codec.CollValue[bondtypes.Params](cdc)),
Bonds: collections.NewIndexedMap(sb, bondtypes.BondsPrefix, "bonds", collections.StringKey, codec.CollValue[bondtypes.Bond](cdc), newBondIndexes(sb)),
usageKeepers: nil,
Bonds: collections.NewIndexedMap(
sb, bondtypes.BondsPrefix, "bonds", collections.StringKey, codec.CollValue[bondtypes.Bond](cdc), newBondIndexes(sb),
),
usageKeepers: nil,
}
schema, err := sb.Build()

View File

@ -63,12 +63,17 @@ func (qs queryServer) GetBondById(c context.Context, req *bondtypes.QueryGetBond
}
// GetBondsByOwner implements bond.QueryServer.
func (qs queryServer) GetBondsByOwner(c context.Context, req *bondtypes.QueryGetBondsByOwnerRequest) (*bondtypes.QueryGetBondsByOwnerResponse, error) {
func (qs queryServer) GetBondsByOwner(
c context.Context,
req *bondtypes.QueryGetBondsByOwnerRequest,
) (*bondtypes.QueryGetBondsByOwnerResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
owner := req.GetOwner()
if len(owner) == 0 {
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "owner required")
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest,
"owner required",
)
}
bonds, err := qs.k.GetBondsByOwner(ctx, owner)
@ -80,9 +85,14 @@ func (qs queryServer) GetBondsByOwner(c context.Context, req *bondtypes.QueryGet
}
// GetBondModuleBalance implements bond.QueryServer.
func (qs queryServer) GetBondModuleBalance(c context.Context, _ *bondtypes.QueryGetBondModuleBalanceRequest) (*bondtypes.QueryGetBondModuleBalanceResponse, error) {
func (qs queryServer) GetBondModuleBalance(
c context.Context,
_ *bondtypes.QueryGetBondModuleBalanceRequest,
) (*bondtypes.QueryGetBondModuleBalanceResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
balances := qs.k.GetBondModuleBalances(ctx)
return &bondtypes.QueryGetBondModuleBalanceResponse{Balance: balances}, nil
return &bondtypes.QueryGetBondModuleBalanceResponse{
Balance: balances,
}, nil
}

View File

@ -4,7 +4,6 @@ import (
"cosmossdk.io/core/appmodule"
"cosmossdk.io/core/store"
"cosmossdk.io/depinject"
"golang.org/x/exp/maps"
"github.com/cosmos/cosmos-sdk/codec"
auth "github.com/cosmos/cosmos-sdk/x/auth/keeper"
@ -60,15 +59,14 @@ func InvokeSetBondHooks(
keeper *keeper.Keeper,
bondHooks map[string]bond.BondHooksWrapper,
) error {
// all arguments to invokers are optional
// All arguments to invokers are optional
if keeper == nil || config == nil {
return nil
}
var usageKeepers []bond.BondUsageKeeper
usageKeepers := make([]bond.BondUsageKeeper, 0, len(bondHooks))
for _, modName := range maps.Keys(bondHooks) {
hook := bondHooks[modName]
for _, hook := range bondHooks {
usageKeepers = append(usageKeepers, hook)
}

View File

@ -6,9 +6,7 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
var (
_ sdk.Msg = &MsgCreateBond{}
)
var _ sdk.Msg = &MsgCreateBond{}
// NewMsgCreateBond is the constructor function for MsgCreateBond.
func NewMsgCreateBond(coins sdk.Coins, signer sdk.AccAddress) MsgCreateBond {

View File

@ -8,7 +8,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)
// Default parameter values.
// DefaultMaxBondAmountTokens are the default parameter values.
var DefaultMaxBondAmountTokens = sdkmath.NewInt(100000000000)
func NewParams(maxBondAmount sdk.Coin) Params {

View File

@ -44,7 +44,9 @@ func NewKeeper(cdc codec.BinaryCodec, addressCodec address.Codec, storeService s
addressCodec: addressCodec,
authority: authority,
Params: collections.NewItem(sb, onboardingTypes.ParamsPrefix, "params", codec.CollValue[onboardingTypes.Params](cdc)),
Participants: collections.NewMap(sb, onboardingTypes.ParticipantsPrefix, "participants", collections.StringKey, codec.CollValue[onboardingTypes.Participant](cdc)),
Participants: collections.NewMap(
sb, onboardingTypes.ParticipantsPrefix, "participants", collections.StringKey, codec.CollValue[onboardingTypes.Participant](cdc),
),
}
schema, err := sb.Build()
@ -66,7 +68,11 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", onboardingTypes.ModuleName)
}
func (k Keeper) OnboardParticipant(ctx sdk.Context, msg *onboardingTypes.MsgOnboardParticipant, signerAddress sdk.AccAddress) (*onboardingTypes.MsgOnboardParticipantResponse, error) {
func (k Keeper) OnboardParticipant(
ctx sdk.Context,
msg *onboardingTypes.MsgOnboardParticipant,
signerAddress sdk.AccAddress,
) (*onboardingTypes.MsgOnboardParticipantResponse, error) {
params, err := k.Params.Get(ctx)
if err != nil {
return nil, err
@ -82,6 +88,10 @@ func (k Keeper) OnboardParticipant(ctx sdk.Context, msg *onboardingTypes.MsgOnbo
}
ethereumAddress, err := utils.DecodeEthereumAddress(message, msg.EthSignature)
if err != nil {
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Failed to decode Ethereum address")
}
if ethereumAddress != msg.EthPayload.Address {
return nil, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "Recovered ethereum address does not match the address set in payload")
}
@ -100,9 +110,7 @@ func (k Keeper) OnboardParticipant(ctx sdk.Context, msg *onboardingTypes.MsgOnbo
func (k Keeper) StoreParticipant(ctx sdk.Context, participant *onboardingTypes.Participant) error {
key := participant.CosmosAddress
k.Participants.Set(ctx, key, *participant)
return nil
return k.Participants.Set(ctx, key, *participant)
}
// ListParticipants - get all participants.

View File

@ -20,7 +20,10 @@ func NewQueryServerImpl(k *Keeper) onboardingtypes.QueryServer {
}
// Participants implements Participants.QueryServer.
func (qs queryServer) Participants(c context.Context, _ *onboardingtypes.QueryParticipantsRequest) (*onboardingtypes.QueryParticipantsResponse, error) {
func (qs queryServer) Participants(
c context.Context,
_ *onboardingtypes.QueryParticipantsRequest,
) (*onboardingtypes.QueryParticipantsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
resp, err := qs.k.ListParticipants(ctx)

View File

@ -6,9 +6,7 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
var (
_ sdk.Msg = &MsgOnboardParticipant{}
)
var _ sdk.Msg = &MsgOnboardParticipant{}
func (msg MsgOnboardParticipant) ValidateBasic() error {
if len(msg.Participant) == 0 {

View File

@ -61,7 +61,6 @@ func RecordBondInvariant(k *Keeper) sdk.Invariant {
return false, nil
})
if err != nil {
return sdk.FormatInvariant(
types.ModuleName,

View File

@ -243,7 +243,11 @@ func (k Keeper) GetRecordsByBondId(ctx sdk.Context, bondId string) ([]registryty
}
// RecordsFromAttributes gets a list of records whose attributes match all provided values
func (k Keeper) RecordsFromAttributes(ctx sdk.Context, attributes []*registrytypes.QueryRecordsRequest_KeyValueInput, all bool) ([]registrytypes.Record, error) {
func (k Keeper) RecordsFromAttributes(
ctx sdk.Context,
attributes []*registrytypes.QueryRecordsRequest_KeyValueInput,
all bool,
) ([]registrytypes.Record, error) {
resultRecordIds := []string{}
for i, attr := range attributes {
suffix, err := QueryValueToJSON(attr.Value)

View File

@ -320,7 +320,10 @@ func (ms msgServer) DissociateBond(c context.Context, msg *registrytypes.MsgDiss
return &registrytypes.MsgDissociateBondResponse{}, nil
}
func (ms msgServer) DissociateRecords(c context.Context, msg *registrytypes.MsgDissociateRecords) (*registrytypes.MsgDissociateRecordsResponse, error) {
func (ms msgServer) DissociateRecords(
c context.Context,
msg *registrytypes.MsgDissociateRecords,
) (*registrytypes.MsgDissociateRecordsResponse, error) {
if err := msg.ValidateBasic(); err != nil {
return nil, err
}

View File

@ -75,7 +75,10 @@ func (qs queryServer) GetRecord(c context.Context, req *registrytypes.QueryGetRe
return &registrytypes.QueryGetRecordResponse{Record: record}, nil
}
func (qs queryServer) GetRecordsByBondId(c context.Context, req *registrytypes.QueryGetRecordsByBondIdRequest) (*registrytypes.QueryGetRecordsByBondIdResponse, error) {
func (qs queryServer) GetRecordsByBondId(
c context.Context,
req *registrytypes.QueryGetRecordsByBondIdRequest,
) (*registrytypes.QueryGetRecordsByBondIdResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
records, err := qs.k.GetRecordsByBondId(ctx, req.GetId())