Example #1
0
 private bool AddTransaction(Transaction tx)
 {
     if (Blockchain.Default == null)
     {
         return(false);
     }
     lock (MemoryPool)
     {
         if (MemoryPool.ContainsKey(tx.Hash))
         {
             return(false);
         }
         if (Blockchain.Default.ContainsTransaction(tx.Hash))
         {
             return(false);
         }
         if (!tx.Verify(MemoryPool.Values))
         {
             return(false);
         }
         AddingTransactionEventArgs args = new AddingTransactionEventArgs(tx);
         AddingTransaction?.Invoke(this, args);
         if (!args.Cancel)
         {
             MemoryPool.Add(tx.Hash, tx);
         }
         return(!args.Cancel);
     }
 }
Example #2
0
 private bool AddTransaction(Transaction tx)
 {
     if (Blockchain.Default == null)
     {
         return(false);
     }
     lock (MemoryPool)
     {
         if (MemoryPool.ContainsKey(tx.Hash))
         {
             return(false);
         }
         if (MemoryPool.Values.SelectMany(p => p.GetAllInputs()).Intersect(tx.GetAllInputs()).Count() > 0)
         {
             return(false);
         }
         if (Blockchain.Default.ContainsTransaction(tx.Hash))
         {
             return(false);
         }
         if (!tx.Verify())
         {
             return(false);
         }
         AddingTransactionEventArgs args = new AddingTransactionEventArgs(tx);
         AddingTransaction?.Invoke(this, args);
         if (!args.Cancel)
         {
             MemoryPool.Add(tx.Hash, tx);
         }
         return(!args.Cancel);
     }
 }
            public AddingTxEventArgs CanAddTransaction(Block block, Transaction currentTx, IReadOnlySet <Transaction> transactionsInBlock, IStateProvider stateProvider)
            {
                AddingTxEventArgs args = new(transactionsInBlock.Count, currentTx, block, transactionsInBlock);

                long gasRemaining = block.Header.GasLimit - block.GasUsed;

                // No more gas available in block for any transactions,
                // the only case we have to really stop
                if (GasCostOf.Transaction > gasRemaining)
                {
                    return(args.Set(TxAction.Stop, "Block full"));
                }

                if (currentTx.SenderAddress is null)
                {
                    return(args.Set(TxAction.Skip, "Null sender"));
                }

                if (currentTx.GasLimit > gasRemaining)
                {
                    return(args.Set(TxAction.Skip, $"Not enough gas in block, gas limit {currentTx.GasLimit} > {gasRemaining}"));
                }

                if (transactionsInBlock.Contains(currentTx))
                {
                    return(args.Set(TxAction.Skip, "Transaction already in block"));
                }

                IReleaseSpec spec = _specProvider.GetSpec(block.Number);

                if (stateProvider.IsInvalidContractSender(spec, currentTx.SenderAddress))
                {
                    return(args.Set(TxAction.Skip, $"Sender is contract"));
                }

                UInt256 expectedNonce = stateProvider.GetNonce(currentTx.SenderAddress);

                if (expectedNonce != currentTx.Nonce)
                {
                    return(args.Set(TxAction.Skip, $"Invalid nonce - expected {expectedNonce}"));
                }

                UInt256 balance = stateProvider.GetBalance(currentTx.SenderAddress);

                if (!HasEnoughFounds(currentTx, balance, args, block, spec))
                {
                    return(args);
                }

                AddingTransaction?.Invoke(this, args);
                return(args);
            }