Skip to content

Commit

Permalink
[RelayerProxy] feat: implement relayerProxy struct (#82)
Browse files Browse the repository at this point in the history
* feat: add notifiable observable

Co-authored-by: red-0ne <[email protected]>

* fixup: observable

(cherry picked from commit bcf700405b5e4bd71bf9bb650c988526fa16c728)

* refactor/fix: notifiable observable improvements

* chore: more review improvements

* refactor: renaming

- `notifiable` pkg to `channel`
- `notifiableObservable` struct to `channelObservable`
- `observer` struct to `channelObserver`
- `notifier` vars to `producer`
- `notifee` vars to `observable` (or similar)

* chore: update comments

* refactor: simplify drainCh test helper

* test: fix timeout

* test: rename observable test functions

* test: add test TODOs

* chore: update comments

* refactor: simplify observable & observer

* test: fix & add observable tests

* test: cleanup & comment observable tests

* fixup: observable

(cherry picked from commit 33f3196535b7dae154e01f93aab36f70cda8fc4f)

* fixup: observable test

(cherry picked from commit 9c206da115dc35843d588313c2215a0e649c6df6)

* refactor: simplify & cleanup

* chore: cleanup logs & comments

* chore: improve comments

* refactor: DrainChannel test helper

* shore: cleanup & simplify

* test: comment out flaky test cases

* fixup: drain channel helper

* chore: improve var name

* fixup: drain channel helper

* test: shorten timeout

* chore: cleanup

* chore: cleanup, simplification, review improvements

(cherry picked from commit 92a547da29ec526d415f6967ccfa5988c3f5ca1d)

* chore: improve comments

Co-authored-by: Daniel Olshansky <[email protected]>

* chore: improve comments

Co-authored-by: Daniel Olshansky <[email protected]>

* refactor: rename `Observable#Close()` to `#UnsubscribeAll()`

* chore: improve comments

* chore: misc. review feedback improvements

* chore: improve comment

* chore: review improvements

* chore: last minute improvements

* feat: add RelayerProxy interface

* Fix grammar in comments

Co-authored-by: Daniel Olshansky <[email protected]>

* chore: rename package to relayerproxy

* feat: implement relayerProxy struct and its constructor args

* fix: change directory structure

* fix: change directory structure

* chore: address change requests

* chore: comment unavailable interface and its usage

---------

Co-authored-by: Bryan White <[email protected]>
Co-authored-by: Daniel Olshansky <[email protected]>
  • Loading branch information
3 people authored Oct 23, 2023
1 parent 9966b8a commit 9af3ca0
Showing 1 changed file with 118 additions and 0 deletions.
118 changes: 118 additions & 0 deletions pkg/relayer/proxy/proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package proxy

import (
"context"

sdkclient "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
accounttypes "github.com/cosmos/cosmos-sdk/x/auth/types"

// TODO_INCOMPLETE(@red-0ne): Import the appropriate block client interface once available.
// blocktypes "pocket/pkg/client"
"pocket/pkg/observable"
"pocket/pkg/observable/channel"
"pocket/x/service/types"
sessiontypes "pocket/x/session/types"
suppliertypes "pocket/x/supplier/types"
)

var _ RelayerProxy = &relayerProxy{}

type relayerProxy struct {
// keyName is the supplier's key name in the Cosmos's keybase. It is used along with the keyring to
// get the supplier address and sign the relay responses.
keyName string
keyring keyring.Keyring

// blocksClient is the client used to get the block at the latest height from the blockchain
// and be notified of new incoming blocks. It is used to update the current session data.
// TODO_INCOMPLETE(@red-0ne): Uncomment once the BlockClient interface is available.
// blockClient blocktypes.BlockClient

// accountsQuerier is the querier used to get account data (e.g. app publicKey) from the blockchain,
// which, in the context of the RelayerProxy, is used to verify the relay request signatures.
accountsQuerier accounttypes.QueryClient

// supplierQuerier is the querier used to get the supplier's advertised information from the blockchain,
// which contains the supported services, RPC types, and endpoints, etc...
supplierQuerier suppliertypes.QueryClient

// sessionQuerier is the querier used to get the current session from the blockchain,
// which is needed to check if the relay proxy should be serving an incoming relay request.
sessionQuerier sessiontypes.QueryClient

// providedServices is a map of the services provided by the relayer proxy. Each provided service
// has the necessary information to start the server that listens for incoming relay requests and
// the client that proxies the request to the supported native service.
providedServices map[string][]ProvidedService

// servedRelays is an observable that notifies the miner about the relays that have been served.
servedRelays observable.Observable[*types.Relay]

// servedRelaysProducer is a channel that emits the relays that have been served so that the
// servedRelays observable can fan out the notifications to its subscribers.
servedRelaysProducer chan<- *types.Relay
}

func NewRelayerProxy(
ctx context.Context,
clientCtx sdkclient.Context,
keyName string,
keyring keyring.Keyring,

// TODO_INCOMPLETE(@red-0ne): Uncomment once the BlockClient interface is available.
// blockClient blocktypes.BlockClient,
) RelayerProxy {
accountQuerier := accounttypes.NewQueryClient(clientCtx)
supplierQuerier := suppliertypes.NewQueryClient(clientCtx)
sessionQuerier := sessiontypes.NewQueryClient(clientCtx)
providedServices := buildProvidedServices(ctx, supplierQuerier)
servedRelays, servedRelaysProducer := channel.NewObservable[*types.Relay]()

return &relayerProxy{
// TODO_INCOMPLETE(@red-0ne): Uncomment once the BlockClient interface is available.
// blockClient: blockClient,
keyName: keyName,
keyring: keyring,
accountsQuerier: accountQuerier,
supplierQuerier: supplierQuerier,
sessionQuerier: sessionQuerier,
providedServices: providedServices,
servedRelays: servedRelays,
servedRelaysProducer: servedRelaysProducer,
}
}

// Start starts all supported proxies and returns an error if any of them fail to start.
func (rp *relayerProxy) Start(ctx context.Context) error {
panic("TODO: implement relayerProxy.Start")
}

// Stop stops all supported proxies and returns an error if any of them fail.
func (rp *relayerProxy) Stop(ctx context.Context) error {
panic("TODO: implement relayerProxy.Stop")
}

// ServedRelays returns an observable that notifies the miner about the relays that have been served.
// A served relay is one whose RelayRequest's signature and session have been verified,
// and its RelayResponse has been signed and successfully sent to the client.
func (rp *relayerProxy) ServedRelays() observable.Observable[*types.Relay] {
panic("TODO: implement relayerProxy.ServedRelays")
}

// buildProvidedServices builds the provided services map from the supplier's advertised information.
// It loops over the retrieved `SupplierServiceConfig` and, for each `SupplierEndpoint`, it creates the necessary
// server and client to populate the corresponding `ProvidedService` struct in the map.
func buildProvidedServices(
ctx context.Context,
supplierQuerier suppliertypes.QueryClient,
) map[string]ProvidedService {
panic("TODO: implement buildProvidedServices")
}

// TODO_INCOMPLETE(@red-0ne): Add the appropriate server and client interfaces to be implemented by each RPC type.
type ProvidedService struct {
serviceId string
server struct{}
client struct{}
}

0 comments on commit 9af3ca0

Please sign in to comment.