예제 #1
0
        private TransactionReceipt Execute(params byte[] code)
        {
            _stateProvider.CreateAccount(A, 100.Ether());

            _stateProvider.CreateAccount(B, 100.Ether());
            Keccak codeHash = _stateProvider.UpdateCode(code);

            _stateProvider.UpdateCodeHash(TestObject.AddressB, codeHash, _spec.GenesisSpec);

            _stateProvider.Commit(_spec.GenesisSpec);

            Transaction transaction = Build.A.Transaction
                                      .WithGasLimit(100000)
                                      .WithGasPrice(1)
                                      .WithTo(TestObject.AddressB)
                                      .SignedAndResolved(_ethereumSigner, TestObject.PrivateKeyA, 100000)
                                      .TestObject;

            Assert.AreEqual(A, _ethereumSigner.RecoverAddress(transaction, 100000));

            Block block = Build.A.Block.WithNumber(10000).TestObject;
            TransactionReceipt receipt = _processor.Execute(transaction, block.Header);

            return(receipt);
        }
예제 #2
0
        private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            _timer.Interval = RandomizeDelay().TotalMilliseconds;
            _logger.Debug($"Generating a test transaction for testing ({_count}).");

            Transaction tx = new Transaction();

            tx.GasPrice      = 1;
            tx.GasLimit      = 21000;
            tx.To            = new Address(0x0f.ToBigEndianByteArray().PadLeft(20));
            tx.Nonce         = _nonce++;
            tx.Value         = 1;
            tx.Data          = new byte[0];
            tx.Nonce         = _count++;
            tx.SenderAddress = SenderAddress;
            _signer.Sign(_privateKey, tx, 1);
            Address address = _signer.RecoverAddress(tx, 1);

            if (address != tx.SenderAddress)
            {
                throw new InvalidDataException($"{nameof(TestTransactionsGenerator)} producing invalid transactions");
            }

            tx.Hash = Transaction.CalculateHash(tx);

            _transactionPool.AddTransaction(tx, 1);
            _logger.Debug($"Generated a test transaction for testing ({_count - 1}).");
        }
예제 #3
0
        public Address GetBlockSealer(BlockHeader header)
        {
            int     extraSeal = 65;
            Address address   = _signatures?.Get(header.Hash);

            if (address != null)
            {
                return(address);
            }

            // Retrieve the signature from the header extra-data
            if (header.ExtraData.Length < extraSeal)
            {
                return(null);
            }

            byte[]    signatureBytes = header.ExtraData.Slice(header.ExtraData.Length - extraSeal, extraSeal);
            Signature signature      = new Signature(signatureBytes);

            signature.V += 27;
            Keccak message = header.HashCliqueHeader();

            address = _signer.RecoverAddress(signature, message);
            _signatures?.Set(header.Hash, address);
            return(address);
        }
        private void TimerOnElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
        {
            _timer.Interval = RandomizeDelay().TotalMilliseconds;
            _logger.Debug($"Generating a test transaction for testing ({_count}).");

            Transaction tx = new Transaction();

            tx.GasPrice = 1;
            tx.GasLimit = 21000;
            tx.To       = new Address(0x0f.ToBigEndianByteArray().PadLeft(20));
            tx.Nonce    = 0;
            tx.Value    = 1;
            tx.Data     = new byte[0];
            tx.Nonce    = _count++;
            _signer.Sign(_privateKey, tx, 0);
            Address address = _signer.RecoverAddress(tx, 0);

            if (address != SenderAddress)
            {
                _logger.Debug($"Signature mismatch in tests generator (EIP?).");
            }

            tx.Hash = Transaction.CalculateHash(tx);

            _store.AddPending(tx);
            _logger.Debug($"Generated a test transaction for testing ({_count - 1}).");
        }
예제 #5
0
        public Address GetBlockSealer(BlockHeader header)
        {
            if (header.Author != null)
            {
                return(header.Author);
            }
            if (header.Number == UInt256.Zero)
            {
                return(Address.Zero);
            }
            if (_signatures.Get(header.Hash) != null)
            {
                return(_signatures.Get(header.Hash));
            }

            int extraSeal = 65;

            // Retrieve the signature from the header extra-data
            if (header.ExtraData.Length < extraSeal)
            {
                return(null);
            }

            var       signatureBytes = header.ExtraData.Slice(header.ExtraData.Length - extraSeal, extraSeal);
            Signature signature      = new Signature(signatureBytes);

            signature.V += 27;
            Keccak  message = CalculateCliqueHeaderHash(header);
            Address address = _signer.RecoverAddress(signature, message);

            _signatures.Set(header.Hash, address);
            return(address);
        }
        public void RecoverData(Block block)
        {
            if (block.Transactions.Length == 0 || block.Transactions[0].SenderAddress != null)
            {
                return;
            }

            for (int i = 0; i < block.Transactions.Length; i++)
            {
                _transactionPool.TryGetSender(block.Transactions[i].Hash, out Address sender);
                block.Transactions[i].SenderAddress = sender ?? _signer.RecoverAddress(block.Transactions[i], block.Number);
            }
        }
예제 #7
0
        public AddTransactionResult AddTransaction(Transaction transaction, UInt256 blockNumber)
        {
            Metrics.PendingTransactionsReceived++;

            // beware we are discarding here the old signature scheme without ChainId
            if (transaction.Signature.GetChainId == null)
            {
                Metrics.PendingTransactionsDiscarded++;
                return(AddTransactionResult.OldScheme);
            }

            if (transaction.Signature.GetChainId != _specProvider.ChainId)
            {
                Metrics.PendingTransactionsDiscarded++;
                return(AddTransactionResult.InvalidChainId);
            }

            if (!_pendingTransactions.TryAdd(transaction.Hash, transaction))
            {
                Metrics.PendingTransactionsKnown++;
                return(AddTransactionResult.AlreadyKnown);
            }

            if (_transactionStorage.Get(transaction.Hash) != null)
            {
                Metrics.PendingTransactionsKnown++;
                return(AddTransactionResult.AlreadyKnown);
            }

            transaction.SenderAddress = _signer.RecoverAddress(transaction, blockNumber);

            // check nonce

            if (transaction.DeliveredBy == null)
            {
                _ownTransactions.TryAdd(transaction.Hash, transaction);
                _ownTimer.Enabled = true;

                if (_logger.IsInfo)
                {
                    _logger.Info($"Broadcasting own transaction {transaction.Hash} to {_peers.Count} peers");
                }
            }

            NotifySelectedPeers(transaction);

            FilterAndStoreTransaction(transaction, blockNumber);
            NewPending?.Invoke(this, new TransactionEventArgs(transaction));
            return(AddTransactionResult.Added);
        }
예제 #8
0
        private void FilterAndStoreTransaction(Transaction transaction, UInt256 blockNumber)
        {
            var filters = _filters.Values;

            if (filters.Any(filter => !filter.IsValid(transaction)))
            {
                return;
            }

            transaction.SenderAddress = _signer.RecoverAddress(transaction, blockNumber);
            _transactionStorage.Add(transaction, blockNumber);
            if (_logger.IsTrace)
            {
                _logger.Trace($"Added a transaction: {transaction.Hash}");
            }
        }
예제 #9
0
 public Transaction MapTransaction(Core.Transaction transaction, Core.Block block)
 {
     return(new Transaction
     {
         Hash = new Data(transaction.Hash.Bytes),
         Nonce = new Quantity(transaction.Nonce),
         BlockHash = block != null ? new Data(block.Hash.Bytes) : null,
         BlockNumber = block?.Header != null ? new Quantity(block.Header.Number) : null,
         TransactionIndex = block?.Transactions != null ? new Quantity(GetTransactionIndex(transaction, block)) : null,
         From = new Data(_signer.RecoverAddress(transaction, block.Number).Bytes),
         To = new Data(transaction.To.Bytes),
         Value = new Quantity(transaction.Value),
         GasPrice = new Quantity(transaction.GasPrice),
         Gas = new Quantity(transaction.GasLimit),
         Data = new Data(transaction.Data)
     });
 }
예제 #10
0
        public Transaction MapTransaction(Core.Transaction transaction, Core.Block block)
        {
            throw new NotImplementedException(); // TODO: look at new transaction recover (that takes block number)

            return(new Transaction
            {
                Hash = new Data(transaction.Hash.Bytes),
                Nonce = new Quantity(transaction.Nonce),
                BlockHash = block != null ? new Data(block.Hash.Bytes) : null,
                BlockNumber = block?.Header != null ? new Quantity(block.Header.Number) : null,
                TransactionIndex = block?.Transactions != null ? new Quantity(GetTransactionIndex(transaction, block)) : null,
                From = new Data(_signer.RecoverAddress(transaction, block.Number).Hex),
                To = new Data(transaction.To.Hex),
                Value = new Quantity(transaction.Value),
                GasPrice = new Quantity(transaction.GasPrice),
                Gas = new Quantity(transaction.GasLimit),
                Data = new Data(transaction.Data)
            });
        }
예제 #11
0
        public AddTransactionResult AddTransaction(Transaction transaction, UInt256 blockNumber)
        {
            Metrics.PendingTransactionsReceived++;

            // beware we are discarding here the old signature scheme without ChainId
            if (transaction.Signature.GetChainId == null)
            {
                Metrics.PendingTransactionsDiscarded++;
                return(AddTransactionResult.OldScheme);
            }

            if (transaction.Signature.GetChainId != _specProvider.ChainId)
            {
                Metrics.PendingTransactionsDiscarded++;
                return(AddTransactionResult.InvalidChainId);
            }

            if (!_pendingTransactions.TryAdd(transaction.Hash, transaction))
            {
                Metrics.PendingTransactionsKnown++;
                return(AddTransactionResult.AlreadyKnown);
            }

            if (_transactionStorage.Get(transaction.Hash) != null)
            {
                Metrics.PendingTransactionsKnown++;
                return(AddTransactionResult.AlreadyKnown);
            }

            transaction.SenderAddress = _signer.RecoverAddress(transaction, blockNumber);

            // check nonce

            List <ISynchronizationPeer> selectedPeers = SelectPeers(transaction);

            NotifyPeers(selectedPeers, transaction);

            FilterAndStoreTransaction(transaction, blockNumber);
            NewPending?.Invoke(this, new TransactionEventArgs(transaction));
            return(AddTransactionResult.Added);
        }