Skip to content

server/msgBook: atomic seq updates with respect to order book contents#2

Open
norwnd wants to merge 2 commits into
masterfrom
server-msgBook-consider-atomic-seq-updates
Open

server/msgBook: atomic seq updates with respect to order book contents#2
norwnd wants to merge 2 commits into
masterfrom
server-msgBook-consider-atomic-seq-updates

Conversation

@norwnd
Copy link
Copy Markdown
Owner

@norwnd norwnd commented Mar 8, 2023

seq updates on server for msgBook are not atomic with respect to order book contents, this means 2 clients (or even 1 client sending 2 requests in parallel) can see different order book contents for the same seq number (e.g. one order book snapshot already including last book_order/update_remaining/unbook_order update effects, while the other snapshot lacking those because that update technically belongs to the next seq and is only there for a brief period of time because there is no atomicity there)

which, in turn, means:

  1. client has to handle it with extra care to avoid applying the effects of the same update twice (e.g. client got snapshot with latest update applied already, but he also can get same update notification with seq+1 afterwards); currently dexc resolves such redundant book_order/unbook_order notifications by checking order existence in OrderBook.orders map but doesn't seem to do anything that would prevent update_remaining from applying twice (which is another way we can get to app: ignore zero-quantity book_order updates decred/dcrdex#1543)
  2. if client were to issue multiple concurrent subscribe/resubscribe requests it probably opens lots more possibilities to get screwed, but we prevent those requests from running concurrently (in client/core: OrderBook update notifications races #1) for other reasons too; so that's off the table
  3. if somebody takes periodic server order book snapshots, and, say, counts how much buy/sell orders there is in the book (for debuging/stats-gathering purposes or whatnot) he can't rely on this giving him exact results because of that extra ghost update that might be present in the older snapshot (of 2 consecutive snapshots seq and seq+1); if server is running in VM and it gets frozen at just the right instruction for a sec ... to resume later ... or something like that; gotta be pretty unlikely to happen in practice, probably also off the table too

It's not an issue per se? I think it is, see 1) above.
Overall, it's a tradeoff that leaves more room for shooting yourself in the foot for seemingly no good reason.

This PR adds aforementioned atomicity property.

@norwnd norwnd force-pushed the server-msgBook-consider-atomic-seq-updates branch from 3083cf1 to a6fb6f7 Compare March 8, 2023 06:47
Comment on lines 562 to 565
func (r *BookRouter) msgOrderBook(book *msgBook) *msgjson.OrderBook {
book.mtx.RLock()
defer book.mtx.RUnlock()

if !book.running {
// Don't want to block client requests for too long, so return fast if order book
// isn't initialized yet instead of proceeding to wait on mutex below for who
// knows how long.
if !book.running.Load() {
return nil
}
Copy link
Copy Markdown
Owner Author

@norwnd norwnd Mar 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this was the original intent (see the comment I added there) for having running flag there, it didn't work because client request would block on book.mtx before order book is available or not. Or is there any other purpose for running ?

Or maybe it just got out of date. Moved running from under book.mtx.RLock()/book.mtx.RUnlock() section for now.

@norwnd
Copy link
Copy Markdown
Owner Author

norwnd commented Mar 8, 2023

Just to clarify this is the expected behavior (it seems to work like that on master now):

  • for until msgBook is ready (running=true) we are returning error response along the lines of market not running to clients
  • for suspended market we return empty book (which isn't exactly the same as returning error) or frozen order book (depending on persist flag value)

@norwnd norwnd force-pushed the master branch 4 times, most recently from ad9d264 to e298e04 Compare November 24, 2024 18:25
@norwnd norwnd force-pushed the master branch 5 times, most recently from f9959eb to a66bbae Compare January 10, 2025 06:09
@norwnd norwnd force-pushed the master branch 3 times, most recently from e3c487c to 333e9f6 Compare January 18, 2025 13:45
norwnd pushed a commit that referenced this pull request Apr 13, 2026
…decred#3121)

* client: Use the app build version as Version in UI in hamburger menu #2.

	- This is a rework of decred#3096 and keeps the Build ID in the
	  settings dialog.

	- Webpack Build ID for caching site/dist build will be
	  addressed in another PR if required.

* client: Re-work profile dropdown to show simplified, user-facing app version

* client,webserver: re-work to modify config per JoeGruff suggestions #2

* client,app,webserver: Remove un-needed configuration variables.

---------

Co-authored-by: dev-warrior777 <>
norwnd pushed a commit that referenced this pull request Apr 13, 2026
* multi: Add Monero wallet - Phase I

        Add an XMR wallet that can:
        - Configure a monerod
        - configure and run monero rpc server
        - Send, Receive & Withdraw funds
	- Live reconfigure fee priority
	- Rescan wallet transactions
	- Tx Fee estimation
	- New sub-addresses

* module: updated tag for go-monero to v0.1.1

* modules: Ran `go mod tidy` on loadbot & bisonw-desktop

* client: Changes for Marton's review.

	Note: remote daemon login removed. It is unused by any
	remote daemons on <https://monero.fail> which all seem
	to be configured as 'restricted'. That means the RPCs
	they can answer are restricted in the monero code itself.

* multi: Wallet sync working and type changed to seeded

	- Use monero-wallet-cli for initial sync
	- Enable wallet password storeage in os keystore
	- Allow 2 simnet wallet-rpc servers for simnet

* test: disable xmrlive test

* bisonw-desktop: run go mod tidy

* xmr: Add minimal tx parser to inspect Vout

* xmr: Add version checking and other tests

* multi: lock user while syncing, update keystore

	- app starts locked and user cannot unlock during initial sync
	- refactor keystore and tests

* test: commented out TestKeystore

* xmr: remove offending comments

* test,backend: Get simnet working

	- scripts and support to enable simnet development
	- added minimal back end code

* client,asset: Add new interface Sender to send block unlock time

	// Sender sends with more granular control parameters
	type Sender interface {
		// SendAndLock sends the exact value to the specified address with an unlock time.
		// This can be n blocks or n milliseconds depending on interpretation.
		SendAndLock(address string, value uint64, unlock uint64, feeRate uint64) (Coin, error)
	}

* testing/doc: Tidy up some loose ends

* client/server: Fixes for JoeGruff review and comments

	- Increased WalletServerInitializeWait to 5s and used select to allow context cancel.
	- Removed the "Unlock button while syncing" logic.
	- Other minor changes

* client: Simplify start wallet server logic

* tools: Remove run_tests_no_bw_dsktp.sh

* client: Remove testing for <= reccomended version

* merge conflict:

* docs: Update main README for v0.18.4.2

* multi: Update the go-monero dependency repo

	go-monero is a wrapper library on monero RPC's

	- previous repo: github.com/dev-warrior777/go-monero
	- current  repo: github.com/bisoncraft/go-monero

	Also: answered most of JoeGruffins review #2. any
	outstanding issues will be addressed in a new PR.

---------

Co-authored-by: dev-warrior777 <>
norwnd pushed a commit that referenced this pull request Apr 16, 2026
Three small follow-ups from the B-L5 SettingsPage cleanup observations.

1) Hoist DCRAssetID to a shared constant in stores/types.ts.
   Previously SettingsPage defined a local `DCR_ASSET_ID = 42` and
   ProposalPage hardcoded `|| 42` as the default `assetID` from the
   URL. Both refer to the same DCR BIP-44 coin type. Now both import
   `DCRAssetID` from `stores/types.ts`, sitting next to `PrepaidBondID`.
   No behavior change -- just removes drift risk.

2) Add loading state to the Change App Password form. Mirrors the
   SP-06 export-seed pattern and vanilla `settings.ts` `changeAppPW()`
   (L450) `app().loading(page.changeAppPW)`. While the
   `/api/changeapppass` round trip is in flight: all three password
   inputs are `disabled`, and the Submit button shows `'...'`.
   Without this, the user could click Submit multiple times or
   navigate the form mid-flight.

3) Lock the import-account file picker + Remove button while
   `importLoading` is true. Same defensive pattern as #2 -- prevents
   the user from changing the file selection while the previous
   upload is in flight.

Build clean (46 pre-existing warnings, zero errors).
norwnd pushed a commit that referenced this pull request Apr 16, 2026
Second T18 batch — four more items from the consolidation list.

T18#5: formatProfit duplication
- Hoisted `formatProfit(profit)` to `hooks/useFormatters.ts` and
  deleted the local copies in MMPage.tsx and MMArchivesPage.tsx.
  The two versions were identical modulo the result-field name
  (`cls` vs `colorClass`). Standardized on `cls` at the shared
  location; updated MMArchivesPage's two call sites
  (`total.colorClass`, `p.colorClass`) to `total.cls` / `p.cls`.

T18#3: MM URL building consistency
- MMArchivesPage's two navigation buttons previously built URLs via
  manual template strings with individual encodeURIComponent calls.
  Refactored to use URLSearchParams like MMPage.tsx does. Cleaner
  and handles encoding automatically (though the previous manual
  encoding was also correct).

T18#8: manage peers concurrent removal race
- Added a `removingAddrs: Set<string>` state to ManagePeers. The
  removePeer callback now bails out if a removal POST for the same
  address is already in flight, and the Remove icon for that row
  renders as a spinner while the removal is pending. Uses
  functional setState so rapid-fire clicks on different rows
  don't read stale closure state. Prevents the last-one-wins
  refresh() race when the user double-clicks the Remove icon.

T18#2: mw-500 consolidation
- Deleted `#proposals { max-width: 500px; width: 100% }` rule from
  css/proposals.scss. ProposalsPage's `<section>` now uses the
  shared `mw-500` utility class (already defined in
  css/utilities.scss and already used by ProposalPage). Removed
  the `id="proposals"` attribute since nothing else referenced it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant