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

Commit bf6c291

Browse files
authored
Merge pull request #1775 from OpenBazaar/cryptoquantity
Fix bugs handling big inventory
2 parents 1d285c7 + 703feb2 commit bf6c291

16 files changed

+119
-86
lines changed

api/jsonapi.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,7 +1320,7 @@ func (i *jsonAPIHandler) POSTInventory(w http.ResponseWriter, r *http.Request) {
13201320
type inv struct {
13211321
Slug string `json:"slug"`
13221322
Variant int `json:"variant"`
1323-
Quantity int64 `json:"quantity"`
1323+
Quantity string `json:"quantity"`
13241324
}
13251325
decoder := json.NewDecoder(r.Body)
13261326
var invList []inv
@@ -1330,7 +1330,12 @@ func (i *jsonAPIHandler) POSTInventory(w http.ResponseWriter, r *http.Request) {
13301330
return
13311331
}
13321332
for _, in := range invList {
1333-
err = i.node.Datastore.Inventory().Put(in.Slug, in.Variant, in.Quantity)
1333+
q, ok := new(big.Int).SetString(in.Quantity, 10)
1334+
if !ok {
1335+
ErrorResponse(w, http.StatusBadRequest, "error parsing quantity")
1336+
return
1337+
}
1338+
err = i.node.Datastore.Inventory().Put(in.Slug, in.Variant, q)
13341339
if err != nil {
13351340
ErrorResponse(w, http.StatusInternalServerError, err.Error())
13361341
return

api/jsonapi_data_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ const headerValidJSONResponse = `{
289289
const inventoryUpdateJSON = `[{
290290
"slug": "ron_swanson_tshirt",
291291
"variant": 0,
292-
"quantity": 17
292+
"quantity": "17"
293293
}]`
294294

295295
//

core/errors.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/json"
66
"errors"
7+
"math/big"
78
"strconv"
89

910
peer "gx/ipfs/QmYVXrKrKHDC9FobgmcmshCDyWwdrfwfanNQN4oxJ9Fk3h/go-libp2p-peer"
@@ -67,17 +68,17 @@ func (err CodedError) Error() string {
6768
// purchasing too many of an item
6869
type ErrOutOfInventory struct {
6970
CodedError
70-
RemainingInventory int64 `json:"remainingInventory"`
71+
RemainingInventory string `json:"remainingInventory"`
7172
}
7273

7374
// NewErrOutOfInventory - return out of inventory err with available inventory
74-
func NewErrOutOfInventory(inventoryRemaining int64) ErrOutOfInventory {
75+
func NewErrOutOfInventory(inventoryRemaining *big.Int) ErrOutOfInventory {
7576
return ErrOutOfInventory{
7677
CodedError: CodedError{
7778
Reason: "not enough inventory",
7879
Code: "ERR_INSUFFICIENT_INVENTORY",
7980
},
80-
RemainingInventory: inventoryRemaining,
81+
RemainingInventory: inventoryRemaining.String(),
8182
}
8283
}
8384

core/inventory.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package core
33
import (
44
"encoding/json"
55
"errors"
6+
"math/big"
67

78
peer "gx/ipfs/QmYVXrKrKHDC9FobgmcmshCDyWwdrfwfanNQN4oxJ9Fk3h/go-libp2p-peer"
89
"time"
@@ -18,7 +19,7 @@ var (
1819

1920
// InventoryListing is the listing representation stored on IPFS
2021
type InventoryListing struct {
21-
Inventory int64 `json:"inventory"`
22+
Inventory string `json:"inventory"`
2223
LastUpdated string `json:"lastUpdated"`
2324
}
2425

@@ -33,16 +34,18 @@ func (n *OpenBazaarNode) GetLocalInventory() (Inventory, error) {
3334
return nil, err
3435
}
3536

36-
inventory := make(Inventory, len(listings))
37-
var totalCount int64
37+
var (
38+
totalCount *big.Int
39+
inventory = make(Inventory, len(listings))
40+
)
3841
for slug, variants := range listings {
39-
totalCount = 0
42+
totalCount = big.NewInt(0)
4043
for _, variantCount := range variants {
41-
totalCount += variantCount
44+
totalCount = new(big.Int).Add(totalCount, variantCount)
4245
}
4346

4447
inventory[slug] = &InventoryListing{
45-
Inventory: totalCount,
48+
Inventory: totalCount.String(),
4649
LastUpdated: time.Now().UTC().Format(time.RFC3339),
4750
}
4851
}
@@ -58,13 +61,13 @@ func (n *OpenBazaarNode) GetLocalInventoryForSlug(slug string) (*InventoryListin
5861
}
5962

6063
var inventory *InventoryListing
61-
var totalCount int64
64+
totalCount := big.NewInt(0)
6265
for _, variantCount := range variants {
63-
totalCount += variantCount
66+
totalCount = new(big.Int).Add(totalCount, variantCount)
6467
}
6568

6669
inventory = &InventoryListing{
67-
Inventory: totalCount,
70+
Inventory: totalCount.String(),
6871
LastUpdated: time.Now().UTC().Format(time.RFC3339),
6972
}
7073

core/listings.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (n *OpenBazaarNode) SetListingInventory(l repo.Listing) error {
8484

8585
// If SKUs were omitted, set a default with unlimited inventory
8686
if len(listingInv) == 0 {
87-
err = n.Datastore.Inventory().Put(slug, 0, -1)
87+
err = n.Datastore.Inventory().Put(slug, 0, big.NewInt(-1))
8888
if err != nil {
8989
return err
9090
}
@@ -678,7 +678,7 @@ func (n *OpenBazaarNode) GetListingFromSlug(slug string) (*pb.SignedListing, err
678678
for variant, count := range inventory {
679679
for i, s := range sl.Listing.Item.Skus {
680680
if variant == i {
681-
s.BigQuantity = fmt.Sprintf("%d", count)
681+
s.BigQuantity = count.String()
682682
break
683683
}
684684
}

core/order.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,7 +1471,7 @@ collectListings:
14711471
type inventory struct {
14721472
Slug string
14731473
Variant int
1474-
Count int64
1474+
Count *big.Int
14751475
}
14761476
var inventoryList []inventory
14771477
for _, item := range contract.BuyerOrder.Items {
@@ -1514,7 +1514,7 @@ collectListings:
15141514
}
15151515
// Create inventory paths to check later
15161516
if q := GetOrderQuantity(listingMap[item.ListingHash], item); q.IsInt64() {
1517-
inv.Count = q.Int64()
1517+
inv.Count = q
15181518
} else {
15191519
// TODO: https://github.com/OpenBazaar/openbazaar-go/issues/1739
15201520
return errors.New("big inventory quantity not supported")
@@ -1577,7 +1577,7 @@ collectListings:
15771577
if err != nil {
15781578
return errors.New("vendor has no inventory for the selected variant")
15791579
}
1580-
if amt >= 0 && amt < inv.Count {
1580+
if amt.Cmp(big.NewInt(0)) >= 0 && amt.Cmp(inv.Count) < 0 {
15811581
return NewErrOutOfInventory(amt)
15821582
}
15831583
}

core/signed_listings.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package core
22

33
import (
4-
"fmt"
54
"io/ioutil"
5+
"math/big"
66

77
"github.com/OpenBazaar/jsonpb"
88
"github.com/OpenBazaar/openbazaar-go/pb"
@@ -39,11 +39,11 @@ func AssignMatchingCoupons(savedCoupons []repo.Coupon, sl *pb.SignedListing) err
3939
return nil
4040
}
4141

42-
func AssignMatchingQuantities(inventory map[int]int64, sl *pb.SignedListing) error {
42+
func AssignMatchingQuantities(inventory map[int]*big.Int, sl *pb.SignedListing) error {
4343
for variant, count := range inventory {
4444
for i, s := range sl.Listing.Item.Skus {
4545
if variant == i {
46-
s.BigQuantity = fmt.Sprintf("%d", count)
46+
s.BigQuantity = count.String()
4747
break
4848
}
4949
}

core/signed_listings_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package core_test
22

33
import (
4+
"math/big"
45
"path/filepath"
56
"testing"
67

@@ -76,8 +77,8 @@ func TestOpenBazaarSignedListings_AssignMatchingCoupons(t *testing.T) {
7677
func TestOpenBazaarSignedListings_AssignMatchingQuantities(t *testing.T) {
7778
absPath, _ := filepath.Abs("../test/contracts/signed_listings_1.json")
7879

79-
inventory := map[int]int64{
80-
0: 1000,
80+
inventory := map[int]*big.Int{
81+
0: big.NewInt(1000),
8182
}
8283

8384
listing, err := core.GetSignedListingFromPath(absPath)

qa/manage_crypto_listings.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def run_test(self):
4545
raise TestFailure("ManageCryptoListingsTest - FAIL: Incorrect listing count: %d", len(resp))
4646
for listing in resp:
4747
if listing['contractType'] == 'CRYPTOCURRENCY':
48-
print(listing)
4948
if listing["cryptoCurrencyCode"] != "TETH":
5049
raise TestFailure("ManageCryptoListingsTest - FAIL: cryptoCurrencyCode incorrect: %s", listing["cryptoCurrencyCode"])
5150

qa/market_price_modifier.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def run_test(self):
4444
listing_json["metadata"]["coinDivisibility"] = 8
4545
listing_json["metadata"]["acceptedCurrencies"] = ["T" + self.cointype]
4646
listing_json_with_modifier = deepcopy(listing_json)
47-
listing_json_with_modifier["metadata"]["priceModifier"] = self.price_modifier
47+
listing_json_with_modifier["item"]["priceModifier"] = self.price_modifier
4848

4949
api_url = vendor["gateway_url"] + "ob/listing"
5050
r = requests.post(api_url, data=json.dumps(listing_json, indent=4))
@@ -71,7 +71,7 @@ def run_test(self):
7171
raise TestFailure("MarketPriceModifierTest - FAIL: Couldn't get vendor local listings")
7272
resp = json.loads(r.text)
7373
for listing in resp:
74-
if "modifier" not in listing["price"]:
74+
if "modifier" not in listing:
7575
raise TestFailure("MarketPriceModifierTest - FAIL: Vendor's local listings index doesn't include price modifier")
7676

7777
# check vendor's listings from buyer and check for modifier
@@ -81,7 +81,7 @@ def run_test(self):
8181
raise TestFailure("MarketPriceModifierTest - FAIL: Couldn't get vendor listings from buyer")
8282
resp = json.loads(r.text)
8383
for listing in resp:
84-
if "modifier" not in listing["price"]:
84+
if "modifier" not in listing:
8585
raise TestFailure("MarketPriceModifierTest - FAIL: Vendor's listings don't include price modifier from buyer")
8686

8787
# get listing hashes
@@ -122,7 +122,7 @@ def run_test(self):
122122
with open('testdata/order_crypto.json') as order_file:
123123
order_json = json.load(order_file, object_pairs_hook=OrderedDict)
124124
order_json["items"][0]["listingHash"] = listing_id_with_modifier
125-
order_json["paymentCoin"] = "t" + self.cointype
125+
order_json["paymentCoin"] = "T" + self.cointype
126126
api_url = buyer["gateway_url"] + "ob/purchase"
127127
r = requests.post(api_url, data=json.dumps(order_json, indent=4))
128128
if r.status_code == 404:

0 commit comments

Comments
 (0)