Beispiel #1
0
            public ResultWrapper <TResult> ExecuteTx(
                TransactionForRpc transactionCall,
                BlockParameter?blockParameter)
            {
                SearchResult <BlockHeader> searchResult = _blockFinder.SearchForHeader(blockParameter);

                if (searchResult.IsError)
                {
                    return(ResultWrapper <TResult> .Fail(searchResult));
                }

                BlockHeader header = searchResult.Object;

                if (!HasStateForBlock(_blockchainBridge, header))
                {
                    return(ResultWrapper <TResult> .Fail($"No state available for block {header.Hash}",
                                                         ErrorCodes.ResourceUnavailable));
                }

                FixCallTx(transactionCall);

                using CancellationTokenSource cancellationTokenSource = new(_rpcConfig.Timeout);
                Transaction tx = transactionCall.ToTransaction(_blockchainBridge.GetChainId());

                return(ExecuteTx(header, tx, cancellationTokenSource.Token));
            }
Beispiel #2
0
        private ResultWrapper <UInt256?> EstimateGas(TransactionForRpc transactionCall, BlockHeader head)
        {
            // 2021-03-04 08:54:18.6489|DEBUG|101|Responded to ID 40, eth_estimateGas({
            //     "from": "0x2b5ad5c4795c026514f8317c7a215e218dccd6cf",
            //     "to": "0xa28afda14be5789564ae5fa03665c4180e3c680b",
            //     "data": "0x25936984"
            // })

            // 2021-03-04 08:54:18.6533|DEBUG|13|Responded to ID 41, eth_sendTransaction({
            //     "gas": "0x1f815f1",
            //     "from": "0x2b5ad5c4795c026514f8317c7a215e218dccd6cf",
            //     "to": "0xa28afda14be5789564ae5fa03665c4180e3c680b",
            //     "data": "0x25936984",
            //     "gasPrice": "0x4a817c800"
            // })

            FixCallTx(transactionCall);

            // using CancellationTokenSource cancellationTokenSource = new(_cancellationTokenTimeout);
            CancellationToken cancellationToken = CancellationToken.None;

            BlockchainBridge.CallOutput result =
                _blockchainBridge.EstimateGas(head, transactionCall.ToTransaction(), cancellationToken);

            if (result.Error == null)
            {
                return(ResultWrapper <UInt256?> .Success((UInt256)result.GasSpent));
            }

            return(ResultWrapper <UInt256?> .Fail(result.Error, result.InputError?ErrorCodes.InvalidInput : ErrorCodes.InternalError));
        }
Beispiel #3
0
        public ResultWrapper <byte[]> eth_call(TransactionForRpc transactionCall, BlockParameter blockParameter = null)
        {
            BlockHeader block = _blockchainBridge.GetHeader(blockParameter ?? BlockParameter.Latest);

            var tx = transactionCall.ToTransaction();

            tx.GasPrice = 0;
            if (tx.GasLimit < 21000)
            {
                tx.GasLimit = 10000000;
            }

            if (tx.To == null)
            {
                return(ResultWrapper <byte[]> .Fail($"Recipient address not specified on the transaction.", ErrorType.InvalidParams));
            }

            BlockchainBridge.CallOutput result = _blockchainBridge.Call(block, tx);

            if (result.Error != null)
            {
                return(ResultWrapper <byte[]> .Fail($"VM Exception while processing transaction: {result.Error}", ErrorType.ExecutionError, result.OutputData));
            }

            return(ResultWrapper <byte[]> .Success(result.OutputData));
        }
Beispiel #4
0
        public ResultWrapper <string> eth_call(TransactionForRpc transactionCall, BlockParameter blockParameter = null)
        {
            SearchResult <BlockHeader> searchResult = _blockFinder.SearchForHeader(blockParameter);

            if (searchResult.IsError)
            {
                return(ResultWrapper <string> .Fail(searchResult));
            }

            BlockHeader header = searchResult.Object;

            if (!HasStateForBlock(header))
            {
                return(ResultWrapper <string> .Fail($"No state available for block {header.Hash}", ErrorCodes.ResourceUnavailable));
            }

            FixCallTx(transactionCall, header);

            using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(_cancellationTokenTimeout);
            CancellationToken cancellationToken = cancellationTokenSource.Token;
            Transaction       tx = transactionCall.ToTransaction();

            BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx, cancellationToken);

            return(result.Error != null ? ResultWrapper <string> .Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error) : ResultWrapper <string> .Success(result.OutputData.ToHexString(true)));
        }
Beispiel #5
0
        public ResultWrapper <UInt256?> eth_estimateGas(TransactionForRpc transactionCall)
        {
            BlockHeader head = _blockchainBridge.FindLatestHeader();

            FixCallTx(transactionCall, head);

            long result = _blockchainBridge.EstimateGas(head, transactionCall.ToTransaction());

            return(ResultWrapper <UInt256?> .Success((UInt256)result));
        }
Beispiel #6
0
        public void can_convert_from_Transaction_to_TransactionForRpc_and_back()
        {
            _transaction      = new Transaction();
            _transaction.Type = TxType.AccessList;

            _transaction.AccessList = GetTestAccessList();
            _transactionForRpc      = new TransactionForRpc(_transaction);
            Transaction afterConversion = _transactionForRpc.ToTransaction();

            afterConversion.Should().BeEquivalentTo(_transaction);
        }
Beispiel #7
0
        public ResultWrapper <CallResultWithProof> proof_call(TransactionForRpc tx, BlockParameter blockParameter)
        {
            SearchResult <BlockHeader> searchResult = _blockFinder.SearchForHeader(blockParameter);

            if (searchResult.IsError)
            {
                return(ResultWrapper <CallResultWithProof> .Fail(searchResult));
            }

            BlockHeader sourceHeader = searchResult.Object;
            BlockHeader callHeader   = new BlockHeader(
                sourceHeader.Hash,
                Keccak.OfAnEmptySequenceRlp,
                Address.Zero,
                0,
                sourceHeader.Number + 1,
                sourceHeader.GasLimit,
                sourceHeader.Timestamp,
                Array.Empty <byte>());

            callHeader.TxRoot          = Keccak.EmptyTreeHash;
            callHeader.ReceiptsRoot    = Keccak.EmptyTreeHash;
            callHeader.Author          = Address.SystemUser;
            callHeader.TotalDifficulty = sourceHeader.TotalDifficulty + callHeader.Difficulty;
            callHeader.Hash            = callHeader.CalculateHash();

            Transaction transaction = tx.ToTransaction();

            transaction.SenderAddress ??= Address.SystemUser;

            if (transaction.GasLimit == 0)
            {
                transaction.GasLimit = callHeader.GasLimit;
            }

            Block block = new Block(callHeader, new[] { transaction }, Enumerable.Empty <BlockHeader>());

            ProofBlockTracer proofBlockTracer = new ProofBlockTracer(null, transaction.SenderAddress == Address.SystemUser);

            _tracer.Trace(block, proofBlockTracer);

            CallResultWithProof callResultWithProof = new CallResultWithProof();
            ProofTxTracer       proofTxTracer       = proofBlockTracer.BuildResult().Single();

            callResultWithProof.BlockHeaders = CollectHeaderBytes(proofTxTracer, sourceHeader);
            callResultWithProof.Result       = proofTxTracer.Output;

            // we collect proofs from before execution (after learning which addresses will be touched)
            // if we wanted to collect post execution proofs then we would need to use BeforeRestore on the tracer
            callResultWithProof.Accounts = CollectAccountProofs(sourceHeader.StateRoot, proofTxTracer);

            return(ResultWrapper <CallResultWithProof> .Success(callResultWithProof));
        }
Beispiel #8
0
        public ResultWrapper <UInt256?> eth_estimateGas(TransactionForRpc transactionCall)
        {
            Block headBlock = _blockchainBridge.FindHeadBlock();

            if (transactionCall.Gas == null)
            {
                transactionCall.Gas = headBlock.GasLimit;
            }

            long result = _blockchainBridge.EstimateGas(headBlock, transactionCall.ToTransaction());

            return(ResultWrapper <UInt256?> .Success((UInt256)result));
        }
Beispiel #9
0
 public ResultWrapper <Keccak> eth_sendTransaction(TransactionForRpc transactionForRpc)
 {
     try
     {
         _readerWriterLockSlim.EnterWriteLock();
         Transaction tx     = transactionForRpc.ToTransaction();
         Keccak      txHash = _blockchainBridge.SendTransaction(tx);
         return(ResultWrapper <Keccak> .Success(txHash));
     }
     finally
     {
         _readerWriterLockSlim.ExitWriteLock();
     }
 }
Beispiel #10
0
        public ResultWrapper <Keccak> eth_sendTransaction(TransactionForRpc transactionForRpc)
        {
            Transaction tx = transactionForRpc.ToTransaction();

            if (tx.Signature == null)
            {
                tx.Nonce = _blockchainBridge.GetNonce(tx.SenderAddress);
                _blockchainBridge.Sign(tx);
            }

            Keccak txHash = _blockchainBridge.SendTransaction(tx, true);

            return(ResultWrapper <Keccak> .Success(txHash));
        }
Beispiel #11
0
        public ResultWrapper <UInt256?> eth_estimateGas(TransactionForRpc transactionCall)
        {
            BlockHeader head = _blockchainBridge.FindLatestHeader();

            FixCallTx(transactionCall, head);

            BlockchainBridge.CallOutput result = _blockchainBridge.EstimateGas(head, transactionCall.ToTransaction());
            if (result.Error == null)
            {
                return(ResultWrapper <UInt256?> .Success((UInt256)result.GasSpent));
            }

            return(ResultWrapper <UInt256?> .Fail(result.Error));
        }
Beispiel #12
0
        private ResultWrapper <UInt256?> EstimateGas(TransactionForRpc transactionCall, BlockHeader head)
        {
            FixCallTx(transactionCall, head);

            var tokenTimeout = TimeSpan.FromMilliseconds(_rpcConfig.TracerTimeout);
            CancellationToken cancellationToken = new CancellationTokenSource(tokenTimeout).Token;

            BlockchainBridge.CallOutput result = _blockchainBridge.EstimateGas(head, transactionCall.ToTransaction(), cancellationToken);

            if (result.Error == null)
            {
                return(ResultWrapper <UInt256?> .Success((UInt256)result.GasSpent));
            }

            return(ResultWrapper <UInt256?> .Fail(result.Error));
        }
Beispiel #13
0
        private ResultWrapper <UInt256?> EstimateGas(TransactionForRpc transactionCall, BlockHeader head)
        {
            FixCallTx(transactionCall, head);

            using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(_cancellationTokenTimeout);
            CancellationToken cancellationToken = cancellationTokenSource.Token;

            BlockchainBridge.CallOutput result = _blockchainBridge.EstimateGas(head, transactionCall.ToTransaction(), cancellationToken);

            if (result.Error == null)
            {
                return(ResultWrapper <UInt256?> .Success((UInt256)result.GasSpent));
            }

            return(ResultWrapper <UInt256?> .Fail(result.Error));
        }
Beispiel #14
0
        public async Task <ResultWrapper <Keccak> > eth_sendTransaction(TransactionForRpc transactionForRpc)
        {
            var transaction = transactionForRpc.ToTransaction();

            if (transaction.Signature is null)
            {
                var chainIdResult = await _proxy.eth_chainId();

                var chainId     = chainIdResult?.IsValid == true ? (int)chainIdResult.Result : 0;
                var nonceResult =
                    await _proxy.eth_getTransactionCount(transaction.SenderAddress, BlockParameterModel.Pending);

                transaction.Nonce = nonceResult?.IsValid == true ? nonceResult.Result ?? UInt256.Zero : UInt256.Zero;
                _wallet.Sign(transaction, chainId);
            }

            return(ResultWrapper <Keccak> .From(await _proxy.eth_sendRawTransaction(Rlp.Encode(transaction).Bytes)));
        }
Beispiel #15
0
        public ResultWrapper <BigInteger?> eth_estimateGas(TransactionForRpc transactionCall)
        {
            try
            {
                _readerWriterLockSlim.EnterWriteLock();
                Block headBlock = _blockchainBridge.RetrieveHeadBlock();
                if (transactionCall.Gas == null)
                {
                    transactionCall.Gas = headBlock.GasLimit;
                }

                long result = _blockchainBridge.EstimateGas(headBlock, transactionCall.ToTransaction());
                return(ResultWrapper <BigInteger?> .Success(result));
            }
            finally
            {
                _readerWriterLockSlim.ExitWriteLock();
            }
        }
Beispiel #16
0
        public ResultWrapper <string> eth_call(TransactionForRpc transactionCall, BlockParameter blockParameter = null)
        {
            SearchResult <BlockHeader> searchResult = _blockchainBridge.SearchForHeader(blockParameter);

            if (searchResult.IsError)
            {
                return(ResultWrapper <string> .Fail(searchResult));
            }

            BlockHeader header = searchResult.Object;

            FixCallTx(transactionCall, header);

            Transaction tx = transactionCall.ToTransaction();

            BlockchainBridge.CallOutput result = _blockchainBridge.Call(header, tx);

            return(result.Error != null ? ResultWrapper <string> .Fail("VM execution error.", ErrorCodes.ExecutionError, result.Error) : ResultWrapper <string> .Success(result.OutputData.ToHexString(true)));
        }
Beispiel #17
0
        public ResultWrapper <UInt256?> eth_estimateGas(TransactionForRpc transactionCall)
        {
            BlockHeader head = _blockchainBridge.FindLatestHeader();

            if (!HasStateForBlock(head))
            {
                return(ResultWrapper <UInt256?> .Fail($"No state available for block {head.Hash}", ErrorCodes.ResourceUnavailable));
            }

            FixCallTx(transactionCall, head);

            BlockchainBridge.CallOutput result = _blockchainBridge.EstimateGas(head, transactionCall.ToTransaction());
            if (result.Error == null)
            {
                return(ResultWrapper <UInt256?> .Success((UInt256)result.GasSpent));
            }

            return(ResultWrapper <UInt256?> .Fail(result.Error));
        }
Beispiel #18
0
        public ResultWrapper <byte[]> eth_call(TransactionForRpc transactionCall, BlockParameter blockParameter = null)
        {
            try
            {
                _readerWriterLockSlim.EnterWriteLock();
                BlockHeader block = blockParameter == null ? _blockchainBridge.Head : GetBlock(blockParameter).Data.Header;
                BlockchainBridge.CallOutput result = _blockchainBridge.Call(block, transactionCall.ToTransaction());

                if (result.Error != null)
                {
                    return(ResultWrapper <byte[]> .Fail($"VM Exception while processing transaction: {result.Error}", ErrorType.ExecutionError, result.OutputData));
                }

                return(ResultWrapper <byte[]> .Success(result.OutputData));
            }
            finally
            {
                _readerWriterLockSlim.ExitWriteLock();
            }
        }
Beispiel #19
0
        public ResultWrapper <Keccak> eth_sendTransaction(TransactionForRpc transactionForRpc)
        {
            try
            {
                _readerWriterLockSlim.EnterWriteLock();
                Transaction tx = transactionForRpc.ToTransaction();
                if (tx.Signature == null)
                {
                    tx.Nonce = (UInt256)_blockchainBridge.GetNonce(tx.SenderAddress);
                    _blockchainBridge.Sign(tx);
                }

                Keccak txHash = _blockchainBridge.SendTransaction(tx);
                return(ResultWrapper <Keccak> .Success(txHash));
            }
            finally
            {
                _readerWriterLockSlim.ExitWriteLock();
            }
        }
Beispiel #20
0
        public ResultWrapper <string> eth_call(TransactionForRpc transactionCall, BlockParameter blockParameter = null)
        {
            BlockHeader block = _blockchainBridge.GetHeader(blockParameter ?? BlockParameter.Latest);

            var tx = transactionCall.ToTransaction();

            tx.GasPrice = 0;
            if (tx.GasLimit < 21000)
            {
                tx.GasLimit = 10000000;
            }

            BlockchainBridge.CallOutput result = _blockchainBridge.Call(block, tx);

            if (result.Error != null)
            {
                return(ResultWrapper <string> .Fail("VM execution error.", ErrorType.ExecutionError, result.Error));
            }

            return(ResultWrapper <string> .Success(result.OutputData.ToHexString(true)));
        }
Beispiel #21
0
        public ResultWrapper <ParityTxTraceFromReplay> trace_call(TransactionForRpc message, string[] traceTypes, BlockParameter blockParameter)
        {
            Transaction tx = message.ToTransaction();

            return(TraceTx(tx, traceTypes, blockParameter));
        }