Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dao improvements #1746

Merged
merged 20 commits into from Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion common/src/main/proto/pb.proto
Expand Up @@ -1336,7 +1336,6 @@ message Tx {
repeated BaseTxOutput tx_outputs = 1;
TxType txType = 2;
int64 burnt_fee = 3;
int32 unlock_block_height = 4;
}

enum TxType {
Expand Down Expand Up @@ -1381,6 +1380,7 @@ message RawTxOutput {
message TxOutput {
TxOutputType tx_output_type = 1;
int32 lock_time = 2;
int32 unlock_block_height = 3;
}

enum TxOutputType {
Expand Down
22 changes: 9 additions & 13 deletions core/src/main/java/bisq/core/dao/node/parser/TxInputParser.java
Expand Up @@ -115,20 +115,16 @@ void process(TxOutputKey txOutputKey, int blockHeight, String txId, int inputInd
break;
case UNLOCK_OUTPUT:
// This txInput is Spending an UNLOCK txOutput
int unlockBlockHeight = connectedTxOutput.getUnlockBlockHeight();
if (blockHeight < unlockBlockHeight) {
accumulatedInputValue -= inputValue;
burntBondValue += inputValue;
} else {
log.warn("We got a tx which spends the output from an unlock tx but before the " +
"unlockTime has passed. That leads to burned BSQ! " +
"blockHeight={}, unLockHeight={}", blockHeight, unlockBlockHeight);
}

//TODO We should add unlockBlockHeight to TempTxOutput and remove unlockBlockHeight from tempTx
// then we can use connectedTxOutput to access the unlockBlockHeight instead of the tx
bsqStateService.getTx(connectedTxOutput.getTxId()).ifPresent(unlockTx -> {
// Only count the input as BSQ input if spent after unlock time
if (blockHeight < unlockTx.getUnlockBlockHeight()) {
accumulatedInputValue -= inputValue;
burntBondValue += inputValue;
} else {
log.warn("We got a tx which spends the output from an unlock tx but before the " +
"unlockTime has passed. That leads to burned BSQ!");
}
});
// TODO what if tx is not present?
break;
case INVALID_OUTPUT:
default:
Expand Down
15 changes: 8 additions & 7 deletions core/src/main/java/bisq/core/dao/node/parser/TxOutputParser.java
Expand Up @@ -121,9 +121,11 @@ void processOpReturnOutput(TempTxOutput tempTxOutput) {
tempTxOutput.setTxOutputType(txOutputType);

optionalOpReturnType = getMappedOpReturnType(txOutputType);
// TODO: Do we really want to store the lockTime in another output as where we get it delivered?

// If we have a LOCKUP opReturn output we save the lockTime to apply it later to the LOCKUP output.
// We keep that data in that other output as it makes parsing of the UNLOCK tx easier.
optionalOpReturnType.filter(opReturnType -> opReturnType == OpReturnType.LOCKUP)
.ifPresent(verifiedOpReturnType -> lockTime = BondingConsensus.getLockTime(opReturnData));
.ifPresent(opReturnType -> lockTime = BondingConsensus.getLockTime(opReturnData));
}

/**
Expand Down Expand Up @@ -174,12 +176,9 @@ private void handleUnlockBondTx(TempTxOutput txOutput) {
availableInputValue -= optionalSpentLockupTxOutput.get().getValue();

txOutput.setTxOutputType(TxOutputType.UNLOCK_OUTPUT);
txOutput.setUnlockBlockHeight(unlockBlockHeight);
tempTxOutputs.add(txOutput);

//TODO move up to TxParser
// We should add unlockBlockHeight to TempTxOutput and remove unlockBlockHeight from tempTx
tempTx.setUnlockBlockHeight(unlockBlockHeight);

bsqOutputFound = true;
}

Expand All @@ -203,7 +202,9 @@ private void handleBsqOutput(TempTxOutput txOutput, int index, long txOutputValu
} else if (isFirstOutput && opReturnTypeCandidate == OpReturnType.LOCKUP) {
bsqOutput = TxOutputType.LOCKUP_OUTPUT;

// TODO: Do we really want to store the lockTime in another output as where we get it delivered (opReturn)?
// We store the lockTime in the output which will be used as input for a unlock tx.
// That makes parsing of that data easier as if we would need to access it from the opReturn output of
// that tx.
txOutput.setLockTime(lockTime);
optionalLockupOutput = Optional.of(txOutput);
} else {
Expand Down
Expand Up @@ -43,7 +43,6 @@ public static TempTx fromRawTx(RawTx rawTx) {
rawTx.getTxInputs(),
ImmutableList.copyOf(rawTx.getRawTxOutputs().stream().map(TempTxOutput::fromRawTxOutput).collect(Collectors.toList())),
null,
0,
0);
}

Expand All @@ -53,8 +52,6 @@ public static TempTx fromRawTx(RawTx rawTx) {
@Nullable
private TxType txType;
private long burntFee;
// If not set it is -1. LockTime of 0 is a valid value.
private int unlockBlockHeight;


///////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -69,8 +66,7 @@ private TempTx(String txVersion,
ImmutableList<TxInput> txInputs,
ImmutableList<TempTxOutput> tempTxOutputs,
@Nullable TxType txType,
long burntFee,
int unlockBlockHeight) {
long burntFee) {
super(txVersion,
id,
blockHeight,
Expand All @@ -80,17 +76,14 @@ private TempTx(String txVersion,
this.tempTxOutputs = tempTxOutputs;
this.txType = txType;
this.burntFee = burntFee;
this.unlockBlockHeight = unlockBlockHeight;
}


@Override
public String toString() {
return "TempTx{" +
"\n txOutputs=" + tempTxOutputs +
",\n txType=" + txType +
",\n burntFee=" + burntFee +
",\n unlockBlockHeight=" + unlockBlockHeight +
"\n} " + super.toString();
}
}
Expand Up @@ -38,11 +38,14 @@ public static TempTxOutput fromRawTxOutput(RawTxOutput txOutput) {
txOutput.getOpReturnData(),
txOutput.getBlockHeight(),
TxOutputType.UNDEFINED_OUTPUT,
-1,
0);
}

private TxOutputType txOutputType;
// If not set it is -1, 0 is a valid value.
private int lockTime;
private int unlockBlockHeight;

private TempTxOutput(int index,
long value,
Expand All @@ -52,7 +55,8 @@ private TempTxOutput(int index,
@Nullable byte[] opReturnData,
int blockHeight,
TxOutputType txOutputType,
int lockTime) {
int lockTime,
int unlockBlockHeight) {
super(index,
value,
txId,
Expand All @@ -63,6 +67,7 @@ private TempTxOutput(int index,

this.txOutputType = txOutputType;
this.lockTime = lockTime;
this.unlockBlockHeight = unlockBlockHeight;
}


Expand All @@ -71,6 +76,7 @@ public String toString() {
return "TempTxOutput{" +
"\n txOutputType=" + txOutputType +
"\n lockTime=" + lockTime +
"\n unlockBlockHeight=" + unlockBlockHeight +
"\n} " + super.toString();
}
}
28 changes: 13 additions & 15 deletions core/src/main/java/bisq/core/dao/state/blockchain/Tx.java
Expand Up @@ -53,16 +53,13 @@ public static Tx fromTempTx(TempTx tempTx) {
tempTx.getTxInputs(),
txOutputs,
tempTx.getTxType(),
tempTx.getBurntFee(),
tempTx.getUnlockBlockHeight());
tempTx.getBurntFee());
}

private final ImmutableList<TxOutput> txOutputs;
@Nullable
private final TxType txType;
private final long burntFee;
// If not set it is -1. LockTime of 0 is a valid value.
private final int unlockBlockHeight;


///////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -77,8 +74,7 @@ private Tx(String txVersion,
ImmutableList<TxInput> txInputs,
ImmutableList<TxOutput> txOutputs,
@Nullable TxType txType,
long burntFee,
int unlockBlockHeight) {
long burntFee) {
super(txVersion,
id,
blockHeight,
Expand All @@ -88,7 +84,7 @@ private Tx(String txVersion,
this.txOutputs = txOutputs;
this.txType = txType;
this.burntFee = burntFee;
this.unlockBlockHeight = unlockBlockHeight;

}

@Override
Expand All @@ -97,8 +93,7 @@ public PB.BaseTx toProtoMessage() {
.addAllTxOutputs(txOutputs.stream()
.map(TxOutput::toProtoMessage)
.collect(Collectors.toList()))
.setBurntFee(burntFee)
.setUnlockBlockHeight(unlockBlockHeight);
.setBurntFee(burntFee);
Optional.ofNullable(txType).ifPresent(txType -> builder.setTxType(txType.toProtoMessage()));
return getBaseTxBuilder().setTx(builder).build();
}
Expand All @@ -123,8 +118,7 @@ public static Tx fromProto(PB.BaseTx protoBaseTx) {
txInputs,
outputs,
TxType.fromProto(protoTx.getTxType()),
protoTx.getBurntFee(),
protoTx.getUnlockBlockHeight());
protoTx.getBurntFee());
}


Expand All @@ -138,21 +132,25 @@ public TxOutput getLastTxOutput() {


/**
* The locktime is stored in the LOCKUP txOutput, which is the first txOutput.
*
* @return
* The lockTime is stored in the LOCKUP txOutput, which is the first txOutput.
*/
public int getLockTime() {
return txOutputs.get(0).getLockTime();
}

/**
* The unlockBlockHeight is stored in the LOCKUP txOutput, which is the first txOutput.
ManfredKarrer marked this conversation as resolved.
Show resolved Hide resolved
*/
public int getUnlockBlockHeight() {
return txOutputs.get(0).getUnlockBlockHeight();
}

@Override
public String toString() {
return "Tx{" +
"\n txOutputs=" + txOutputs +
",\n txType=" + txType +
",\n burntFee=" + burntFee +
",\n unlockBlockHeight=" + unlockBlockHeight +
"\n} " + super.toString();
}

Expand Down
19 changes: 14 additions & 5 deletions core/src/main/java/bisq/core/dao/state/blockchain/TxOutput.java
Expand Up @@ -44,11 +44,14 @@ public static TxOutput fromTempOutput(TempTxOutput tempTxOutput) {
tempTxOutput.getOpReturnData(),
tempTxOutput.getBlockHeight(),
tempTxOutput.getTxOutputType(),
tempTxOutput.getLockTime());
tempTxOutput.getLockTime(),
tempTxOutput.getUnlockBlockHeight());
}

private final TxOutputType txOutputType;
// If not set it is -1, 0 is a valid value.
private final int lockTime;
private final int unlockBlockHeight;

public TxOutput(int index,
long value,
Expand All @@ -58,7 +61,8 @@ public TxOutput(int index,
@Nullable byte[] opReturnData,
int blockHeight,
TxOutputType txOutputType,
int lockTime) {
int lockTime,
int unlockBlockHeight) {
super(index,
value,
txId,
Expand All @@ -69,6 +73,7 @@ public TxOutput(int index,

this.txOutputType = txOutputType;
this.lockTime = lockTime;
this.unlockBlockHeight = unlockBlockHeight;
}


Expand All @@ -80,20 +85,23 @@ public TxOutput(int index,
public PB.BaseTxOutput toProtoMessage() {
PB.TxOutput.Builder builder = PB.TxOutput.newBuilder()
.setTxOutputType(txOutputType.toProtoMessage())
.setLockTime(lockTime);
.setLockTime(lockTime)
.setUnlockBlockHeight(unlockBlockHeight);
return getRawTxOutputBuilder().setTxOutput(builder).build();
}

public static TxOutput fromProto(PB.BaseTxOutput proto) {
PB.TxOutput protoTxOutput = proto.getTxOutput();
return new TxOutput(proto.getIndex(),
proto.getValue(),
proto.getTxId(),
proto.hasPubKeyScript() ? PubKeyScript.fromProto(proto.getPubKeyScript()) : null,
proto.getAddress().isEmpty() ? null : proto.getAddress(),
proto.getOpReturnData().isEmpty() ? null : proto.getOpReturnData().toByteArray(),
proto.getBlockHeight(),
TxOutputType.fromProto(proto.getTxOutput().getTxOutputType()),
proto.getTxOutput().getLockTime());
TxOutputType.fromProto(protoTxOutput.getTxOutputType()),
protoTxOutput.getLockTime(),
protoTxOutput.getUnlockBlockHeight());
}


Expand All @@ -102,6 +110,7 @@ public String toString() {
return "TxOutput{" +
"\n txOutputType=" + txOutputType +
"\n lockTime=" + lockTime +
",\n unlockBlockHeight=" + unlockBlockHeight +
"\n} " + super.toString();
}
}