Skip to content

Commit

Permalink
feat(toolkit): add db query
Browse files Browse the repository at this point in the history
  • Loading branch information
halibobo1205 committed Jul 23, 2024
1 parent b89051c commit 29b6499
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 0 deletions.
1 change: 1 addition & 0 deletions plugins/src/main/java/org/tron/plugins/Db.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
DbCopy.class,
DbRoot.class,
DbCheckpointCompare.class,
DbQuery.class,
},
commandListHeading = "%nCommands:%n%nThe most commonly used db commands are:%n"
)
Expand Down
108 changes: 108 additions & 0 deletions plugins/src/main/java/org/tron/plugins/DbQuery.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.tron.plugins;

import com.google.common.collect.Lists;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import lombok.extern.slf4j.Slf4j;
import org.rocksdb.RocksDBException;
import org.tron.plugins.utils.ByteArray;
import org.tron.plugins.utils.DBUtils;
import org.tron.plugins.utils.db.DBInterface;
import org.tron.plugins.utils.db.DbTool;
import picocli.CommandLine;


@Slf4j(topic = "query")
@CommandLine.Command(name = "query",
aliases = {"q"},
description = "query data from db.",
exitCodeListHeading = "Exit Codes:%n",
exitCodeList = {
"0:Successful",
"n:query failed,please check toolkit.log"})
public class DbQuery implements Callable<Integer> {

enum Type {
hex(""), block("block"),
account("account"), exchange("exchange,exchange-v2");

final List<String> dbs;

Type(String dbs) {
this.dbs = Lists.newArrayList(dbs.split(","));
}
}

@CommandLine.Spec
CommandLine.Model.CommandSpec spec;
@CommandLine.Parameters(index = "0",
description = " db path for query")
private Path db;
@CommandLine.Option(names = { "--keys"},
description = "key for query in hex")
private List<String> keys;
@CommandLine.Option(names = {"-h", "--help"}, help = true, description = "display a help message")
private boolean help;

@Override
public Integer call() throws Exception {
if (help) {
spec.commandLine().usage(System.out);
return 0;
}
if (!db.toFile().exists()) {
logger.info(" {} does not exist.", db);
spec.commandLine().getErr().println(spec.commandLine().getColorScheme()
.errorText(String.format("%s does not exist.", db)));
return 404;
}
return query();
}


private int query() throws RocksDBException, IOException {
try (
DBInterface database = DbTool.getDB(this.db.getParent(),
this.db.getFileName().toString())) {
if (keys != null && !keys.isEmpty()) {
keys.stream().map(ByteArray::fromHexString).forEach(k -> print(k, database.get(k)));
}
}
return 0;
}

private void print(byte[] k, byte[] b) {
String dbName;
if (this.db.endsWith(DBUtils.TMP) || this.db.getParent().endsWith(DBUtils.CHECKPOINT_DB_V2)) {
dbName = DBUtils.simpleDecode(k);
k = Arrays.copyOfRange(k, dbName.getBytes().length + 4, k.length);
b = b.length == 1 ? new byte[0] : Arrays.copyOfRange(b, 1, b.length);
} else {
dbName = this.db.getFileName().toString();
}
String key = ByteArray.toHexString(k);
if (b.length == 0) {
spec.commandLine().getOut().format("%s\t%s", dbName, key).println();
logger.info("{}\t{}", dbName, key);
} else {
Type type = Arrays.stream(Type.values()).filter(t -> t.dbs.contains(dbName))
.findFirst().orElse(Type.hex);
String json;
switch (type) {
case block: json = ByteArray.toJson(ByteArray.toBlock(b));
break;
case account: json = ByteArray.toJson(ByteArray.toAccount(b));
break;
case exchange: json = ByteArray.toJson(ByteArray.toExchange(b));
break;
default: json = ByteArray.toHexString(b);
break;
}
spec.commandLine().getOut().format("%s\t%s\t%s", dbName, key, json).println();
logger.info("{}\t{}\t{}", dbName, key, json);
}
}
}
136 changes: 136 additions & 0 deletions plugins/src/main/java/org/tron/plugins/utils/ByteArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,121 @@

import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageOrBuilder;
import com.google.protobuf.TypeRegistry;
import com.google.protobuf.util.JsonFormat;
import java.math.BigInteger;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.util.encoders.Hex;
import org.tron.protos.Protocol;
import org.tron.protos.contract.AccountContract;
import org.tron.protos.contract.AssetIssueContractOuterClass;
import org.tron.protos.contract.BalanceContract;
import org.tron.protos.contract.ExchangeContract;
import org.tron.protos.contract.MarketContract;
import org.tron.protos.contract.ProposalContract;
import org.tron.protos.contract.ShieldContract;
import org.tron.protos.contract.SmartContractOuterClass;
import org.tron.protos.contract.StorageContract;
import org.tron.protos.contract.VoteAssetContractOuterClass;
import org.tron.protos.contract.WitnessContract;


public class ByteArray {

public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
public static final byte[] ZERO_BYTE_ARRAY = new byte[]{0};
public static final int WORD_SIZE = 32;

public static JsonFormat.Printer PRINTER;

static {
TypeRegistry.Builder registry = TypeRegistry.newBuilder();
// see ContractType
registry.add(AccountContract.AccountCreateContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.TransferContract.getDefaultInstance()
.getDescriptorForType());
registry.add(AssetIssueContractOuterClass.TransferAssetContract.getDefaultInstance()
.getDescriptorForType());
registry.add(VoteAssetContractOuterClass.VoteAssetContract.getDefaultInstance()
.getDescriptorForType());
registry.add(WitnessContract.VoteWitnessContract.getDefaultInstance()
.getDescriptorForType());
registry.add(WitnessContract.WitnessCreateContract.getDefaultInstance()
.getDescriptorForType());
registry.add(AssetIssueContractOuterClass.AssetIssueContract.getDefaultInstance()
.getDescriptorForType());
registry.add(WitnessContract.WitnessUpdateContract.getDefaultInstance()
.getDescriptorForType());
registry.add(AssetIssueContractOuterClass.ParticipateAssetIssueContract
.getDefaultInstance()
.getDescriptorForType());
registry.add(AccountContract.AccountUpdateContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.FreezeBalanceContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.UnfreezeBalanceContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.WithdrawBalanceContract.getDefaultInstance()
.getDescriptorForType());
registry.add(AssetIssueContractOuterClass.UnfreezeAssetContract.getDefaultInstance()
.getDescriptorForType());
registry.add(AssetIssueContractOuterClass.UpdateAssetContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ProposalContract.ProposalCreateContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ProposalContract.ProposalApproveContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ProposalContract.ProposalDeleteContract.getDefaultInstance()
.getDescriptorForType());
registry.add(AccountContract.SetAccountIdContract.getDefaultInstance()
.getDescriptorForType());
registry.add(SmartContractOuterClass.CreateSmartContract.getDefaultInstance()
.getDescriptorForType());
registry.add(SmartContractOuterClass.TriggerSmartContract.getDefaultInstance()
.getDescriptorForType());
registry.add(SmartContractOuterClass.UpdateSettingContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ExchangeContract.ExchangeCreateContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ExchangeContract.ExchangeInjectContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ExchangeContract.ExchangeWithdrawContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ExchangeContract.ExchangeTransactionContract.getDefaultInstance()
.getDescriptorForType());
registry.add(SmartContractOuterClass.UpdateEnergyLimitContract.getDefaultInstance()
.getDescriptorForType());
registry.add(AccountContract.AccountPermissionUpdateContract.getDefaultInstance()
.getDescriptorForType());
registry.add(SmartContractOuterClass.ClearABIContract.getDefaultInstance()
.getDescriptorForType());
registry.add(StorageContract.UpdateBrokerageContract.getDefaultInstance()
.getDescriptorForType());
registry.add(ShieldContract.ShieldedTransferContract.getDefaultInstance()
.getDescriptorForType());
registry.add(MarketContract.MarketSellAssetContract.getDefaultInstance()
.getDescriptorForType());
registry.add(MarketContract.MarketCancelOrderContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.FreezeBalanceV2Contract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.UnfreezeBalanceV2Contract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.WithdrawExpireUnfreezeContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.DelegateResourceContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.UnDelegateResourceContract.getDefaultInstance()
.getDescriptorForType());
registry.add(BalanceContract.CancelAllUnfreezeV2Contract.getDefaultInstance()
.getDescriptorForType());
PRINTER = JsonFormat.printer().usingTypeRegistry(registry.build()).sortingMapKeys();
}

/**
* get bytes data from string data.
*/
Expand Down Expand Up @@ -98,4 +202,36 @@ public static byte[] fromHexString(String data) {
}
return Hex.decode(data);
}

public static Protocol.Block toBlock(byte[] b) {
try {
return Protocol.Block.parseFrom(b);
} catch (InvalidProtocolBufferException e) {
throw new RuntimeException(e);
}
}

public static Protocol.Account toAccount(byte[] b) {
try {
return Protocol.Account.parseFrom(b);
} catch (InvalidProtocolBufferException e) {
throw new RuntimeException(e);
}
}

public static Protocol.Exchange toExchange(byte[] b) {
try {
return Protocol.Exchange.parseFrom(b);
} catch (InvalidProtocolBufferException e) {
throw new RuntimeException(e);
}
}

public static String toJson(MessageOrBuilder messageOrBuilder) {
try {
return PRINTER.print(messageOrBuilder);
} catch (InvalidProtocolBufferException e) {
throw new RuntimeException(e);
}
}
}

0 comments on commit 29b6499

Please sign in to comment.