mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-18 21:32:35 +01:00
Wallet: always enforce OP_RETURN
limit in completeTx()
Without this fix (and code cleanup) the `OP_RETURN` limit is not enforced when `ensureMinRequiredFee` is false or `emptyWallet` is true. Parameterize `twoOpReturnsPerTransactionTest()` to test all combinations of `ensureMinRequiredFee` and `emptyWallet`.
This commit is contained in:
parent
3a28163d50
commit
27ff0823bb
@ -4550,17 +4550,16 @@ public class Wallet extends BaseTaggableObject
|
||||
// Calculate the amount of value we need to import.
|
||||
Coin valueNeeded = req.tx.getOutputSum().subtract(totalInput);
|
||||
|
||||
// Check for dusty sends and the OP_RETURN limit.
|
||||
// Enforce the OP_RETURN limit
|
||||
if (req.tx.getOutputs().stream()
|
||||
.filter(o -> ScriptPattern.isOpReturn(o.getScriptPubKey()))
|
||||
.count() > 1) // Only 1 OP_RETURN per transaction allowed.
|
||||
throw new MultipleOpReturnRequested();
|
||||
|
||||
// Check for dusty sends
|
||||
if (req.ensureMinRequiredFee && !req.emptyWallet) { // Min fee checking is handled later for emptyWallet.
|
||||
int opReturnCount = 0;
|
||||
for (TransactionOutput output : req.tx.getOutputs()) {
|
||||
if (output.isDust())
|
||||
throw new DustySendRequested();
|
||||
if (ScriptPattern.isOpReturn(output.getScriptPubKey()))
|
||||
++opReturnCount;
|
||||
}
|
||||
if (opReturnCount > 1) // Only 1 OP_RETURN per transaction allowed.
|
||||
throw new MultipleOpReturnRequested();
|
||||
if (req.tx.getOutputs().stream().anyMatch(TransactionOutput::isDust))
|
||||
throw new DustySendRequested();
|
||||
}
|
||||
|
||||
// Calculate a list of ALL potential candidates for spending and then ask a coin selector to provide us
|
||||
|
@ -18,6 +18,8 @@
|
||||
package org.bitcoinj.wallet;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import junitparams.JUnitParamsRunner;
|
||||
import junitparams.Parameters;
|
||||
import org.bitcoinj.base.BitcoinNetwork;
|
||||
import org.bitcoinj.base.ScriptType;
|
||||
import org.bitcoinj.base.internal.TimeUtils;
|
||||
@ -75,6 +77,7 @@ import org.easymock.EasyMock;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -126,6 +129,7 @@ import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(JUnitParamsRunner.class)
|
||||
public class WalletTest extends TestWithWallet {
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletTest.class);
|
||||
|
||||
@ -2121,7 +2125,8 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
@Test(expected = Wallet.MultipleOpReturnRequested.class)
|
||||
public void twoOpReturnsPerTransactionTest() throws Exception {
|
||||
@Parameters({"false, false", "false, true", "true, false", "true, true"})
|
||||
public void twoOpReturnsPerTransactionTest(boolean ensureMinRequiredFee, boolean emptyWallet) throws Exception {
|
||||
// Tests sending transaction where there are 2 attempts to write OP_RETURN scripts - this should fail and throw MultipleOpReturnRequested.
|
||||
receiveATransaction(wallet, myAddress);
|
||||
Transaction tx = new Transaction();
|
||||
@ -2131,7 +2136,8 @@ public class WalletTest extends TestWithWallet {
|
||||
tx.addOutput(messagePrice, script1);
|
||||
tx.addOutput(messagePrice, script2);
|
||||
SendRequest request = SendRequest.forTx(tx);
|
||||
request.ensureMinRequiredFee = true;
|
||||
request.ensureMinRequiredFee = ensureMinRequiredFee;
|
||||
request.emptyWallet = emptyWallet;
|
||||
wallet.completeTx(request);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user