Transaction: make more use of getInput(index)

This commit is contained in:
Andreas Schildbach 2023-04-08 16:33:15 +02:00
parent 054defe54c
commit 87bf6c0266
11 changed files with 27 additions and 27 deletions

View file

@ -157,7 +157,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
try { try {
ListIterator<Script> prevOutIt = prevOutScripts.listIterator(); ListIterator<Script> prevOutIt = prevOutScripts.listIterator();
for (int index = 0; index < tx.getInputs().size(); index++) { for (int index = 0; index < tx.getInputs().size(); index++) {
tx.getInputs().get(index).getScriptSig().correctlySpends(tx, index, null, null, prevOutIt.next(), tx.getInput(index).getScriptSig().correctlySpends(tx, index, null, null, prevOutIt.next(),
verifyFlags); verifyFlags);
} }
} catch (VerificationException e) { } catch (VerificationException e) {
@ -242,7 +242,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
// For each input of the transaction remove the corresponding output from the set of unspent // For each input of the transaction remove the corresponding output from the set of unspent
// outputs. // outputs.
for (int index = 0; index < tx.getInputs().size(); index++) { for (int index = 0; index < tx.getInputs().size(); index++) {
TransactionInput in = tx.getInputs().get(index); TransactionInput in = tx.getInput(index);
UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().hash(), UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().hash(),
in.getOutpoint().index()); in.getOutpoint().index());
if (prevOut == null) if (prevOut == null)
@ -373,7 +373,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
if (!isCoinBase) { if (!isCoinBase) {
for (int index = 0; index < tx.getInputs().size(); index++) { for (int index = 0; index < tx.getInputs().size(); index++) {
final TransactionInput in = tx.getInputs().get(index); final TransactionInput in = tx.getInput(index);
final UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().hash(), final UTXO prevOut = blockStore.getTransactionOutput(in.getOutpoint().hash(),
in.getOutpoint().index()); in.getOutpoint().index());
if (prevOut == null) if (prevOut == null)

View file

@ -1687,7 +1687,7 @@ public class Transaction extends Message {
checkState(isCoinBase()); checkState(isCoinBase());
// Check block height is in coinbase input script // Check block height is in coinbase input script
final TransactionInput in = this.getInputs().get(0); final TransactionInput in = this.getInput(0);
final ScriptBuilder builder = new ScriptBuilder(); final ScriptBuilder builder = new ScriptBuilder();
builder.number(height); builder.number(height);
final byte[] expected = builder.build().getProgram(); final byte[] expected = builder.build().getProgram();

View file

@ -110,7 +110,7 @@ public class BitcoinSerializerTest {
transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES)); transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES));
assertNotNull(transaction); assertNotNull(transaction);
transaction.getInputs().get(0).setSequenceNumber(1); transaction.getInput(0).setSequenceNumber(1);
bos = new ByteArrayOutputStream(); bos = new ByteArrayOutputStream();
serializer.serialize(transaction, bos); serializer.serialize(transaction, bos);
@ -127,7 +127,7 @@ public class BitcoinSerializerTest {
transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES)); transaction = (Transaction) serializer.deserialize(ByteBuffer.wrap(TRANSACTION_MESSAGE_BYTES));
assertNotNull(transaction); assertNotNull(transaction);
transaction.getInputs().get(0).setSequenceNumber(transaction.getInputs().get(0).getSequenceNumber()); transaction.getInput(0).setSequenceNumber(transaction.getInputs().get(0).getSequenceNumber());
bos = new ByteArrayOutputStream(); bos = new ByteArrayOutputStream();
serializer.serialize(transaction, bos); serializer.serialize(transaction, bos);

View file

@ -483,7 +483,7 @@ public class FullBlockTestGenerator {
// //
NewBlock b26 = createNextBlock(b15, chainHeadHeight + 7, out6, null); NewBlock b26 = createNextBlock(b15, chainHeadHeight + 7, out6, null);
// 1 is too small, but we already generate every other block with 2, so that is tested // 1 is too small, but we already generate every other block with 2, so that is tested
b26.block.getTransactions().get(0).getInputs().get(0).clearScriptBytes(); b26.block.getTransactions().get(0).getInput(0).clearScriptBytes();
b26.block.setMerkleRoot(null); b26.block.setMerkleRoot(null);
b26.solve(); b26.solve();
blocks.add(new BlockAndValidity(b26, false, true, b23.getHash(), chainHeadHeight + 7, "b26")); blocks.add(new BlockAndValidity(b26, false, true, b23.getHash(), chainHeadHeight + 7, "b26"));
@ -496,7 +496,7 @@ public class FullBlockTestGenerator {
{ {
byte[] coinbase = new byte[101]; byte[] coinbase = new byte[101];
Arrays.fill(coinbase, (byte)0); Arrays.fill(coinbase, (byte)0);
b28.block.getTransactions().get(0).getInputs().get(0).setScriptBytes(coinbase); b28.block.getTransactions().get(0).getInput(0).setScriptBytes(coinbase);
} }
b28.block.setMerkleRoot(null); b28.block.setMerkleRoot(null);
b28.solve(); b28.solve();
@ -510,7 +510,7 @@ public class FullBlockTestGenerator {
{ {
byte[] coinbase = new byte[100]; byte[] coinbase = new byte[100];
Arrays.fill(coinbase, (byte)0); Arrays.fill(coinbase, (byte)0);
b30.block.getTransactions().get(0).getInputs().get(0).setScriptBytes(coinbase); b30.block.getTransactions().get(0).getInput(0).setScriptBytes(coinbase);
} }
b30.block.setMerkleRoot(null); b30.block.setMerkleRoot(null);
b30.solve(); b30.solve();
@ -1193,7 +1193,7 @@ public class FullBlockTestGenerator {
NewBlock b63 = createNextBlock(b60, chainHeadHeight + 19, null, null); NewBlock b63 = createNextBlock(b60, chainHeadHeight + 19, null, null);
{ {
b63.block.getTransactions().get(0).setLockTime(0xffffffffL); b63.block.getTransactions().get(0).setLockTime(0xffffffffL);
b63.block.getTransactions().get(0).getInputs().get(0).setSequenceNumber(0xdeadbeefL); b63.block.getTransactions().get(0).getInput(0).setSequenceNumber(0xdeadbeefL);
checkState(!b63.block.getTransactions().get(0).isFinal(chainHeadHeight + 17, b63.block.getTimeSeconds())); checkState(!b63.block.getTransactions().get(0).isFinal(chainHeadHeight + 17, b63.block.getTimeSeconds()));
} }
b63.solve(); b63.solve();

View file

@ -217,7 +217,7 @@ public class ParseByteCacheTest {
if (b1.getTransactions().size() > 0) { if (b1.getTransactions().size() > 0) {
Transaction tx1 = b1.getTransactions().get(0); Transaction tx1 = b1.getTransactions().get(0);
TransactionInput tin = tx1.getInputs().get(0); TransactionInput tin = tx1.getInput(0);
// does it still match ref tx? // does it still match ref tx?
bos.reset(); bos.reset();
@ -235,9 +235,9 @@ public class ParseByteCacheTest {
Transaction tx1 = b1.getTransactions().get(0); Transaction tx1 = b1.getTransactions().get(0);
if (tx1.getInputs().size() > 0) { if (tx1.getInputs().size() > 0) {
tx1.addInput(tx1.getInputs().get(0)); tx1.addInput(tx1.getInput(0));
// replicate on reference tx // replicate on reference tx
bRef.getTransactions().get(0).addInput(bRef.getTransactions().get(0).getInputs().get(0)); bRef.getTransactions().get(0).addInput(bRef.getTransactions().get(0).getInput(0));
bos.reset(); bos.reset();
serializerRef.serialize(bRef, bos); serializerRef.serialize(bRef, bos);
@ -265,11 +265,11 @@ public class ParseByteCacheTest {
Transaction tx2 = b2.getTransactions().get(0); Transaction tx2 = b2.getTransactions().get(0);
if (tx1.getInputs().size() > 0) { if (tx1.getInputs().size() > 0) {
TransactionInput fromTx1 = tx1.getInputs().get(0); TransactionInput fromTx1 = tx1.getInput(0);
tx2.addInput(fromTx1); tx2.addInput(fromTx1);
// replicate on reference tx // replicate on reference tx
TransactionInput fromTxRef = bRef.getTransactions().get(0).getInputs().get(0); TransactionInput fromTxRef = bRef.getTransactions().get(0).getInput(0);
bRef2.getTransactions().get(0).addInput(fromTxRef); bRef2.getTransactions().get(0).addInput(fromTxRef);
bos.reset(); bos.reset();
@ -322,7 +322,7 @@ public class ParseByteCacheTest {
// retrieve a value from a child // retrieve a value from a child
t1.getInputs(); t1.getInputs();
if (t1.getInputs().size() > 0) { if (t1.getInputs().size() > 0) {
TransactionInput tin = t1.getInputs().get(0); TransactionInput tin = t1.getInput(0);
// does it still match ref tx? // does it still match ref tx?
serDeser(serializer, t1, bos.toByteArray(), null, null); serDeser(serializer, t1, bos.toByteArray(), null, null);
@ -335,10 +335,10 @@ public class ParseByteCacheTest {
// add an input // add an input
if (t1.getInputs().size() > 0) { if (t1.getInputs().size() > 0) {
t1.addInput(t1.getInputs().get(0)); t1.addInput(t1.getInput(0));
// replicate on reference tx // replicate on reference tx
tRef.addInput(tRef.getInputs().get(0)); tRef.addInput(tRef.getInput(0));
bos.reset(); bos.reset();
serializerRef.serialize(tRef, bos); serializerRef.serialize(tRef, bos);

View file

@ -608,7 +608,7 @@ public class TransactionTest {
Transaction tx = FakeTxBuilder.createFakeTx(TESTNET); Transaction tx = FakeTxBuilder.createFakeTx(TESTNET);
assertFalse(tx.isOptInFullRBF()); assertFalse(tx.isOptInFullRBF());
tx.getInputs().get(0).setSequenceNumber(TransactionInput.NO_SEQUENCE - 2); tx.getInput(0).setSequenceNumber(TransactionInput.NO_SEQUENCE - 2);
assertTrue(tx.isOptInFullRBF()); assertTrue(tx.isOptInFullRBF());
} }

View file

@ -396,7 +396,7 @@ public class ScriptTest {
Set<VerifyFlag> verifyFlags = parseVerifyFlags(test.get(2).asText()); Set<VerifyFlag> verifyFlags = parseVerifyFlags(test.get(2).asText());
for (int i = 0; i < transaction.getInputs().size(); i++) { for (int i = 0; i < transaction.getInputs().size(); i++) {
TransactionInput input = transaction.getInputs().get(i); TransactionInput input = transaction.getInput(i);
assertTrue(scriptPubKeys.containsKey(input.getOutpoint())); assertTrue(scriptPubKeys.containsKey(input.getOutpoint()));
input.getScriptSig().correctlySpends(transaction, i, null, null, input.getScriptSig().correctlySpends(transaction, i, null, null,
scriptPubKeys.get(input.getOutpoint()), verifyFlags); scriptPubKeys.get(input.getOutpoint()), verifyFlags);
@ -448,7 +448,7 @@ public class ScriptTest {
} }
for (int i = 0; i < transaction.getInputs().size() && valid; i++) { for (int i = 0; i < transaction.getInputs().size() && valid; i++) {
TransactionInput input = transaction.getInputs().get(i); TransactionInput input = transaction.getInput(i);
assertTrue(scriptPubKeys.containsKey(input.getOutpoint())); assertTrue(scriptPubKeys.containsKey(input.getOutpoint()));
try { try {
input.getScriptSig().correctlySpends(transaction, i, null, null, input.getScriptSig().correctlySpends(transaction, i, null, null,

View file

@ -164,7 +164,7 @@ public class WalletProtobufSerializerTest {
assertEquals(Protos.Transaction.Pool.PENDING, t1p.getPool()); assertEquals(Protos.Transaction.Pool.PENDING, t1p.getPool());
assertFalse(t1p.hasLockTime()); assertFalse(t1p.hasLockTime());
assertFalse(t1p.getTransactionInput(0).hasSequence()); assertFalse(t1p.getTransactionInput(0).hasSequence());
assertArrayEquals(t1.getInputs().get(0).getOutpoint().hash().getBytes(), assertArrayEquals(t1.getInput(0).getOutpoint().hash().getBytes(),
t1p.getTransactionInput(0).getTransactionOutPointHash().toByteArray()); t1p.getTransactionInput(0).getTransactionOutPointHash().toByteArray());
assertEquals(0, t1p.getTransactionInput(0).getTransactionOutPointIndex()); assertEquals(0, t1p.getTransactionInput(0).getTransactionOutPointIndex());
assertEquals(t1p.getTransactionOutput(0).getValue(), v1.value); assertEquals(t1p.getTransactionOutput(0).getValue(), v1.value);

View file

@ -208,7 +208,7 @@ public class DefaultRiskAnalysisTest {
"010000000200a2be4376b7f47250ad9ad3a83b6aa5eb6a6d139a1f50771704d77aeb8ce76c010000006a4730440220055723d363cd2d4fe4e887270ebdf5c4b99eaf233a5c09f9404f888ec8b839350220763c3794d310b384ce86decfb05787e5bfa5d31983db612a2dde5ffec7f396ae012102ef47e27e0c4bdd6dc83915f185d972d5eb8515c34d17bad584a9312e59f4e0bcffffffff52239451d37757eeacb86d32864ec1ee6b6e131d1e3fee6f1cff512703b71014030000006c493046022100ea266ac4f893d98a623a6fc0e6a961cd5a3f32696721e87e7570a68851917e75022100a928a3c4898be60909347e765f52872a613d8aada66c57a8c8791316d2f298710121038bb455ca101ebbb0ecf7f5c01fa1dcb7d14fbf6b7d7ea52ee56f0148e72a736cffffffff0630b15a00000000001976a9146ae477b690cf85f21c2c01e2c8639a5c18dc884e88ac4f260d00000000001976a91498d08c02ab92a671590adb726dddb719695ee12e88ac65753b00000000001976a9140b2eb4ba6d364c82092f25775f56bc10cd92c8f188ac65753b00000000001976a914d1cb414e22081c6ba3a935635c0f1d837d3c5d9188ac65753b00000000001976a914df9d137a0d279471a2796291874c29759071340b88ac3d753b00000000001976a91459f5aa4815e3aa8e1720e8b82f4ac8e6e904e47d88ac00000000"))); "010000000200a2be4376b7f47250ad9ad3a83b6aa5eb6a6d139a1f50771704d77aeb8ce76c010000006a4730440220055723d363cd2d4fe4e887270ebdf5c4b99eaf233a5c09f9404f888ec8b839350220763c3794d310b384ce86decfb05787e5bfa5d31983db612a2dde5ffec7f396ae012102ef47e27e0c4bdd6dc83915f185d972d5eb8515c34d17bad584a9312e59f4e0bcffffffff52239451d37757eeacb86d32864ec1ee6b6e131d1e3fee6f1cff512703b71014030000006c493046022100ea266ac4f893d98a623a6fc0e6a961cd5a3f32696721e87e7570a68851917e75022100a928a3c4898be60909347e765f52872a613d8aada66c57a8c8791316d2f298710121038bb455ca101ebbb0ecf7f5c01fa1dcb7d14fbf6b7d7ea52ee56f0148e72a736cffffffff0630b15a00000000001976a9146ae477b690cf85f21c2c01e2c8639a5c18dc884e88ac4f260d00000000001976a91498d08c02ab92a671590adb726dddb719695ee12e88ac65753b00000000001976a9140b2eb4ba6d364c82092f25775f56bc10cd92c8f188ac65753b00000000001976a914d1cb414e22081c6ba3a935635c0f1d837d3c5d9188ac65753b00000000001976a914df9d137a0d279471a2796291874c29759071340b88ac3d753b00000000001976a91459f5aa4815e3aa8e1720e8b82f4ac8e6e904e47d88ac00000000")));
assertEquals("dbe4147cf89b89fd9fa6c8ce6a3e2adecb234db094ec88301ae09073ca17d61d", tx2.getTxId().toString()); assertEquals("dbe4147cf89b89fd9fa6c8ce6a3e2adecb234db094ec88301ae09073ca17d61d", tx2.getTxId().toString());
assertFalse(ECKey.ECDSASignature assertFalse(ECKey.ECDSASignature
.decodeFromDER(new Script(tx2.getInputs().get(1).getScriptBytes()).getChunks().get(0).data) .decodeFromDER(new Script(tx2.getInput(1).getScriptBytes()).getChunks().get(0).data)
.isCanonical()); .isCanonical());
assertEquals(RuleViolation.SIGNATURE_CANONICAL_ENCODING, DefaultRiskAnalysis.isStandard(tx2)); assertEquals(RuleViolation.SIGNATURE_CANONICAL_ENCODING, DefaultRiskAnalysis.isStandard(tx2));

View file

@ -485,7 +485,7 @@ public class WalletTest extends TestWithWallet {
assertEquals(wallet.currentChangeAddress(), t.getOutput(1).getScriptPubKey().getToAddress(BitcoinNetwork.TESTNET)); assertEquals(wallet.currentChangeAddress(), t.getOutput(1).getScriptPubKey().getToAddress(BitcoinNetwork.TESTNET));
assertEquals(valueOf(0, 50), t.getOutput(1).getValue()); assertEquals(valueOf(0, 50), t.getOutput(1).getValue());
// Check the script runs and signatures verify. // Check the script runs and signatures verify.
t.getInputs().get(0).verify(); t.getInput(0).verify();
} }
private static void broadcastAndCommit(Wallet wallet, Transaction t) throws Exception { private static void broadcastAndCommit(Wallet wallet, Transaction t) throws Exception {
@ -1571,8 +1571,8 @@ public class WalletTest extends TestWithWallet {
Transaction t2 = wallet.createSend(OTHER_ADDRESS, value); Transaction t2 = wallet.createSend(OTHER_ADDRESS, value);
assertNotNull(t2); assertNotNull(t2);
// TODO: This code is messy, improve the Script class and fixinate! // TODO: This code is messy, improve the Script class and fixinate!
assertEquals(t2.toString(), 1, t2.getInputs().get(0).getScriptSig().getChunks().size()); assertEquals(t2.toString(), 1, t2.getInput(0).getScriptSig().getChunks().size());
assertTrue(t2.getInputs().get(0).getScriptSig().getChunks().get(0).data.length > 50); assertTrue(t2.getInput(0).getScriptSig().getChunks().get(0).data.length > 50);
} }
@Test @Test

View file

@ -707,7 +707,7 @@ public class WalletTool implements Callable<Integer> {
if (lockTimeStr != null) { if (lockTimeStr != null) {
tx.setLockTime(parseLockTimeStr(lockTimeStr)); tx.setLockTime(parseLockTimeStr(lockTimeStr));
// For lock times to take effect, at least one output must have a non-final sequence number. // For lock times to take effect, at least one output must have a non-final sequence number.
tx.getInputs().get(0).setSequenceNumber(0); tx.getInput(0).setSequenceNumber(0);
// And because we modified the transaction after it was completed, we must re-sign the inputs. // And because we modified the transaction after it was completed, we must re-sign the inputs.
wallet.signTransaction(req); wallet.signTransaction(req);
} }