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

Commit 4a63ec4

Browse files
committed
Fix bug handling big int inventory
1 parent 8cb1bd1 commit 4a63ec4

File tree

13 files changed

+97
-58
lines changed

13 files changed

+97
-58
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

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: 8 additions & 7 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,8 +19,8 @@ var (
1819

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

2526
// Inventory is the complete inventory representation stored on IPFS
@@ -34,11 +35,11 @@ func (n *OpenBazaarNode) GetLocalInventory() (Inventory, error) {
3435
}
3536

3637
inventory := make(Inventory, len(listings))
37-
var totalCount int64
38+
totalCount := big.NewInt(0)
3839
for slug, variants := range listings {
39-
totalCount = 0
40+
totalCount = big.NewInt(0)
4041
for _, variantCount := range variants {
41-
totalCount += variantCount
42+
totalCount = new(big.Int).Add(totalCount, variantCount)
4243
}
4344

4445
inventory[slug] = &InventoryListing{
@@ -58,9 +59,9 @@ func (n *OpenBazaarNode) GetLocalInventoryForSlug(slug string) (*InventoryListin
5859
}
5960

6061
var inventory *InventoryListing
61-
var totalCount int64
62+
totalCount := big.NewInt(0)
6263
for _, variantCount := range variants {
63-
totalCount += variantCount
64+
totalCount = new(big.Int).Add(totalCount, variantCount)
6465
}
6566

6667
inventory = &InventoryListing{

core/listings.go

Lines changed: 1 addition & 1 deletion
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
}

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
}

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:

qa/testdata/listing_crypto.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
"description": "",
1616
"processingTime": "1 to 2 hours",
1717
"price": "0",
18+
"priceCurrency": {
19+
"code": "TETH",
20+
"divisibility": 8,
21+
"name": "A",
22+
"currencyType": "A"
23+
},
1824
"images": [{
1925
"tiny": "QmUAuYuiafnJRZxDDX7MuruMNsicYNuyub5vUeAcupUBNs",
2026
"small": "QmXSEqXLCzpCByJU4wqbJ37TcBEj77FKMUWUP1qLh56847",
@@ -26,7 +32,8 @@
2632
"grams": 0,
2733
"options": [],
2834
"skus": [{
29-
"bigQuantity": "350000000"
35+
"bigQuantity": "350000000",
36+
"bigSurcharge": "0"
3037
}]
3138
},
3239
"moderators": [],

repo/datastore.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package repo
22

33
import (
44
"database/sql"
5+
"math/big"
56

67
peer "gx/ipfs/QmYVXrKrKHDC9FobgmcmshCDyWwdrfwfanNQN4oxJ9Fk3h/go-libp2p-peer"
78
"time"
@@ -162,16 +163,16 @@ type InventoryStore interface {
162163

163164
/* Put an inventory count for a listing
164165
Override the existing count if it exists */
165-
Put(slug string, variantIndex int, count int64) error
166+
Put(slug string, variantIndex int, count *big.Int) error
166167

167168
// Return the count for a specific listing including variants
168-
GetSpecific(slug string, variantIndex int) (int64, error)
169+
GetSpecific(slug string, variantIndex int) (*big.Int, error)
169170

170171
// Get the count for all variants of a given listing
171-
Get(slug string) (map[int]int64, error)
172+
Get(slug string) (map[int]*big.Int, error)
172173

173174
// Fetch all inventory maps for each slug
174-
GetAll() (map[string]map[int]int64, error)
175+
GetAll() (map[string]map[int]*big.Int, error)
175176

176177
// Delete a listing and related count
177178
Delete(slug string, variant int) error

0 commit comments

Comments
 (0)