3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-31 23:32:16 +00:00

Refuse to create transactions larger than the max standard size.

This commit is contained in:
Mike Hearn 2013-03-01 19:48:45 +01:00
parent 1c8ee2b116
commit 6799dcc348
3 changed files with 31 additions and 2 deletions

View File

@ -47,8 +47,12 @@ public class Transaction extends ChildMessage implements Serializable {
private static final Logger log = LoggerFactory.getLogger(Transaction.class); private static final Logger log = LoggerFactory.getLogger(Transaction.class);
private static final long serialVersionUID = -8567546957352643140L; private static final long serialVersionUID = -8567546957352643140L;
// Threshold for lockTime: below this value it is interpreted as block number, otherwise as timestamp. /** Threshold for lockTime: below this value it is interpreted as block number, otherwise as timestamp. **/
static final int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC public static final int LOCKTIME_THRESHOLD = 500000000; // Tue Nov 5 00:53:20 1985 UTC
/** How many bytes a transaction can be before it won't be relayed anymore. */
public static final int MAX_STANDARD_TX_SIZE = 100 * 1024;
// These are serialized in both bitcoin and java serialization. // These are serialized in both bitcoin and java serialization.
private long version; private long version;

View File

@ -1751,6 +1751,14 @@ public class Wallet implements Serializable, BlockChainListener {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
// Check size.
int size = req.tx.bitcoinSerialize().length;
if (size > Transaction.MAX_STANDARD_TX_SIZE) {
// TODO: Throw an exception here.
log.error("Transaction could not be created without exceeding max size: {} vs {}", size, Transaction.MAX_STANDARD_TX_SIZE);
return false;
}
// Label the transaction as being self created. We can use this later to spend its change output even before // Label the transaction as being self created. We can use this later to spend its change output even before
// the transaction is confirmed. // the transaction is confirmed.
req.tx.getConfidence().setSource(TransactionConfidence.Source.SELF); req.tx.getConfidence().setSource(TransactionConfidence.Source.SELF);

View File

@ -32,6 +32,7 @@ import java.net.InetAddress;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -896,6 +897,22 @@ public class WalletTest {
} }
} }
@Test
public void respectMaxStandardSize() throws Exception {
// Check that we won't create txns > 100kb. Average tx size is ~220 bytes so this would have to be enormous.
sendMoneyToWallet(Utils.toNanoCoins(100, 0), AbstractBlockChain.NewBlockType.BEST_CHAIN);
Transaction tx = new Transaction(params);
byte[] bits = new byte[20];
new Random().nextBytes(bits);
BigInteger v = Utils.toNanoCoins(0, 1);
// 3100 outputs to a random address.
for (int i = 0; i < 3100; i++) {
tx.addOutput(v, new Address(params, bits));
}
Wallet.SendRequest req = Wallet.SendRequest.forTx(tx);
assertFalse(wallet.completeTx(req));
}
// There is a test for spending a coinbase transaction as it matures in BlockChainTest#coinbaseTransactionAvailability // There is a test for spending a coinbase transaction as it matures in BlockChainTest#coinbaseTransactionAvailability
// Support for offline spending is tested in PeerGroupTest // Support for offline spending is tested in PeerGroupTest