mirror of
https://github.com/sparrowwallet/drongo.git
synced 2024-12-26 10:06:45 +00:00
sequence number handling improvements
This commit is contained in:
parent
d28186f8c9
commit
130fea0937
4 changed files with 57 additions and 14 deletions
|
@ -21,9 +21,10 @@ public class Transaction extends TransactionPart {
|
||||||
public static final int MAX_BLOCK_SIZE = 1000 * 1000;
|
public static final int MAX_BLOCK_SIZE = 1000 * 1000;
|
||||||
public static final long MAX_BITCOIN = 21 * 1000 * 1000L;
|
public static final long MAX_BITCOIN = 21 * 1000 * 1000L;
|
||||||
public static final long SATOSHIS_PER_BITCOIN = 100 * 1000 * 1000L;
|
public static final long SATOSHIS_PER_BITCOIN = 100 * 1000 * 1000L;
|
||||||
|
public static final long MAX_BLOCK_LOCKTIME = 500000000L;
|
||||||
|
|
||||||
private long version;
|
private long version;
|
||||||
private long lockTime;
|
private long locktime;
|
||||||
private boolean segwit;
|
private boolean segwit;
|
||||||
private int segwitVersion;
|
private int segwitVersion;
|
||||||
|
|
||||||
|
@ -45,19 +46,34 @@ public class Transaction extends TransactionPart {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLockTime() {
|
public long getLocktime() {
|
||||||
return lockTime;
|
return locktime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLockTime(long lockTime) {
|
public void setLocktime(long locktime) {
|
||||||
this.lockTime = lockTime;
|
this.locktime = locktime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLockTimeEnabled() {
|
public boolean isLocktimeEnabled() {
|
||||||
if(lockTime == 0) return false;
|
if(locktime == 0) return false;
|
||||||
|
return isLocktimeSequenceEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isLocktimeSequenceEnabled() {
|
||||||
|
for(TransactionInput input : inputs) {
|
||||||
|
if(!input.isAbsoluteTimeLockDisabled()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReplaceByFee() {
|
||||||
|
if(locktime == 0) return false;
|
||||||
|
|
||||||
for(TransactionInput input : inputs) {
|
for(TransactionInput input : inputs) {
|
||||||
if(input.getSequenceNumber() != TransactionInput.SEQUENCE_LOCKTIME_DISABLED) {
|
if(input.isReplaceByFeeEnabled()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,7 +165,7 @@ public class Transaction extends TransactionPart {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// lock_time
|
// lock_time
|
||||||
uint32ToByteStreamLE(lockTime, stream);
|
uint32ToByteStreamLE(locktime, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,7 +192,7 @@ public class Transaction extends TransactionPart {
|
||||||
if (segwit)
|
if (segwit)
|
||||||
parseWitnesses();
|
parseWitnesses();
|
||||||
// lock_time
|
// lock_time
|
||||||
lockTime = readUint32();
|
locktime = readUint32();
|
||||||
|
|
||||||
length = cursor - offset;
|
length = cursor - offset;
|
||||||
}
|
}
|
||||||
|
@ -456,7 +472,7 @@ public class Transaction extends TransactionPart {
|
||||||
uint64ToByteStreamLE(BigInteger.valueOf(prevValue), bos);
|
uint64ToByteStreamLE(BigInteger.valueOf(prevValue), bos);
|
||||||
uint32ToByteStreamLE(inputs.get(inputIndex).getSequenceNumber(), bos);
|
uint32ToByteStreamLE(inputs.get(inputIndex).getSequenceNumber(), bos);
|
||||||
bos.write(hashOutputs);
|
bos.write(hashOutputs);
|
||||||
uint32ToByteStreamLE(this.lockTime, bos);
|
uint32ToByteStreamLE(this.locktime, bos);
|
||||||
uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
|
uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e); // Cannot happen.
|
throw new RuntimeException(e); // Cannot happen.
|
||||||
|
|
|
@ -6,7 +6,10 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
public class TransactionInput extends TransactionPart {
|
public class TransactionInput extends TransactionPart {
|
||||||
public static final long SEQUENCE_LOCKTIME_DISABLED = 0xFFFFFFFF;
|
public static final long SEQUENCE_LOCKTIME_DISABLED = 4294967295L;
|
||||||
|
public static final long SEQUENCE_RBF_ENABLED = 4294967293L;
|
||||||
|
public static final long MAX_RELATIVE_TIMELOCK = 0x40FFFF;
|
||||||
|
public static final long MAX_RELATIVE_TIMELOCK_IN_BLOCKS = 0xFFFF;
|
||||||
|
|
||||||
// Allows for altering transactions after they were broadcast. Values below NO_SEQUENCE-1 mean it can be altered.
|
// Allows for altering transactions after they were broadcast. Values below NO_SEQUENCE-1 mean it can be altered.
|
||||||
private long sequence;
|
private long sequence;
|
||||||
|
@ -97,6 +100,30 @@ public class TransactionInput extends TransactionPart {
|
||||||
(outpoint.getIndex() & 0xFFFFFFFFL) == 0xFFFFFFFFL; // -1 but all is serialized to the wire as unsigned int.
|
(outpoint.getIndex() & 0xFFFFFFFFL) == 0xFFFFFFFFL; // -1 but all is serialized to the wire as unsigned int.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isReplaceByFeeEnabled() {
|
||||||
|
return sequence <= SEQUENCE_RBF_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAbsoluteTimeLockDisabled() {
|
||||||
|
return sequence >= SEQUENCE_LOCKTIME_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAbsoluteTimeLocked() {
|
||||||
|
return !isAbsoluteTimeLockDisabled() && !isRelativeTimeLocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRelativeTimeLocked() {
|
||||||
|
return sequence <= MAX_RELATIVE_TIMELOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRelativeTimeLockedInBlocks() {
|
||||||
|
return sequence <= MAX_RELATIVE_TIMELOCK_IN_BLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getRelativeLocktime() {
|
||||||
|
return sequence & MAX_RELATIVE_TIMELOCK_IN_BLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
protected void bitcoinSerializeToStream(OutputStream stream) throws IOException {
|
||||||
outpoint.bitcoinSerializeToStream(stream);
|
outpoint.bitcoinSerializeToStream(stream);
|
||||||
stream.write(new VarInt(scriptBytes.length).encode());
|
stream.write(new VarInt(scriptBytes.length).encode());
|
||||||
|
|
|
@ -202,7 +202,7 @@ public class PSBT {
|
||||||
transaction.verify();
|
transaction.verify();
|
||||||
inputs = transaction.getInputs().size();
|
inputs = transaction.getInputs().size();
|
||||||
outputs = transaction.getOutputs().size();
|
outputs = transaction.getOutputs().size();
|
||||||
log.debug("Transaction with txid: " + transaction.getTxId() + " version " + transaction.getVersion() + " size " + transaction.getMessageSize() + " locktime " + transaction.getLockTime());
|
log.debug("Transaction with txid: " + transaction.getTxId() + " version " + transaction.getVersion() + " size " + transaction.getMessageSize() + " locktime " + transaction.getLocktime());
|
||||||
for(TransactionInput input: transaction.getInputs()) {
|
for(TransactionInput input: transaction.getInputs()) {
|
||||||
if(input.getScriptSig().getProgram().length != 0) {
|
if(input.getScriptSig().getProgram().length != 0) {
|
||||||
throw new PSBTParseException("Unsigned tx input does not have empty scriptSig");
|
throw new PSBTParseException("Unsigned tx input does not have empty scriptSig");
|
||||||
|
|
|
@ -65,7 +65,7 @@ public class PSBTInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nonWitnessUtxo = nonWitnessTx;
|
this.nonWitnessUtxo = nonWitnessTx;
|
||||||
log.debug("Found input non witness utxo with txid: " + nonWitnessTx.getTxId() + " version " + nonWitnessTx.getVersion() + " size " + nonWitnessTx.getMessageSize() + " locktime " + nonWitnessTx.getLockTime());
|
log.debug("Found input non witness utxo with txid: " + nonWitnessTx.getTxId() + " version " + nonWitnessTx.getVersion() + " size " + nonWitnessTx.getMessageSize() + " locktime " + nonWitnessTx.getLocktime());
|
||||||
for(TransactionInput input: nonWitnessTx.getInputs()) {
|
for(TransactionInput input: nonWitnessTx.getInputs()) {
|
||||||
log.debug(" Transaction input references txid: " + input.getOutpoint().getHash() + " vout " + input.getOutpoint().getIndex() + " with script " + input.getScriptSig());
|
log.debug(" Transaction input references txid: " + input.getOutpoint().getHash() + " vout " + input.getOutpoint().getIndex() + " with script " + input.getScriptSig());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue