@@ -53,19 +53,22 @@ func escrowTransfer(c *gin.Context) {
5353 }
5454 }
5555 if fromUser == nil {
56+ usersMutex .Unlock ()
5657 c .JSON (404 , gin.H {"error" : "Sender user not found" })
5758 return
5859 }
5960
6061 // Check sender balance
6162 fromCurrency := fromUser .GetCredits ()
6263 if fromCurrency == 0 {
64+ usersMutex .Unlock ()
6365 c .JSON (400 , gin.H {"error" : "Sender user has no currency" })
6466 return
6567 }
6668 fromCurrency = roundVal (fromCurrency )
6769
6870 if fromCurrency < nAmount {
71+ usersMutex .Unlock ()
6972 c .JSON (400 , gin.H {"error" : "Insufficient funds" , "required" : nAmount , "available" : fromCurrency })
7073 return
7174 }
@@ -75,12 +78,9 @@ func escrowTransfer(c *gin.Context) {
7578 if newBal < 0 { // guard against tiny floating error
7679 newBal = 0
7780 }
78- usersMutex .Unlock ()
79-
80- fromUser .SetBalance (newBal )
81-
82- usersMutex .Lock ()
83- defer usersMutex .Unlock ()
81+
82+ // Update balance directly while holding lock
83+ setUserKeyDirect (fromUser , "sys.currency" , roundVal (newBal ))
8484
8585 // Add escrow transaction to sender
8686 now := time .Now ().UnixMilli ()
@@ -92,15 +92,27 @@ func escrowTransfer(c *gin.Context) {
9292 note = note [:50 ]
9393 }
9494
95- fromUser .addTransaction (map [string ]any {
95+ // Add transaction directly while holding lock
96+ txs := getObjectSlice (* fromUser , "sys.transactions" )
97+ benefits := fromUser .GetSubscriptionBenefits ()
98+
99+ tx := map [string ]any {
96100 "note" : note ,
97101 "user" : "devfund-escrow" ,
98102 "time" : now ,
99103 "amount" : nAmount ,
100104 "type" : "escrow_out" ,
101105 "petition_id" : req .PetitionID ,
102106 "new_total" : newBal ,
103- })
107+ }
108+
109+ txs = append ([]map [string ]any {tx }, txs ... )
110+ if len (txs ) > benefits .Max_Transaction_History {
111+ txs = txs [:benefits .Max_Transaction_History ]
112+ }
113+ setUserKeyDirect (fromUser , "sys.transactions" , txs )
114+
115+ usersMutex .Unlock ()
104116
105117 go saveUsers ()
106118
@@ -164,24 +176,20 @@ func escrowRelease(c *gin.Context) {
164176 }
165177 }
166178 if toUser == nil {
179+ usersMutex .Unlock ()
167180 c .JSON (404 , gin.H {"error" : "Recipient user not found" })
168181 return
169182 }
170183
171- usersMutex .Unlock ()
172184 // Get recipient balance
173185 toCurrency := toUser .GetCredits ()
174186 if toCurrency == 0 {
175- toUser .SetBalance (float64 (0 ))
176187 toCurrency = float64 (0 )
177188 }
178189
179190 // Add credits to recipient
180191 newBal := roundVal (toCurrency + nAmount )
181- toUser .SetBalance (newBal )
182-
183- usersMutex .Lock ()
184- defer usersMutex .Unlock ()
192+ setUserKeyDirect (toUser , "sys.currency" , newBal )
185193
186194 // Add transaction to recipient
187195 now := time .Now ().UnixMilli ()
@@ -193,16 +201,27 @@ func escrowRelease(c *gin.Context) {
193201 note = note [:50 ]
194202 }
195203
196- // Helper to add transaction
197- toUser .addTransaction (map [string ]any {
204+ // Add transaction directly while holding lock
205+ txs := getObjectSlice (* toUser , "sys.transactions" )
206+ benefits := toUser .GetSubscriptionBenefits ()
207+
208+ tx := map [string ]any {
198209 "note" : note ,
199210 "user" : "devfund-escrow" ,
200211 "time" : now ,
201212 "amount" : nAmount ,
202213 "type" : "escrow_in" ,
203214 "petition_id" : req .PetitionID ,
204215 "new_total" : newBal ,
205- })
216+ }
217+
218+ txs = append ([]map [string ]any {tx }, txs ... )
219+ if len (txs ) > benefits .Max_Transaction_History {
220+ txs = txs [:benefits .Max_Transaction_History ]
221+ }
222+ setUserKeyDirect (toUser , "sys.transactions" , txs )
223+
224+ usersMutex .Unlock ()
206225
207226 go saveUsers ()
208227
0 commit comments