-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
client/{webserver,app}: Update Market Making UI #2491
Conversation
client/mm/mm.go
Outdated
syncedOracleMtx sync.RWMutex | ||
syncedOracle *priceOracle | ||
|
||
unsyncedOracle *priceOracle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please doc the difference between syncedOracle
and unsyncedOracle
.
client/mm/mm.go
Outdated
m.syncedOracleMtx.RUnlock() | ||
if err != nil && !errors.Is(err, errUnsyncedMarket) { | ||
m.log.Errorf("failed to get oracle info for market %d-%d: %v", base, quote, err) | ||
} | ||
if err == nil { | ||
return &MarketReport{ | ||
Price: price, | ||
Oracles: oracles, | ||
BaseFiatRate: baseFiatRate, | ||
QuoteFiatRate: quoteFiatRate, | ||
}, nil | ||
} | ||
} | ||
m.syncedOracleMtx.RUnlock() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this double RUnlock
if err != nil
?
client/mm/mm.go
Outdated
user := m.core.User() | ||
baseFiatRate := user.FiatRates[base] | ||
quoteFiatRate := user.FiatRates[quote] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
User
is a bit much. Maybe buck54321/dcrdex@42a3766...buck54321:dcrdex:core-fiat-rates
client/webserver/api.go
Outdated
func (s *WebServer) getMarketMakingConfig() ([]*mm.BotConfig, error) { | ||
cfg := []*mm.BotConfig{} | ||
if s.mmCfgPath != "" { | ||
data, err := ioutil.ReadFile(s.mmCfgPath) | ||
if err == nil { | ||
err = json.Unmarshal(data, &cfg) | ||
if err != nil { | ||
return nil, fmt.Errorf("error unmarshalling market making config: %v", err) | ||
} | ||
} else if !os.IsNotExist(err) { | ||
return nil, fmt.Errorf("error reading file: %v", err) | ||
} | ||
} | ||
|
||
return cfg, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Less indentation is better
func (s *WebServer) getMarketMakingConfig() ([]*mm.BotConfig, error) {
cfg := []*mm.BotConfig{}
if s.mmCfgPath == "" {
return cfg, nil
}
data, err := os.ReadFile(s.mmCfgPath)
if err == nil {
return cfg, json.Unmarshal(data, &cfg)
}
if os.IsNotExist(err) {
return cfg, nil
}
return nil, fmt.Errorf("error reading file: %w", err)
}
client/mm/mm.go
Outdated
noteMtx sync.RWMutex | ||
noteChans map[uint64]chan core.Notification |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused now.
client/webserver/api.go
Outdated
err = ioutil.WriteFile(s.mmCfgPath, data, 0644) | ||
if err != nil { | ||
s.writeAPIError(w, fmt.Errorf("error writing market making config: %v", err)) | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the roles are confused here. Handling config files for the MarketMaker
falls squarely under the purview of the MarketMaker
. Please consider buck54321/dcrdex@94eec59...buck54321:dcrdex:config-roles
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I'm also adding an alternate config file path to MarketMaker.Run
so that the RPC server can use whatever file the user specifies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it this way because when using the RPC server, I think it would be more convenient if you could just specify the path to the config file instead of having to first update the config and then run it. Should Run
take an alternate config file path and if it is nil, then the configured one is used.
client/webserver/api.go
Outdated
return | ||
} | ||
|
||
err = ioutil.WriteFile(s.mmCfgPath, data, 0644) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ioutil
is deprecated. Use os.WriteFile
.
tsconfigRootDir: './' | ||
tsconfigRootDir: __dirname |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you comment on this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This allows eslint to be run from the command line.
3205c06
to
b57a3aa
Compare
client/asset/interface.go
Outdated
QuoteAssetOnly bool `json:"quoteAssetOnly"` | ||
// DependsOn is the key of another config option that if is set to true, | ||
// this config option will be shown. | ||
DependsOn string `json:"dependsOn"` | ||
Range *XYRange `json:"range"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of adding QuoteAssetOnly
here, did you consider making WalletDefinition.MultiFundingOpts []*ConfigOption
into an []*OrderOption
instead? OrderOption
already has a Range
field, and QuoteAssetOnly
is an order-specific configuration option that would fit nicely there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
client/webserver/site/src/js/mm.ts
Outdated
this.updateProgramDiv(tmpl, report) | ||
this.programs[report.programID] = Object.assign({ tmpl, div }, report) | ||
return div | ||
console.log(JSON.stringify(filteredMkts)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to leave this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope.
If I navigate to stack trace
If I navigate to Maybe I am doing something wrong? I forgot how to navigate to these pages in the UI... |
@JoeGruffins I'm unable to reproduce this.. works fine for me with the same build ID. The market making tab is in the hamburger menu, and you get to the |
client/webserver/webserver.go
Outdated
apiAuth.Post("/startmarketmaking", s.apiStartMarketMaking) | ||
apiAuth.Post("/stopmarketmaking", s.apiStopMarketMaking) | ||
apiAuth.Get("/marketmakingconfig", s.apiMarketMakingConfig) | ||
apiAuth.Post("/updatemarketmakingconfig", s.apiUpdateMarketMakingConfig) | ||
apiAuth.Post("/removemarketmakingconfig", s.apiRemoveMarketMakingConfig) | ||
apiAuth.Get("/marketmakingstatus", s.apiMarketMakingStatus) | ||
apiAuth.Post("/marketreport", s.apiMarketReport) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the cause of @JoeGruffins panic. No --experimental
flag, no market maker, but he manually navigated to /mm
. Not something that a normal user would think to do. be we shouldn't be adding these endpoints if --experimental
is not on anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh sorry, that is it. Will build run with the experimental flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Running with the --experimental
flag now.
If I navigate to /mmsettings
without a token it will still look like the odd page posted above.
Also maybe the cancel
on the /mmsettings
screen would be better as back
? After you change the settings you want to go back and not cancel.
It doesn't seem to save when I unclick "Empty Market Rate"
The delete x for entire bots could use a confirmation dialog imo.
Updates the market making UI to reflect the updated way in which market making works. A JSON configuration file, the same that would be used by the RPC server, is stored on disk, and the UI gives users an interactive way to read/update the config file, and also to start/stop market making. The updated UI includes two screens, `/mm` and `/mmsettings`. `/mm` allows users to see each of the market for which a market maker is configured, allows the user to add/remove market makers, and links to the `/mmsettings` page of each market maker. The `/mmsettings` page allows users to configure each setting of each of the market makers. The markets page is also updated to not allow users to place orders manually while market making is running.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting a panic when not running with experimental. This time just navigating to a market, not messing with the new endpoints:
panic
2023/09/21 14:35:24 http: panic serving 127.0.0.1:39028: runtime error: slice bounds out of range [-1:]
goroutine 2788 [running]:
net/http.(*conn).serve.func1()
/usr/lib/go/src/net/http/server.go:1868 +0xb9
panic({0x19e5720?, 0xc0013a1170?})
/usr/lib/go/src/runtime/panic.go:920 +0x270
github.com/go-chi/chi/v5/middleware.prettyStack.decorateFuncCallLine({}, {0xc001ad486c, 0x1f}, 0xd6?, 0x8)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/recoverer.go:130 +0x525
github.com/go-chi/chi/v5/middleware.prettyStack.decorateLine({}, {0xc001ad486c?, 0x11e9?}, 0xd0?, 0x1?)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/recoverer.go:106 +0x151
github.com/go-chi/chi/v5/middleware.prettyStack.parse({}, {0xc001afc000, 0x11e9, 0xc00094d278?}, {0x1855260, 0x313d860})
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/recoverer.go:89 +0x3d0
github.com/go-chi/chi/v5/middleware.PrintPrettyStack({0x1855260, 0x313d860})
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/recoverer.go:46 +0x3b
github.com/go-chi/chi/v5/middleware.(*defaultLogEntry).Panic(0x2?, {0x1855260?, 0x313d860?}, {0xc0016b1860?, 0x3?, 0xc0013a1143?})
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/logger.go:165 +0x25
github.com/go-chi/chi/v5/middleware.Recoverer.func1.1()
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/recoverer.go:28 +0xc8
panic({0x1855260?, 0x313d860?})
/usr/lib/go/src/runtime/panic.go:914 +0x21f
decred.org/dcrdex/client/mm.(*MarketMaker).Running(...)
/home/joe/git/dcrdex/client/mm/mm.go:213
decred.org/dcrdex/client/webserver.(*WebServer).apiMarketMakingStatus(0xc0008ca0c0, {0x7fd158505078, 0xc0017d3480}, 0x1000000000001?)
/home/joe/git/dcrdex/client/webserver/api.go:1854 +0x25
net/http.HandlerFunc.ServeHTTP(0xc0008ca0c0?, {0x7fd158505078?, 0xc0017d3480?}, 0x838457?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
decred.org/dcrdex/client/webserver.(*WebServer).rejectUnauthed-fm.(*WebServer).rejectUnauthed.func1({0x7fd158505078, 0xc0017d3480}, 0x1?)
/home/joe/git/dcrdex/client/webserver/middleware.go:133 +0x68
net/http.HandlerFunc.ServeHTTP(0xc0007a7d60?, {0x7fd158505078?, 0xc0017d3480?}, 0xc001a95370?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
github.com/go-chi/chi/v5.(*ChainHandler).ServeHTTP(0x1844760?, {0x7fd158505078?, 0xc0017d3480?}, 0xc0013a1140?)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/chain.go:31 +0x26
github.com/go-chi/chi/v5.(*Mux).routeHTTP(0xc0005d8f00, {0x7fd158505078, 0xc0017d3480}, 0xc001a9d900)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/mux.go:437 +0x1f4
net/http.HandlerFunc.ServeHTTP(0x0?, {0x7fd158505078?, 0xc0017d3480?}, 0x45979c?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
github.com/go-chi/chi/v5/middleware.AllowContentType.func1.1({0x7fd158505078?, 0xc0017d3480?}, 0xc0013a1141?)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/content_type.go:31 +0x110
net/http.HandlerFunc.ServeHTTP(0xc00094d7d0?, {0x7fd158505078?, 0xc0017d3480?}, 0xc00094d7b0?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
github.com/go-chi/chi/v5.(*Mux).ServeHTTP(0xc0005d8f00, {0x7fd158505078, 0xc0017d3480}, 0xc001a9d900)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/mux.go:71 +0x356
github.com/go-chi/chi/v5.(*Mux).Mount.func1({0x7fd158505078, 0xc0017d3480}, 0xc001a9d900)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/mux.go:312 +0x1bb
net/http.HandlerFunc.ServeHTTP(0x1844760?, {0x7fd158505078?, 0xc0017d3480?}, 0xc0013ad5f4?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
github.com/go-chi/chi/v5.(*Mux).routeHTTP(0xc0008a0360, {0x7fd158505078, 0xc0017d3480}, 0xc001a9d900)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/mux.go:437 +0x1f4
net/http.HandlerFunc.ServeHTTP(0xc0015a4928?, {0x7fd158505078?, 0xc0017d3480?}, 0x17bc1a0?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
github.com/go-chi/chi/v5/middleware.Recoverer.func1({0x7fd158505078?, 0xc0017d3480?}, 0xc001aad0e0?)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/recoverer.go:37 +0x78
net/http.HandlerFunc.ServeHTTP(0xf8?, {0x7fd158505078?, 0xc0017d3480?}, 0x1b8ecd1?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
decred.org/dcrdex/client/webserver.(*WebServer).securityMiddleware-fm.(*WebServer).securityMiddleware.func1({0x7fd158505078, 0xc0017d3480}, 0xc001aad100?)
/home/joe/git/dcrdex/client/webserver/middleware.go:34 +0x169
net/http.HandlerFunc.ServeHTTP(0xc001a9d800?, {0x7fd158505078?, 0xc0017d3480?}, 0x30?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
decred.org/dcrdex/client/webserver.New.RequestLogger.func3.1({0x25875a8, 0xc0013bf500}, 0xc001a9d800)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/middleware/logger.go:57 +0x16d
net/http.HandlerFunc.ServeHTTP(0x258a840?, {0x25875a8?, 0xc0013bf500?}, 0x3140330?)
/usr/lib/go/src/net/http/server.go:2136 +0x29
github.com/go-chi/chi/v5.(*Mux).ServeHTTP(0xc0008a0360, {0x25875a8, 0xc0013bf500}, 0xc001a9d700)
/home/joe/go/pkg/mod/github.com/go-chi/chi/v5@v5.0.1/mux.go:88 +0x315
net/http.serverHandler.ServeHTTP({0xc001aad050?}, {0x25875a8?, 0xc0013bf500?}, 0x6?)
/usr/lib/go/src/net/http/server.go:2938 +0x8e
net/http.(*conn).serve(0xc001aa2d80, {0x258a808, 0xc0008760c0})
/usr/lib/go/src/net/http/server.go:2009 +0x5f4
created by net/http.(*Server).Serve in goroutine 80
/usr/lib/go/src/net/http/server.go:3086 +0x5cb
@JoeGruffins Sorry I forgot to comment, the configuration of the config file changed since the Arbitrage strategy was added. Try deleting the config file.
I fixed the other issues, but not this one yet. I definitely agree with it though, and I'll come back to it once @buck54321 gives his more detailed UI review. |
Updates the market making UI to reflect the updated way in which market making works. A JSON configuration file, the same that would be used by the RPC server, is stored on disk, and the UI gives users an interactive way to read/update the config file, and also to start/stop market making.
The updated UI includes two screens,
/mm
and/mmsettings
./mm
allows users to see each of the market for which a market maker is configured, allows the user to add/remove market makers, and links to the/mmsettings
page of each market maker. The/mmsettings
page allows users to configure each setting of each of the market makers.The markets page is also updated to not allow users to place orders manually while market making is running.