Skip to content
This repository has been archived by the owner on Nov 13, 2024. It is now read-only.

[CHORE] Add first part of tests for pocket basic client #15

Merged
merged 6 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 4 additions & 126 deletions pkg/pokt/pokt_v0/basic_client.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package pokt_v0

import (
"encoding/hex"
"github.com/pquerna/ffjson/ffjson"
"github.com/valyala/fasthttp"
"math/rand"
"os-gateway/pkg/common"
"os-gateway/pkg/pokt/pokt_v0/models"
"slices"
"time"
)

Expand Down Expand Up @@ -77,7 +75,7 @@ func (r BasicClient) SendRelay(req *models.SendRelayRequest) (*models.SendRelayR
}

// Get the preferred selected node, or chose a random one.
node, err := r.getNodeFromRequest(session, req.SelectedNodePubKey)
node, err := getNodeFromRequest(session, req.SelectedNodePubKey)

if err != nil {
return nil, err
Expand All @@ -87,14 +85,15 @@ func (r BasicClient) SendRelay(req *models.SendRelayRequest) (*models.SendRelayR

relayMetadata := &models.RelayMeta{BlockHeight: currentSessionHeight}

relayProof := r.generateRelayProof(req.Chain, currentSessionHeight, node.PublicKey, relayMetadata, req.Payload, req.Signer)
entropy := uint64(rand.Int63())
relayProof := generateRelayProof(entropy, req.Chain, currentSessionHeight, node.PublicKey, relayMetadata, req.Payload, req.Signer)

// Relay created, generating a request to the servicer
var sessionResponse models.SendRelayResponse
err = r.makeRequest(endpointSendRelay, "POST", &models.Relay{
Payload: req.Payload,
Metadata: relayMetadata,
RelayProof: &relayProof,
RelayProof: relayProof,
}, &sessionResponse, &node.ServiceUrl)

if err != nil {
Expand Down Expand Up @@ -162,124 +161,3 @@ func (r BasicClient) makeRequest(endpoint string, method string, requestData any
}
return ffjson.Unmarshal(response.Body(), responseModel)
}

// generateRelayProof generates a relay proof.
// Parameters:
// - chainId: Blockchain ID.
// - sessionHeight: Session block height.
// - servicerPubKey: Servicer public key.
// - requestMetadata: Request metadata.
// - account: Ed25519 account used for signing.
//
// Returns:
// - models.RelayProof: Generated relay proof.
func (r BasicClient) generateRelayProof(chainId string, sessionHeight uint, servicerPubKey string, relayMetadata *models.RelayMeta, reqPayload *models.Payload, account *models.Ed25519Account) models.RelayProof {
entropy := uint64(rand.Int63())
aat := account.GetAAT()

requestMetadata := models.RequestHashPayload{
Metadata: relayMetadata,
Payload: reqPayload,
}

requestHash := requestMetadata.Hash()

unsignedAAT := &models.AAT{
Version: aat.Version,
AppPubKey: aat.AppPubKey,
ClientPubKey: aat.ClientPubKey,
Signature: "",
}

proofObj := &models.RelayProofHashPayload{
RequestHash: requestHash,
Entropy: entropy,
SessionBlockHeight: sessionHeight,
ServicerPubKey: servicerPubKey,
Blockchain: chainId,
Signature: "",
UnsignedAAT: unsignedAAT.Hash(),
}

hashedPayload := common.Sha3_256Hash(proofObj)
hashSignature := hex.EncodeToString(account.Sign(hashedPayload))
return models.RelayProof{
RequestHash: requestHash,
Entropy: entropy,
SessionBlockHeight: sessionHeight,
ServicerPubKey: servicerPubKey,
Blockchain: chainId,
AAT: aat,
Signature: hashSignature,
}
}

// getSessionFromRequest obtains a session from a relay request.
// Parameters:
// - req: SendRelayRequest instance containing the relay request parameters.
//
// Returns:
// - (*GetSessionResponse): Session response.
// - (error): Error, if any.
func GetSessionFromRequest(pocketService PocketService, req *models.SendRelayRequest) (*models.Session, error) {
if req.Session != nil {
return req.Session, nil
}
sessionResp, err := pocketService.GetSession(&models.GetSessionRequest{
AppPubKey: req.Signer.PublicKey,
Chain: req.Chain,
})
if err != nil {
return nil, err
}
return sessionResp.Session, nil
}

// getNodeFromRequest obtains a node from a relay request.
// Parameters:
// - req: SendRelayRequest instance containing the relay request parameters.
//
// Returns:
// - (*models.Node): Node instance.
// - (error): Error, if any.
func (r BasicClient) getNodeFromRequest(session *models.Session, selectedNodePubKey string) (*models.Node, error) {
if selectedNodePubKey == "" {
return getRandomNodeOrError(session.Nodes, models.ErrSessionHasZeroNodes)
}
return findNodeOrError(session.Nodes, selectedNodePubKey, models.ErrNodeNotFound)
}

// getRandomNodeOrError gets a random node or returns an error if the node list is empty.
// Parameters:
// - nodes: List of nodes.
// - err: Error to be returned if the node list is empty.
//
// Returns:
// - (*models.Node): Random node.
// - (error): Error, if any.
func getRandomNodeOrError(nodes []*models.Node, err error) (*models.Node, error) {
node := common.GetRandomElement(nodes)
if node == nil {
return nil, err
}
return node, nil
}

// findNodeOrError finds a node by public key or returns an error if the node is not found.
// Parameters:
// - nodes: List of nodes.
// - pubKey: Public key of the node to find.
// - err: Error to be returned if the node is not found.
//
// Returns:
// - (*models.Node): Found node.
// - (error): Error, if any.
func findNodeOrError(nodes []*models.Node, pubKey string, err error) (*models.Node, error) {
idx := slices.IndexFunc(nodes, func(node *models.Node) bool {
return node.PublicKey == pubKey
})
if idx == -1 {
return nil, err
}
return nodes[idx], nil
}
58 changes: 58 additions & 0 deletions pkg/pokt/pokt_v0/generate_proof_bytes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package pokt_v0

import (
"encoding/hex"
"os-gateway/pkg/common"
"os-gateway/pkg/pokt/pokt_v0/models"
)

// generateRelayProof generates a relay proof.
// Parameters:
// - entropy - random generated number to signify unique proof
// - chainId: Blockchain ID.
// - sessionHeight: Session block height.
// - servicerPubKey: Servicer public key.
// - requestMetadata: Request metadata.
// - account: Ed25519 account used for signing.
//
// Returns:
// - models.RelayProof: Generated relay proof.
func generateRelayProof(entropy uint64, chainId string, sessionHeight uint, servicerPubKey string, relayMetadata *models.RelayMeta, reqPayload *models.Payload, account *models.Ed25519Account) *models.RelayProof {
aat := account.GetAAT()

requestMetadata := models.RequestHashPayload{
Metadata: relayMetadata,
Payload: reqPayload,
}

requestHash := requestMetadata.Hash()

unsignedAAT := &models.AAT{
Version: aat.Version,
AppPubKey: aat.AppPubKey,
ClientPubKey: aat.ClientPubKey,
Signature: "",
}

proofObj := &models.RelayProofHashPayload{
RequestHash: requestHash,
Entropy: entropy,
SessionBlockHeight: sessionHeight,
ServicerPubKey: servicerPubKey,
Blockchain: chainId,
Signature: "",
UnsignedAAT: unsignedAAT.Hash(),
}

hashedPayload := common.Sha3_256Hash(proofObj)
hashSignature := hex.EncodeToString(account.Sign(hashedPayload))
return &models.RelayProof{
RequestHash: requestHash,
Entropy: entropy,
SessionBlockHeight: sessionHeight,
ServicerPubKey: servicerPubKey,
Blockchain: chainId,
AAT: aat,
Signature: hashSignature,
}
}
40 changes: 40 additions & 0 deletions pkg/pokt/pokt_v0/generate_proof_bytes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package pokt_v0

import (
"github.com/stretchr/testify/assert"
"os-gateway/pkg/pokt/pokt_v0/models"
"testing"
)

func Test_generateRelayProof(t *testing.T) {

account, err := models.NewAccount("3fe64039816c44e8872e4ef981725b968422e3d49e95a1eb800707591df30fe374039dbe881dd2744e2e0c469cc2241e1e45f14af6975dd89079d22938377849")
assert.Equal(t, err, nil)

chainId := "0001"
sessionHeight := uint(1)
servicerPubKey := "0x"
relayMetadata := &models.RelayMeta{BlockHeight: sessionHeight}
requestPayload := &models.Payload{
Data: "randomJsonPayload",
Method: "post",
Path: "",
Headers: nil,
}
entropy := uint64(1)
assert.Equal(t, generateRelayProof(entropy, chainId, sessionHeight, servicerPubKey, relayMetadata, requestPayload, account), &models.RelayProof{
Entropy: 1,
SessionBlockHeight: 1,
ServicerPubKey: "0x",
Blockchain: "0001",
AAT: &models.AAT{
Version: "0.0.1",
AppPubKey: "74039dbe881dd2744e2e0c469cc2241e1e45f14af6975dd89079d22938377849",
ClientPubKey: "74039dbe881dd2744e2e0c469cc2241e1e45f14af6975dd89079d22938377849",
Signature: "f233ca857b4ada2ca4996e0da8c1761cfbc855edf282fc5a753d4631785946d6c2b08c781c84abbca2dc929de50008729079124e5c5c16921a81139279020a05",
},
Signature: "befcc42130fb9e46fb9874acfb5bd8a9f783db60f86d1b1eb61cdba23fdb7e9e17544cb99afb480c9e1308532e07cdf6f4e2da27790f47dae30133725191b309",
RequestHash: "c5b64f9a7901ed8c3341f7440913a5ddd7b694dc7b4daeb234a47a9c42b653bb",
})

}
56 changes: 56 additions & 0 deletions pkg/pokt/pokt_v0/get_node_from_request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package pokt_v0

import (
"os-gateway/pkg/common"
"os-gateway/pkg/pokt/pokt_v0/models"
"slices"
)

// getNodeFromRequest obtains a node from a relay request.
// Parameters:
// - req: SendRelayRequest instance containing the relay request parameters.
//
// Returns:
// - (*models.Node): Node instance.
// - (error): Error, if any.
func getNodeFromRequest(session *models.Session, selectedNodePubKey string) (*models.Node, error) {
if selectedNodePubKey == "" {
return getRandomNodeOrError(session.Nodes, models.ErrSessionHasZeroNodes)
}
return findNodeOrError(session.Nodes, selectedNodePubKey, models.ErrNodeNotFound)
}

// getRandomNodeOrError gets a random node or returns an error if the node list is empty.
// Parameters:
// - nodes: List of nodes.
// - err: Error to be returned if the node list is empty.
//
// Returns:
// - (*models.Node): Random node.
// - (error): Error, if any.
func getRandomNodeOrError(nodes []*models.Node, err error) (*models.Node, error) {
node := common.GetRandomElement(nodes)
if node == nil {
return nil, err
}
return node, nil
}

// findNodeOrError finds a node by public key or returns an error if the node is not found.
// Parameters:
// - nodes: List of nodes.
// - pubKey: Public key of the node to find.
// - err: Error to be returned if the node is not found.
//
// Returns:
// - (*models.Node): Found node.
// - (error): Error, if any.
func findNodeOrError(nodes []*models.Node, pubKey string, err error) (*models.Node, error) {
idx := slices.IndexFunc(nodes, func(node *models.Node) bool {
return node.PublicKey == pubKey
})
if idx == -1 {
return nil, err
}
return nodes[idx], nil
}
Loading