Skip to content

Commit 95cc259

Browse files
author
huzhenyuan
committed
add solidity node impl
1 parent b2d5c8c commit 95cc259

11 files changed

Lines changed: 343 additions & 5 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package org.tron.common.overlay.client;
2+
3+
import io.grpc.ManagedChannel;
4+
import io.grpc.ManagedChannelBuilder;
5+
import org.tron.api.DatabaseGrpc;
6+
import org.tron.api.GrpcAPI.EmptyMessage;
7+
import org.tron.api.GrpcAPI.NumberMessage;
8+
import org.tron.protos.Protocol.Block;
9+
import org.tron.protos.Protocol.DynamicProperties;
10+
11+
public class DatabaseGrpcClient {
12+
13+
private final ManagedChannel channel;
14+
private final DatabaseGrpc.DatabaseBlockingStub databaseBlockingStub;
15+
16+
public DatabaseGrpcClient(String host, int port) {
17+
channel = ManagedChannelBuilder.forAddress(host, port)
18+
.usePlaintext(true)
19+
.build();
20+
databaseBlockingStub = DatabaseGrpc.newBlockingStub(channel);
21+
}
22+
23+
public DatabaseGrpcClient(String host) {
24+
channel = ManagedChannelBuilder.forTarget(host)
25+
.usePlaintext(true)
26+
.build();
27+
databaseBlockingStub = DatabaseGrpc.newBlockingStub(channel);
28+
}
29+
30+
31+
public Block getBlock(long blockNum) {
32+
if (blockNum < 0) {
33+
return databaseBlockingStub.getNowBlock(EmptyMessage.newBuilder().build());
34+
}
35+
NumberMessage.Builder builder = NumberMessage.newBuilder();
36+
builder.setNum(blockNum);
37+
return databaseBlockingStub.getBlockByNum(builder.build());
38+
}
39+
40+
public DynamicProperties getDynamicProperties() {
41+
return databaseBlockingStub.getDynamicProperties(EmptyMessage.newBuilder().build());
42+
}
43+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package org.tron.common.overlay.client;
2+
3+
import com.google.protobuf.ByteString;
4+
import io.grpc.ManagedChannel;
5+
import io.grpc.ManagedChannelBuilder;
6+
import org.tron.api.GrpcAPI.*;
7+
import org.tron.api.WalletGrpc;
8+
import org.tron.protos.Contract;
9+
import org.tron.protos.Contract.AssetIssueContract;
10+
import org.tron.protos.Protocol.Account;
11+
import org.tron.protos.Protocol.Block;
12+
import org.tron.protos.Protocol.Transaction;
13+
14+
import java.util.Optional;
15+
import java.util.concurrent.TimeUnit;
16+
17+
public class WalletGrpcClient {
18+
19+
private final ManagedChannel channel;
20+
private final WalletGrpc.WalletBlockingStub walletBlockingStub;
21+
22+
public WalletGrpcClient(String host, int port) {
23+
channel = ManagedChannelBuilder.forAddress(host, port)
24+
.usePlaintext(true)
25+
.build();
26+
walletBlockingStub = WalletGrpc.newBlockingStub(channel);
27+
}
28+
29+
public WalletGrpcClient(String host) {
30+
channel = ManagedChannelBuilder.forTarget(host)
31+
.usePlaintext(true)
32+
.build();
33+
walletBlockingStub = WalletGrpc.newBlockingStub(channel);
34+
}
35+
36+
public void shutdown() throws InterruptedException {
37+
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
38+
}
39+
40+
public Account queryAccount(byte[] address) {
41+
ByteString addressBS = ByteString.copyFrom(address);
42+
Account request = Account.newBuilder().setAddress(addressBS).build();
43+
return walletBlockingStub.getAccount(request);
44+
}
45+
46+
public Transaction createTransaction(Contract.TransferContract contract) {
47+
return walletBlockingStub.createTransaction(contract);
48+
}
49+
50+
public Transaction createTransferAssetTransaction(Contract.TransferAssetContract contract) {
51+
return walletBlockingStub.transferAsset(contract);
52+
}
53+
54+
public Transaction createParticipateAssetIssueTransaction(
55+
Contract.ParticipateAssetIssueContract contract) {
56+
return walletBlockingStub.participateAssetIssue(contract);
57+
}
58+
59+
public Transaction createAccount(Contract.AccountCreateContract contract) {
60+
return walletBlockingStub.createAccount(contract);
61+
}
62+
63+
public Transaction createAssetIssue(AssetIssueContract contract) {
64+
return walletBlockingStub.createAssetIssue(contract);
65+
}
66+
67+
public Transaction voteWitnessAccount(Contract.VoteWitnessContract contract) {
68+
return walletBlockingStub.voteWitnessAccount(contract);
69+
}
70+
71+
public Transaction createWitness(Contract.WitnessCreateContract contract) {
72+
return walletBlockingStub.createWitness(contract);
73+
}
74+
75+
public boolean broadcastTransaction(Transaction signaturedTransaction) {
76+
Return response = walletBlockingStub.broadcastTransaction(signaturedTransaction);
77+
return response.getResult();
78+
}
79+
80+
public Block getBlock(long blockNum) {
81+
if (blockNum < 0) {
82+
return walletBlockingStub.getNowBlock(EmptyMessage.newBuilder().build());
83+
}
84+
NumberMessage.Builder builder = NumberMessage.newBuilder();
85+
builder.setNum(blockNum);
86+
return walletBlockingStub.getBlockByNum(builder.build());
87+
}
88+
89+
public Optional<AccountList> listAccounts() {
90+
AccountList accountList = walletBlockingStub.listAccounts(EmptyMessage.newBuilder().build());
91+
if (accountList != null) {
92+
return Optional.of(accountList);
93+
}
94+
return Optional.empty();
95+
}
96+
97+
public Optional<WitnessList> listWitnesses() {
98+
WitnessList witnessList = walletBlockingStub.listWitnesses(EmptyMessage.newBuilder().build());
99+
if (witnessList != null) {
100+
return Optional.of(witnessList);
101+
}
102+
return Optional.empty();
103+
}
104+
105+
public Optional<AssetIssueList> getAssetIssueList() {
106+
AssetIssueList assetIssueList = walletBlockingStub
107+
.getAssetIssueList(EmptyMessage.newBuilder().build());
108+
if (assetIssueList != null) {
109+
return Optional.of(assetIssueList);
110+
}
111+
return Optional.empty();
112+
}
113+
114+
public Optional<NodeList> listNodes() {
115+
NodeList nodeList = walletBlockingStub
116+
.listNodes(EmptyMessage.newBuilder().build());
117+
if (nodeList != null) {
118+
return Optional.of(nodeList);
119+
}
120+
return Optional.empty();
121+
}
122+
123+
public Optional<AssetIssueList> getAssetIssueByAccount(byte[] address) {
124+
ByteString addressBS = ByteString.copyFrom(address);
125+
Account request = Account.newBuilder().setAddress(addressBS).build();
126+
AssetIssueList assetIssueList = walletBlockingStub
127+
.getAssetIssueByAccount(request);
128+
if (assetIssueList != null) {
129+
return Optional.of(assetIssueList);
130+
}
131+
return Optional.empty();
132+
}
133+
134+
public AssetIssueContract getAssetIssueByName(String assetName) {
135+
ByteString assetNameBs = ByteString.copyFrom(assetName.getBytes());
136+
BytesMessage request = BytesMessage.newBuilder().setValue(assetNameBs).build();
137+
return walletBlockingStub.getAssetIssueByName(request);
138+
}
139+
140+
public NumberMessage getTotalTransaction() {
141+
return walletBlockingStub.totalTransaction(EmptyMessage.newBuilder().build());
142+
}
143+
144+
}

src/main/java/org/tron/core/config/args/Args.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,16 @@ public class Args {
151151
@Setter
152152
private String p2pNodeId;
153153

154+
@Getter
155+
@Setter
156+
//If you are running a solidity node for java tron, this flag is set to true
157+
private boolean solidityNode;
158+
159+
@Getter
160+
@Setter
161+
//If you are running a solidity node for java tron, solidity node must assign a trust node for sync solidity block
162+
private String trustNodeAddr;
163+
154164
public static void clearParam() {
155165
INSTANCE.outputDirectory = "output-directory";
156166
INSTANCE.help = false;
@@ -179,6 +189,8 @@ public static void clearParam() {
179189
INSTANCE.syncNodeCount = 0;
180190
INSTANCE.nodeP2pVersion = 0;
181191
INSTANCE.p2pNodeId = "";
192+
INSTANCE.solidityNode = false;
193+
INSTANCE.trustNodeAddr = "";
182194
}
183195

184196
/**
@@ -286,6 +298,9 @@ public static void setParam(final String[] args, final String configFilePath) {
286298

287299
INSTANCE.nodeP2pVersion =
288300
config.hasPath("node.p2p.version") ? config.getInt("node.p2p.version") : 0;
301+
302+
INSTANCE.trustNodeAddr =
303+
config.hasPath("node.trust") ? config.getString("node.trust") : null;
289304
}
290305

291306

src/main/java/org/tron/core/db/Manager.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -767,15 +767,15 @@ private void setUtxoStore(final UtxoStore utxoStore) {
767767
*/
768768
public void processBlock(BlockCapsule block)
769769
throws ValidateSignatureException, ContractValidateException, ContractExeException {
770-
for (TransactionCapsule transactionCapsule : block.getTransactions()) {
771-
processTransaction(transactionCapsule);
772-
}
773-
774770
// todo set revoking db max size.
775771
this.updateDynamicProperties(block);
776772
this.updateSignedWitness(block);
777773
this.updateLatestSolidifiedBlock();
778774

775+
for (TransactionCapsule transactionCapsule : block.getTransactions()) {
776+
processTransaction(transactionCapsule);
777+
}
778+
779779
boolean needMaint = needMaintenance(block.getTimeStamp());
780780
if (needMaint) {
781781
if (block.getNum() == 1) {

src/main/java/org/tron/core/services/RpcApiService.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@
4343
import org.tron.protos.Contract.TransferContract;
4444
import org.tron.protos.Contract.VoteWitnessContract;
4545
import org.tron.protos.Contract.WitnessCreateContract;
46+
import org.tron.protos.Protocol;
4647
import org.tron.protos.Protocol.Account;
4748
import org.tron.protos.Protocol.Block;
4849
import org.tron.protos.Protocol.Transaction;
4950
import org.tron.protos.Protocol.Transaction.Contract.ContractType;
51+
import org.tron.protos.Protocol.DynamicProperties;
5052

5153
@Slf4j
5254
public class RpcApiService implements Service {
@@ -115,6 +117,16 @@ public void getBlockReference(org.tron.api.GrpcAPI.EmptyMessage request,
115117
responseObserver.onNext(ref);
116118
responseObserver.onCompleted();
117119
}
120+
121+
@Override
122+
public void getDynamicProperties(EmptyMessage request,
123+
StreamObserver<DynamicProperties> responseObserver) {
124+
DynamicProperties.Builder builder = DynamicProperties.newBuilder();
125+
builder.setLastSolidityBlockNum(app.getDbManager().getDynamicPropertiesStore().getLatestSolidifiedBlockNum());
126+
DynamicProperties dynamicProperties = builder.build();
127+
responseObserver.onNext(dynamicProperties);
128+
responseObserver.onCompleted();
129+
}
118130
}
119131

120132
private class WalletApi extends WalletImplBase {
@@ -383,6 +395,7 @@ public void totalTransaction(EmptyMessage request,
383395
responseObserver.onNext(wallet.totalTransaction());
384396
responseObserver.onCompleted();
385397
}
398+
386399
}
387400

388401
@Override

src/main/java/org/tron/program/FullNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public class FullNode {
1818
* Start the FullNode.
1919
*/
2020
public static void main(String[] args) throws InterruptedException {
21-
21+
logger.info("Full node running.");
2222
Args.setParam(args, Constant.NORMAL_CONF);
2323
Args cfgArgs = Args.getInstance();
2424

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package org.tron.program;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.context.ApplicationContext;
5+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
6+
import org.tron.common.application.Application;
7+
import org.tron.common.application.ApplicationFactory;
8+
import org.tron.common.overlay.client.DatabaseGrpcClient;
9+
import org.tron.common.overlay.client.WalletGrpcClient;
10+
import org.tron.core.Constant;
11+
import org.tron.core.capsule.BlockCapsule;
12+
import org.tron.core.config.DefaultConfig;
13+
import org.tron.core.config.args.Args;
14+
import org.tron.core.db.Manager;
15+
import org.tron.core.exception.*;
16+
import org.tron.core.services.RpcApiService;
17+
import org.tron.protos.Protocol.DynamicProperties;
18+
import org.tron.protos.Protocol.Block;
19+
20+
@Slf4j
21+
public class SolidityNode {
22+
23+
private static DatabaseGrpcClient databaseGrpcClient;
24+
private static Manager dbManager;
25+
26+
public static void initGrpcClient(String addr) {
27+
databaseGrpcClient = new DatabaseGrpcClient(addr);
28+
}
29+
30+
private static void syncLoop() {
31+
while (true) {
32+
try {
33+
syncSolidityBlock();
34+
} catch (Exception e) {
35+
logger.error("Error in sync solidity block {}", e.getMessage());
36+
}
37+
try {
38+
Thread.sleep(5000);
39+
} catch (InterruptedException e) {
40+
e.printStackTrace();
41+
}
42+
}
43+
}
44+
45+
private static void syncSolidityBlock() throws BadBlockException {
46+
while (true) {
47+
DynamicProperties remoteDynamicProperties = databaseGrpcClient.getDynamicProperties();
48+
long remoteLastSolidityBlockNum = remoteDynamicProperties.getLastSolidityBlockNum();
49+
long lastSolidityBlockNum = dbManager.getDynamicPropertiesStore().getLatestSolidifiedBlockNum();
50+
if (lastSolidityBlockNum < remoteLastSolidityBlockNum) {
51+
Block block = databaseGrpcClient.getBlock(lastSolidityBlockNum + 1);
52+
try {
53+
BlockCapsule blockCapsule = new BlockCapsule(block);
54+
dbManager.pushBlock(blockCapsule);
55+
dbManager.getDynamicPropertiesStore().saveLatestSolidifiedBlockNum(lastSolidityBlockNum + 1);
56+
} catch (ValidateScheduleException e) {
57+
throw new BadBlockException("validate schedule exception");
58+
} catch (ValidateSignatureException e) {
59+
throw new BadBlockException("validate signature exception");
60+
} catch (ContractValidateException e) {
61+
throw new BadBlockException("ContractValidate exception");
62+
} catch (ContractExeException e) {
63+
throw new BadBlockException("Contract Exectute exception");
64+
} catch (UnLinkedBlockException e) {
65+
throw new BadBlockException("Contract Exectute exception");
66+
}
67+
} else {
68+
break;
69+
}
70+
}
71+
logger.info("Sync with trust node completed!!!");
72+
}
73+
74+
/**
75+
* Start the SolidityNode.
76+
*/
77+
public static void main(String[] args) throws InterruptedException {
78+
logger.info("Solidity node running.");
79+
Args.setParam(args, Constant.NORMAL_CONF);
80+
Args cfgArgs = Args.getInstance();
81+
cfgArgs.setSolidityNode(true);
82+
83+
ApplicationContext context = new AnnotationConfigApplicationContext(DefaultConfig.class);
84+
85+
if (cfgArgs.isHelp()) {
86+
logger.info("Here is the help message.");
87+
return;
88+
}
89+
Application appT = ApplicationFactory.create(context);
90+
//appT.init(cfgArgs);
91+
RpcApiService rpcApiService = new RpcApiService(appT, context);
92+
appT.addService(rpcApiService);
93+
94+
appT.initServices(cfgArgs);
95+
appT.startServices();
96+
// appT.startup();
97+
98+
dbManager = appT.getDbManager();
99+
100+
initGrpcClient(cfgArgs.getTrustNodeAddr());
101+
102+
new Thread(() -> syncLoop(), logger.getName()).start();
103+
rpcApiService.blockUntilShutdown();
104+
}
105+
}

0 commit comments

Comments
 (0)