Skip to content

Commit

Permalink
Draft: overall SDK structure
Browse files Browse the repository at this point in the history
  • Loading branch information
adshmh committed Jun 24, 2024
1 parent dc2b742 commit 450fac4
Show file tree
Hide file tree
Showing 11 changed files with 422 additions and 485 deletions.
65 changes: 65 additions & 0 deletions account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package sdk

import (
"context"

"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
"github.com/cosmos/cosmos-sdk/types"
accounttypes "github.com/cosmos/cosmos-sdk/x/auth/types"
grpc "github.com/cosmos/gogoproto/grpc"
)

var queryCodec *codec.ProtoCodec

// init initializes the codec for the account module
func init() {
reg := cdctypes.NewInterfaceRegistry()
accounttypes.RegisterInterfaces(reg)
queryCodec = codec.NewProtoCodec(reg)
}

// AccountClient is used to interact with the account module.
// It uses an AccountClient implementation that uses the gRPC query client
type AccountClient struct {
PoktNodeAccountFetcher
}

// GetPubKeyFromAddress returns the public key of the account with the given address.
// It queries the account module using the gRPC query client.
func (ac *AccountClient) GetPubKeyFromAddress(
ctx context.Context,
address string,
) (pubKey cryptotypes.PubKey, err error) {
req := &accounttypes.QueryAccountRequest{Address: address}
res, err := ac.queryClient.Account(ctx, req)

Check failure on line 36 in account.go

View workflow job for this annotation

GitHub Actions / go-test

ac.queryClient undefined (type *AccountClient has no field or method queryClient)
if err != nil {
return nil, err
}

var fetchedAccount types.AccountI
if err = queryCodec.UnpackAny(res.Account, &fetchedAccount); err != nil {
return nil, err
}

return fetchedAccount.GetPubKey(), nil
}

// NewPoktNodeAccountFetcher returns the default implementation of the PoktNodeAccountFetcher interfce.

Check warning on line 49 in account.go

View workflow job for this annotation

GitHub Actions / misspell

[misspell] account.go#L49

"interfce" is a misspelling of "interface"
Raw output
./account.go:49:94: "interfce" is a misspelling of "interface"
// It connects to a POKT full node, through the account module's query client, to get account data.
func NewAccountClient(grpcConn grpc.ClientConn) PoktNodeAccountFetcher {
return accounttypes.NewQueryClient(grpcConn)

Check failure on line 52 in account.go

View workflow job for this annotation

GitHub Actions / go-test

cannot use accounttypes.NewQueryClient(grpcConn) (value of type "github.com/cosmos/cosmos-sdk/x/auth/types".QueryClient) as PoktNodeAccountFetcher value in return statement: "github.com/cosmos/cosmos-sdk/x/auth/types".QueryClient does not implement PoktNodeAccountFetcher (wrong type for method Account)
}

// PoktNodeAccountFetcher is used by the AccountClient to fetch accounts using poktroll request/response types.
//
// Most users can rely on the default implementation provided by NewPoktNodeAccountFetcher function.
// A custom implementation of this interface can be used to gain more granular control over the interactions
// of the AccountClient with the POKT full node.
type PoktNodeAccountFetcher interface {
Account(
context.Context,
*accounttypes.QueryAccountRequest,
) (*accounttypes.QueryAccountResponse, error)
}
117 changes: 117 additions & 0 deletions application.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,120 @@ func (ac *ApplicationClient) GetApplication(

return res.Application, nil
}

// GetApplicationsDelegatingToGateway returns the application addresses that are
// delegating to the given gateway address.
func (ac *ApplicationClient) GetApplicationsDelegatingToGateway(
ctx context.Context,
gatewayAddress string,
queryHeight int64,
) ([]string, error) {
allApplications, err := ac.GetAllApplications(ctx)
if err != nil {
return nil, fmt.Errorf("GetApplicationsDelegatingToGateway: error getting all applications: %w", err)

Check failure on line 70 in application.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: fmt
}

gatewayDelegatingApplications := make([]string, 0)
for _, application := range allApplications {
appRing := ApplicationRing{Application: application}
// Get the gateways that are delegated to the application
// at the query height and check if the given gateway address is in the list.
gatewaysDelegatedTo := appRing.ringAddressesAtBlock(queryHeight)
if slices.Contains(gatewaysDelegatedTo, gatewayAddress) {
// The application is delegating to the given gateway address, add it to the list.
gatewayDelegatingApplications = append(gatewayDelegatingApplications, application.Address)
}
}

return gatewayDelegatingApplications, nil
}

type ApplicationRing struct {
types.Application
PublicKeyFetcher
}

// GetRing returns the ring for the application.
// The ring is created using the application's public key and the public keys of
// the gateways that are currently delegated from the application.
func (a ApplicationRing) GetRing(
ctx context.Context,
queryHeight int64,
) (addressRing *ring.Ring, err error) {

Check failure on line 99 in application.go

View workflow job for this annotation

GitHub Actions / go-test

undefined: ring
// Get the gateway addresses that are delegated from the application
// at the query height.
currentGatewayAddresses := a.ringAddressesAtBlock(queryHeight)

ringAddresses := make([]string, 0)
ringAddresses = append(ringAddresses, a.Application.Address)

// If there are no current gateway addresses, use the application address as the ring address.
if len(currentGatewayAddresses) == 0 {
ringAddresses = append(ringAddresses, a.Application.Address)
} else {
ringAddresses = append(ringAddresses, currentGatewayAddresses...)
}

curve := ring_secp256k1.NewCurve()
ringPoints := make([]ringtypes.Point, 0, len(ringAddresses))

// Create a ring point for each address.
for _, address := range ringAddresses {
pubKey, err := a.PublicKeyFetcher.GetPubKeyFromAddress(ctx, address)
if err != nil {
return nil, err
}

point, err := curve.DecodeToPoint(pubKey.Bytes())
if err != nil {
return nil, err
}

ringPoints = append(ringPoints, point)
}

return ring.NewFixedKeyRingFromPublicKeys(ring_secp256k1.NewCurve(), ringPoints)
}

func (a ApplicationRing) ringAddressesAtBlock(
queryHeight int64,
) []string {
// Get the current active delegations for the application and use them as a base.
activeDelegationsAtHeight := a.Application.DelegateeGatewayAddresses

// Use a map to keep track of the gateways addresses that have been added to
// the active delegations slice to avoid duplicates.
addedDelegations := make(map[string]struct{})

// Iterate over the pending undelegations recorded at their respective block
// height and check whether to add them back as active delegations.
for pendingUndelegationHeight, undelegatedGateways := range a.Application.PendingUndelegations {
// If the pending undelegation happened BEFORE the target session end height, skip it.
// The gateway is pending undelegation and simply has not been pruned yet.
// It will be pruned in the near future.
if pendingUndelegationHeight < sessionEndHeight {
continue
}
// Add back any gateway address that was undelegated after the target session
// end height, as we consider it not happening yet relative to the target height.
for _, gatewayAddress := range undelegatedGateways.GatewayAddresses {
if _, ok := addedDelegations[gatewayAddress]; ok {
continue
}

activeDelegationsAtHeight = append(activeDelegationsAtHeight, gatewayAddress)
// Mark the gateway address as added to avoid duplicates.
addedDelegations[gatewayAddress] = struct{}{}
}

}

return activeDelegationsAtHeight
}

// PublicKeyFetcher specifies an interface that allows getting the public key corresponding to an address.
// It is used by the ApplicationRing struct to construct the Application's Ring for signing relay requests.
// The AccountClient struct provides an implementation of this interface.
type PublicKeyFetcher interface {
GetPubKeyFromAddress(context.Context, string) ([]byte, error)
}
59 changes: 0 additions & 59 deletions clients/account.go

This file was deleted.

12 changes: 4 additions & 8 deletions clients/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,23 @@ import (

"github.com/cosmos/gogoproto/grpc"
"github.com/pokt-network/poktroll/x/shared/types"

"github.com/pokt-network/shannon-sdk/sdk"
)

var _ sdk.SharedParamsClient = (*sharedParamsClient)(nil)

// sharedParamsClient is a SharedParamsClient implementation that uses the gRPC
// query client of the on-chain shared module.
type sharedParamsClient struct {
type SharedParamsClient struct {
queryClient types.QueryClient
}

// NewSharedParamsClient creates a new share params client with the provided gRPC connection.
func NewSharedParamsClient(grpcConn grpc.ClientConn) (sdk.SharedParamsClient, error) {
return &sharedParamsClient{
func NewSharedParamsClient(grpcConn grpc.ClientConn) (*SharedParamsClient, error) {
return &SharedParamsClient{
queryClient: types.NewQueryClient(grpcConn),
}, nil
}

// GetParams returns the params of the poktroll on-chain shared module.
func (pc *sharedParamsClient) GetParams(
func (pc *SharedParamsClient) GetParams(
ctx context.Context,
) (*types.Params, error) {
req := &types.QueryParamsRequest{}
Expand Down
58 changes: 0 additions & 58 deletions clients/relay.go

This file was deleted.

23 changes: 0 additions & 23 deletions clients/signer.go

This file was deleted.

Loading

0 comments on commit 450fac4

Please sign in to comment.