Skip to content

Commit

Permalink
DB: fix the transaction result index issue, close #221
Browse files Browse the repository at this point in the history
  • Loading branch information
semux committed Jul 18, 2019
1 parent a31bd82 commit 3ac1ad6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 24 deletions.
1 change: 1 addition & 0 deletions src/main/java/org/semux/api/ApiHandlerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public Response service(HttpMethod method, String path, Map<String, String> para
try {
return (Response) route.invoke(params);
} catch (Exception e) {
logger.warn("Internal error", e);
return Response.status(INTERNAL_SERVER_ERROR).entity(HttpHandler.INTERNAL_SERVER_ERROR_RESPONSE).build();
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/semux/core/Block.java
Original file line number Diff line number Diff line change
Expand Up @@ -438,10 +438,10 @@ public Pair<byte[], List<Integer>> getEncodedTransactionsAndIndices() {
* @return
*/
public byte[] getEncodedResults() {
return getEncodedResultsAndIndex().getLeft();
return getEncodedResultsAndIndices().getLeft();
}

public Pair<byte[], List<Integer>> getEncodedResultsAndIndex() {
public Pair<byte[], List<Integer>> getEncodedResultsAndIndices() {
List<Integer> indices = new ArrayList<>();

SimpleEncoder enc = new SimpleEncoder();
Expand Down
62 changes: 40 additions & 22 deletions src/main/java/org/semux/core/BlockchainImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,34 @@ public boolean hasBlock(long number) {
return blockDB.get(Bytes.merge(TYPE_BLOCK_HEADER_BY_NUMBER, Bytes.of(number))) != null;
}

private static class TransactionIndex {
long blockNumber;
int transactionOffset;
int resultOffset;

public TransactionIndex(long blockNumber, int transactionOffset, int resultOffset) {
this.blockNumber = blockNumber;
this.transactionOffset = transactionOffset;
this.resultOffset = resultOffset;
}

public byte[] toBytes() {
SimpleEncoder enc = new SimpleEncoder();
enc.writeLong(blockNumber);
enc.writeInt(transactionOffset);
enc.writeInt(resultOffset);
return enc.toBytes();
}

public static TransactionIndex fromBytes(byte[] bytes) {
SimpleDecoder dec = new SimpleDecoder(bytes);
long number = dec.readLong();
int transactionOffset = dec.readInt();
int resultOffset = dec.readInt();
return new TransactionIndex(number, transactionOffset, resultOffset);
}
}

@Override
public Transaction getTransaction(byte[] hash) {
byte[] bytes = indexDB.get(Bytes.merge(TYPE_TRANSACTION_INDEX_BY_HASH, hash));
Expand All @@ -259,13 +287,10 @@ public Transaction getTransaction(byte[] hash) {
return Transaction.fromBytes(bytes);
}

SimpleDecoder dec = new SimpleDecoder(bytes);
long number = dec.readLong();
int start = dec.readInt();
dec.readInt();

byte[] transactions = blockDB.get(Bytes.merge(TYPE_BLOCK_TRANSACTIONS_BY_NUMBER, Bytes.of(number)));
dec = new SimpleDecoder(transactions, start);
TransactionIndex index = TransactionIndex.fromBytes(bytes);
byte[] transactions = blockDB
.get(Bytes.merge(TYPE_BLOCK_TRANSACTIONS_BY_NUMBER, Bytes.of(index.blockNumber)));
SimpleDecoder dec = new SimpleDecoder(transactions, index.transactionOffset);
return Transaction.fromBytes(dec.readBytes());
}

Expand All @@ -290,16 +315,12 @@ public TransactionResult getTransactionResult(byte[] hash) {
if (bytes != null) {
// coinbase transaction
if (bytes.length > 64) {
return null; // no results for coinbase transaction
return new TransactionResult();
}

SimpleDecoder dec = new SimpleDecoder(bytes);
long number = dec.readLong();
dec.readInt();
int start = dec.readInt();

byte[] results = blockDB.get(Bytes.merge(TYPE_BLOCK_RESULTS_BY_NUMBER, Bytes.of(number)));
dec = new SimpleDecoder(results, start);
TransactionIndex index = TransactionIndex.fromBytes(bytes);
byte[] results = blockDB.get(Bytes.merge(TYPE_BLOCK_RESULTS_BY_NUMBER, Bytes.of(index.blockNumber)));
SimpleDecoder dec = new SimpleDecoder(results, index.resultOffset);
return TransactionResult.fromBytes(dec.readBytes());
}

Expand Down Expand Up @@ -343,18 +364,15 @@ public synchronized void addBlock(Block block) {
// [2] update transaction indices
List<Transaction> txs = block.getTransactions();
Pair<byte[], List<Integer>> transactionIndices = block.getEncodedTransactionsAndIndices();
Pair<byte[], List<Integer>> resultIndices = block.getEncodedTransactionsAndIndices();
Pair<byte[], List<Integer>> resultIndices = block.getEncodedResultsAndIndices();
Amount reward = Block.getBlockReward(block, config);

for (int i = 0; i < txs.size(); i++) {
Transaction tx = txs.get(i);

SimpleEncoder enc = new SimpleEncoder();
enc.writeLong(number);
enc.writeInt(transactionIndices.getRight().get(i));
enc.writeInt(resultIndices.getRight().get(i));

indexDB.put(Bytes.merge(TYPE_TRANSACTION_INDEX_BY_HASH, tx.getHash()), enc.toBytes());
TransactionIndex index = new TransactionIndex(number, transactionIndices.getRight().get(i),
resultIndices.getRight().get(i));
indexDB.put(Bytes.merge(TYPE_TRANSACTION_INDEX_BY_HASH, tx.getHash()), index.toBytes());

// [3] update transaction_by_account index
addTransactionToAccount(tx, tx.getFrom());
Expand Down

0 comments on commit 3ac1ad6

Please sign in to comment.