Skip to content

Commit

Permalink
[Proxy] chore: Use depinject for relayerProxy (#173)
Browse files Browse the repository at this point in the history
* chore: Use depinject for relayerProxy

* chore: rename option validation function

* chore: Add godoc comments

* chore: Improve errors readability
  • Loading branch information
red-0ne authored Nov 10, 2023
1 parent 55b3f4c commit 22aa52a
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 34 deletions.
2 changes: 2 additions & 0 deletions pkg/relayer/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ type RelayerProxy interface {
SignRelayResponse(relayResponse *types.RelayResponse) error
}

type RelayerProxyOption func(RelayerProxy)

// RelayServer is the interface of the advertised relay servers provided by the RelayerProxy.
type RelayServer interface {
// Start starts the service server and returns an error if it fails.
Expand Down
12 changes: 7 additions & 5 deletions pkg/relayer/proxy/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package proxy
import sdkerrors "cosmossdk.io/errors"

var (
codespace = "relayer/proxy"
ErrUnsupportedRPCType = sdkerrors.Register(codespace, 1, "unsupported rpc type")
ErrInvalidRelayRequestSignature = sdkerrors.Register(codespace, 2, "invalid relay request signature")
ErrInvalidSession = sdkerrors.Register(codespace, 3, "invalid session")
ErrInvalidSupplier = sdkerrors.Register(codespace, 4, "invalid supplier")
codespace = "relayer_proxy"
ErrRelayerProxyUnsupportedRPCType = sdkerrors.Register(codespace, 1, "unsupported relayer proxy rpc type")
ErrRelayerProxyInvalidRelayRequestSignature = sdkerrors.Register(codespace, 2, "invalid relay request signature")
ErrRelayerProxyInvalidSession = sdkerrors.Register(codespace, 3, "invalid session in relayer request")
ErrRelayerProxyInvalidSupplier = sdkerrors.Register(codespace, 4, "invalid relayer proxy supplier")
ErrRelayerProxyUndefinedSigningKeyName = sdkerrors.Register(codespace, 5, "undefined relayer proxy signing key name")
ErrRelayerProxyUndefinedProxiedServicesEndpoints = sdkerrors.Register(codespace, 6, "undefined proxied services endpoints for relayer proxy")
)
20 changes: 20 additions & 0 deletions pkg/relayer/proxy/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package proxy

import (
"github.com/pokt-network/poktroll/pkg/relayer"
)

// WithSigningKeyName sets the signing key name used by the relayer proxy to sign relay responses.
// It is used along with the keyring to get the supplier address and sign the relay responses.
func WithSigningKeyName(keyName string) relayer.RelayerProxyOption {
return func(relProxy relayer.RelayerProxy) {
relProxy.(*relayerProxy).signingKeyName = keyName
}
}

// WithProxiedServicesEndpoints sets the endpoints of the proxied services.
func WithProxiedServicesEndpoints(proxiedServicesEndpoints servicesEndpointsMap) relayer.RelayerProxyOption {
return func(relProxy relayer.RelayerProxy) {
relProxy.(*relayerProxy).proxiedServicesEndpoints = proxiedServicesEndpoints
}
}
71 changes: 48 additions & 23 deletions pkg/relayer/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"net/url"

"cosmossdk.io/depinject"
sdkclient "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/crypto/keyring"
accounttypes "github.com/cosmos/cosmos-sdk/x/auth/types"
Expand Down Expand Up @@ -32,10 +33,10 @@ type (
// when the miner enters the claim/proof phase.
// TODO_TEST: Have tests for the relayer proxy.
type relayerProxy struct {
// keyName is the supplier's key name in the Cosmos's keybase. It is used along with the keyring to
// signingKeyName 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
signingKeyName 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.
Expand Down Expand Up @@ -75,30 +76,40 @@ type relayerProxy struct {
supplierAddress string
}

// NewRelayerProxy creates a new relayer proxy with the given dependencies or returns
// an error if the dependencies fail to resolve or the options are invalid.
func NewRelayerProxy(
clientCtx sdkclient.Context,
keyName string,
keyring keyring.Keyring,
proxiedServicesEndpoints servicesEndpointsMap,
blockClient blocktypes.BlockClient,
) relayer.RelayerProxy {
accountQuerier := accounttypes.NewQueryClient(clientCtx)
supplierQuerier := suppliertypes.NewQueryClient(clientCtx)
sessionQuerier := sessiontypes.NewQueryClient(clientCtx)
deps depinject.Config,
opts ...relayer.RelayerProxyOption,
) (relayer.RelayerProxy, error) {
rp := &relayerProxy{}

if err := depinject.Inject(
deps,
&rp.clientCtx,
&rp.blockClient,
); err != nil {
return nil, err
}

servedRelays, servedRelaysProducer := channel.NewObservable[*types.Relay]()

return &relayerProxy{
blockClient: blockClient,
keyName: keyName,
keyring: keyring,
accountsQuerier: accountQuerier,
supplierQuerier: supplierQuerier,
sessionQuerier: sessionQuerier,
proxiedServicesEndpoints: proxiedServicesEndpoints,
servedRelays: servedRelays,
servedRelaysProducer: servedRelaysProducer,
clientCtx: clientCtx,
rp.servedRelays = servedRelays
rp.servedRelaysProducer = servedRelaysProducer
rp.accountsQuerier = accounttypes.NewQueryClient(rp.clientCtx)
rp.supplierQuerier = suppliertypes.NewQueryClient(rp.clientCtx)
rp.sessionQuerier = sessiontypes.NewQueryClient(rp.clientCtx)
rp.keyring = rp.clientCtx.Keyring

for _, opt := range opts {
opt(rp)
}

if err := rp.validateConfig(); err != nil {
return nil, err
}

return rp, nil
}

// Start concurrently starts all advertised relay servers and returns an error if any of them fails to start.
Expand Down Expand Up @@ -145,3 +156,17 @@ func (rp *relayerProxy) Stop(ctx context.Context) error {
func (rp *relayerProxy) ServedRelays() observable.Observable[*types.Relay] {
return rp.servedRelays
}

// validateConfig validates the relayer proxy's configuration options and returns an error if it is invalid.
// TODO_TEST: Add tests for validating these configurations.
func (rp *relayerProxy) validateConfig() error {
if rp.signingKeyName == "" {
return ErrRelayerProxyUndefinedSigningKeyName
}

if rp.proxiedServicesEndpoints == nil {
return ErrRelayerProxyUndefinedProxiedServicesEndpoints
}

return nil
}
2 changes: 1 addition & 1 deletion pkg/relayer/proxy/relay_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (rp *relayerProxy) SignRelayResponse(relayResponse *types.RelayResponse) er
}

hash := crypto.Sha256(responseBz)
relayResponse.Meta.SupplierSignature, _, err = rp.keyring.Sign(rp.keyName, hash)
relayResponse.Meta.SupplierSignature, _, err = rp.keyring.Sign(rp.signingKeyName, hash)

return err
}
6 changes: 3 additions & 3 deletions pkg/relayer/proxy/relay_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (rp *relayerProxy) VerifyRelayRequest(
}

if !account.GetPubKey().VerifySignature(hash, relayRequest.Meta.Signature) {
return ErrInvalidRelayRequestSignature
return ErrRelayerProxyInvalidRelayRequestSignature
}

// Query for the current session to check if relayRequest sessionId matches the current session.
Expand All @@ -62,7 +62,7 @@ func (rp *relayerProxy) VerifyRelayRequest(
// matches the relayRequest sessionId.
// TODO_INVESTIGATE: Revisit the assumptions above at some point in the future, but good enough for now.
if session.SessionId != relayRequest.Meta.SessionHeader.SessionId {
return ErrInvalidSession
return ErrRelayerProxyInvalidSession
}

// Check if the relayRequest is allowed to be served by the relayer proxy.
Expand All @@ -72,5 +72,5 @@ func (rp *relayerProxy) VerifyRelayRequest(
}
}

return ErrInvalidSupplier
return ErrRelayerProxyInvalidSupplier
}
4 changes: 2 additions & 2 deletions pkg/relayer/proxy/server_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
// is responsible for listening for incoming relay requests and relaying them to the supported proxied service.
func (rp *relayerProxy) BuildProvidedServices(ctx context.Context) error {
// Get the supplier address from the keyring
supplierAddress, err := rp.keyring.Key(rp.keyName)
supplierAddress, err := rp.keyring.Key(rp.signingKeyName)
if err != nil {
return err
}
Expand Down Expand Up @@ -48,7 +48,7 @@ func (rp *relayerProxy) BuildProvidedServices(ctx context.Context) error {
rp,
)
default:
return ErrUnsupportedRPCType
return ErrRelayerProxyUnsupportedRPCType
}

serviceEndpoints = append(serviceEndpoints, server)
Expand Down

0 comments on commit 22aa52a

Please sign in to comment.