Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonce Develop #328

Open
wants to merge 32 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5938a39
Update the randomx library version in the pom.xml file to 0.2.0.
Sdkyl Jan 17, 2025
e98bae2
Adjustment and Use of the New Randomx Algorithm.
Sdkyl Jan 17, 2025
9688baa
Fixed the issue where the mining pool could not connect to the node.
Rushin2211 Jan 17, 2025
7c0e5cd
Merge pull request #1 from Rushin2211/develop
Sdkyl Jan 17, 2025
5b2a79b
Add nonce to the transaction block generated in the node transfer met…
Rushin2211 Jan 17, 2025
1ac0533
Add a method to query the number of transactions in the node.
Rushin2211 Jan 17, 2025
6267b29
Added a method to restore the transaction quantity for each address f…
Rushin2211 Jan 17, 2025
b0f2626
Limit the number of transaction inputs to 1.
Rushin2211 Jan 17, 2025
ff71125
Modify the names of some variables.
Rushin2211 Jan 17, 2025
6c63ca4
Added a method to query nonce via rpc.
Rushin2211 Jan 17, 2025
08c1bb4
1. Add nonce to the original rpc transfer method.
Rushin2211 Jan 17, 2025
370e1ae
Fix some bugs in the test code.
Rushin2211 Jan 17, 2025
0272e5c
Merge pull request #2 from Rushin2211/develop
Sdkyl Jan 17, 2025
3d8c284
During the transaction execution phase, the handling of nonce does no…
Sdkyl Jan 17, 2025
b48ec22
The processing logic when receiving a 512 byte transaction data block
Sdkyl Jan 17, 2025
fd7c870
Telnet query account confirmed transaction nonce count.
Sdkyl Jan 17, 2025
169745e
When loading a snapshot, nonce is reset to the current height state.
Sdkyl Jan 17, 2025
bab3bed
Modify unit testing.
Sdkyl Jan 17, 2025
90f5fe5
Troubleshooting the issue of HTTP port not listening on Linux.
Sdkyl Jan 22, 2025
ac145a0
Add new rpc tests.
Rushin2211 Feb 8, 2025
822e0ff
Merge pull request #3 from Rushin2211/develop
Sdkyl Feb 8, 2025
c7148dc
Check whether the node generates block settings in telnet.
Rushin2211 Feb 9, 2025
a69fda2
Merge pull request #4 from Rushin2211/develop
Sdkyl Feb 9, 2025
a039fb5
Adding some interfaces to the browser
Sdkyl Feb 9, 2025
c8058ad
Check the node tags in Telnet.
Rushin2211 Feb 11, 2025
b6df688
Merge pull request #6 from Rushin2211/develop
Sdkyl Feb 11, 2025
fd8391f
Complete transaction nonce query results.
Sdkyl Feb 13, 2025
e2f1b3f
Add some RPC interfaces.
Sdkyl Feb 13, 2025
f9fa4d9
rpc modify
Sdkyl Feb 23, 2025
1fc7c6e
Minor modifications to the nonce reset logic after snapshot
Sdkyl Feb 25, 2025
7e3b9ab
Update the version of xdagj-native-randomx in the pom.xml file to 0.2.1.
Rushin2211 Feb 25, 2025
3eca140
Merge pull request #7 from Rushin2211/develop
Sdkyl Feb 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<dist.phase>package</dist.phase>
<dist.base>${project.basedir}/dist</dist.base>

<xdagj-native-randomx.version>0.1.9</xdagj-native-randomx.version>
<xdagj-native-randomx.version>0.2.1</xdagj-native-randomx.version>
<netty.version>4.1.116.Final</netty.version>
<tuweni.version>2.4.2</tuweni.version>
<jackson.version>2.18.2</jackson.version>
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/io/xdag/Kernel.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,8 @@ public synchronized void testStart() throws Exception {
// Create genesis block if first startup
if (xdagStats.getOurLastBlockHash() == null) {
firstAccount = Keys.toBytesAddress(wallet.getDefKey().getPublicKey());
firstBlock = new Block(config, XdagTime.getCurrentTimestamp(), null, null, false, null, null, -1, XAmount.ZERO);
firstBlock = new Block(config, XdagTime.getCurrentTimestamp(), null, null, false,
null, null, -1, XAmount.ZERO, null);
firstBlock.signOut(wallet.getDefKey());
xdagStats.setOurLastBlockHash(firstBlock.getHashLow().toArray());
if (xdagStats.getGlobalMiner() == null) {
Expand Down Expand Up @@ -229,7 +230,10 @@ public synchronized void testStart() throws Exception {
// Initialize mining
pow = new XdagPow(this);

//getWsServer().start();
if (webSocketServer == null) {
webSocketServer = new WebSocketServer(this, config.getPoolWhiteIPList(), config.getWebsocketServerPort());
}
webSocketServer.start();

// Start RPC
api = new XdagApiImpl(this);
Expand Down
39 changes: 28 additions & 11 deletions src/main/java/io/xdag/Wallet.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import org.apache.commons.io.FileUtils;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.units.bigints.UInt64;
import org.bouncycastle.crypto.generators.BCrypt;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.hyperledger.besu.crypto.KeyPair;
Expand Down Expand Up @@ -485,7 +486,7 @@ private void requireHdWalletInitialized() {
* @param remark Optional remark to include in transaction
* @return List of transaction block wrappers
*/
public List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys, Bytes32 to, String remark) {
public List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys, Bytes32 to, String remark, UInt64 txNonce) {
// Check if remark exists
int hasRemark = remark == null ? 0 : 1;

Expand All @@ -501,8 +502,14 @@ public List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys,
// Add default key
keysPerBlock.add(getDefKey());

// Base count for block (header + send address + default key signature)
int base = 1 + 1 + 2 + hasRemark;
int base;
if (txNonce != null) {
// base count a block <header + transaction nonce + send address + defKey signature>
base = 1 + 1 + 1 + 2 + hasRemark;
} else {
// base count a block <header + send address + defKey signature>
base = 1 + 1 + 2 + hasRemark;
}
XAmount amount = XAmount.ZERO;

while (!stack.isEmpty()) {
Expand All @@ -522,17 +529,21 @@ public List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys,
stack.poll();
} else {
// Create block with current keys
res.add(createTransaction(to, amount, keys, remark));
res.add(createTransaction(to, amount, keys, remark, txNonce));
// Reset for next block
keys = new HashMap<>();
keysPerBlock = new HashSet<>();
keysPerBlock.add(getDefKey());
base = 1 + 1 + 2 + hasRemark;
if (txNonce != null) {
base = 1 + 1 + 1 + 2 + hasRemark;
} else {
base = 1 + 1 + 2 + hasRemark;
}
amount = XAmount.ZERO;
}
}
if (!keys.isEmpty()) {
res.add(createTransaction(to, amount, keys, remark));
res.add(createTransaction(to, amount, keys, remark, txNonce));
}

return res;
Expand All @@ -547,11 +558,11 @@ public List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys,
* @param remark Optional remark
* @return Transaction block wrapper
*/
private BlockWrapper createTransaction(Bytes32 to, XAmount amount, Map<Address, KeyPair> keys, String remark) {
private BlockWrapper createTransaction(Bytes32 to, XAmount amount, Map<Address, KeyPair> keys, String remark, UInt64 txNonce) {

List<Address> tos = Lists.newArrayList(new Address(to, XDAG_FIELD_OUTPUT, amount,true));

Block block = createNewBlock(new HashMap<>(keys), tos, remark);
Block block = createNewBlock(new HashMap<>(keys), tos, remark, txNonce);

if (block == null) {
return null;
Expand Down Expand Up @@ -586,7 +597,7 @@ private BlockWrapper createTransaction(Bytes32 to, XAmount amount, Map<Address,
* @return New transaction block
*/
private Block createNewBlock(Map<Address, KeyPair> pairs, List<Address> to,
String remark) {
String remark, UInt64 txNonce) {
int hasRemark = remark == null ? 0 : 1;

int defKeyIndex = -1;
Expand Down Expand Up @@ -614,7 +625,12 @@ private Block createNewBlock(Map<Address, KeyPair> pairs, List<Address> to,
all.addAll(to);

// Calculate total fields needed
int res = 1 + pairs.size() + to.size() + 3 * keys.size() + (defKeyIndex == -1 ? 2 : 0) + hasRemark;
int res;
if (txNonce != null) {
res = 1 + 1 + pairs.size() + to.size() + 3 * keys.size() + (defKeyIndex == -1 ? 2 : 0) + hasRemark;
} else {
res = 1 + pairs.size() + to.size() + 3 * keys.size() + (defKeyIndex == -1 ? 2 : 0) + hasRemark;
}

// Validate block size
if (res > 16) {
Expand All @@ -623,7 +639,8 @@ private Block createNewBlock(Map<Address, KeyPair> pairs, List<Address> to,

long sendTime = XdagTime.getCurrentTimestamp();

return new Block(getConfig(), sendTime, all, null, false, keys, remark, defKeyIndex, XAmount.of(100, XUnit.MILLI_XDAG));
return new Block(getConfig(), sendTime, all, null, false, keys, remark,
defKeyIndex, XAmount.of(100, XUnit.MILLI_XDAG), txNonce);
}

}
84 changes: 71 additions & 13 deletions src/main/java/io/xdag/cli/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.tuweni.bytes.Bytes32;
import org.apache.tuweni.bytes.MutableBytes32;
import org.apache.tuweni.units.bigints.UInt64;
import org.bouncycastle.util.encoders.Hex;
import org.hyperledger.besu.crypto.KeyPair;

Expand Down Expand Up @@ -135,7 +136,7 @@ public static String getStateByFlags(int flags) {
}

/**
* List addresses and balances
* List addresses, balances and current transaction quantity
* @param num Number of addresses to display
*/
public String account(int num) {
Expand All @@ -158,10 +159,19 @@ public String account(int num) {
if (num == 0) {
break;
}

UInt64 txQuantity = kernel.getAddressStore().getTxQuantity(toBytesAddress(keyPair));
UInt64 exeTxNonceNum = kernel.getAddressStore().getExecutedNonceNum(toBytesAddress(keyPair));

str.append(toBase58(toBytesAddress(keyPair)))
.append(" ")
.append(kernel.getAddressStore().getBalanceByAddress(toBytesAddress(keyPair)).toDecimal(9, XUnit.XDAG).toPlainString())
.append(" XDAG")
.append(" [Current TX Quantity: ")
.append(txQuantity.toUInt64())
.append(", Confirmed TX Quantity: ")
.append(exeTxNonceNum.toUInt64())
.append("]")
.append("\n");
num--;
}
Expand Down Expand Up @@ -199,7 +209,29 @@ public String balance(String address) {
Block block = kernel.getBlockStore().getBlockInfoByHash(Bytes32.wrap(key));
return String.format("Block balance: %s XDAG", block.getInfo().getAmount().toDecimal(9, XUnit.XDAG).toPlainString());
}
}
}

public String txQuantity(String address) {
if (StringUtils.isEmpty(address)) {
UInt64 ourTxQuantity = UInt64.ZERO;
UInt64 exeTxQuantit = UInt64.ZERO;
List<KeyPair> list = kernel.getWallet().getAccounts();
for (KeyPair key : list) {
ourTxQuantity = ourTxQuantity.add(kernel.getAddressStore().getTxQuantity(toBytesAddress(key)));
exeTxQuantit = exeTxQuantit.add(kernel.getAddressStore().getExecutedNonceNum(toBytesAddress(key)));
}
return String.format("Current Transaction Quantity: %s, executed Transaction Quantity: %s \n", ourTxQuantity.toLong(), exeTxQuantit.toLong());
} else {
UInt64 addressTxQuantity = UInt64.ZERO;
UInt64 addressExeTxQuantity = UInt64.ZERO;
if (checkAddress(address)) {
addressTxQuantity = addressTxQuantity.add(kernel.getAddressStore().getTxQuantity(fromBase58(address)));
addressExeTxQuantity = addressExeTxQuantity.add(kernel.getAddressStore().getExecutedNonceNum(fromBase58(address)));
return String.format("Current Transaction Quantity: %s, executed Transaction Quantity: %s \n", addressTxQuantity.toLong(), addressExeTxQuantity.toLong());
} else {
return "The account address format is incorrect! \n";
}
}
}

Expand All @@ -223,9 +255,13 @@ public String xfer(double sendAmount, Bytes32 address, String remark) {
// Collect input accounts
Map<Address, KeyPair> ourAccounts = Maps.newHashMap();
List<KeyPair> accounts = kernel.getWallet().getAccounts();
UInt64 txNonce = null;

for (KeyPair account : accounts) {
byte[] addr = toBytesAddress(account);
XAmount addrBalance = kernel.getAddressStore().getBalanceByAddress(addr);
UInt64 currentTxQuantity = kernel.getAddressStore().getTxQuantity(addr);
txNonce = currentTxQuantity.add(UInt64.ONE);

if (compareAmountTo(remain.get(), addrBalance) <= 0) {
ourAccounts.put(new Address(keyPair2Hash(account), XDAG_FIELD_INPUT, remain.get(), true), account);
Expand All @@ -245,22 +281,33 @@ public String xfer(double sendAmount, Bytes32 address, String remark) {
}

// Create and broadcast transaction blocks
List<BlockWrapper> txs = createTransactionBlock(ourAccounts, to, remark);
List<BlockWrapper> txs = createTransactionBlock(ourAccounts, to, remark, txNonce);
for (BlockWrapper blockWrapper : txs) {
ImportResult result = kernel.getSyncMgr().validateAndAddNewBlock(blockWrapper);
if (result == ImportResult.IMPORTED_BEST || result == ImportResult.IMPORTED_NOT_BEST) {
kernel.getChannelMgr().sendNewBlock(blockWrapper);
Block block = new Block(new XdagBlock(blockWrapper.getBlock().getXdagBlock().getData().toArray()));
List<Address> inputs = block.getInputs();
UInt64 blockNonce = block.getTxNonceField().getTransactionNonce();
for (Address input : inputs) {
if (input.getType() == XDAG_FIELD_INPUT) {
byte[] addr = BytesUtils.byte32ToArray(input.getAddress());
kernel.getAddressStore().updateTxQuantity(addr, blockNonce);
}
}
str.append(hash2Address(blockWrapper.getBlock().getHashLow())).append("\n");
} else if (result == ImportResult.INVALID_BLOCK) {
str.append(result.getErrorInfo());
}
}

return str.append("}, it will take several minutes to complete the transaction.").toString();
return str.append("}, it will take several minutes to complete the transaction. \n").toString();
}

/**
* Create transaction blocks from inputs to recipient
*/
private List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys, Bytes32 to, String remark) {
private List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys, Bytes32 to, String remark, UInt64 txNonce) {
// Check if remark exists
int hasRemark = remark == null ? 0 : 1;

Expand All @@ -274,8 +321,14 @@ private List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys,
Set<KeyPair> keysPerBlock = Sets.newHashSet();
keysPerBlock.add(kernel.getWallet().getDefKey());

// Base field count for block
int base = 1 + 1 + 2 + hasRemark;
int base;
if (txNonce != null) {
// base count a block <header + transaction nonce + send address + defKey signature>
base = 1 + 1 + 1 + 2 + hasRemark;
} else {
// base count a block <header + send address + defKey signature>
base = 1 + 1 + 2 + hasRemark;
}
XAmount amount = XAmount.ZERO;

while (!stack.isEmpty()) {
Expand All @@ -296,28 +349,33 @@ private List<BlockWrapper> createTransactionBlock(Map<Address, KeyPair> ourKeys,
stack.poll();
} else {
// Create block and reset for next
res.add(createTransaction(to, amount, keys, remark));
res.add(createTransaction(to, amount, keys, remark, txNonce));
keys = new HashMap<>();
keysPerBlock = new HashSet<>();
keysPerBlock.add(kernel.getWallet().getDefKey());
base = 1 + 1 + 2 + hasRemark;
if (txNonce != null) {
base = 1 + 1 + 1 + 2 + hasRemark;
} else {
base = 1 + 1 + 2 + hasRemark;
}
amount = XAmount.ZERO;
}
}

// Create final block if needed
if (!keys.isEmpty()) {
res.add(createTransaction(to, amount, keys, remark));
res.add(createTransaction(to, amount, keys, remark, txNonce));
}
return res;
}

/**
* Create single transaction block
*/
private BlockWrapper createTransaction(Bytes32 to, XAmount amount, Map<Address, KeyPair> keys, String remark) {
private BlockWrapper createTransaction(Bytes32 to, XAmount amount, Map<Address, KeyPair> keys, String remark, UInt64 txNonce) {
List<Address> tos = Lists.newArrayList(new Address(to, XDAG_FIELD_OUTPUT, amount, true));
Block block = kernel.getBlockchain().createNewBlock(new HashMap<>(keys), tos, false, remark, XAmount.of(100, XUnit.MILLI_XDAG));
Block block = kernel.getBlockchain().createNewBlock(new HashMap<>(keys), tos, false, remark,
XAmount.of(100, XUnit.MILLI_XDAG), txNonce);

if (block == null) {
return null;
Expand Down Expand Up @@ -737,7 +795,7 @@ public String xferToNew() {
});

// Generate multiple transaction blocks
List<BlockWrapper> txs = createTransactionBlock(ourBlocks, to, remark);
List<BlockWrapper> txs = createTransactionBlock(ourBlocks, to, remark, null);
for (BlockWrapper blockWrapper : txs) {
ImportResult result = kernel.getSyncMgr().validateAndAddNewBlock(blockWrapper);
if (result == ImportResult.IMPORTED_BEST || result == ImportResult.IMPORTED_NOT_BEST) {
Expand All @@ -761,7 +819,7 @@ public StringBuilder xferToNode(Map<Address, KeyPair> paymentsToNodesMap) {
String remark = "Pay to " + kernel.getConfig().getNodeSpec().getNodeTag();

// Generate transaction blocks to reward node
List<BlockWrapper> txs = createTransactionBlock(paymentsToNodesMap, to, remark);
List<BlockWrapper> txs = createTransactionBlock(paymentsToNodesMap, to, remark, null);
for (BlockWrapper blockWrapper : txs) {
ImportResult result = kernel.getSyncMgr().validateAndAddNewBlock(blockWrapper);
if (result == ImportResult.IMPORTED_BEST || result == ImportResult.IMPORTED_NOT_BEST) {
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/io/xdag/cli/Shell.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public Shell() {
commandExecute.put("terminate", new CommandMethods(this::processTerminate, this::defaultCompleter));
commandExecute.put("address", new CommandMethods(this::processAddress, this::defaultCompleter));
commandExecute.put("oldbalance", new CommandMethods(this::processOldBalance, this::defaultCompleter));
commandExecute.put("txQuantity", new CommandMethods(this::processTxQuantity, this::defaultCompleter));
registerCommands(commandExecute);
}

Expand Down Expand Up @@ -210,6 +211,23 @@ private void processBalance(CommandInput input) {
}
}

private void processTxQuantity(CommandInput input) {
final String[] usage = {
"txQuantity - print current transaction quantity of the address [ADDRESS] or current nonce of our address \n",
"Usage: txQuantity [ADDRESS](optional)",
" -? --help Show help",
};
try {
Options opt = parseOptions(usage, input.args());
if (opt.isSet("help")) {
throw new Options.HelpException(opt.usage());
}
List<String> argv = opt.args();
println(commands.txQuantity(!argv.isEmpty() ? argv.get(0) : null));
} catch (Exception error) {
saveException(error);
}
}

private void processBlock(CommandInput input) {
final String[] usage = {
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/io/xdag/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,6 @@ public interface Config {
*/
FundSpec getFundSpec();

String getNodeTag();

}
4 changes: 2 additions & 2 deletions src/main/java/io/xdag/consensus/XdagPow.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public void newBlock() {

public Block generateRandomXBlock(long sendTime) {
taskIndex.incrementAndGet();
Block block = blockchain.createNewBlock(null, null, true, null, XAmount.ZERO);
Block block = blockchain.createNewBlock(null, null, true, null, XAmount.ZERO, null);
block.signOut(wallet.getDefKey());
// The first 20 bytes of the initial nonce are the node wallet address.
minShare.set(Bytes32.wrap(BytesUtils.merge(hash2byte(keyPair2Hash(wallet.getDefKey())),
Expand All @@ -199,7 +199,7 @@ public Block generateRandomXBlock(long sendTime) {

public Block generateBlock(long sendTime) {
taskIndex.incrementAndGet();
Block block = blockchain.createNewBlock(null, null, true, null, XAmount.ZERO);
Block block = blockchain.createNewBlock(null, null, true, null, XAmount.ZERO, null);
block.signOut(wallet.getDefKey());
minShare.set(Bytes32.wrap(BytesUtils.merge(hash2byte(keyPair2Hash(wallet.getDefKey())),
XdagRandomUtils.nextNewBytes(12))));
Expand Down
Loading