diff --git a/Makefile b/Makefile index a95908f28c..99c379d5d7 100755 --- a/Makefile +++ b/Makefile @@ -22,11 +22,11 @@ help: .PHONY: ios_framework ios_framework: ## Build iOS Framework for mobile - gomobile bind -target=ios github.com/OpenBazaar/openbazaar-go/mobile + gomobile bind -target=ios/arm64,ios/amd64 -iosversion=10 -ldflags="-s -w" github.com/OpenBazaar/openbazaar-go/mobile .PHONY: android_framework android_framework: ## Build Android Framework for mobile - gomobile bind -target=android github.com/OpenBazaar/openbazaar-go/mobile + gomobile bind -target=android/arm,android/arm64,android/amd64 -ldflags="-s -w" github.com/OpenBazaar/openbazaar-go/mobile ## ## Protobuf compilation diff --git a/core/core.go b/core/core.go index af899fa909..c9d5acefaf 100644 --- a/core/core.go +++ b/core/core.go @@ -265,7 +265,7 @@ func (n *OpenBazaarNode) retryableSeedStoreToPeer(pid peer.ID, graphHash string, } err := n.SendStore(pid.Pretty(), graph) if err != nil { - if retryTimeout > 60*time.Second { + if retryTimeout > 8*time.Second { log.Errorf("error pushing to peer %s: %s", pid.Pretty(), err.Error()) return } diff --git a/core/net.go b/core/net.go index a0da9d0016..acfb8f7499 100644 --- a/core/net.go +++ b/core/net.go @@ -98,23 +98,32 @@ func (n *OpenBazaarNode) SendOfflineMessage(p peer.ID, k *libp2p.PubKey, m *pb.M } } log.Debugf("Sending offline message to: %s, Message Type: %s, PointerID: %s, Location: %s", p.Pretty(), m.MessageType.String(), pointer.Cid.String(), pointer.Value.Addrs[0].String()) - OfflineMessageWaitGroup.Add(2) - go func() { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - err := ipfs.PublishPointer(n.DHT, ctx, pointer) - if err != nil { - log.Error(err) - } - // Push provider to our push nodes for redundancy - for _, p := range n.PushNodes { + // We publish our pointers to three different locations: + // 1. The pushnodes + // 2. The DHT + // 3. Pubsub + // Each one is done in a separate goroutine so as to not block but we + // do increment the OfflineMessageWaitGroup which is used to block + // shutdown until all publishing is finished. + OfflineMessageWaitGroup.Add(2 + len(n.PushNodes)) + for _, p := range n.PushNodes { + go func(pid peer.ID) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - err := ipfs.PutPointerToPeer(n.DHT, ctx, p, pointer) + err := ipfs.PutPointerToPeer(n.DHT, ctx, pid, pointer) if err != nil { log.Error(err) } + OfflineMessageWaitGroup.Done() + }(p) + } + go func() { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err := ipfs.PublishPointer(n.DHT, ctx, pointer) + if err != nil { + log.Error(err) } OfflineMessageWaitGroup.Done() diff --git a/mobile/cmd/main.go b/mobile/cmd/main.go index a6865d61ff..27e01fc5c7 100644 --- a/mobile/cmd/main.go +++ b/mobile/cmd/main.go @@ -2,12 +2,10 @@ package main import ( "fmt" - "os" - "sync" - "time" - "github.com/OpenBazaar/openbazaar-go/mobile" "github.com/jessevdk/go-flags" + "os" + "path" ) type Options struct { @@ -21,7 +19,7 @@ var ( ) func main() { - var dataPath = "/Users/mg/work/ob/openbazaar-go/config_mobile_test" + var dataPath = path.Join(os.TempDir(), "ob-mobile") if _, err := parser.Parse(); err != nil { if len(os.Args) > 1 && os.Args[1] == "-h" { os.Exit(0) @@ -35,7 +33,6 @@ func main() { } var ( - wg sync.WaitGroup n, err = mobile.NewNodeWithConfig(&mobile.NodeConfig{ RepoPath: dataPath, Testnet: options.TestnetEnabled, @@ -48,18 +45,5 @@ func main() { fmt.Println(err.Error()) } - time.Sleep(time.Second * 10) - fmt.Println("restarting...", time.Now()) - - wg.Add(1) - - go func() { - err := n.Restart() - if err != nil { - panic(fmt.Sprintf("failed to restart: %s", err.Error())) - } - }() - - wg.Wait() - + select {} } diff --git a/mobile/node.go b/mobile/node.go index 5a5d16a1ba..1ab091a016 100644 --- a/mobile/node.go +++ b/mobile/node.go @@ -70,7 +70,7 @@ type Node struct { var ( fileLogFormat = logging.MustStringFormatter( - `%{time:2006-01-02 15:04:05.000} [%{level}] [%{module}/%{shortfunc}] %{message}`, + `[Haven] %{time:2006-01-02 15:04:05.000} [%{level}] [%{module}/%{shortfunc}] %{message}`, ) publishUnlocked = false mainLoggingBackend logging.Backend @@ -122,7 +122,9 @@ func NewNodeWithConfig(config *NodeConfig, password string, mnemonic string) (*N } obFileBackend := logging.NewLogBackend(obLog, "", 0) obFileBackendFormatted := logging.NewBackendFormatter(obFileBackend, fileLogFormat) - mainLoggingBackend = logging.SetBackend(obFileBackendFormatted) + stdoutBackend := logging.NewLogBackend(os.Stdout, "", 0) + stdoutBackendFormatted := logging.NewBackendFormatter(stdoutBackend, fileLogFormat) + mainLoggingBackend = logging.SetBackend(obFileBackendFormatted, stdoutBackendFormatted) logging.SetLevel(logging.INFO, "") sqliteDB, err := initializeRepo(config.RepoPath, "", "", true, time.Now(), wi.Bitcoin) @@ -282,7 +284,7 @@ func NewNodeWithConfig(config *NodeConfig, password string, mnemonic string) (*N Datastore: sqliteDB, MasterPrivateKey: mPrivKey, Multiwallet: mw, - OfflineMessageFailoverTimeout: 5 * time.Second, + OfflineMessageFailoverTimeout: 3 * time.Second, PushNodes: pushNodes, RepoPath: config.RepoPath, UserAgent: core.USERAGENT, @@ -324,6 +326,13 @@ func (n *Node) startIPFSNode(repoPath string, config *ipfscore.BuildCfg) (*ipfsc n.cancel = cancel ctx := commands.Context{} + + ipfscore.DefaultBootstrapConfig = ipfscore.BootstrapConfig{ + MinPeerThreshold: 8, + Period: time.Second * 10, + ConnectionTimeout: time.Second * 10 / 3, + } + nd, err := ipfscore.NewNode(cctx, config) if err != nil { return nil, ctx, err diff --git a/net/retriever/retriever.go b/net/retriever/retriever.go index 82c8b5753e..a7399a28dc 100644 --- a/net/retriever/retriever.go +++ b/net/retriever/retriever.go @@ -91,24 +91,25 @@ func NewMessageRetriever(cfg MRConfig) *MessageRetriever { WaitGroup: new(sync.WaitGroup), } - mr.Add(1) + mr.Add(2) return &mr } func (m *MessageRetriever) Run() { dht := time.NewTicker(time.Hour) - peers := time.NewTicker(time.Minute * 10) + peers := time.NewTicker(time.Minute) defer dht.Stop() defer peers.Stop() - go m.fetchPointers(true) + go m.fetchPointersFromDHT() + go m.fetchPointersFromPushNodes() for { select { case <-dht.C: m.Add(1) - go m.fetchPointers(true) + go m.fetchPointersFromDHT() case <-peers.C: m.Add(1) - go m.fetchPointers(false) + go m.fetchPointersFromPushNodes() } } } @@ -116,41 +117,44 @@ func (m *MessageRetriever) Run() { // RunOnce - used to fetch messages only once func (m *MessageRetriever) RunOnce() { m.Add(1) - go m.fetchPointers(true) + go m.fetchPointersFromDHT() m.Add(1) - go m.fetchPointers(false) + go m.fetchPointersFromPushNodes() } -func (m *MessageRetriever) fetchPointers(useDHT bool) { +func (m *MessageRetriever) fetchPointersFromDHT() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - wg := new(sync.WaitGroup) - downloaded := 0 mh, _ := multihash.FromB58String(m.node.Identity.Pretty()) peerOut := make(chan ps.PeerInfo) go func(c chan ps.PeerInfo) { - pwg := new(sync.WaitGroup) - pwg.Add(1) - go func(c chan ps.PeerInfo) { - out := m.getPointersDataPeers() - for p := range out { - c <- p - } - pwg.Done() - }(c) - if useDHT { - pwg.Add(1) - go func(c chan ps.PeerInfo) { - iout := ipfs.FindPointersAsync(m.routing, ctx, mh, m.prefixLen) - for p := range iout { - c <- p - } - pwg.Done() - }(c) + iout := ipfs.FindPointersAsync(m.routing, ctx, mh, m.prefixLen) + for p := range iout { + c <- p + } + close(c) + + }(peerOut) + + m.downloadMessages(peerOut) +} + +func (m *MessageRetriever) fetchPointersFromPushNodes() { + peerOut := make(chan ps.PeerInfo) + go func(c chan ps.PeerInfo) { + out := m.getPointersDataPeers() + for p := range out { + c <- p } - pwg.Wait() close(c) + }(peerOut) + m.downloadMessages(peerOut) +} + +func (m *MessageRetriever) downloadMessages(peerOut chan ps.PeerInfo) { + wg := new(sync.WaitGroup) + downloaded := 0 inFlight := make(map[string]bool) // Iterate over the pointers, adding 1 to the waitgroup for each pointer found @@ -239,7 +243,7 @@ func (m *MessageRetriever) fetchIPFS(pid peer.ID, n *core.IpfsNode, addr ma.Mult var err error go func() { - ciphertext, err = ipfs.Cat(n, addr.String(), time.Minute*5) + ciphertext, err = ipfs.Cat(n, addr.String(), time.Second*10) c <- struct{}{} }() diff --git a/net/service/messagesender.go b/net/service/messagesender.go index c2df2172ac..8407aa68cb 100644 --- a/net/service/messagesender.go +++ b/net/service/messagesender.go @@ -111,8 +111,9 @@ func (ms *messageSender) prep() error { if ms.s != nil { return nil } - - nstr, err := ms.service.host.NewStream(ms.service.ctx, ms.p, ipfs.IPFSProtocolAppMainnetOne) + ctx, cancel := context.WithTimeout(ms.service.ctx, 3*time.Second) + defer cancel() + nstr, err := ms.service.host.NewStream(ctx, ms.p, ipfs.IPFSProtocolAppMainnetOne) if err != nil { return err } diff --git a/repo/listing.go b/repo/listing.go index 92c80a232b..e555697c4f 100644 --- a/repo/listing.go +++ b/repo/listing.go @@ -185,6 +185,18 @@ func UpdateListing(r []byte, isTestnet bool, dstore *Datastore, repoPath string) if err != nil { return Listing{}, err } + skus := ld.Item.Skus + for _, sku := range skus { + if sku.BigSurcharge == "" { + sku.BigSurcharge = "0" + } + if sku.BigQuantity == "" { + sku.BigQuantity = "0" + } + } + + ld.Item.Skus = skus + slug := ld.Slug exists, err := listingExists(slug, repoPath, isTestnet) if err != nil { diff --git a/wallet/listeners/transaction_listener.go b/wallet/listeners/transaction_listener.go index 1a9973ebca..6210301f04 100644 --- a/wallet/listeners/transaction_listener.go +++ b/wallet/listeners/transaction_listener.go @@ -90,8 +90,6 @@ func (l *TransactionListener) cleanupOrderState(isSale bool, contract *pb.Ricard } func (l *TransactionListener) OnTransactionReceived(cb wallet.TransactionCallback) { - log.Info("Transaction received", cb.Txid, cb.Height) - l.Lock() defer l.Unlock() for _, output := range cb.Outputs {