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

Add price and listingType fields to order websocket notification #1223

Merged
merged 8 commits into from
Oct 30, 2018
Merged
4 changes: 3 additions & 1 deletion Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ RUN wget https://github.com/google/protobuf/releases/download/v3.6.0/protoc-3.6.
mv ./bin/protoc /usr/local/bin/ && \
rm -rf ./include ./bin

WORKDIR /go/src/github.com/OpenBazaar/openbazaar-go
RUN go get -u github.com/gogo/protobuf/proto \
github.com/golang/protobuf/protoc-gen-go \
github.com/icrowley/fake \
github.com/derekparker/delve/cmd/dlv

RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.10

WORKDIR /go/src/github.com/OpenBazaar/openbazaar-go
RUN useradd -ms /bin/bash ob_user
USER ob_user

Expand Down
2 changes: 1 addition & 1 deletion cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ func (x *Start) Execute(args []string) error {
if resyncManager == nil {
core.Node.WaitForMessageRetrieverCompletion()
}
TL := lis.NewTransactionListener(core.Node.Datastore, core.Node.Broadcast)
TL := lis.NewTransactionListener(core.Node.Multiwallet, core.Node.Datastore, core.Node.Broadcast)
for ct, wal := range mw {
WL := lis.NewWalletListener(core.Node.Datastore, core.Node.Broadcast, ct)
wal.AddTransactionListener(WL.OnTransactionReceived)
Expand Down
5 changes: 5 additions & 0 deletions core/currency.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package core

// DefaultCurrencyDivisibility is the Divisibility of the Currency if not
// defined otherwise
const DefaultCurrencyDivisibility uint32 = 1e8
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left this here. Hope no one minds.

26 changes: 13 additions & 13 deletions core/listings.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ const (
PriceModifierMin = -99.99
// PriceModifierMax = max price modifier
PriceModifierMax = 1000.00

// DefaultCoinDivisibility - decimals for price
DefaultCoinDivisibility uint32 = 1e8
)

type price struct {
Expand Down Expand Up @@ -185,7 +182,7 @@ func (n *OpenBazaarNode) SignListing(listing *pb.Listing) (*pb.SignedListing, er

// Check the listing data is correct for continuing
testingEnabled := n.TestNetworkEnabled() || n.RegressionNetworkEnabled()
if err := validateListing(listing, testingEnabled); err != nil {
if err := n.validateListing(listing, testingEnabled); err != nil {
return sl, err
}

Expand Down Expand Up @@ -357,7 +354,7 @@ func (n *OpenBazaarNode) saveListing(listing *pb.Listing) error {
}

if listing.Metadata.ContractType == pb.Listing_Metadata_CRYPTOCURRENCY {
err := validateCryptocurrencyListing(listing)
err := n.validateCryptocurrencyListing(listing)
if err != nil {
return err
}
Expand Down Expand Up @@ -449,10 +446,6 @@ func setCryptocurrencyListingDefaults(listing *pb.Listing) {
listing.Metadata.Format = pb.Listing_Metadata_MARKET_PRICE
}

func coinDivisibilityForType(coinType string) uint32 {
return DefaultCoinDivisibility
}

func (n *OpenBazaarNode) extractListingData(listing *pb.SignedListing) (ListingData, error) {
listingPath := path.Join(n.RepoPath, "root", "listings", listing.Listing.Slug+".json")

Expand Down Expand Up @@ -866,7 +859,7 @@ func (n *OpenBazaarNode) GetListingFromSlug(slug string) (*pb.SignedListing, err
/* Performs a ton of checks to make sure the listing is formatted correctly. We should not allow
invalid listings to be saved or purchased as it can lead to ambiguity when moderating a dispute
or possible attacks. This function needs to be maintained in conjunction with contracts.proto */
func validateListing(listing *pb.Listing, testnet bool) (err error) {
func (n *OpenBazaarNode) validateListing(listing *pb.Listing, testnet bool) (err error) {
defer func() {
if r := recover(); r != nil {
switch x := r.(type) {
Expand Down Expand Up @@ -1173,7 +1166,7 @@ func validateListing(listing *pb.Listing, testnet bool) (err error) {
return err
}
} else if listing.Metadata.ContractType == pb.Listing_Metadata_CRYPTOCURRENCY {
err := validateCryptocurrencyListing(listing)
err := n.validateCryptocurrencyListing(listing)
if err != nil {
return err
}
Expand Down Expand Up @@ -1287,7 +1280,7 @@ func validatePhysicalListing(listing *pb.Listing) error {
return nil
}

func validateCryptocurrencyListing(listing *pb.Listing) error {
func (n *OpenBazaarNode) validateCryptocurrencyListing(listing *pb.Listing) error {
switch {
case len(listing.Coupons) > 0:
return ErrCryptocurrencyListingIllegalField("coupons")
Expand All @@ -1303,7 +1296,14 @@ func validateCryptocurrencyListing(listing *pb.Listing) error {
return ErrCryptocurrencyListingCoinTypeRequired
}

if listing.Metadata.CoinDivisibility != coinDivisibilityForType(listing.Metadata.CoinType) {
var expectedDivisibility uint32
if wallet, err := n.Multiwallet.WalletForCurrencyCode(listing.Metadata.CoinType); err != nil {
expectedDivisibility = DefaultCurrencyDivisibility
} else {
expectedDivisibility = uint32(wallet.ExchangeRates().UnitsPerCoin())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if UnitsPerCoin matched types with the listing data. (OpenBazaar/wallet-interface#9)

}

if listing.Metadata.CoinDivisibility != expectedDivisibility {
return ErrListingCoinDivisibilityIncorrect
}

Expand Down
96 changes: 0 additions & 96 deletions core/listings_test.go

This file was deleted.

2 changes: 1 addition & 1 deletion core/order.go
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ func (n *OpenBazaarNode) createContractWithOrder(data *PurchaseData) (*pb.Ricard
if err := validateVendorID(sl.Listing); err != nil {
return nil, err
}
if err := validateListing(sl.Listing, n.TestNetworkEnabled() || n.RegressionNetworkEnabled()); err != nil {
if err := n.validateListing(sl.Listing, n.TestNetworkEnabled() || n.RegressionNetworkEnabled()); err != nil {
return nil, fmt.Errorf("listing failed to validate, reason: %q", err.Error())
}
if err := verifySignaturesOnListing(sl); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion mobile/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ func (n *Node) Start() error {
if resyncManager == nil {
core.Node.WaitForMessageRetrieverCompletion()
}
TL := lis.NewTransactionListener(core.Node.Datastore, core.Node.Broadcast)
TL := lis.NewTransactionListener(n.OpenBazaarNode.Multiwallet, core.Node.Datastore, core.Node.Broadcast)
for ct, wal := range n.OpenBazaarNode.Multiwallet {
WL := lis.NewWalletListener(core.Node.Datastore, core.Node.Broadcast, ct)
wal.AddTransactionListener(WL.OnTransactionReceived)
Expand Down
19 changes: 14 additions & 5 deletions repo/notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,15 +399,24 @@ type messageTypingWrapper struct {
MessageRead Notifier `json:"messageTyping"`
}

type ListingPrice struct {
Amount uint64 `json:"amount"`
CurrencyCode string `json:"currencyCode"`
PriceModifier float32 `json:"priceModifier"`
CoinDivisibility uint32 `json:"coinDivisibility"`
}

type OrderNotification struct {
ID string `json:"notificationId"`
Type NotificationType `json:"type"`
Title string `json:"title"`
BuyerID string `json:"buyerId"`
BuyerHandle string `json:"buyerHandle"`
Thumbnail Thumbnail `json:"thumbnail"`
BuyerID string `json:"buyerId"`
ID string `json:"notificationId"`
ListingType string `json:"listingType"`
OrderId string `json:"orderId"`
Price ListingPrice `json:"price"`
Slug string `json:"slug"`
Thumbnail Thumbnail `json:"thumbnail"`
Title string `json:"title"`
Type NotificationType `json:"type"`
}

func (n OrderNotification) Data() ([]byte, error) {
Expand Down
49 changes: 34 additions & 15 deletions wallet/listeners/transaction_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"sync"
"time"

"github.com/OpenBazaar/multiwallet"
"github.com/OpenBazaar/openbazaar-go/core"
"github.com/OpenBazaar/openbazaar-go/pb"
"github.com/OpenBazaar/openbazaar-go/repo"
Expand All @@ -17,14 +18,14 @@ import (
var log = logging.MustGetLogger("transaction-listener")

type TransactionListener struct {
db repo.Datastore
broadcast chan repo.Notifier
broadcast chan repo.Notifier
db repo.Datastore
multiwallet multiwallet.MultiWallet
*sync.Mutex
}

func NewTransactionListener(db repo.Datastore, broadcast chan repo.Notifier) *TransactionListener {
l := &TransactionListener{db, broadcast, new(sync.Mutex)}
return l
func NewTransactionListener(mw multiwallet.MultiWallet, db repo.Datastore, broadcast chan repo.Notifier) *TransactionListener {
return &TransactionListener{broadcast, db, mw, new(sync.Mutex)}
}

func (l *TransactionListener) OnTransactionReceived(cb wallet.TransactionCallback) {
Expand Down Expand Up @@ -149,11 +150,10 @@ func (l *TransactionListener) OnTransactionReceived(cb wallet.TransactionCallbac
}
}
}

}

func (l *TransactionListener) processSalePayment(txid string, output wallet.TransactionOutput, contract *pb.RicardianContract, state pb.OrderState, funded bool, records []*wallet.TransactionRecord) {
funding := output.Value
var funding = output.Value
for _, r := range records {
funding += r.Value
// If we have already seen this transaction for some reason, just return
Expand All @@ -179,14 +179,21 @@ func (l *TransactionListener) processSalePayment(txid string, output wallet.Tran
l.adjustInventory(contract)

n := repo.OrderNotification{
repo.NewNotificationID(),
"order",
contract.VendorListings[0].Item.Title,
contract.BuyerOrder.BuyerID.PeerID,
contract.BuyerOrder.BuyerID.Handle,
repo.Thumbnail{contract.VendorListings[0].Item.Images[0].Tiny, contract.VendorListings[0].Item.Images[0].Small},
orderId,
contract.VendorListings[0].Slug,
BuyerHandle: contract.BuyerOrder.BuyerID.Handle,
BuyerID: contract.BuyerOrder.BuyerID.PeerID,
ID: repo.NewNotificationID(),
ListingType: contract.VendorListings[0].Metadata.ContractType.String(),
OrderId: orderId,
Price: repo.ListingPrice{
Amount: contract.BuyerOrder.Payment.Amount,
CoinDivisibility: currencyDivisibilityFromContract(l.multiwallet, contract),
CurrencyCode: contract.BuyerOrder.Payment.Coin,
PriceModifier: contract.VendorListings[0].Metadata.PriceModifier,
},
Slug: contract.VendorListings[0].Slug,
Thumbnail: repo.Thumbnail{contract.VendorListings[0].Item.Images[0].Tiny, contract.VendorListings[0].Item.Images[0].Small},
Title: contract.VendorListings[0].Item.Title,
Type: "order",
}

l.broadcast <- n
Expand Down Expand Up @@ -218,6 +225,18 @@ func (l *TransactionListener) processSalePayment(txid string, output wallet.Tran
l.db.TxMetadata().Put(repo.Metadata{txid, "", title, orderId, thumbnail, bumpable})
}

func currencyDivisibilityFromContract(mw multiwallet.MultiWallet, contract *pb.RicardianContract) uint32 {
var currencyDivisibility = contract.VendorListings[0].Metadata.CoinDivisibility
if currencyDivisibility != 0 {
return currencyDivisibility
}
wallet, err := mw.WalletForCurrencyCode(contract.BuyerOrder.Payment.Coin)
if err == nil {
return uint32(wallet.ExchangeRates().UnitsPerCoin())
}
return core.DefaultCurrencyDivisibility
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer divisibility from listing, then check wallet's preference, then fail to default as a last resort.

}

func (l *TransactionListener) processPurchasePayment(txid string, output wallet.TransactionOutput, contract *pb.RicardianContract, state pb.OrderState, funded bool, records []*wallet.TransactionRecord) {
funding := output.Value
for _, r := range records {
Expand Down