decred.org/dcrdex@v1.0.5/server/db/driver/pg/internal/matches.go (about) 1 package internal 2 3 const ( 4 // CreateMatchesTable creates the matches table for storing data related to 5 // a match and the related swap. This only includes trade matches, not 6 // cancel order matches that just remove one order from the book (and change 7 // the target order status in the orders table). 8 // 9 // The takerSell column indicates the asset of the address and coinID 10 // columns for both maker and taker. Sell refers to sell of the base asset, 11 // and the opposite is implied for the counterparty (makerSell = !takerSell) 12 // 13 // takerSell | takerAddress | aContractCoinID | aRedeemCoinID || (makerSell) | makerAddress | bContractCoinID | bRedeemCoinID 14 // --------------------------------------------------------------------------------------------------------------------------------- 15 // true (B->Q) | quote | base | quote || false (Q->B) | base | quote | base 16 // false (Q->B) | base | quote | base || true (B->Q) | quote | base | quote 17 CreateMatchesTable = `CREATE TABLE IF NOT EXISTS %s ( 18 matchid BYTEA PRIMARY KEY, 19 active BOOL DEFAULT TRUE, -- negotiation active, where FALSE includes failure, successful completion, or a taker cancel order 20 takerSell BOOL, -- to identify asset of address and coinIDs, NULL for cancel orders 21 takerOrder BYTEA, -- INDEX this 22 takerAccount BYTEA, -- INDEX this 23 takerAddress TEXT, -- NULL for cancel orders 24 makerOrder BYTEA, -- INDEX this 25 makerAccount BYTEA, -- INDEX this 26 makerAddress TEXT, -- NULL for cancel orders 27 epochIdx INT8, 28 epochDur INT8, 29 quantity INT8, 30 rate INT8, 31 baseRate INT8, quoteRate INT8, -- contract tx fee rates, NULL for cancel orders 32 status INT2, -- also updated during swap negotiation, independent from active for failed swaps 33 forgiven BOOL, 34 35 -- The remaining columns are only set during swap negotiation. 36 sigMatchAckMaker BYTEA, -- maker's ack of the match 37 sigMatchAckTaker BYTEA, -- taker's ack of the match 38 39 -- initiator/A (maker) CONTRACT data 40 aContractCoinID BYTEA, -- coinID (e.g. tx:vout) with the contract 41 aContract BYTEA, -- includes secret hash, get with ExtractSwapDetails for DCR 42 aContractTime INT8, -- server time stamp 43 bSigAckOfAContract BYTEA, -- counterparty's (participant) sig with ack of initiator CONTRACT data 44 45 -- participant/B (taker) CONTRACT data 46 bContractCoinID BYTEA, 47 bContract BYTEA, 48 bContractTime INT8, -- server time stamp 49 aSigAckOfBContract BYTEA, -- counterparty's (initiator) sig with ack of participant CONTRACT data 50 51 -- initiator/A (maker) REDEEM data 52 aRedeemCoinID BYTEA, -- the input spending the taker's contract output includes the secret 53 aRedeemSecret BYTEA, 54 aRedeemTime INT8, -- server time stamp 55 bSigAckOfARedeem BYTEA, -- counterparty's (participant) sig with ack of initiator REDEEM data 56 57 -- participant/B (taker) REDEEM data 58 bRedeemCoinID BYTEA, 59 bRedeemTime INT8 -- server time stamp 60 )` 61 62 RetrieveMatchStatsByEpoch = `SELECT quantity, rate, takerSell FROM %s 63 WHERE takerSell IS NOT NULL AND epochIdx = $1 AND epochDur = $2;` 64 65 RetrieveSwapData = `SELECT status, sigMatchAckMaker, sigMatchAckTaker, 66 aContractCoinID, aContract, aContractTime, bSigAckOfAContract, 67 bContractCoinID, bContract, bContractTime, aSigAckOfBContract, 68 aRedeemCoinID, aRedeemSecret, aRedeemTime, bSigAckOfARedeem, 69 bRedeemCoinID, bRedeemTime 70 FROM %s WHERE matchid = $1;` 71 72 InsertMatch = `INSERT INTO %s (matchid, takerSell, 73 takerOrder, takerAccount, takerAddress, 74 makerOrder, makerAccount, makerAddress, 75 epochIdx, epochDur, 76 quantity, rate, baseRate, quoteRate, status) 77 VALUES ($1, $2, 78 $3, $4, $5, 79 $6, $7, $8, 80 $9, $10, 81 $11, $12, $13, $14, $15) ` // do not terminate with ; 82 83 UpsertMatch = InsertMatch + ` ON CONFLICT (matchid) DO 84 UPDATE SET quantity = $11, status = $15;` 85 86 InsertCancelMatch = `INSERT INTO %s (matchid, active, -- omit takerSell 87 takerOrder, takerAccount, -- no taker address for a cancel order 88 makerOrder, makerAccount, -- omit maker's swap address too 89 epochIdx, epochDur, 90 quantity, rate, status) -- omit base and quote fee rates 91 VALUES ($1, FALSE, -- no active swap for a cancel 92 $2, $3, 93 $4, $5, 94 $6, $7, 95 $8, $9, $10) ` // status should be MatchComplete although there is no swap 96 97 UpsertCancelMatch = InsertCancelMatch + ` ON CONFLICT (matchid) DO NOTHING;` 98 99 RetrieveMatchByID = `SELECT matchid, active, takerSell, 100 takerOrder, takerAccount, takerAddress, 101 makerOrder, makerAccount, makerAddress, 102 epochIdx, epochDur, quantity, rate, baseRate, quoteRate, status 103 FROM %s WHERE matchid = $1;` 104 105 RetrieveUserMatches = `SELECT matchid, active, takerSell, 106 takerOrder, takerAccount, takerAddress, 107 makerOrder, makerAccount, makerAddress, 108 epochIdx, epochDur, quantity, rate, baseRate, quoteRate, status 109 FROM %s 110 WHERE takerAccount = $1 OR makerAccount = $1;` 111 112 RetrieveActiveUserMatches = `SELECT matchid, takerSell, 113 takerOrder, takerAccount, takerAddress, 114 makerOrder, makerAccount, makerAddress, 115 epochIdx, epochDur, quantity, rate, baseRate, quoteRate, status 116 FROM %s 117 WHERE (takerAccount = $1 OR makerAccount = $1) 118 AND active;` 119 120 RetrieveMarketMatches = `SELECT matchid, active, takerSell, 121 takerOrder, takerAccount, takerAddress, 122 makerOrder, makerAccount, makerAddress, 123 epochIdx, epochDur, quantity, rate, baseRate, quoteRate, status, 124 aContractCoinID, bContractCoinID, aRedeemCoinID, bRedeemCoinID 125 FROM %s 126 WHERE takerSell IS NOT NULL -- not a cancel order 127 ORDER BY epochIdx * epochDur DESC 128 LIMIT $1;` 129 130 RetrieveActiveMarketMatches = `SELECT matchid, takerSell, 131 takerOrder, takerAccount, takerAddress, 132 makerOrder, makerAccount, makerAddress, 133 epochIdx, epochDur, quantity, rate, baseRate, quoteRate, status, 134 aContractCoinID, bContractCoinID, aRedeemCoinID, bRedeemCoinID 135 FROM %s 136 WHERE takerSell IS NOT NULL -- not a cancel order 137 AND active 138 ORDER BY epochIdx * epochDur DESC;` 139 140 // RetrieveActiveMarketMatchesExtended combines RetrieveSwapData with 141 // RetrieveActiveMarketMatches. 142 RetrieveActiveMarketMatchesExtended = `SELECT matchid, takerSell, 143 takerOrder, takerAccount, takerAddress, 144 makerOrder, makerAccount, makerAddress, 145 epochIdx, epochDur, quantity, rate, baseRate, quoteRate, status, 146 sigMatchAckMaker, sigMatchAckTaker, 147 aContractCoinID, aContract, aContractTime, bSigAckOfAContract, 148 bContractCoinID, bContract, bContractTime, aSigAckOfBContract, 149 aRedeemCoinID, aRedeemSecret, aRedeemTime, bSigAckOfARedeem, 150 bRedeemCoinID, bRedeemTime 151 FROM %s 152 WHERE takerSell IS NOT NULL -- not a cancel order 153 AND active 154 ORDER BY epochIdx * epochDur DESC;` 155 156 // CompletedOrAtFaultMatchesLastN retrieves inactive matches for a user that 157 // are either successfully completed by the user (MatchComplete or 158 // MakerRedeemed with user as maker), or failed because of this user's 159 // inaction. Note that the literal status values used in this query MUST BE 160 // UPDATED if the order.OrderStatus enum is changed. 161 CompletedOrAtFaultMatchesLastN = ` 162 WITH acct (aid) AS ( VALUES($1::BYTEA) ) 163 164 SELECT matchid, status, quantity, (status=4 OR (status=3 AND makerAccount = aid AND takerAccount != aid)) AS success, 165 GREATEST((epochIdx+1)*epochDur, aContractTime, bContractTime, aRedeemTime, bRedeemTime) AS lastTime 166 FROM %s, acct 167 WHERE takerSell IS NOT NULL -- exclude cancel order matches 168 AND (makerAccount = aid OR takerAccount = aid) 169 AND ( 170 -- swap success for both 171 status=4 -- success for both 172 OR 173 -- swap success for maker unless maker==taker 174 (status=3 AND makerAccount = aid AND takerAccount != aid) 175 OR 176 ( -- at-fault swap failures 177 NOT active -- failure means inactive/revoked 178 AND (forgiven IS NULL OR NOT forgiven) 179 AND ( 180 (status=0 AND makerAccount = aid) OR -- fault for maker 181 (status=1 AND takerAccount = aid) OR -- fault for taker 182 (status=2 AND makerAccount = aid) OR -- fault for maker 183 (status=3 AND takerAccount = aid) -- fault for taker 184 ) 185 ) 186 ) 187 ORDER BY lastTime DESC -- last action time i.e. success or approx. when could have acted 188 LIMIT $2;` 189 190 UserMatchFails = ` 191 WITH acct (aid) AS ( VALUES($1::BYTEA) ) 192 193 SELECT matchid, status 194 FROM %s, acct 195 WHERE takerSell IS NOT NULL -- exclude cancel order matches 196 AND (makerAccount = aid OR takerAccount = aid) 197 AND NOT active -- failure means inactive/revoked 198 AND (forgiven IS NULL OR NOT forgiven) 199 AND ( 200 (status=0 AND makerAccount = aid) OR -- fault for maker 201 (status=1 AND takerAccount = aid) OR -- fault for taker 202 (status=2 AND makerAccount = aid) OR -- fault for maker 203 (status=3 AND takerAccount = aid) -- fault for taker 204 ) 205 ORDER BY GREATEST((epochIdx+1)*epochDur, aContractTime, bContractTime, aRedeemTime, bRedeemTime) DESC -- last action time i.e. success or approx. when could have acted 206 LIMIT $2;` 207 208 ForgiveMatchFail = `UPDATE %s SET forgiven = TRUE 209 WHERE matchid = $1 AND NOT active;` 210 211 SetMakerMatchAckSig = `UPDATE %s SET sigMatchAckMaker = $2 WHERE matchid = $1;` 212 SetTakerMatchAckSig = `UPDATE %s SET sigMatchAckTaker = $2 WHERE matchid = $1;` 213 214 SetInitiatorSwapData = `UPDATE %s SET status = $2, 215 aContractCoinID = $3, aContract = $4, aContractTime = $5 216 WHERE matchid = $1;` 217 SetParticipantSwapData = `UPDATE %s SET status = $2, 218 bContractCoinID = $3, bContract = $4, bContractTime = $5 219 WHERE matchid = $1;` 220 221 SetParticipantContractAuditSig = `UPDATE %s SET bSigAckOfAContract = $2 WHERE matchid = $1;` 222 SetInitiatorContractAuditSig = `UPDATE %s SET aSigAckOfBContract = $2 WHERE matchid = $1;` 223 224 SetInitiatorRedeemData = `UPDATE %s SET status = $2, 225 aRedeemCoinID = $3, aRedeemSecret = $4, aRedeemTime = $5 226 WHERE matchid = $1;` 227 SetParticipantRedeemData = `UPDATE %s SET status = $2, 228 bRedeemCoinID = $3, bRedeemTime = $4, active = FALSE 229 WHERE matchid = $1;` 230 231 SetParticipantRedeemAckSig = `UPDATE %s 232 SET bSigAckOfARedeem = $2 233 WHERE matchid = $1;` 234 235 SetSwapDone = `UPDATE %s SET active = FALSE -- leave forgiven NULL 236 WHERE matchid = $1;` 237 238 SetSwapDoneForgiven = `UPDATE %s SET active = FALSE, forgiven = TRUE 239 WHERE matchid = $1;` 240 241 SelectMatchStatuses = `SELECT takerSell, (takerAccount = $1) AS isTaker, (makerAccount = $1) AS isMaker, matchid, status, aContract, bContract, aContractCoinID, 242 bContractCoinID, aRedeemCoinID, bRedeemCoinID, aRedeemSecret, active 243 FROM %s 244 WHERE matchid = ANY($2) 245 AND (takerAccount = $1 OR makerAccount = $1);` 246 )