mirror of
https://github.com/bisq-network/bisq.git
synced 2024-11-19 09:52:23 +01:00
Merge pull request #6200 from jmacxx/fix_issue_6175
Refactor BSQ fee validation to handle multiple txins.
This commit is contained in:
commit
52b1e13d46
@ -260,25 +260,16 @@ public class TxValidator {
|
||||
JsonObject jsonVin0 = jsonVin.get(0).getAsJsonObject();
|
||||
JsonObject jsonVout0 = jsonVout.get(0).getAsJsonObject();
|
||||
JsonElement jsonVIn0Value = jsonVin0.getAsJsonObject("prevout").get("value");
|
||||
JsonElement jsonFeeValue = jsonVout0.get("value");
|
||||
if (jsonVIn0Value == null || jsonFeeValue == null) {
|
||||
JsonElement jsonVOut0Value = jsonVout0.getAsJsonObject().get("value");
|
||||
if (jsonVIn0Value == null || jsonVOut0Value == null) {
|
||||
throw new JsonSyntaxException("vin/vout missing data");
|
||||
}
|
||||
Param minFeeParam = isMaker ? Param.MIN_MAKER_FEE_BSQ : Param.MIN_TAKER_FEE_BSQ;
|
||||
Coin expectedFee = calculateFee(tradeAmount,
|
||||
long expectedFeeAsLong = calculateFee(tradeAmount,
|
||||
isMaker ? getMakerFeeRateBsq(blockHeight) : getTakerFeeRateBsq(blockHeight),
|
||||
minFeeParam);
|
||||
long feeValue = jsonVIn0Value.getAsLong() - jsonFeeValue.getAsLong();
|
||||
// if the first output (BSQ) is greater than the first input (BSQ) include the second input (presumably BSQ)
|
||||
if ((jsonFeeValue.getAsLong() > jsonVIn0Value.getAsLong() ||
|
||||
expectedFee.getValue() > jsonVIn0Value.getAsLong()) && jsonVin.size() > 2) {
|
||||
// in this case 2 or more UTXOs were spent to pay the fee:
|
||||
JsonObject jsonVin1 = jsonVin.get(1).getAsJsonObject();
|
||||
JsonElement jsonVIn1Value = jsonVin1.getAsJsonObject("prevout").get("value");
|
||||
feeValue += jsonVIn1Value.getAsLong();
|
||||
}
|
||||
minFeeParam).getValue();
|
||||
long feeValue = getBsqBurnt(jsonVin, jsonVOut0Value.getAsLong(), expectedFeeAsLong);
|
||||
log.debug("BURNT BSQ maker fee: {} BSQ ({} sats)", (double) feeValue / 100.0, feeValue);
|
||||
long expectedFeeAsLong = expectedFee.getValue();
|
||||
String description = String.format("Expected fee: %.2f BSQ, actual fee paid: %.2f BSQ",
|
||||
(double) expectedFeeAsLong / 100.0, (double) feeValue / 100.0);
|
||||
|
||||
@ -359,6 +350,39 @@ public class TxValidator {
|
||||
// we don't care if it is confirmed or not, just that it exists.
|
||||
}
|
||||
|
||||
// a BSQ maker/taker fee transaction looks like this:
|
||||
// BSQ INPUT 1 BSQ OUTPUT
|
||||
// BSQ INPUT 2 BTC OUTPUT FOR RESERVED AMOUNT
|
||||
// BSQ INPUT n BTC OUTPUT FOR CHANGE
|
||||
// BTC INPUT 1
|
||||
// BTC INPUT 2
|
||||
// BTC INPUT n
|
||||
// there can be any number of BSQ inputs and BTC inputs
|
||||
// BSQ inputs always come first in the tx, followed by BTC for the collateral.
|
||||
// the sum of all BSQ inputs minus the BSQ output is the burnt amount, or trading fee.
|
||||
long getBsqBurnt(JsonArray jsonVin, long bsqOutValue, long expectedFee) {
|
||||
// sum consecutive inputs until we have accumulated enough to cover the output + burnt amount
|
||||
long bsqInValue = 0;
|
||||
for (int txIndex = 0; txIndex < jsonVin.size() - 1; txIndex++) {
|
||||
bsqInValue += jsonVin.get(txIndex).getAsJsonObject().getAsJsonObject("prevout").get("value").getAsLong();
|
||||
if (bsqInValue - expectedFee >= bsqOutValue) {
|
||||
break; // target reached - bsq input exceeds the output and expected burn amount
|
||||
}
|
||||
}
|
||||
// guard against negative burn amount (i.e. only 1 tx input, or first in < first out)
|
||||
long burntAmount = Math.max(0, bsqInValue - bsqOutValue);
|
||||
// since we do not know which of the first 'n' are definitively BSQ inputs, sanity-check that the burnt amount
|
||||
// is not too ridiculously high, as that would imply that we counted a BTC input.
|
||||
if (burntAmount > 10 * expectedFee) {
|
||||
log.error("The apparent BSQ fee burnt seems ridiculously high ({}) compared to expected ({})", burntAmount, expectedFee);
|
||||
burntAmount = 0; // returning zero will flag the trade for manual review
|
||||
}
|
||||
if (burntAmount == 0) {
|
||||
log.error("Could not obtain the burnt BSQ amount, trade will be flagged for manual review.");
|
||||
}
|
||||
return burntAmount;
|
||||
}
|
||||
|
||||
private static long getTxConfirms(String jsonTxt, long chainHeight) {
|
||||
long blockHeight = getTxBlockHeight(jsonTxt);
|
||||
if (blockHeight > 0) {
|
||||
|
@ -77,27 +77,27 @@ public class TxValidatorTest {
|
||||
public void testMakerTx() {
|
||||
String mempoolData, offerData;
|
||||
|
||||
// paid the correct amount of BSQ fees
|
||||
log.info("expected: paid the correct amount of BSQ fees");
|
||||
offerData = "msimscqb,0636bafb14890edfb95465e66e2b1e15915f7fb595f9b653b9129c15ef4c1c4b,1000000,10,0,662390";
|
||||
mempoolData = "{\"txid\":\"0636bafb14890edfb95465e66e2b1e15915f7fb595f9b653b9129c15ef4c1c4b\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":7899}},{\"vout\":2,\"prevout\":{\"value\":54877439}}],\"vout\":[{\"scriptpubkey_address\":\"1FCUu7hqKCSsGhVJaLbGEoCWdZRJRNqq8w\",\"value\":7889},{\"scriptpubkey_address\":\"bc1qkj5l4wxl00ufdx6ygcnrck9fz5u927gkwqcgey\",\"value\":1600000},{\"scriptpubkey_address\":\"bc1qkw4a8u9l5w9fhdh3ue9v7e7celk4jyudzg5gk5\",\"value\":53276799}],\"size\":405,\"weight\":1287,\"fee\":650,\"status\":{\"confirmed\":true,\"block_height\":663140}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateMakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// paid the correct amount of BSQ fees with two UTXOs
|
||||
log.info("expected: paid the correct amount of BSQ fees with two UTXOs");
|
||||
offerData = "qmmtead,94b2589f3270caa0df63437707d4442cae34498ee5b0285090deed9c0ce8584d,800000,10,0,705301";
|
||||
mempoolData = "{\"txid\":\"94b2589f3270caa0df63437707d4442cae34498ee5b0285090deed9c0ce8584d\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":577}},{\"vout\":0,\"prevout\":{\"value\":19989}},{\"vout\":2,\"prevout\":{\"value\":3008189}}],\"vout\":[{\"scriptpubkey_address\":\"bc1q48p2nvqf3tepjy7x33c5sfx3tp89e8c05z46cs\",\"value\":20555},{\"scriptpubkey_address\":\"bc1q9h69k8l0vy2yv3c72lw2cgn95sd7hlwjjzul05\",\"value\":920000},{\"scriptpubkey_address\":\"bc1qxmwscy2krw7zzfryw5g8868dexfy6pnq9yx3rv\",\"value\":2085750}],\"size\":550,\"weight\":1228,\"fee\":2450,\"status\":{\"confirmed\":true,\"block_height\":705301}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateMakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// UNDERPAID expected 1.01 BSQ, actual fee paid 0.80 BSQ (USED 8.00 RATE INSTEAD OF 10.06 RATE)
|
||||
log.info("expected: UNDERPAID expected 1.01 BSQ, actual fee paid 0.80 BSQ (USED 8.00 RATE INSTEAD OF 10.06 RATE");
|
||||
offerData = "48067552,3b6009da764b71d79a4df8e2d8960b6919cae2e9bdccd5ef281e261fa9cd31b3,10000000,80,0,667656";
|
||||
mempoolData = "{\"txid\":\"3b6009da764b71d79a4df8e2d8960b6919cae2e9bdccd5ef281e261fa9cd31b3\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":9717}},{\"vout\":0,\"prevout\":{\"value\":4434912}},{\"vout\":2,\"prevout\":{\"value\":12809932}}],\"vout\":[{\"scriptpubkey_address\":\"1Nzqa4J7ck5bgz7QNXKtcjZExAvReozFo4\",\"value\":9637},{\"scriptpubkey_address\":\"bc1qhmmulf5prreqhccqy2wqpxxn6dcye7ame9dd57\",\"value\":11500000},{\"scriptpubkey_address\":\"bc1qx6hg8km2jdjc5ukhuedmkseu9wlsjtd8zeajpj\",\"value\":5721894}],\"size\":553,\"weight\":1879,\"fee\":23030,\"status\":{\"confirmed\":true,\"block_height\":667660}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateMakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// UNDERPAID Expected fee: 0.61 BSQ, actual fee paid: 0.35 BSQ (USED 5.75 RATE INSTEAD OF 10.06 RATE)
|
||||
log.info("expected: UNDERPAID Expected fee: 0.61 BSQ, actual fee paid: 0.35 BSQ (USED 5.75 RATE INSTEAD OF 10.06 RATE");
|
||||
offerData = "am7DzIv,4cdea8872a7d96210f378e0221dc1aae8ee9abb282582afa7546890fb39b7189,6100000,35,0,668195";
|
||||
mempoolData = "{\"txid\":\"4cdea8872a7d96210f378e0221dc1aae8ee9abb282582afa7546890fb39b7189\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":23893}},{\"vout\":1,\"prevout\":{\"value\":1440000}},{\"vout\":2,\"prevout\":{\"value\":16390881}}],\"vout\":[{\"scriptpubkey_address\":\"1Kmrzq3WGCQsZw5kroEphuk1KgsEr65yB7\",\"value\":23858},{\"scriptpubkey_address\":\"bc1qyw5qql9m7rkse9mhcun225nrjpwycszsa5dpjg\",\"value\":7015000},{\"scriptpubkey_address\":\"bc1q90y3p6mg0pe3rvvzfeudq4mfxafgpc9rulruff\",\"value\":10774186}],\"size\":554,\"weight\":1559,\"fee\":41730,\"status\":{\"confirmed\":true,\"block_height\":668198}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateMakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// UNDERPAID expected 0.11 BSQ, actual fee paid 0.08 BSQ (USED 5.75 RATE INSTEAD OF 7.53)
|
||||
log.info("expected: UNDERPAID expected 0.11 BSQ, actual fee paid 0.08 BSQ (USED 5.75 RATE INSTEAD OF 7.53");
|
||||
offerData = "F1dzaFNQ,f72e263947c9dee6fbe7093fc85be34a149ef5bcfdd49b59b9cc3322fea8967b,1440000,8,0,670822, bsq paid too little";
|
||||
mempoolData = "{\"txid\":\"f72e263947c9dee6fbe7093fc85be34a149ef5bcfdd49b59b9cc3322fea8967b\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":15163}},{\"vout\":2,\"prevout\":{\"value\":6100000}}],\"vout\":[{\"scriptpubkey_address\":\"1MEsc2m4MSomNJWSr1p6fhnUQMyA3DRGrN\",\"value\":15155},{\"scriptpubkey_address\":\"bc1qztgwe9ry9a9puchjuscqdnv4v9lsm2ut0jtfec\",\"value\":2040000},{\"scriptpubkey_address\":\"bc1q0nstwxc0vqkj4x000xt328mfjapvlsd56nn70h\",\"value\":4048308}],\"size\":406,\"weight\":1291,\"fee\":11700,\"status\":{\"confirmed\":true,\"block_height\":670823}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateMakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
@ -107,48 +107,79 @@ public class TxValidatorTest {
|
||||
public void testTakerTx() {
|
||||
String mempoolData, offerData;
|
||||
|
||||
// The fee was more than what we expected: Expected BTC fee: 5000 sats , actual fee paid: 6000 sats
|
||||
log.info("========== test case: The fee was what we expected (5000 sats)");
|
||||
offerData = "00072328,3524364062c96ba0280621309e8b539d152154422294c2cf263a965dcde9a8ca,1000000,6000,1,614672";
|
||||
mempoolData = "{\"txid\":\"3524364062c96ba0280621309e8b539d152154422294c2cf263a965dcde9a8ca\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":1,\"prevout\":{\"value\":2971000}}],\"vout\":[{\"scriptpubkey_address\":\"3A8Zc1XioE2HRzYfbb5P8iemCS72M6vRJV\",\"value\":6000},{\"scriptpubkey_address\":\"1Hxu2X9Nr2fT3qEk9yjhiF54TJEz1Cxjoa\",\"value\":1607600},{\"scriptpubkey_address\":\"16VP6nHDDkmCMwaJj4PeyVHB88heDdVu9e\",\"value\":1353600}],\"size\":257,\"weight\":1028,\"fee\":3800,\"status\":{\"confirmed\":true,\"block_height\":614672}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// The fee matched what we expected
|
||||
log.info("========== test case: The fee matched what we expected (BSQ)");
|
||||
offerData = "00072328,12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166,6250000,188,0,615955";
|
||||
mempoolData = "{\"txid\":\"12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":19980}},{\"vout\":2,\"prevout\":{\"value\":2086015}},{\"vout\":0,\"prevout\":{\"value\":1100000}},{\"vout\":2,\"prevout\":{\"value\":938200}}],\"vout\":[{\"scriptpubkey_address\":\"17qiF1TYgT1YvsCPJyXQoKMtBZ7YJBW9GH\",\"value\":19792},{\"scriptpubkey_address\":\"16aFKD5hvEjJgPme5yRNJT2rAPdTXzdQc2\",\"value\":3768432},{\"scriptpubkey_address\":\"1D5V3QW8f5n4PhwfPgNkW9eWZwNJFyVU8n\",\"value\":346755}],\"size\":701,\"weight\":2804,\"fee\":9216,\"status\":{\"confirmed\":true,\"block_height\":615955}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// The fee was more than what we expected: Expected BTC fee: 5000 sats , actual fee paid: 7000 sats
|
||||
log.info("========== test case: No BSQ was burnt (error)");
|
||||
offerData = "NOBURN,12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166,6250000,188,0,615955";
|
||||
mempoolData = "{\"txid\":\"12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":19980}},{\"vout\":2,\"prevout\":{\"value\":2086015}},{\"vout\":0,\"prevout\":{\"value\":1100000}},{\"vout\":2,\"prevout\":{\"value\":938200}}],\"vout\":[{\"scriptpubkey_address\":\"17qiF1TYgT1YvsCPJyXQoKMtBZ7YJBW9GH\",\"value\":19980},{\"scriptpubkey_address\":\"16aFKD5hvEjJgPme5yRNJT2rAPdTXzdQc2\",\"value\":3768432},{\"scriptpubkey_address\":\"1D5V3QW8f5n4PhwfPgNkW9eWZwNJFyVU8n\",\"value\":346755}],\"size\":701,\"weight\":2804,\"fee\":9216,\"status\":{\"confirmed\":true,\"block_height\":615955}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
log.info("========== test case: No BSQ input (error)");
|
||||
offerData = "NOBSQ,12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166,6250000,188,0,615955";
|
||||
mempoolData = "{\"txid\":\"12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":2,\"prevout\":{\"value\":2086015}},{\"vout\":0,\"prevout\":{\"value\":1100000}},{\"vout\":2,\"prevout\":{\"value\":938200}}],\"vout\":[{\"scriptpubkey_address\":\"16aFKD5hvEjJgPme5yRNJT2rAPdTXzdQc2\",\"value\":3768432},{\"scriptpubkey_address\":\"1D5V3QW8f5n4PhwfPgNkW9eWZwNJFyVU8n\",\"value\":346755}],\"size\":701,\"weight\":2804,\"fee\":9216,\"status\":{\"confirmed\":true,\"block_height\":615955}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
log.info("========== test case: only one input (error)");
|
||||
offerData = "1INPUT,12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166,6250000,188,0,615955";
|
||||
mempoolData = "{\"txid\":\"12f658954890d38ce698355be0b27fdd68d092c7b1b7475381918db060f46166\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":2,\"prevout\":{\"value\":4186015}}],\"vout\":[{\"scriptpubkey_address\":\"16aFKD5hvEjJgPme5yRNJT2rAPdTXzdQc2\",\"value\":3768432},{\"scriptpubkey_address\":\"1D5V3QW8f5n4PhwfPgNkW9eWZwNJFyVU8n\",\"value\":346755}],\"size\":701,\"weight\":2804,\"fee\":9216,\"status\":{\"confirmed\":true,\"block_height\":615955}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
log.info("========== test case: The fee was what we expected: (7000 sats)");
|
||||
offerData = "bsqtrade,dfa4555ab78c657cad073e3f29c38c563d9dafc53afaa8c6af28510c734305c4,1000000,10,1,662390";
|
||||
mempoolData = "{\"txid\":\"dfa4555ab78c657cad073e3f29c38c563d9dafc53afaa8c6af28510c734305c4\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":678997}}],\"vout\":[{\"scriptpubkey_address\":\"3EfRGckBQQuk7cpU7SwatPv8kFD1vALkTU\",\"value\":7000},{\"scriptpubkey_address\":\"bc1qu6vey3e7flzg8gmhun05m43uc2vz0ay33kuu6r\",\"value\":647998}],\"size\":224,\"weight\":566,\"fee\":23999,\"status\":{\"confirmed\":true,\"block_height\":669720}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// The fee matched what we expected
|
||||
log.info("========== test case: The fee matched what we expected");
|
||||
offerData = "89284,e1269aad63b3d894f5133ad658960971ef5c0fce6a13ad10544dc50fa3360588,900000,9,0,666473";
|
||||
mempoolData = "{\"txid\":\"e1269aad63b3d894f5133ad658960971ef5c0fce6a13ad10544dc50fa3360588\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":72738}},{\"vout\":0,\"prevout\":{\"value\":1600000}}],\"vout\":[{\"scriptpubkey_address\":\"17Kh5Ype9yNomqRrqu2k1mdV5c6FcKfGwQ\",\"value\":72691},{\"scriptpubkey_address\":\"bc1qdr9zcw7gf2sehxkux4fmqujm5uguhaqz7l9lca\",\"value\":629016},{\"scriptpubkey_address\":\"bc1qgqrrqv8q6l5d3t52fe28ghuhz4xqrsyxlwn03z\",\"value\":956523}],\"size\":404,\"weight\":1286,\"fee\":14508,\"status\":{\"confirmed\":true,\"block_height\":672388}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// UNDERPAID: Expected fee: 7.04 BSQ, actual fee paid: 1.01 BSQ
|
||||
log.info("========== test case for UNDERPAID: Expected fee: 7.04 BSQ, actual fee paid: 1.01 BSQ");
|
||||
offerData = "VOxRS,e99ea06aefc824fd45031447f7a0b56efb8117a09f9b8982e2c4da480a3a0e91,10000000,101,0,669129";
|
||||
mempoolData = "{\"txid\":\"e99ea06aefc824fd45031447f7a0b56efb8117a09f9b8982e2c4da480a3a0e91\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":16739}},{\"vout\":2,\"prevout\":{\"value\":113293809}}],\"vout\":[{\"scriptpubkey_address\":\"1F14nF6zoUfJkqZrFgdmK5VX5QVwEpAnKW\",\"value\":16638},{\"scriptpubkey_address\":\"bc1q80y688ev7u43vqy964yf7feqddvt2mkm8977cm\",\"value\":11500000},{\"scriptpubkey_address\":\"bc1q9whgyc2du9mrgnxz0nl0shwpw8ugrcae0j0w8p\",\"value\":101784485}],\"size\":406,\"weight\":1291,\"fee\":9425,\"status\":{\"confirmed\":true,\"block_height\":669134}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// UNDERPAID: Expected fee: 1029000 sats BTC, actual fee paid: 441000 sats BTC because they used the default rate of 0.003 should have been 0.007 per BTC
|
||||
log.info("========== test case for UNDERPAID: Expected fee: 1029000 sats BTC, actual fee paid: 441000 sats BTC because they used the default rate of 0.003 should have been 0.007 per BTC");
|
||||
// after 1.6.0 we introduce additional leniency to allow the default rate (which is not stored in the DAO param change list)
|
||||
// after 1.8.0 we use fee values obtained from filter => result=false meaning the user did not pay enough
|
||||
offerData = "AKA,6779b7571f21a5a1af01d675bf032b8a3c571416d05345491018cbc2d016e888,147000000,441000,1,676543";
|
||||
mempoolData = "{'txid':'6779b7571f21a5a1af01d675bf032b8a3c571416d05345491018cbc2d016e888','version':1,'locktime':0,'vin':[{'txid':'94c36c0a9c5c99844ddfe17ef05a3ebbe94b14d76ee4bed7b00c7d45e681b441','vout':0,'prevout':{'scriptpubkey_address':'bc1qt5uprdzeh9g4el0k9cttn40qzagvpca9q0q6vl','value':177920825},'sequence':4294967295}],'vout':[{'scriptpubkey_address':'19BNi5EpZhgBBWAt5ka7xWpJpX2ZWJEYyq','value':441000},{'scriptpubkey_address':'bc1qxxcl9dz6usrx4z456g6fg8n3u9327hl458d6mx','value':177008388},{'scriptpubkey_address':'bc1qdq0894p2nmg04ceyqgapln6addfl80zy7z36jd','value':467243}],'size':256,'weight':697,'fee':4194,'status':{'confirmed':true,'block_height':676543}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// UNDERPAID: Expected fee: 2.12 BSQ, actual fee paid: 0.03 BSQ
|
||||
// this is the example from the BSQ fee scammer Oct 2021
|
||||
log.info("========== test case for UNDERPAID: Expected fee: 2.12 BSQ, actual fee paid: 0.03 BSQ -- this is the example from the BSQ fee scammer Oct 2021");
|
||||
offerData = "957500,26e1a5e1f842cb7baa18bd197bd084e7f043d07720b9853e947158eb0a32677d,2000000,101,0,709426";
|
||||
mempoolData = "{\"txid\":\"26e1a5e1f842cb7baa18bd197bd084e7f043d07720b9853e947158eb0a32677d\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"\",\"vout\":0,\"prevout\":{\"scriptpubkey\":\"\",\"scriptpubkey_asm\":\"\",\"scriptpubkey_type\":\"v0_p2wpkh\",\"scriptpubkey_address\":\"\",\"value\":3688},\"scriptsig\":\"\",\"scriptsig_asm\":\"\",\"witness\":[\"\",\"\"],\"is_coinbase\":false,\"sequence\":4294967295},{\"txid\":\"\",\"vout\":2,\"prevout\":{\"scriptpubkey\":\"\",\"scriptpubkey_asm\":\"\",\"scriptpubkey_type\":\"v0_p2wpkh\",\"scriptpubkey_address\":\"\",\"value\":796203},\"scriptsig\":\"\",\"scriptsig_asm\":\"\",\"witness\":[\"\",\"\"],\"is_coinbase\":false,\"sequence\":4294967295}],\"vout\":[{\"scriptpubkey\":\"\",\"scriptpubkey_asm\":\"\",\"scriptpubkey_type\":\"v0_p2wpkh\",\"scriptpubkey_address\":\"bc1qydcyfe7kp6968hywcp0uek2xvgem3nlx0x0hfy\",\"value\":3685},{\"scriptpubkey\":\"\",\"scriptpubkey_asm\":\"\",\"scriptpubkey_type\":\"v0_p2wpkh\",\"scriptpubkey_address\":\"bc1qc4amk6sd3c4gzxjgd5sdlaegt0r5juq54vnrll\",\"value\":503346},{\"scriptpubkey\":\"\",\"scriptpubkey_asm\":\"\",\"scriptpubkey_type\":\"v0_p2wpkh\",\"scriptpubkey_address\":\"bc1q66e7m8y5lzfk5smg2a80xeaqzhslgeavg9y70t\",\"value\":291187}],\"size\":403,\"weight\":958,\"fee\":1673,\"status\":{\"confirmed\":true,\"block_height\":709426,\"block_hash\":\"\",\"block_time\":1636751288}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
// expected fee of 87.96 BSQ, paid fee=87.96 BSQ, was paid using two BSQ UTXOs, this revealed a bug in validation
|
||||
log.info("========== test case: expected fee paid using two BSQ UTXOs");
|
||||
offerData = "ZHNYCAE,a91c6f1cb62721a7943678547aa814d6f29125ed63ad076073eb5ae7f16a76e9,83000000,101,0,717000";
|
||||
mempoolData = "{\"txid\":\"a91c6f1cb62721a7943678547aa814d6f29125ed63ad076073eb5ae7f16a76e9\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":3510}},{\"vout\":0,\"prevout\":{\"value\":6190}},{\"vout\":0,\"prevout\":{\"value\":46000000}}],\"vout\":[{\"scriptpubkey_address\":\"bc1qmqphx028eu4tzdvgccf5re52qtv6pmjanrpq29\",\"value\":904},{\"scriptpubkey_address\":\"bc1qtkvu4zeh0g0pce452335tgnswxd8ayxlktfj2s\",\"value\":30007648},{\"scriptpubkey_address\":\"bc1qdatwgzrrntp2m53tpzmax4dxu6md2c0c9vj8ut\",\"value\":15997324}],\"size\":549,\"weight\":1227,\"fee\":3824,\"status\":{\"confirmed\":true,\"block_height\":716444}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
log.info("========== test case: expected fee paid using three BSQ UTXOs");
|
||||
offerData = "3UTXOGOOD,c7dddc267a366fa1d87840eeb0dcd89918a886ccb9aabee80f667635a5d4e262,200000000,101,0,733715";
|
||||
mempoolData = "{\"txid\":\"c7dddc267a366fa1d87840eeb0dcd89918a886ccb9aabee80f667635a5d4e262\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":9833}},{\"vout\":0,\"prevout\":{\"value\":1362}},{vout\":0,\"prevout\":{\"value\":17488}},{\"vout\":2,\"prevout\":{\"value\":573360131}}],\"vout\":[{\"scriptpubkey_address\":\"bc1qvwpm87kmrlgave9srxk6nfwleehll0kxetu5j0\",\"value\":10795},{\"scriptpubkey_address\":\"bc1qz5n83ppfpdznnzff4e7tjep5c6f6jce9mqnrzh\",\"value\":230004780},{\"scriptpubkey_address\":\"bc1qcfyjajhuv55fyu6g5ug664r57u9a7qg55cgt5p\",\"value\":343370849}],\"size\":699,\"weight\":1500,\"fee\":2390,\"status\":{\"confirmed\":true,\"block_height\":733715}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
log.info("========== test case: expected fee paid using four BSQ UTXOs");
|
||||
offerData = "4UTXOGOOD,c7dddc267a366fa1d87840eeb0dcd89918a886ccb9aabee80f667635a5d4e262,200000000,101,0,733715";
|
||||
mempoolData = "{\"txid\":\"c7dddc267a366fa1d87840eeb0dcd89918a886ccb9aabee80f667635a5d4e262\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":4833}},{\"vout\":0,\"prevout\":{\"value\":5000}},{\"vout\":0,\"prevout\":{\"value\":1362}},{vout\":0,\"prevout\":{\"value\":17488}},{\"vout\":2,\"prevout\":{\"value\":573360131}}],\"vout\":[{\"scriptpubkey_address\":\"bc1qvwpm87kmrlgave9srxk6nfwleehll0kxetu5j0\",\"value\":10795},{\"scriptpubkey_address\":\"bc1qz5n83ppfpdznnzff4e7tjep5c6f6jce9mqnrzh\",\"value\":230004780},{\"scriptpubkey_address\":\"bc1qcfyjajhuv55fyu6g5ug664r57u9a7qg55cgt5p\",\"value\":343370849}],\"size\":699,\"weight\":1500,\"fee\":2390,\"status\":{\"confirmed\":true,\"block_height\":733715}}";
|
||||
Assert.assertTrue(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
log.info("========== test case: three BSQ UTXOs, but fee paid is too low");
|
||||
offerData = "3UTXOLOWFEE,c7dddc267a366fa1d87840eeb0dcd89918a886ccb9aabee80f667635a5d4e262,200000000,101,0,733715";
|
||||
mempoolData = "{\"txid\":\"c7dddc267a366fa1d87840eeb0dcd89918a886ccb9aabee80f667635a5d4e262\",\"version\":1,\"locktime\":0,\"vin\":[{\"vout\":0,\"prevout\":{\"value\":9833}},{\"vout\":0,\"prevout\":{\"value\":1362}},{vout\":0,\"prevout\":{\"value\":1362}},{\"vout\":2,\"prevout\":{\"value\":573360131}}],\"vout\":[{\"scriptpubkey_address\":\"bc1qvwpm87kmrlgave9srxk6nfwleehll0kxetu5j0\",\"value\":10795},{\"scriptpubkey_address\":\"bc1qz5n83ppfpdznnzff4e7tjep5c6f6jce9mqnrzh\",\"value\":230004780},{\"scriptpubkey_address\":\"bc1qcfyjajhuv55fyu6g5ug664r57u9a7qg55cgt5p\",\"value\":343370849}],\"size\":699,\"weight\":1500,\"fee\":2390,\"status\":{\"confirmed\":true,\"block_height\":733715}}";
|
||||
Assert.assertFalse(createTxValidator(offerData).parseJsonValidateTakerFeeTx(mempoolData, btcFeeReceivers).getResult());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -260,6 +291,7 @@ public class TxValidatorTest {
|
||||
private LinkedHashMap<Long, String> mockedGetFeeRateMap(Param param) {
|
||||
LinkedHashMap<Long, String> feeMap = new LinkedHashMap<>();
|
||||
if (param == Param.DEFAULT_MAKER_FEE_BSQ) {
|
||||
feeMap.put(721063L, "12.78"); // https://github.com/bisq-network/proposals/issues/357
|
||||
feeMap.put(706305L, "15.14"); // https://github.com/bisq-network/proposals/issues/345
|
||||
feeMap.put(697011L, "13.16"); // https://github.com/bisq-network/proposals/issues/339
|
||||
feeMap.put(682901L, "11.45"); // https://github.com/bisq-network/proposals/issues/333
|
||||
@ -276,6 +308,7 @@ public class TxValidatorTest {
|
||||
feeMap.put(585787L, "8.0");
|
||||
feeMap.put(581107L, "1.6");
|
||||
} else if (param == Param.DEFAULT_TAKER_FEE_BSQ) {
|
||||
feeMap.put(721063L, "89.44"); // https://github.com/bisq-network/proposals/issues/357
|
||||
feeMap.put(706305L, "105.97"); // https://github.com/bisq-network/proposals/issues/345
|
||||
feeMap.put(697011L, "92.15"); // https://github.com/bisq-network/proposals/issues/339
|
||||
feeMap.put(682901L, "80.13"); // https://github.com/bisq-network/proposals/issues/333
|
||||
|
Loading…
Reference in New Issue
Block a user