ethereum/ethereumj

PendingTransactionUpdate always complain "Invalid nonce: required: 0 , tx.nonce: 1" , the new transaction can not include into the last block.

fangyun opened this issue · 12 comments

Hi all. I am a newer for ethereumj. Yesterday I setup a private network sample by using ethereumj , I made a miner node and two regular nodes, here is my private genesis and sample code and configurations. https://gist.github.com/fangyun/a058ef8ca226cd18acd804aa00b45c73 , I write those codes by following the org.ethereum.samples.PrivateMinerSample . After running this sample at three computers, in the miner node , LIGHT_DATASET_GENERATED and FULL_DATASET_GENERATED, then transaction begin submit. But log always show like this:

" DEBUG [pending] PendingTransactionUpdate: (Tot: 6) PENDING : 310bc319 1 #12 (db7f54 <~ e21734) Txs:0, Unc: 0 [Invalid nonce: required: 0 , tx.nonce: 1]

DEBUG [pending] PendingTransactionUpdate: (Tot: 6) PENDING : 310bc319 2 #12 (db7f54 <~ e21734) Txs:0, Unc: 0 [Invalid nonce: required: 0 , tx.nonce: 2]

.......

DEBUG [pending] PendingTransactionUpdate: (Tot: 6) DROPPED : 310bc319 7 #12 (db7f54 <~ e21734) Txs:0, Unc: 0 [Invalid nonce: required: 0 , tx.nonce: 7]
"
The transaction cannot include into the last blocks. How to fix this issue? Thanks a lot!

You may see in the logs that the error is [Invalid nonce: required: 0 , tx.nonce: 1]. How do you send those Txes?

in the https://gist.github.com/fangyun/a058ef8ca226cd18acd804aa00b45c73 , post all code, just like below:

	private void generateTransactions() throws Exception {
		if (config.getConfig().getString("sample.name").equals("regular1")) {
			logger.info("Start generating transactions...");
			ECKey senderKey = ECKey.fromPrivate(Hex.decode("166a94b0bb06d32152e2ada5b46c4adb9618fef66b2f3b3df78a4f98c4cb56f8"));
			byte[] receiverAddr = Hex.decode("923e27e786dd26fcf657e3881c51a8dc07019598"); // regular2

			for (int i = ethereum.getRepository().getNonce(senderKey.getAddress())
					.intValue(), j = 0; j < 20000; i++, j++) {
				{
					Transaction tx = new Transaction(ByteUtil.intToBytesNoLeadZeroes(i),
							ByteUtil.longToBytesNoLeadZeroes(50_000_000_000L),
							ByteUtil.longToBytesNoLeadZeroes(0xfffff), receiverAddr, new byte[] { 77 }, new byte[0],
							ethereum.getChainIdForNextBlock());
					tx.sign(senderKey);
					logger.info("<== Submitting tx: " + tx);
					ethereum.submitTransaction(tx);
				}
				Thread.sleep(7000);
			}
		}
	}

Could you try to send only one transaction? The code looks correct, but in the log excerpt I don't see Tx with zero nonce which should be the first one

Yes,this sample code fragment generateTransactions is copy from org.ethereum.samples.PrivateMinerSample.

I just run the PrivateMinerSample , this invalid nonce is also happened , but it is like below:

[Invalid nonce: required: 1 , tx.nonce: 0]
[Invalid nonce: required: 2 , tx.nonce: 0]
....
....
DROPPED : 31e2e1ed 0 #15 (88cd77 <~ c3661c) Txs:0, Unc: 0 [Tx was not included into last 10 blocks]

I found the difference between those two samples: in my sample the required nonce =0 is always less than tx.nonce, but PrivateMinerSample required nonce is increasing , and always great than tx.nonce=0,
and in PrivateMinerSample, when Tx was not included into last 10 blocks, this invalid nonce dropped.

So the question is why my sample generate required nonce=0 is always less than the increasing tx.nonce? that lead to this complain always happened and the transaction can not include into last blocks.

Hm, could you please try out ethereum.getPendingState().getNonce(...)?

After modifying the code, the situation remains the same.

Ok, let's fall back to BigInteger.ZERO as nonce.

I don't get your point, what should I do?

// explicitly pass zero nonce
Transaction tx = new Transaction(ByteUtil.intToBytesNoLeadZeroes(0),
        ByteUtil.longToBytesNoLeadZeroes(50_000_000_000L),
        ByteUtil.longToBytesNoLeadZeroes(0xfffff), receiverAddr, 
        new byte[] { 77 }, new byte[0], ethereum.getChainIdForNextBlock());

ok, let me try.

You means always set Transaction's nonce as zero, I try it out, but it still get the same result.

With help from @mkalinin , the issue is identified , here is chat from him

there are two options

  1. set sync.enabled=false for miner node
  2. set sync.makeDoneByTimeout=0 for miner node.

and, you better enable miner in config rather than starting it manually from the code

miner hasn't include Tx from regular node into mem pool cause sync was enabled and hasn't been finished (by default, it finishes when meets new block, it only works if node is not a solo miner in the net)
in case if there is no other miners in the net sync should be either turned off or forced to get finished

I update the conf and code , this issue is gone. Thanks @mkalinin for your effort on this issue! You are very nice man!