Skip to content

Commit

Permalink
[PSL-231] nft reg, nft cascade & nft sense fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
matee81 committed Mar 21, 2022
1 parent befdc37 commit 3925627
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 65 deletions.
2 changes: 1 addition & 1 deletion dupedetection/ddclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

const (
defaultConnectTimeout = 5 * time.Second
defaultConnectTimeout = 30 * time.Second
)

type client struct{}
Expand Down
8 changes: 4 additions & 4 deletions pastel/action_ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ func DecodeActionTicket(b []byte) (*ActionTicket, error) {

// ActionTicketSignatures represents signatures from parties
type ActionTicketSignatures struct {
Caller map[string]string `json:"caller,omitempty"`
Mn1 map[string]string `json:"mn1,omitempty"`
Mn2 map[string]string `json:"mn2,omitempty"`
Mn3 map[string]string `json:"mn3,omitempty"`
Principal map[string]string `json:"principal,omitempty"`
Mn1 map[string]string `json:"mn1,omitempty"`
Mn2 map[string]string `json:"mn2,omitempty"`
Mn3 map[string]string `json:"mn3,omitempty"`
}

// EncodeActionSignatures encodes ActionTicketSignatures into byte array
Expand Down
4 changes: 0 additions & 4 deletions pastel/dupe_detection.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ type DDAndFingerprints struct {

Maxes *Maxes `json:"maxes"`
Percentile *Percentile `json:"percentile"`

// DD-Server does not directly return these comporessed fingerprints
// We generate and assign to this field to avoid repeated operations
ZstdCompressedFingerprint []byte `json:"zstd_compressed_fingerprint,omitempty"`
}

// RarenessScores defined rareness scores
Expand Down
7 changes: 6 additions & 1 deletion raptorq/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import "fmt"

const (
errValidationStr = "raptorq validation failed - missing val"
defaultHost = "localhost"
defaultPort = 50051
)

// Config contains settings of the p2p service
Expand All @@ -17,7 +19,10 @@ type Config struct {

// NewConfig returns a new Config instance.
func NewConfig() *Config {
return &Config{}
return &Config{
Host: defaultHost,
Port: defaultPort,
}
}

// Validate raptorq configs
Expand Down
32 changes: 22 additions & 10 deletions supernode/services/cascaderegister/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/hex"
"time"

"github.com/google/uuid"
"github.com/pastelnetwork/gonode/common/blocktracker"
"github.com/pastelnetwork/gonode/common/errors"
"github.com/pastelnetwork/gonode/common/log"
Expand Down Expand Up @@ -77,6 +78,14 @@ func (task *CascadeRegistrationTask) UploadAsset(_ context.Context, file *files.
}
task.assetSizeBytes = len(fileBytes)

fileDataInMb := int64(task.assetSizeBytes) / (1024 * 1024)
fee, err := task.PastelHandler.GetEstimatedCascadeFee(ctx, fileDataInMb)
if err != nil {
err = errors.Errorf("getting estimated fee %w", err)
return nil
}
task.registrationFee = int64(fee)

return nil
})

Expand All @@ -97,14 +106,16 @@ func (task *CascadeRegistrationTask) ValidateAndRegister(_ context.Context,

<-task.NewAction(func(ctx context.Context) error {
if err = task.validateSignedTicketFromWN(ctx, ticket, creatorSignature, rqidFile); err != nil {
log.WithContext(ctx).WithError(err).Errorf("validateSignedTicketFromWN")
err = errors.Errorf("validateSignedTicketFromWN: %w", err)
return nil
}

// sign the ticket if not primary node
log.WithContext(ctx).Debugf("isPrimary: %t", task.NetworkHandler.ConnectedTo == nil)
if err = task.signAndSendCascadeTicket(ctx, task.NetworkHandler.ConnectedTo == nil); err != nil {
log.WithContext(ctx).WithError(err).Errorf("signed and send NFT ticket")
err = errors.Errorf("signed and send NFT ticket")
log.WithContext(ctx).WithError(err).Errorf("signed and send Cascade ticket")
err = errors.Errorf("signed and send NFT ticket: %w", err)
return nil
}

Expand Down Expand Up @@ -165,7 +176,7 @@ func (task *CascadeRegistrationTask) validateSignedTicketFromWN(ctx context.Cont
return errors.Errorf("decode action ticket: %w", err)
}

// Verify APISenseTicket
// Verify APICascadeTicket
_, err = task.Ticket.APICascadeTicket()
if err != nil {
log.WithContext(ctx).WithError(err).Errorf("invalid api cascade ticket")
Expand All @@ -174,8 +185,8 @@ func (task *CascadeRegistrationTask) validateSignedTicketFromWN(ctx context.Cont

verified, err := task.PastelClient.Verify(ctx, ticket, string(creatorSignature), task.Ticket.Caller, pastel.SignAlgorithmED448)
if err != nil {
log.WithContext(ctx).WithError(err).Errorf("verify ticket signature")
return errors.Errorf("verify ticket signature %w", err)
log.WithContext(ctx).WithError(err).Errorf("verify cascade ticket signature")
return errors.Errorf("verify cascade ticket signature %w", err)
}

if !verified {
Expand All @@ -201,8 +212,7 @@ func (task *CascadeRegistrationTask) validateSignedTicketFromWN(ctx context.Cont

// validates RQIDs file
func (task *CascadeRegistrationTask) validateRqIDs(ctx context.Context, dd []byte) error {

pastelIDs := task.NetworkHandler.MeshedNodesPastelID()
pastelIDs := []string{task.Ticket.Caller}

apiCascadeTicket, err := task.Ticket.APICascadeTicket()
if err != nil {
Expand All @@ -215,7 +225,7 @@ func (task *CascadeRegistrationTask) validateRqIDs(ctx context.Context, dd []byt
pastelIDs,
task.PastelClient)
if err != nil {
return errors.Errorf("validate dd_and_fingerprints: %w", err)
return errors.Errorf("validate rq_ids file: %w", err)
}

return nil
Expand Down Expand Up @@ -275,7 +285,7 @@ func (task *CascadeRegistrationTask) registerAction(ctx context.Context) (string
APITicketData: task.Ticket.APITicketData,
},
Signatures: &pastel.ActionTicketSignatures{
Caller: map[string]string{
Principal: map[string]string{
task.Ticket.Caller: string(task.creatorSignature),
},
Mn1: map[string]string{
Expand All @@ -291,6 +301,8 @@ func (task *CascadeRegistrationTask) registerAction(ctx context.Context) (string
Mn1PastelID: task.config.PastelID,
Passphrase: task.config.PassPhrase,
Fee: task.registrationFee,
Key1: "key1-" + uuid.New().String(),
Key2: "key2-" + uuid.New().String(),
}

nftRegTxid, err := task.PastelClient.RegisterActionTicket(ctx, req)
Expand All @@ -305,7 +317,7 @@ func (task *CascadeRegistrationTask) ValidateActionActAndStore(ctx context.Conte
var err error

// Wait for action ticket to be activated by walletnode
confirmations := task.waitActionActivation(ctx, actionRegTxID, 2, 30*time.Second)
confirmations := task.waitActionActivation(ctx, actionRegTxID, 3, 30*time.Second)
err = <-confirmations
if err != nil {
return errors.Errorf("wait for confirmation of reg-art ticket %w", err)
Expand Down
27 changes: 13 additions & 14 deletions supernode/services/common/dupe_detection_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func (h *DupeDetectionHandler) ProbeImage(_ context.Context, file *files.File, b
}

var err error
var retCompressed []byte

<-h.NewAction(func(ctx context.Context) error {
defer errors.Recover(func(recErr error) {
Expand All @@ -73,7 +74,7 @@ func (h *DupeDetectionHandler) ProbeImage(_ context.Context, file *files.File, b
h.UpdateStatus(StatusImageProbed)

//SuperNode makes ImageRarenessScore gRPC call to dd-service
h.myDDAndFingerprints, err = h.GenFingerprintsData(ctx, file, blockHash, creatorPastelID)
compressed, err := h.GenFingerprintsData(ctx, file, blockHash, creatorPastelID)
if err != nil {
log.WithContext(ctx).WithError(err).Errorf("generate fingerprints data")
err = errors.Errorf("generate fingerprints data: %w", err)
Expand All @@ -83,7 +84,7 @@ func (h *DupeDetectionHandler) ProbeImage(_ context.Context, file *files.File, b
// Begin send signed DDAndFingerprints to other SNs
// Send base64’ed (and compressed) dd_and_fingerprints and its signature to the 2 OTHER SNs
// step 4.A.5
if h.NetworkHandler.meshedNodes == nil || len(h.NetworkHandler.meshedNodes) != 3 {
if len(h.NetworkHandler.meshedNodes) != 3 {
log.WithContext(ctx).Error("Not enough meshed SuperNodes")
err = errors.New("not enough meshed SuperNodes")
return nil
Expand Down Expand Up @@ -114,7 +115,7 @@ func (h *DupeDetectionHandler) ProbeImage(_ context.Context, file *files.File, b
}

//supernode/services/nftregister/task.go
if err = tasker.SendDDFBack(ctx, node.SuperNodePeerAPIInterface, &nodeInfo, h.ServerPastelID, h.myDDAndFingerprints.ZstdCompressedFingerprint); err != nil {
if err = tasker.SendDDFBack(ctx, node.SuperNodePeerAPIInterface, &nodeInfo, h.ServerPastelID, compressed); err != nil {
log.WithContext(ctx).WithFields(log.Fields{
"nodeID": nodeInfo.NodeID,
"sessID": nodeInfo.SessID,
Expand Down Expand Up @@ -174,17 +175,16 @@ func (h *DupeDetectionHandler) ProbeImage(_ context.Context, file *files.File, b
}

// Creates compress(Base64(dd_and_fingerprints).Base64(signature))
var compressed []byte
compressed, err = h.compressAndSignDDAndFingerprints(ctx, h.calculatedDDAndFingerprints)
retCompressed, err = h.compressAndSignDDAndFingerprints(ctx, h.calculatedDDAndFingerprints)
if err != nil {
log.WithContext(ctx).WithError(err).Errorf("compress combine DDAndFingerPrintAndScore failed")

err = errors.Errorf("compress combine DDAndFingerPrintAndScore failed: %w", err)
return nil
}
h.calculatedDDAndFingerprints.ZstdCompressedFingerprint = compressed

return nil
case <-time.After(30 * time.Second):
case <-time.After(60 * time.Second):
log.WithContext(ctx).Error("waiting for DDAndFingerprints from peers timeout")
err = errors.New("waiting for DDAndFingerprints timeout")
return nil
Expand All @@ -194,24 +194,24 @@ func (h *DupeDetectionHandler) ProbeImage(_ context.Context, file *files.File, b
if err != nil {
return nil, err
}

return h.calculatedDDAndFingerprints.ZstdCompressedFingerprint, nil
log.Println("here ret compressed: ", retCompressed)
return retCompressed, nil
}

// GenFingerprintsData calls DD server to get DD and FP data
// https://pastel.wiki/en/Architecture/Workflows/NewArtRegistration
// Call dd-service to generate near duplicate fingerprints and dupe-detection info from re-sampled image (img1-r)
// Sign dd_and_fingerprints with SN own PastelID (private key) using cNode API
// Step 4.A.3 - 4.A.4
func (h *DupeDetectionHandler) GenFingerprintsData(ctx context.Context, file *files.File, blockHash string, creatorPastelID string) (*pastel.DDAndFingerprints, error) {
func (h *DupeDetectionHandler) GenFingerprintsData(ctx context.Context, file *files.File, blockHash string, creatorPastelID string) ([]byte, error) {
img, err := file.Bytes()
if err != nil {
return nil, errors.Errorf("get content of image %s: %w", file.Name(), err)
}

// Get DDAndFingerprints
// SuperNode makes ImageRarenessScore gRPC call to dd-service
ddAndFingerprints, err := h.DdClient.ImageRarenessScore(
h.myDDAndFingerprints, err = h.DdClient.ImageRarenessScore(
ctx,
img,
file.Format().String(),
Expand All @@ -225,13 +225,12 @@ func (h *DupeDetectionHandler) GenFingerprintsData(ctx context.Context, file *fi

// Creates compress(Base64(dd_and_fingerprints).Base64(signature))
//Sign dd_and_fingerprints with SN own PastelID (private key) using cNode API
compressed, err := h.compressAndSignDDAndFingerprints(ctx, ddAndFingerprints)
compressed, err := h.compressAndSignDDAndFingerprints(ctx, h.myDDAndFingerprints)
if err != nil {
return nil, errors.Errorf("call compressSignedDDAndFingerprints failed: %w", err)
}

ddAndFingerprints.ZstdCompressedFingerprint = compressed
return ddAndFingerprints, nil
return compressed, nil
}

// https://pastel.wiki/en/Architecture/Workflows/NewArtRegistration
Expand Down
2 changes: 1 addition & 1 deletion supernode/services/common/network_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func (h *NetworkHandler) CheckNodeInMeshedNodes(nodeID string) error {

// PastelNodeByExtKey returns information about SN by its PastelID
func (h *NetworkHandler) PastelNodeByExtKey(ctx context.Context, nodeID string) (*SuperNodePeer, error) {
masterNodes, err := h.PastelHandler.PastelClient.MasterNodesTop(ctx)
masterNodes, err := h.PastelHandler.PastelClient.MasterNodesExtra(ctx)
log.WithContext(ctx).Debugf("master node %v", masterNodes)

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion supernode/services/common/node_peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

const (
defaultConnectToNodeTimeout = time.Second * 15
defaultConnectToNodeTimeout = time.Second * 20
)

// SuperNodePeer represents a single supernode
Expand Down
2 changes: 1 addition & 1 deletion supernode/services/common/reg_task_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (h *RegTaskHelper) ValidateIDFiles(ctx context.Context,
}

if verifications != numSignRequired {
return nil, nil, errors.Errorf("file verification failed: need %d verifications, got %d", 3, verifications)
return nil, nil, errors.Errorf("file verification failed: need %d verifications, got %d", numSignRequired, verifications)
}

gotIDs, idFiles, err := pastel.GetIDFiles(decData, ic, max)
Expand Down
6 changes: 3 additions & 3 deletions supernode/services/nftregister/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ type tasker struct {
}

func (t *tasker) SendDDFBack(ctx context.Context, node node.SuperNodePeerAPIInterface, nodeInfo *types.MeshedSuperNode, pastelID string, data []byte) error {
senseNode, ok := node.(*NftRegistrationNode)
regNode, ok := node.(*NftRegistrationNode)
if !ok {
return errors.Errorf("node is not SenseRegistrationNode")
return errors.Errorf("node is not NFTRegistrationNode")
}
return senseNode.SendSignedDDAndFingerprints(ctx, nodeInfo.SessID, pastelID, data)
return regNode.SendSignedDDAndFingerprints(ctx, nodeInfo.SessID, pastelID, data)
}

// Run starts the task
Expand Down
25 changes: 22 additions & 3 deletions supernode/services/senseregister/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"time"

"github.com/google/uuid"
"github.com/pastelnetwork/gonode/common/blocktracker"
"github.com/pastelnetwork/gonode/common/errors"
"github.com/pastelnetwork/gonode/common/log"
Expand Down Expand Up @@ -68,6 +69,22 @@ func (task *SenseRegistrationTask) ProbeImage(ctx context.Context, file *files.F
return nil, errors.Errorf("invalid senseRegMetadata")
}
task.Asset = file

var fileBytes []byte
fileBytes, err := file.Bytes()
if err != nil {
log.WithContext(ctx).WithError(err).Errorf("read image file")
return nil, errors.Errorf("read image file: %w", err)
}

fileDataInMb := int64(len(fileBytes)) / (1024 * 1024)
fee, err := task.PastelHandler.GetEstimatedSenseFee(ctx, fileDataInMb)
if err != nil {
return nil, errors.Errorf("getting estimated fee %w", err)
}

task.registrationFee = int64(fee)

return task.DupeDetectionHandler.ProbeImage(ctx, file,
task.ActionTicketRegMetadata.BlockHash, task.ActionTicketRegMetadata.CreatorPastelID, &tasker{})
}
Expand Down Expand Up @@ -203,10 +220,10 @@ func (task *SenseRegistrationTask) ValidateActionActAndStore(ctx context.Context
var err error

// Wait for action ticket to be activated by walletnode
confirmations := task.waitActionActivation(ctx, actionRegTxID, 2, 30*time.Second)
confirmations := task.waitActionActivation(ctx, actionRegTxID, 3, 30*time.Second)
err = <-confirmations
if err != nil {
return errors.Errorf("wait for confirmation of reg-art ticket %w", err)
return errors.Errorf("wait for confirmation of sense ticket %w", err)
}

// Store dd_and_fingerprints into Kademlia
Expand Down Expand Up @@ -308,7 +325,7 @@ func (task *SenseRegistrationTask) registerAction(ctx context.Context) (string,
APITicketData: task.Ticket.APITicketData,
},
Signatures: &pastel.ActionTicketSignatures{
Caller: map[string]string{
Principal: map[string]string{
task.Ticket.Caller: string(task.creatorSignature),
},
Mn1: map[string]string{
Expand All @@ -324,6 +341,8 @@ func (task *SenseRegistrationTask) registerAction(ctx context.Context) (string,
Mn1PastelID: task.config.PastelID,
Passphrase: task.config.PassPhrase,
Fee: task.registrationFee,
Key1: "key1-" + uuid.New().String(),
Key2: "key2-" + uuid.New().String(),
}

nftRegTxid, err := task.PastelClient.RegisterActionTicket(ctx, req)
Expand Down
Loading

0 comments on commit 3925627

Please sign in to comment.