Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit 0e1f030

Browse files
authored
Merge pull request #1773 from OpenBazaar/1736-divisibility-support
Express repo.Listing.CryptoDivisibility as exponential value
2 parents 8cb1bd1 + 99dd7a5 commit 0e1f030

File tree

2 files changed

+143
-97
lines changed

2 files changed

+143
-97
lines changed

repo/listing.go

Lines changed: 117 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,6 @@ type ListingMetadata struct {
375375
// UnmarshalJSONSignedListing - unmarshal signed listing
376376
func UnmarshalJSONSignedListing(data []byte) (SignedListing, error) {
377377

378-
retSL := SignedListing{}
379378
var err error
380379

381380
var objmap map[string]*json.RawMessage
@@ -399,126 +398,95 @@ func UnmarshalJSONSignedListing(data []byte) (SignedListing, error) {
399398

400399
vendorID, err := ExtractIDFromSignedListing(data)
401400
if err != nil {
402-
return retSL, err
401+
return SignedListing{}, err
403402
}
404403

405404
peerInfo, err := NewPeerInfoFromProtobuf(vendorID)
406405
if err != nil {
407-
return retSL, err
406+
return SignedListing{}, err
408407
}
409408

410409
version, err := ExtractVersionFromSignedListing(data)
411410
if err != nil {
412-
return retSL, err
411+
return SignedListing{}, err
413412
}
414413

415414
if version == 5 {
416415
sl := new(pb.SignedListing)
417416
err = jsonpb.UnmarshalString(string(data), sl)
418417
if err != nil {
419-
return retSL, err
418+
return SignedListing{}, err
420419
}
421420
b0, err := m1.MarshalToString(sl.Listing)
422421
if err != nil {
423-
return retSL, err
424-
}
425-
retSL.Hash = sl.Hash
426-
retSL.ProtoListing = sl.Listing
427-
retSL.RListing = Listing{
428-
Slug: sl.Listing.Slug,
429-
Metadata: ListingMetadata{
430-
Version: 5,
422+
return SignedListing{}, err
423+
}
424+
return SignedListing{
425+
Hash: sl.Hash,
426+
ProtoListing: sl.Listing,
427+
RListing: Listing{
428+
Slug: sl.Listing.Slug,
429+
Metadata: ListingMetadata{
430+
Version: 5,
431+
},
432+
ListingVersion: 5,
433+
ListingBytes: []byte(b0),
434+
ProtoListing: sl.Listing,
435+
Vendor: peerInfo,
431436
},
432-
ListingVersion: 5,
433-
ListingBytes: []byte(b0),
434-
OrigListingBytes: *lbytes,
435-
ProtoListing: sl.Listing,
436-
Vendor: peerInfo,
437-
}
438-
retSL.Signature = sl.Signature
439-
retSL.ProtoSignedListing = sl
440-
return retSL, nil
437+
Signature: sl.Signature,
438+
ProtoSignedListing: sl,
439+
}, nil
441440
}
442441

443442
listing0 := Listing{
444-
ListingBytes: *lbytes,
445-
OrigListingBytes: *lbytes,
443+
ListingBytes: *lbytes,
446444
Metadata: ListingMetadata{
447445
Version: version,
448446
},
449447
ListingVersion: uint32(version),
450448
Vendor: peerInfo,
451449
}
452450

453-
type slisting struct {
451+
var s1 struct {
454452
Hash string `json:"hash"`
455453
Signature []byte `json:"signature"`
456454
Listing json.RawMessage `json:"listing"`
457455
}
458-
var s1 slisting
459456
err = json.Unmarshal(data, &s1)
460457
if err != nil {
461-
return retSL, err
462-
}
463-
464-
proto0, err := listing0.GetProtoListing()
465-
if err != nil {
466-
return retSL, err
467-
}
468-
469-
proto0.VendorID = vendorID
470-
471-
listing0.ProtoListing = proto0
472-
473-
retSL.Signature = s1.Signature
474-
retSL.Hash = s1.Hash
475-
retSL.RListing = listing0
476-
477-
retSL.ProtoListing = proto0
478-
retSL.ProtoSignedListing = &pb.SignedListing{
479-
Listing: proto0,
480-
Hash: s1.Hash,
481-
Signature: s1.Signature,
458+
return SignedListing{}, err
482459
}
483460

484-
out0, err := m1.MarshalToString(proto0)
485-
if err != nil {
486-
//return ret, err
487-
log.Info(err)
461+
// GetProtoListing generates listing0.ProtoListing (mutation is evil)
462+
if _, err = listing0.GetProtoListing(); err != nil {
463+
return SignedListing{}, err
488464
}
489-
490-
log.Info(len(out0))
465+
listing0.ProtoListing.VendorID = vendorID
491466

492467
m := jsonpb.Marshaler{
493468
EnumsAsInts: false,
494469
EmitDefaults: false,
495470
Indent: " ",
496471
OrigName: false,
497472
}
498-
499-
outSL, err := m.MarshalToString(retSL.RListing.ProtoListing)
473+
outSL, err := m.MarshalToString(listing0.ProtoListing)
500474
if err != nil {
501-
return retSL, err
502-
}
503-
retSL.RListing.ListingBytes = []byte(outSL)
504-
505-
proto1 := &pb.Listing{
506-
Slug: proto0.Slug,
507-
VendorID: vendorID,
508-
Metadata: proto0.Metadata,
509-
Item: proto0.Item,
510-
ShippingOptions: proto0.ShippingOptions,
511-
Taxes: proto0.Taxes,
512-
Coupons: proto0.Coupons,
513-
Moderators: proto0.Moderators,
514-
TermsAndConditions: proto0.TermsAndConditions,
515-
RefundPolicy: proto0.RefundPolicy,
475+
return SignedListing{}, err
516476
}
517-
518-
log.Info(proto1.Slug)
519-
520-
return retSL, nil
521-
477+
listing0.ListingBytes = []byte(outSL)
478+
479+
return SignedListing{
480+
Signature: s1.Signature,
481+
Hash: s1.Hash,
482+
RListing: listing0,
483+
ProtoListing: listing0.ProtoListing,
484+
ProtoSignedListing: &pb.SignedListing{
485+
Listing: listing0.ProtoListing,
486+
Hash: s1.Hash,
487+
Signature: s1.Signature,
488+
},
489+
}, nil
522490
}
523491

524492
// UnmarshalJSONListing - unmarshal listing
@@ -609,6 +577,51 @@ func ExtractIDFromListing(data []byte) (*pb.ID, error) {
609577
return vendorPlay, nil
610578
}
611579

580+
// GetCryptoDivisibility returns the listing crypto divisibility
581+
func (l *Listing) GetCryptoDivisibility() uint32 {
582+
ct, err := l.GetContractType()
583+
if err == nil && ct != pb.Listing_Metadata_CRYPTOCURRENCY.String() {
584+
return 0
585+
}
586+
div := parseProtoCryptoDivisibility(l.ListingBytes)
587+
switch l.ListingVersion {
588+
case 5:
589+
return div
590+
default: // version <4
591+
if div != 0 {
592+
return uint32(math.Log10(float64(div)))
593+
}
594+
}
595+
return 0
596+
}
597+
598+
func parseProtoCryptoDivisibility(listing []byte) uint32 {
599+
var listingT struct {
600+
Metadata struct {
601+
CryptoDivisibility uint32 `json:"coinDivisibility"`
602+
} `json:"metadata"`
603+
}
604+
err := json.Unmarshal(listing, &listingT)
605+
if err != nil {
606+
return 0
607+
}
608+
return listingT.Metadata.CryptoDivisibility
609+
}
610+
611+
// GetCryptoCurrencyCode returns the listing crypto currency code
612+
func (l *Listing) GetCryptoCurrencyCode() string {
613+
var listingT struct {
614+
Metadata struct {
615+
CryptoCurrencyCode string `json:"coinType"`
616+
} `json:"metadata"`
617+
}
618+
err := json.Unmarshal(l.ListingBytes, &listingT)
619+
if err != nil {
620+
return ""
621+
}
622+
return listingT.Metadata.CryptoCurrencyCode
623+
}
624+
612625
// GetTitle - return listing title
613626
func (l *Listing) GetTitle() (string, error) {
614627
type title struct {
@@ -1333,6 +1346,8 @@ func (l *Listing) GetMetadata() (*pb.Listing_Metadata, error) {
13331346
Language: lang,
13341347
EscrowTimeoutHours: l.GetEscrowTimeout(),
13351348
PriceModifier: priceMod,
1349+
CryptoDivisibility: parseProtoCryptoDivisibility(l.ListingBytes),
1350+
CryptoCurrencyCode: l.GetCryptoCurrencyCode(),
13361351
}
13371352
return &m, nil
13381353
}
@@ -1615,11 +1630,7 @@ func (l *Listing) Sign(n *core.IpfsNode, timeout uint32,
16151630

16161631
// ValidateCryptoListing - check cryptolisting
16171632
func (l *Listing) ValidateCryptoListing() error {
1618-
listing, err := l.GetProtoListing()
1619-
if err != nil {
1620-
return err
1621-
}
1622-
return validateCryptocurrencyListing(listing)
1633+
return l.validateCryptocurrencyListing()
16231634
}
16241635

16251636
// ValidateSkus - check listing skus
@@ -1967,12 +1978,12 @@ func ValidateListing(l *Listing, testnet bool) (err error) {
19671978

19681979
// Type-specific validations
19691980
if listing.Metadata.ContractType == pb.Listing_Metadata_PHYSICAL_GOOD {
1970-
err := validatePhysicalListing(listing)
1981+
err := l.validatePhysicalListing()
19711982
if err != nil {
19721983
return err
19731984
}
19741985
} else if listing.Metadata.ContractType == pb.Listing_Metadata_CRYPTOCURRENCY {
1975-
err := validateCryptocurrencyListing(listing)
1986+
err := l.validateCryptocurrencyListing()
19761987
if err != nil {
19771988
return err
19781989
}
@@ -1989,7 +2000,11 @@ func ValidateListing(l *Listing, testnet bool) (err error) {
19892000
return nil
19902001
}
19912002

1992-
func validatePhysicalListing(listing *pb.Listing) error {
2003+
func (l *Listing) validatePhysicalListing() error {
2004+
listing, err := l.GetProtoListing()
2005+
if err != nil {
2006+
return fmt.Errorf("producing listing protobuf: %s", err)
2007+
}
19932008
if listing.Item.PriceCurrency.Code == "" {
19942009
return errors.New("listing pricing currency code must not be empty")
19952010
}
@@ -2068,19 +2083,29 @@ func validatePhysicalListing(listing *pb.Listing) error {
20682083
return nil
20692084
}
20702085

2071-
func validateCryptocurrencyListing(listing *pb.Listing) error {
2072-
switch {
2073-
case len(listing.Coupons) > 0:
2086+
func (l *Listing) validateCryptocurrencyListing() error {
2087+
listing, err := l.GetProtoListing()
2088+
if err != nil {
2089+
return fmt.Errorf("producing listing protobuf: %s", err)
2090+
}
2091+
2092+
if len(listing.Coupons) > 0 {
20742093
return ErrCryptocurrencyListingIllegalField("coupons")
2075-
case len(listing.Item.Options) > 0:
2094+
}
2095+
if len(listing.Item.Options) > 0 {
20762096
return ErrCryptocurrencyListingIllegalField("item.options")
2077-
case len(listing.ShippingOptions) > 0:
2097+
}
2098+
if len(listing.ShippingOptions) > 0 {
20782099
return ErrCryptocurrencyListingIllegalField("shippingOptions")
2079-
case len(listing.Item.Condition) > 0:
2100+
}
2101+
if len(listing.Item.Condition) > 0 {
20802102
return ErrCryptocurrencyListingIllegalField("item.condition")
2081-
//case len(listing.Metadata.PricingCurrency.Code) > 0:
2082-
//return ErrCryptocurrencyListingIllegalField("metadata.pricingCurrency")
2083-
case len(listing.Metadata.CryptoCurrencyCode) == 0:
2103+
}
2104+
if listing.Item.PriceCurrency != nil &&
2105+
len(listing.Item.PriceCurrency.Code) > 0 {
2106+
return ErrCryptocurrencyListingIllegalField("metadata.pricingCurrency")
2107+
}
2108+
if len(listing.Metadata.CryptoCurrencyCode) == 0 {
20842109
return ErrListingCryptoCurrencyCodeInvalid
20852110
}
20862111

0 commit comments

Comments
 (0)