-
Notifications
You must be signed in to change notification settings - Fork 0
/
relay.go
94 lines (81 loc) · 2.9 KB
/
relay.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package sdk
import (
"context"
"errors"
"sync"
cosmossdk "github.com/cosmos/cosmos-sdk/types"
"github.com/pokt-network/poktroll/app"
servicetypes "github.com/pokt-network/poktroll/x/service/types"
)
var once sync.Once
func init() {
once.Do(func() {
initCosmosSDKConfig()
})
}
// initCosmosSDKConfig sets the prefix for application address to "pokt"
// This is necessary as otherwise the relay response validation would fail
// while validating the session header which should contain an application
// address in the expected format, i.e. Bech32 format with a "pokt" prefix.
func initCosmosSDKConfig() {
// Set prefixes
accountPubKeyPrefix := app.AccountAddressPrefix + "pub"
validatorAddressPrefix := app.AccountAddressPrefix + "valoper"
validatorPubKeyPrefix := app.AccountAddressPrefix + "valoperpub"
consNodeAddressPrefix := app.AccountAddressPrefix + "valcons"
consNodePubKeyPrefix := app.AccountAddressPrefix + "valconspub"
// Set and seal config
config := cosmossdk.GetConfig()
config.SetBech32PrefixForAccount(app.AccountAddressPrefix, accountPubKeyPrefix)
config.SetBech32PrefixForValidator(validatorAddressPrefix, validatorPubKeyPrefix)
config.SetBech32PrefixForConsensusNode(consNodeAddressPrefix, consNodePubKeyPrefix)
config.Seal()
}
// The returned RelayRequest struct can be marshalled and delivered to a service
// endpoint through an HTTP POST request.
// BuildRelayRequest creates a RelayRequest struct from the given endpoint and request bytes,
// where requestBz is the serialized request (body and header) to be relayed.
func BuildRelayRequest(
endpoint Endpoint,
requestBz []byte,
) (*servicetypes.RelayRequest, error) {
if endpoint == nil {
return nil, errors.New("BuildRelayRequest: endpointSelector not specified")
}
header := endpoint.Header()
return &servicetypes.RelayRequest{
Meta: servicetypes.RelayRequestMetadata{
SessionHeader: &header,
SupplierOperatorAddress: string(endpoint.Supplier()),
},
Payload: requestBz,
}, nil
}
// ValidateRelayResponse validates the RelayResponse and verifies the supplier's signature.
func ValidateRelayResponse(
ctx context.Context,
supplierAddress SupplierAddress,
relayResponseBz []byte,
publicKeyFetcher PublicKeyFetcher,
) (*servicetypes.RelayResponse, error) {
relayResponse := &servicetypes.RelayResponse{}
if err := relayResponse.Unmarshal(relayResponseBz); err != nil {
return nil, err
}
if err := relayResponse.ValidateBasic(); err != nil {
// Even if the relay response is invalid, we still return it to the caller
// as it might contain the reason why it's failing basic validation.
return relayResponse, err
}
supplierPubKey, err := publicKeyFetcher.GetPubKeyFromAddress(
ctx,
string(supplierAddress),
)
if err != nil {
return nil, err
}
if signatureErr := relayResponse.VerifySupplierOperatorSignature(supplierPubKey); signatureErr != nil {
return nil, signatureErr
}
return relayResponse, nil
}