Skip to content

Commit

Permalink
review chnages
Browse files Browse the repository at this point in the history
Signed-off-by: Philemon Ukane <ukanephilemon@gmail.com>
  • Loading branch information
ukane-philemon committed Nov 10, 2023
1 parent 01a2eaa commit b0d7f8e
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 183 deletions.
122 changes: 77 additions & 45 deletions dexcore/core.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dexcore

import (
"context"
"fmt"
"path/filepath"
"sync"
Expand All @@ -11,28 +12,77 @@ import (
libutils "github.com/crypto-power/cryptopower/libwallet/utils"
)

type DEXCore struct {
// Implements the DEXCore interface.
type dexCore struct {
*core.Core

shutdownChan <-chan struct{}
bondBufMtx sync.Mutex
bondBufferCache map[uint32]valStamp
log dex.Logger
}

// New returns a *DEXCore that satisfies Core.
func New(root, lang string, net libutils.NetworkType, log dex.Logger) (*DEXCore, error) {
// Shutdown returns a chan that will be closed if core exits.
func (dc *dexCore) Shutdown() <-chan struct{} {
return dc.shutdownChan
}

type valStamp struct {
val uint64
stamp time.Time
}

// BondsFeeBuffer is a caching helper for the bonds fee buffer because
// (*Core).BondsFeeBuffer returns a fresh fee buffer based on a current (but
// padded) fee rate estimate. Values for a given asset are cached for 45
// minutes. These values are meant to provide a sensible but well-padded fee
// buffer for bond transactions now and well into the future, so a long expiry
// is appropriate.
func (dc *dexCore) BondsFeeBuffer(assetID uint32) (feeBuffer uint64) {
const expiry = 45 * time.Minute
dc.bondBufMtx.Lock()
defer dc.bondBufMtx.Unlock()
if buf, ok := dc.bondBufferCache[assetID]; ok && time.Since(buf.stamp) < expiry {
dc.log.Tracef("Using cached bond fee buffer (%v old): %d",
time.Since(buf.stamp), feeBuffer)
return buf.val
}

feeBuffer, err := dc.Core.BondsFeeBuffer(assetID)
if err != nil {
dc.log.Error("Error fetching bond fee buffer: %v", err)
return 0
}

dc.log.Tracef("Obtained fresh bond fee buffer: %d", feeBuffer)
dc.bondBufferCache[assetID] = valStamp{feeBuffer, time.Now()}

return feeBuffer
}

// Client represents the Decred DEX client. Consumers should always check if the
// DEXCore.Ready() channel is closed before requesting data from or sending data
// to the DEX client. This allows for custom handling when DEX is not ready.
type Client struct {
DEXCore
}

func StartDEXClient(ctx context.Context, root, lang, logDir, logLvl string, net libutils.NetworkType, maxLogZips int) (*Client, error) {
dexNet, err := parseDEXNet(net)
if err != nil {
return nil, fmt.Errorf("error parsing network: %w", err)
}

// Use cryptopower's network data directory in core so we don't have to
// manage two different network directories for dex db incase we are running
// simnet or regnet.
dbPath := filepath.Join(root, string(net), "dexc.db")
logger, logCloser, err := newDexLogger(logDir, logLvl, maxLogZips)
if err != nil {
return nil, err
}

dbPath := filepath.Join(root, "dexc.db")
cfg := &core.Config{
DBPath: dbPath,
Net: dexNet,
Logger: log,
Logger: logger,
Language: lang,
UnlockCoinsOnLogin: false, // TODO: Make configurable.
}
Expand All @@ -42,11 +92,25 @@ func New(root, lang string, net libutils.NetworkType, log dex.Logger) (*DEXCore,
return nil, fmt.Errorf("failed to initialize dex core: %w", err)
}

return &DEXCore{
Core: clientCore,
bondBufferCache: make(map[uint32]valStamp),
log: log,
}, nil
shutdownChan := make(chan struct{})
dc := &Client{
DEXCore: &dexCore{
Core: clientCore,
bondBufferCache: make(map[uint32]valStamp),
shutdownChan: shutdownChan,
log: logger,
},
}

// Use a goroutine to start dex core as it'll blocks until dex core exits.
go func() {
dc.Run(ctx)
close(shutdownChan)
dc.DEXCore = nil
logCloser()
}()

return dc, nil
}

func parseDEXNet(net libutils.NetworkType) (dex.Network, error) {
Expand All @@ -61,35 +125,3 @@ func parseDEXNet(net libutils.NetworkType) (dex.Network, error) {
return 0, fmt.Errorf("unknown network %s", net)
}
}

type valStamp struct {
val uint64
stamp time.Time
}

// BondsFeeBuffer is a caching helper for the bonds fee buffer because
// (*Core).BondsFeeBuffer returns a fresh fee buffer based on a current (but
// padded) fee rate estimate. Values for a given asset are cached for 45
// minutes. These values are meant to provide a sensible but well-padded fee
// buffer for bond transactions now and well into the future, so a long expiry
// is appropriate.
func (dc *DEXCore) BondsFeeBuffer(assetID uint32) (feeBuffer uint64) {
const expiry = 45 * time.Minute
dc.bondBufMtx.Lock()
defer dc.bondBufMtx.Unlock()
if buf, ok := dc.bondBufferCache[assetID]; ok && time.Since(buf.stamp) < expiry {
feeBuffer = buf.val
dc.log.Tracef("Using cached bond fee buffer (%v old): %d",
time.Since(buf.stamp), feeBuffer)
} else {
var err error
feeBuffer, err = dc.Core.BondsFeeBuffer(assetID)
if err != nil {
dc.log.Error("Error fetching bond fee buffer: %v", err)
return 0
}
dc.log.Tracef("Obtained fresh bond fee buffer: %d", feeBuffer)
dc.bondBufferCache[assetID] = valStamp{feeBuffer, time.Now()}
}
return
}
5 changes: 3 additions & 2 deletions ui/page/dcrdex/dex_interface.go → dexcore/dex_interface.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package dcrdex
package dexcore

import (
"context"

"decred.org/dcrdex/client/core"
)

type Core interface {
type DEXCore interface {
Run(ctx context.Context)
Ready() <-chan struct{}
Shutdown() <-chan struct{}
IsInitialized() bool
InitializeClient(pw, seed []byte) error
DiscoverAccount(dexAddr string, pass []byte, certI any) (*core.Exchange, bool, error)
Expand Down
4 changes: 2 additions & 2 deletions dexcore/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (

var dexLogFile = "dexc.log"

// NewDexLogger initializes a new dex.Logger.
func NewDexLogger(logDir, lvl string, maxRolls int) (dex.Logger, func(), error) {
// newDexLogger initializes a new dex.Logger.
func newDexLogger(logDir, lvl string, maxRolls int) (dex.Logger, func(), error) {
err := os.MkdirAll(logDir, libutils.UserFilePerm)
if err != nil {
return nil, nil, fmt.Errorf("failed to create log directory: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion libwallet/assets/btc/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func LoadExisting(w *sharedW.Wallet, params *sharedW.InitParams) (sharedW.Asset,
return btcWallet, nil
}

// SafelyCancelSync shuts down all the upstream processes. If not explicity
// SafelyCancelSync shuts down all the upstream processes. If not explicitly
// deleting a wallet use asset.CancelSync() instead.
func (asset *Asset) SafelyCancelSync() {
if asset.IsConnectedToNetwork() {
Expand Down
2 changes: 0 additions & 2 deletions libwallet/assets_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ type AssetsManager struct {
InstantSwap *instantswap.InstantSwap
ExternalService *ext.Service
RateSource ext.RateSource

MaxLogZips int
}

// initializeAssetsFields validate the network provided is valid for all assets before proceeding
Expand Down
4 changes: 1 addition & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@ func main() {
return
}

assetsManager.MaxLogZips = cfg.MaxLogZips

// if debuglevel is passed at commandLine persist the option.
if cfg.DebugLevel != "" && assetsManager.IsAssetManagerDB() {
assetsManager.SetLogLevels(cfg.DebugLevel)
Expand All @@ -84,7 +82,7 @@ func main() {
logger.SetLogLevels(assetsManager.GetLogLevels())
}

win, err := ui.CreateWindow(assetsManager, Version, buildDate)
win, err := ui.CreateWindow(assetsManager, Version, buildDate, cfg.MaxLogZips)
if err != nil {
log.Errorf("Could not initialize window: %s\ns", err)
return
Expand Down
8 changes: 7 additions & 1 deletion ui/load/appinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ type AppInfo struct {
version string
buildDate time.Time
startUpTime time.Time
maxLogZips int
}

// StartApp returns an instance of AppInfo with the startUpTime set to the current time.
func StartApp(version string, buildDate time.Time) *AppInfo {
func StartApp(version string, buildDate time.Time, maxLogZips int) *AppInfo {
return &AppInfo{
version: version,
buildDate: buildDate,
startUpTime: time.Now(),
maxLogZips: maxLogZips,
}
}

Expand All @@ -31,3 +33,7 @@ func (app *AppInfo) Version() string {
func (app *AppInfo) StartupTime() time.Time {
return app.startUpTime
}

func (app *AppInfo) MaxLogZips() int {
return app.maxLogZips
}
41 changes: 17 additions & 24 deletions ui/page/dcrdex/dcrdex_page.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,16 @@ type DEXPage struct {

*load.Load

dexCore Core
inited bool // TODO: Set value
dexc *dexcore.Client // Might be nil

generalSettingsBtn cryptomaterial.Button
openTradeMainPage *cryptomaterial.Clickable
}

func NewDEXPage(l *load.Load, dexCore Core) *DEXPage {
func NewDEXPage(l *load.Load, dexc *dexcore.Client) *DEXPage {
pg := &DEXPage{
Load: l,
MasterPage: app.NewMasterPage(DCRDEXPageID),
openTradeMainPage: l.Theme.NewClickable(false),
dexCore: dexCore,
Load: l,
dexc: dexc,
generalSettingsBtn: l.Theme.Button(values.StringF(values.StrEnableAPI, values.String(values.StrExchange))),
}

Expand All @@ -56,9 +53,14 @@ func (pg *DEXPage) ID() string {
// displayed.
// Part of the load.Page interface.
func (pg *DEXPage) OnNavigatedTo() {
if pg.dexc == nil {
return

Check failure on line 57 in ui/page/dcrdex/dcrdex_page.go

View workflow job for this annotation

GitHub Actions / Build

File is not `goimports`-ed (goimports)
}

if pg.CurrentPage() == nil {
// TODO: Handle pg.inited
pg.Display(NewDEXOnboarding(pg.Load, pg.dexCore))
// TODO: Check if user is yet to connect to a DEX server. If user is
// connected, display the markets page instead.
pg.Display(NewDEXOnboarding(pg.Load, pg.dexc))
} else {
pg.CurrentPage().OnNavigatedTo()
}
Expand All @@ -72,26 +74,20 @@ func (pg *DEXPage) Layout(gtx C) D {
privacyModeOff := pg.WL.AssetsManager.IsHTTPAPIPrivacyModeOff(utils.ExchangeHTTPAPI)
var msg string
var actionBtn *cryptomaterial.Button
if !hasMultipleWallets {
msg = values.String(values.StrMultipleAssetTypeRequiredToTradeDEX)
} else if !privacyModeOff {
if !privacyModeOff {
actionBtn = &pg.generalSettingsBtn
msg = values.StringF(values.StrNotAllowed, values.String(values.StrExchange))
} else if dexCore, _ := pg.dexCore.(*dexcore.DEXCore); dexCore == nil {
} else if !hasMultipleWallets {
msg = values.String(values.StrMultipleAssetTypeRequiredToTradeDEX)
} else if pg.dexc == nil {
msg = values.String(values.StrDEXInitErrorMsg)
}

if msg != "" {
gtxCopy := gtx
gtx = gtx.Disabled() // Disable main page from receiving events.
return components.DisablePageWithOverlay(pg.Load, nil, gtxCopy, msg, actionBtn)
return components.DisablePageWithOverlay(pg.Load, nil, gtx, msg, actionBtn)
}

return cryptomaterial.LinearLayout{
Width: cryptomaterial.MatchParent,
Height: cryptomaterial.MatchParent,
Orientation: layout.Vertical,
}.Layout2(gtx, pg.CurrentPage().Layout)
return pg.CurrentPage().Layout(gtx)
}

// isMultipleAssetTypeWalletAvailable checks if multiple asset types are
Expand All @@ -118,9 +114,6 @@ func (pg *DEXPage) HandleUserInteractions() {
pg.ParentWindow().Display(settings.NewSettingsPage(pg.Load))
}

if pg.openTradeMainPage.Clicked() {
pg.ParentNavigator().CloseCurrentPage()
}
if pg.CurrentPage() != nil {
pg.CurrentPage().HandleUserInteractions()
}
Expand Down

0 comments on commit b0d7f8e

Please sign in to comment.