From 7907fca5e157defa64afcffbd9d0b9d226d4d375 Mon Sep 17 00:00:00 2001 From: semux Date: Mon, 2 Sep 2019 15:57:01 +0100 Subject: [PATCH] Tools: add VM receipt tracer --- .../java/org/semux/core/BlockchainImpl.java | 9 ++++-- .../org/semux/core/TransactionExecutor.java | 31 +++++++++++++++++-- src/main/java/org/semux/util/SystemUtil.java | 1 + 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/semux/core/BlockchainImpl.java b/src/main/java/org/semux/core/BlockchainImpl.java index c84631154..f49211ec7 100644 --- a/src/main/java/org/semux/core/BlockchainImpl.java +++ b/src/main/java/org/semux/core/BlockchainImpl.java @@ -886,16 +886,21 @@ public static void upgrade(Config config, DatabaseFactory dbFactory) { BlockchainImpl tempChain = new BlockchainImpl(config, tempDbFactory); // import all blocks + long imported = 0; Database indexDB = dbFactory.getDB(DatabaseName.INDEX); Database blockDB = dbFactory.getDB(DatabaseName.BLOCK); byte[] bytes = getLatestBlockNumber(indexDB); long latestBlockNumber = (bytes == null) ? 0 : Bytes.toLong(bytes); for (long i = 1; i <= latestBlockNumber; i++) { - tempChain.importBlock(getBlock(blockDB, i), false); + boolean result = tempChain.importBlock(getBlock(blockDB, i), false); + if (!result) { + break; + } if (i % 1000 == 0) { PubSubFactory.getDefault().publish(new BlockchainDatabaseUpgradingEvent(i, latestBlockNumber)); logger.info("Loaded {} / {} blocks", i, latestBlockNumber); } + imported++; } // close both database factory @@ -908,7 +913,7 @@ public static void upgrade(Config config, DatabaseFactory dbFactory) { tempDbFactory.moveTo(dataDir); delete(backupPath); // delete old database to save space. - logger.info("Database upgraded"); + logger.info("Database upgraded: found blocks = {}, imported = {}", latestBlockNumber, imported); } catch (IOException e) { logger.error("Failed to upgrade database", e); } diff --git a/src/main/java/org/semux/core/TransactionExecutor.java b/src/main/java/org/semux/core/TransactionExecutor.java index 61bd9c3b1..c1be80c55 100644 --- a/src/main/java/org/semux/core/TransactionExecutor.java +++ b/src/main/java/org/semux/core/TransactionExecutor.java @@ -6,6 +6,10 @@ */ package org.semux.core; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -23,7 +27,9 @@ import org.semux.core.state.Account; import org.semux.core.state.AccountState; import org.semux.core.state.DelegateState; +import org.semux.crypto.Hex; import org.semux.util.Bytes; +import org.semux.util.SystemUtil; import org.semux.vm.client.SemuxBlock; import org.semux.vm.client.SemuxInternalTransaction; import org.semux.vm.client.SemuxRepository; @@ -36,13 +42,25 @@ */ public class TransactionExecutor { + private static final boolean TRACE_VM = false; + private static final Logger logger = LoggerFactory.getLogger(TransactionExecutor.class); - private static final boolean[] valid = new boolean[256]; + private static final boolean[] delegateNameAllowedChars = new boolean[256]; + private static PrintStream tracer; static { for (byte b : Bytes.of("abcdefghijklmnopqrstuvwxyz0123456789_")) { - valid[b & 0xff] = true; + delegateNameAllowedChars[b & 0xff] = true; + } + + if (TRACE_VM) { + try { + tracer = new PrintStream(new FileOutputStream(new File("trace.txt"), true)); + } catch (FileNotFoundException e) { + logger.error("Failed to setup VM tracer", e); + SystemUtil.exit(SystemUtil.Code.FAILED_TO_SETUP_TRACER); + } } } @@ -59,7 +77,7 @@ public static boolean validateDelegateName(byte[] data) { } for (byte b : data) { - if (!valid[b & 0xff]) { + if (!delegateNameAllowedChars[b & 0xff]) { return false; } } @@ -289,6 +307,13 @@ private void executeVmTransaction(TransactionResult result, Transaction tx, Acco if (summary == null) { result.setCode(Code.INVALID); } else { + if (tracer != null) { + tracer.println(); + tracer.println(Hex.encode(tx.getHash())); + tracer.println(summary); + tracer.flush(); + } + result.setCode(summary.isSuccess() ? Code.SUCCESS : Code.FAILURE); result.setReturnData(summary.getReturnData()); for (LogInfo log : summary.getLogs()) { diff --git a/src/main/java/org/semux/util/SystemUtil.java b/src/main/java/org/semux/util/SystemUtil.java index 795d005fc..a0c926724 100644 --- a/src/main/java/org/semux/util/SystemUtil.java +++ b/src/main/java/org/semux/util/SystemUtil.java @@ -63,6 +63,7 @@ public static class Code { public static final int FAILED_TO_LOAD_GENESIS = 33; public static final int FAILED_TO_LAUNCH_KERNEL = 34; public static final int INVALID_NETWORK_LABEL = 35; + public static final int FAILED_TO_SETUP_TRACER = 36; // database public static final int FAILED_TO_OPEN_DB = 51;