Skip to content

Commit

Permalink
Added explorer support; fix cash token tx size bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
joshmg committed Nov 13, 2022
1 parent 9550705 commit 0f6785f
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 2 deletions.
6 changes: 6 additions & 0 deletions explorer/www/index.html
Expand Up @@ -166,6 +166,12 @@
<div class="type"><label>Type</label><span class="value">UNKNOWN</span></div>
<div class="script"><label>Operations</label><span class="value"></span></div>
</div>
<div class="cash-token">
<div class="category">-</div>
<div class="nft-capability">-</div>
<div class="commitment">-</div>
<div class="token-amount">-</div>
</div>
</div>

<div class="script-operation">
Expand Down
Expand Up @@ -12,6 +12,7 @@
import com.softwareverde.bitcoin.util.bytearray.CompactVariableLengthInteger;
import com.softwareverde.constable.bytearray.ByteArray;
import com.softwareverde.constable.list.List;
import com.softwareverde.logging.Logger;
import com.softwareverde.util.HexUtil;
import com.softwareverde.util.bytearray.ByteArrayReader;
import com.softwareverde.util.bytearray.Endian;
Expand All @@ -38,6 +39,7 @@ protected MutableTransaction _fromByteArrayReader(final ByteArrayReader byteArra
final TransactionOutputInflater transactionOutputInflater = new TransactionOutputInflater();
final CompactVariableLengthInteger transactionOutputCount = CompactVariableLengthInteger.readVariableLengthInteger(byteArrayReader);
if (! transactionOutputCount.isCanonical()) { return null; }
if (transactionOutputCount.value < 1L) { return null; }
for (int i = 0; i < transactionOutputCount.value; ++i) {
if (byteArrayReader.remainingByteCount() < 1) { return null; }
final MutableTransactionOutput transactionOutput = transactionOutputInflater.fromBytes(i, byteArrayReader);
Expand Down
Expand Up @@ -52,7 +52,18 @@ public Integer getByteCount(final TransactionOutput transactionOutput) {

final Script lockingScript = transactionOutput.getLockingScript();
final int scriptByteCount;
{
if (transactionOutput.hasCashToken()) {
final CashToken cashToken = transactionOutput.getCashToken();
final int lockingScriptByteCount = lockingScript.getByteCount();
final int cashTokenByteCount = cashToken.getByteCount();
final int variableByteCount = (cashTokenByteCount + lockingScriptByteCount);

int byteCount = 0;
byteCount += CompactVariableLengthInteger.variableLengthIntegerToBytes(variableByteCount).getByteCount();
byteCount += variableByteCount;
scriptByteCount = byteCount;
}
else {
int byteCount = 0;
byteCount += CompactVariableLengthInteger.variableLengthIntegerToBytes(lockingScript.getByteCount()).getByteCount();
byteCount += lockingScript.getByteCount();
Expand Down
Expand Up @@ -106,6 +106,26 @@ public ByteArray getBytes() {
return byteArrayBuilder;
}

public Integer getByteCount() {
int byteCount = (1 + Sha256Hash.BYTE_COUNT + 1); // Prefix + Category + Bitfield

final boolean hasCommitment = ( (_commitment != null) && (! _commitment.isEmpty()) );
if (hasCommitment) {
final int commitmentByteCount = _commitment.getByteCount();
final ByteArray commitmentByteCountBytes = CompactVariableLengthInteger.variableLengthIntegerToBytes(commitmentByteCount);
byteCount += commitmentByteCountBytes.getByteCount();
byteCount += commitmentByteCount;
}

final boolean hasAmount = ( (_tokenAmount != null) && (_tokenAmount > 0L) );
if (hasAmount) {
final ByteArray tokenAmountBytes = CompactVariableLengthInteger.variableLengthIntegerToBytes(_tokenAmount);
byteCount += tokenAmountBytes.getByteCount();
}

return byteCount;
}

@Override
public boolean equals(final Object object) {
if (object == this) { return true; }
Expand Down
@@ -1,6 +1,16 @@
package com.softwareverde.bitcoin.server.module;

import com.softwareverde.bitcoin.CoreInflater;
import com.softwareverde.bitcoin.server.Environment;
import com.softwareverde.bitcoin.server.configuration.TestNetCheckpointConfiguration;
import com.softwareverde.bitcoin.server.database.Database;
import com.softwareverde.bitcoin.server.database.DatabaseConnectionFactory;
import com.softwareverde.bitcoin.server.module.node.database.fullnode.FullNodeDatabaseManager;
import com.softwareverde.bitcoin.server.module.node.database.fullnode.FullNodeDatabaseManagerFactory;
import com.softwareverde.bitcoin.server.module.node.store.PendingBlockStoreCore;
import com.softwareverde.bitcoin.server.module.node.store.UtxoCommitmentStoreCore;
import com.softwareverde.bitcoin.server.properties.DatabasePropertiesStore;
import com.softwareverde.logging.Logger;

public class DatabaseModule {
protected final Environment _environment;
Expand All @@ -10,6 +20,29 @@ public DatabaseModule(final Environment environment) {
}

public void loop() {
final String dataDirectory = "data";
final CoreInflater inflater = new CoreInflater();
final Database database = _environment.getDatabase();
final DatabaseConnectionFactory databaseConnectionFactory = _environment.getDatabaseConnectionFactory();
final FullNodeDatabaseManagerFactory databaseManagerFactory = new FullNodeDatabaseManagerFactory(
databaseConnectionFactory,
database.getMaxQueryBatchSize(),
new DatabasePropertiesStore(databaseConnectionFactory),
new PendingBlockStoreCore(dataDirectory, inflater, inflater),
new UtxoCommitmentStoreCore(dataDirectory),
inflater,
new TestNetCheckpointConfiguration(),
1073741824L,
0.5F
);

try (final FullNodeDatabaseManager databaseManager = databaseManagerFactory.newDatabaseManager()) {
// Scratch space...
}
catch (final Exception exception) {
Logger.debug(exception);
}

while (true) {
try { Thread.sleep(5000); } catch (final Exception exception) { break; }
}
Expand Down
Expand Up @@ -97,7 +97,7 @@ else if ( (queryParam.startsWith("00000000")) || (queryParam.length() != hashCha
}

final Json queryBlockTransactionsJson = secondNodeJsonRpcConnection.getBlockTransactions(blockHash, 32, 0);
blockTransactionsJson = queryBlockTransactionsJson.get("transactions");
blockTransactionsJson = (queryBlockTransactionsJson != null ? queryBlockTransactionsJson.get("transactions") : null);
}

final Json blockJson = queryBlockResponseJson.get("block");
Expand Down
@@ -0,0 +1,38 @@
package com.softwareverde.bitcoin.transaction;

import com.softwareverde.bitcoin.test.UnitTest;
import com.softwareverde.constable.bytearray.ByteArray;
import com.softwareverde.util.bytearray.ByteArrayReader;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class TransactionInflaterTests extends UnitTest {
@Before
public void before() throws Exception {
super.before();
}

@After
public void after() throws Exception {
super.after();
}

@Test
public void should_cache_correct_byte_count() throws Exception {
// Setup
final ByteArrayReader byteArrayReader = new ByteArrayReader(ByteArray.fromHexString("0100000001B7149E391C7695D0E3EF07562119074A153C86B57032279BAB6280F3381304CE000000006A473044022059DCCEB41A3647FD79225E425F787CE2B5D09593A08BF66F6263CF6AB492611C02205D5EABBD5F36748CE87B9D8361E6739FE03E44B9DED8B4134B68921212F8084E412102ABAAD90841057DDB1ED929608B536535B0CD8A18BA0A90DBA66BA7B1C1F7B4EAFEFFFFFF02102700000000000040EFB7149E391C7695D0E3EF07562119074A153C86B57032279BAB6280F3381304CE10FE15CD5B0776A9140A373CAF0AB3C2B46CD05625B8D545C295B93D7A88ACC4C9052A010000001976A914EA873AAAFBDD7A7C74D73EE1174E42F620B0A18C88AC00000000"));
final Integer expectedByteCount = 264;

final TransactionInflater transactionInflater = new TransactionInflater();

// Action
final Transaction transaction = transactionInflater.fromBytes(byteArrayReader);
final Transaction constTransaction = transaction.asConst();

// Assert
Assert.assertEquals(expectedByteCount, transaction.getByteCount());
Assert.assertEquals(expectedByteCount, constTransaction.getByteCount());
}
}
6 changes: 6 additions & 0 deletions www-shared/css/blocks.css
Expand Up @@ -229,6 +229,12 @@
.transaction .io .transaction-output > .label .token-amount > .token-name {
padding-left: 0.25em;
}
.transaction .io .transaction-output > .cash-token {
display: none;
}
.transaction .io .transaction-output.cash-token > .cash-token {
display: block;
}

.transaction > div,
.block .block-header {
Expand Down
19 changes: 19 additions & 0 deletions www-shared/js/core.js
Expand Up @@ -280,6 +280,25 @@ class Ui {
}
}

if (transactionOutput.cashToken) {
const cashToken = transactionOutput.cashToken;
transactionOutputUi.toggleClass("cash-token", true);

const cashTokenUi = $(".cash-token", transactionOutputUi);
if (cashToken.category) {
$(".category", cashTokenUi).text(cashToken.category);
}
if (cashToken.nftCapability) {
$(".nft-capability", cashTokenUi).text(cashToken.nftCapability);
}
if (cashToken.commitment) {
$(".commitment", cashTokenUi).text(cashToken.commitment);
}
if (cashToken.tokenAmount) {
$(".token-amount", cashTokenUi).text(cashToken.tokenAmount);
}
}

$("div.label", transactionOutputUi).on("click", function() {
$("> div:not(:first-child)", transactionOutputUi).slideToggle(250, function() {
window.HashResizer(transactionOutputUi);
Expand Down

0 comments on commit 0f6785f

Please sign in to comment.