mirror of
https://github.com/bitcoinj/bitcoinj.git
synced 2025-01-18 21:32:35 +01:00
TransactionWitness: make immutable
Except for the pushes themselves.
This commit is contained in:
parent
2699ea1708
commit
ae22162de5
@ -28,12 +28,14 @@ import java.nio.BufferUnderflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.bitcoinj.base.internal.Preconditions.checkArgument;
|
||||
|
||||
public class TransactionWitness {
|
||||
public static final TransactionWitness EMPTY = new TransactionWitness(0);
|
||||
public static final TransactionWitness EMPTY = TransactionWitness.of(Collections.emptyList());
|
||||
|
||||
/**
|
||||
* Creates the stack pushes necessary to redeem a P2WPKH output. If given signature is null, an empty push will be
|
||||
@ -42,24 +44,22 @@ public class TransactionWitness {
|
||||
public static TransactionWitness redeemP2WPKH(@Nullable TransactionSignature signature, ECKey pubKey) {
|
||||
checkArgument(pubKey.isCompressed(), () ->
|
||||
"only compressed keys allowed");
|
||||
TransactionWitness witness = new TransactionWitness(2);
|
||||
witness.setPush(0, signature != null ? signature.encodeToBitcoin() : new byte[0]); // signature
|
||||
witness.setPush(1, pubKey.getPubKey()); // pubkey
|
||||
return witness;
|
||||
List<byte[]> pushes = new ArrayList<>(2);
|
||||
pushes.add(signature != null ? signature.encodeToBitcoin() : new byte[0]); // signature
|
||||
pushes.add(pubKey.getPubKey()); // pubkey
|
||||
return TransactionWitness.of(pushes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the stack pushes necessary to redeem a P2WSH output.
|
||||
*/
|
||||
public static TransactionWitness redeemP2WSH(Script witnessScript, TransactionSignature... signatures) {
|
||||
TransactionWitness witness = new TransactionWitness(signatures.length + 2);
|
||||
witness.setPush(0, new byte[]{});
|
||||
int i;
|
||||
for (i = 0; i < signatures.length; i++) {
|
||||
witness.setPush(i + 1, signatures[i].encodeToBitcoin());
|
||||
}
|
||||
witness.setPush(i + 1, witnessScript.getProgram());
|
||||
return witness;
|
||||
List<byte[]> pushes = new ArrayList<>(signatures.length + 2);
|
||||
pushes.add(new byte[] {});
|
||||
for (TransactionSignature signature : signatures)
|
||||
pushes.add(signature.encodeToBitcoin());
|
||||
pushes.add(witnessScript.getProgram());
|
||||
return TransactionWitness.of(pushes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,6 +72,16 @@ public class TransactionWitness {
|
||||
return new TransactionWitness(pushes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a transaction witness from a given list of arbitrary pushes.
|
||||
*
|
||||
* @param pushes list of pushes
|
||||
* @return constructed transaction witness
|
||||
*/
|
||||
public static TransactionWitness of(byte[]... pushes) {
|
||||
return of(Arrays.asList(pushes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize this transaction witness from a given payload.
|
||||
*
|
||||
@ -89,10 +99,6 @@ public class TransactionWitness {
|
||||
|
||||
private final List<byte[]> pushes;
|
||||
|
||||
public TransactionWitness(int pushCount) {
|
||||
pushes = new ArrayList<>(Math.min(pushCount, Utils.MAX_INITIAL_ARRAY_LENGTH));
|
||||
}
|
||||
|
||||
private TransactionWitness(List<byte[]> pushes) {
|
||||
this.pushes = pushes;
|
||||
}
|
||||
@ -105,13 +111,6 @@ public class TransactionWitness {
|
||||
return pushes.size();
|
||||
}
|
||||
|
||||
public void setPush(int i, byte[] value) {
|
||||
while (i >= pushes.size()) {
|
||||
pushes.add(new byte[]{});
|
||||
}
|
||||
pushes.set(i, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write this transaction witness into the given buffer.
|
||||
*
|
||||
|
@ -656,10 +656,10 @@ public class WalletProtobufSerializer {
|
||||
if (inputProto.hasWitness()) {
|
||||
Protos.ScriptWitness witnessProto = inputProto.getWitness();
|
||||
if (witnessProto.getDataCount() > 0) {
|
||||
TransactionWitness witness = new TransactionWitness(witnessProto.getDataCount());
|
||||
List<byte[]> pushes = new ArrayList<>(witnessProto.getDataCount());
|
||||
for (int j = 0; j < witnessProto.getDataCount(); j++)
|
||||
witness.setPush(j, witnessProto.getData(j).toByteArray());
|
||||
input.setWitness(witness);
|
||||
pushes.add(witnessProto.getData(j).toByteArray());
|
||||
input.setWitness(TransactionWitness.of(pushes));
|
||||
}
|
||||
}
|
||||
tx.addInput(input);
|
||||
|
@ -713,8 +713,7 @@ public class TransactionTest {
|
||||
inputTx.addOutput(Coin.FIFTY_COINS, new ECKey());
|
||||
this.addInput(inputTx.getOutput(0));
|
||||
this.getInput(0).disconnect();
|
||||
TransactionWitness witness = new TransactionWitness(1);
|
||||
witness.setPush(0, new byte[] {0});
|
||||
TransactionWitness witness = TransactionWitness.of(new byte[] { 0 });
|
||||
this.getInput(0).setWitness(witness);
|
||||
this.addOutput(Coin.COIN, new ECKey());
|
||||
|
||||
|
@ -40,16 +40,14 @@ public class TransactionWitnessTest {
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
TransactionWitness w1 = new TransactionWitness(0);
|
||||
TransactionWitness w1 = TransactionWitness.EMPTY;
|
||||
assertEquals("", w1.toString());
|
||||
|
||||
TransactionWitness w2 = new TransactionWitness(2);
|
||||
assertEquals("", w2.toString());
|
||||
TransactionWitness w2 = TransactionWitness.of(new byte[0], new byte[0]);
|
||||
assertEquals("EMPTY EMPTY", w2.toString());
|
||||
|
||||
TransactionWitness w3 = new TransactionWitness(3);
|
||||
w3.setPush(0, ByteUtils.parseHex("123aaa"));
|
||||
w3.setPush(1, ByteUtils.parseHex("123bbb"));
|
||||
w3.setPush(3, ByteUtils.parseHex("123ccc"));
|
||||
TransactionWitness w3 = TransactionWitness.of(ByteUtils.parseHex("123aaa"), ByteUtils.parseHex("123bbb"),
|
||||
new byte[0], ByteUtils.parseHex("123ccc"));
|
||||
assertEquals("123aaa 123bbb EMPTY 123ccc", w3.toString());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user