@breeztech/breez-sdk-spark 0.20.0-dev1 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,6 +43,17 @@ const WRITE_LOCK_TIMEOUT_SECS = 30;
43
43
  const RESERVATION_TIMEOUT_SECS = 300;
44
44
  const SPENT_MARKER_CLEANUP_THRESHOLD_MS = 5 * 60 * 1000;
45
45
 
46
+ /**
47
+ * Leaves per INSERT when upserting a refreshed leaf set.
48
+ *
49
+ * A wallet can hold six figures of leaves, each serializing to a JSON blob
50
+ * carrying up to five transactions. The upsert goes through conn.query(),
51
+ * which interpolates its placeholders client-side, so the whole set would
52
+ * otherwise be built in memory as one statement and sent as one packet,
53
+ * against max_allowed_packet.
54
+ */
55
+ const LEAF_UPSERT_CHUNK_SIZE = 1000;
56
+
46
57
  /**
47
58
  * Slim projection: only (id, value) for leaves the selection might use.
48
59
  * Includes all leaves with value <= the max target (covers exact-match + the
@@ -958,32 +969,40 @@ class MysqlTreeStore {
958
969
 
959
970
  if (filtered.length === 0) return;
960
971
 
961
- const valueClauses = new Array(filtered.length)
962
- .fill("(?, ?, ?, ?, ?, ?, UTC_TIMESTAMP(6))")
963
- .join(", ");
964
- const params = [];
965
- for (const leaf of filtered) {
966
- params.push(
967
- this.identity,
968
- leaf.id,
969
- leaf.status,
970
- isMissingFromOperators ? 1 : 0,
971
- JSON.stringify(leaf),
972
- leaf.value
972
+ // All chunks run inside the caller's transaction, so the full set still
973
+ // lands atomically. UTC_TIMESTAMP(6) is re-evaluated per statement, so
974
+ // added_at can differ by microseconds between chunks; every value is still
975
+ // after the caller's refreshStartedAt, which is all the timestamp-based
976
+ // deletion in setLeaves depends on.
977
+ for (let i = 0; i < filtered.length; i += LEAF_UPSERT_CHUNK_SIZE) {
978
+ const chunk = filtered.slice(i, i + LEAF_UPSERT_CHUNK_SIZE);
979
+ const valueClauses = new Array(chunk.length)
980
+ .fill("(?, ?, ?, ?, ?, ?, UTC_TIMESTAMP(6))")
981
+ .join(", ");
982
+ const params = [];
983
+ for (const leaf of chunk) {
984
+ params.push(
985
+ this.identity,
986
+ leaf.id,
987
+ leaf.status,
988
+ isMissingFromOperators ? 1 : 0,
989
+ JSON.stringify(leaf),
990
+ leaf.value
991
+ );
992
+ }
993
+
994
+ await conn.query(
995
+ `INSERT INTO brz_tree_leaves (user_id, id, status, is_missing_from_operators, data, value, added_at)
996
+ VALUES ${valueClauses}
997
+ ON DUPLICATE KEY UPDATE
998
+ status = VALUES(status),
999
+ is_missing_from_operators = VALUES(is_missing_from_operators),
1000
+ data = VALUES(data),
1001
+ value = VALUES(value),
1002
+ added_at = UTC_TIMESTAMP(6)`,
1003
+ params
973
1004
  );
974
1005
  }
975
-
976
- await conn.query(
977
- `INSERT INTO brz_tree_leaves (user_id, id, status, is_missing_from_operators, data, value, added_at)
978
- VALUES ${valueClauses}
979
- ON DUPLICATE KEY UPDATE
980
- status = VALUES(status),
981
- is_missing_from_operators = VALUES(is_missing_from_operators),
982
- data = VALUES(data),
983
- value = VALUES(value),
984
- added_at = UTC_TIMESTAMP(6)`,
985
- params
986
- );
987
1006
  }
988
1007
 
989
1008
  async _batchSetReservationId(conn, reservationId, leafIds) {