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

Transactions with insufficient funds can be on-chain and lead to consensus service stuck #1244

Closed
cloud8little opened this issue Nov 15, 2019 · 1 comment · Fixed by #1248

Comments

@cloud8little
Copy link
Contributor

Describe the bug
Transactions with insufficient funds can be on-chain and lead to consensus service stuck.

To Reproduce
Steps to reproduce the behavior:

  1. Run one seed node.
  2. Run a single consensus node, connect to the seed node
  3. Run an external node.
  4. Withdraw the initial NEO/GAS and send 100k GAS to a sender wallet.
  5. Open the sender wallet, use (sendfrom)rpc request to send about 800k requests, 0.00000001 GAS/request to another account.
  6. Around 1hour later, consensus service stuck, not generating blocks anymore.

when the consensus service stuck, there is only 459+GAS with the account.

Expected behavior
Those transactions with not enough gas check should be discarded.
Consensus service should not stuck.

Screenshots
3171573801636_ pic_hd
4281573804642_ pic_hd
4291573804681_ pic

Platform:

@Tommo-L
Copy link
Contributor

Tommo-L commented Nov 15, 2019

This problem related to #1140 @vncoelho

I think we can allow this situation happen but change the calculation of sys_fee.

protected override bool OnPersist(ApplicationEngine engine)
{
if (!base.OnPersist(engine)) return false;
foreach (Transaction tx in engine.Snapshot.PersistingBlock.Transactions)
Burn(engine, tx.Sender, tx.SystemFee + tx.NetworkFee);
ECPoint[] validators = NEO.GetNextBlockValidators(engine.Snapshot);
UInt160 primary = Contract.CreateSignatureRedeemScript(validators[engine.Snapshot.PersistingBlock.ConsensusData.PrimaryIndex]).ToScriptHash();
Mint(engine, primary, engine.Snapshot.PersistingBlock.Transactions.Sum(p => p.NetworkFee));
BigInteger sys_fee = GetSysFeeAmount(engine.Snapshot, engine.Snapshot.PersistingBlock.Index - 1) + engine.Snapshot.PersistingBlock.Transactions.Sum(p => p.SystemFee);
StorageKey key = CreateStorageKey(Prefix_SystemFeeAmount, BitConverter.GetBytes(engine.Snapshot.PersistingBlock.Index));
engine.Snapshot.Storages.Add(key, new StorageItem
{
Value = sys_fee.ToByteArray(),
IsConstant = true
});
return true;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants