Skip to content

Commit

Permalink
Transaction: Add methods for calculating transaction weight and virtu…
Browse files Browse the repository at this point in the history
…al transaction size.

cherry pick bitcoinj@c97ecf6
  • Loading branch information
Andreas Schildbach authored and oscarguindzberg committed Oct 26, 2020
1 parent fcec3da commit 2824953
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
32 changes: 30 additions & 2 deletions core/src/main/java/org/bitcoinj/core/Transaction.java
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,29 @@ public Sha256Hash getWTxId() {
return cachedWTxId;
}

/** Gets the transaction weight as defined in BIP141. */
public int getWeight() {
if (!hasWitnesses())
return getMessageSize() * 4;
try (final ByteArrayOutputStream stream = new UnsafeByteArrayOutputStream(length)) {
bitcoinSerializeToStream(stream, false);
final int baseSize = stream.size();
stream.reset();
bitcoinSerializeToStream(stream, true);
final int totalSize = stream.size();
return baseSize * 3 + totalSize;
} catch (IOException e) {
throw new RuntimeException(e); // cannot happen
}
}

/** Gets the virtual transaction size as defined in BIP141. */
public int getVsize() {
if (!hasWitnesses())
return getMessageSize();
return (getWeight() + 3) / 4; // round up
}

/**
* Gets the sum of the inputs, regardless of who owns them.
*/
Expand Down Expand Up @@ -886,8 +909,13 @@ public String toString(@Nullable AbstractBlockChain chain, @Nullable CharSequenc
final Coin fee = getFee();
if (fee != null) {
final int size = unsafeBitcoinSerialize().length;
s.append(indent).append(" fee ").append(fee.multiply(1000).divide(size).toFriendlyString()).append("/kB, ")
.append(fee.toFriendlyString()).append(" for ").append(size).append(" bytes\n");
final int vsize = getVsize();
s.append(indent).append(" fee ").append(fee.multiply(1000).divide(size).toFriendlyString())
.append("/kB – ");
s.append(fee.toFriendlyString()).append(" for ");
if (size != vsize)
s.append(vsize).append(" virtual bytes, ");
s.append(size).append(" bytes\n");
}
return s.toString();
}
Expand Down
10 changes: 10 additions & 0 deletions core/src/test/java/org/bitcoinj/core/TransactionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -759,4 +759,14 @@ protected void bitcoinSerializeToStream(OutputStream stream, boolean useSegwit)
uint32ToByteStreamLE(getLockTime(), stream);
}
}

@Test
public void getWeightAndVsize() {
// example from https://en.bitcoin.it/wiki/Weight_units
String txHex = "0100000000010115e180dc28a2327e687facc33f10f2a20da717e5548406f7ae8b4c811072f85603000000171600141d7cd6c75c2e86f4cbf98eaed221b30bd9a0b928ffffffff019caef505000000001976a9141d7cd6c75c2e86f4cbf98eaed221b30bd9a0b92888ac02483045022100f764287d3e99b1474da9bec7f7ed236d6c81e793b20c4b5aa1f3051b9a7daa63022016a198031d5554dbb855bdbe8534776a4be6958bd8d530dc001c32b828f6f0ab0121038262a6c6cec93c2d3ecd6c6072efea86d02ff8e3328bbd0242b20af3425990ac00000000";
Transaction tx = new Transaction(UNITTEST, HEX.decode(txHex));
assertEquals(218, tx.getMessageSize());
assertEquals(542, tx.getWeight());
assertEquals(136, tx.getVsize());
}
}

0 comments on commit 2824953

Please sign in to comment.