Example #1
0
        public TransactionVerifierResult Verify(TxReceipt receipt)
        {
            var confirmations = 0;
            var block         = _blockchainBridge.FindBlock(_blockchainBridge.Head.Hash);

            if (block is null)
            {
                return(new TransactionVerifierResult(false, 0, _requiredBlockConfirmations));
            }

            while (block.Number >= receipt.BlockNumber)
            {
                confirmations++;
                if (block.Hash == receipt.BlockHash)
                {
                    break;
                }

                block = _blockchainBridge.FindBlock(block.ParentHash);
                if (block is null)
                {
                    break;
                }
            }

            return(new TransactionVerifierResult(true, confirmations, _requiredBlockConfirmations));
        }
Example #2
0
        public async Task find_block_by_hash_should_invoke_blockchain_bridge_find_block_by_hash()
        {
            var block = Build.A.Block.TestObject;

            _blockchainBridge.FindBlock(block.Hash).Returns(block);
            var result = await _ndmBridge.FindBlockAsync(block.Hash);

            _blockchainBridge.Received().FindBlock(block.Hash);
            result.Should().Be(block);
        }
        public void Eth_get_block_by_hash()
        {
            IBlockchainBridge bridge = Substitute.For <IBlockchainBridge>();

            bridge.FindBlock(Arg.Any <Keccak>(), Arg.Any <bool>()).Returns(Build.A.Block.WithTotalDifficulty(0).WithTransactions(Build.A.Transaction.TestObject).TestObject);

            IEthModule module = new EthModule(NullLogManager.Instance, bridge);

            string serialized = RpcTest.TestSerializedRequest(module, "eth_getBlockByHash", TestItem.KeccakA.ToString(), "true");

            Assert.AreEqual("{\"id\":\"0x43\",\"jsonrpc\":\"2.0\",\"result\":{\"number\":\"0x0\",\"hash\":\"0xa2a9f03b9493046696099d27b2612b99497aa1f392ec966716ab393c715a5bb6\",\"parentHash\":\"0xff483e972a04a9a62bb4b7d04ae403c615604e4090521ecc5bb7af67f71be09c\",\"nonce\":\"0x3e8\",\"mixHash\":\"0x2ba5557a4c62a513c7e56d1bf13373e0da6bec016755483e91589fe1c6d212e2\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"stateRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"difficulty\":\"0xf4240\",\"totalDifficulty\":\"0x0\",\"extraData\":\"0x010203\",\"size\":\"0x0\",\"gasLimit\":\"0x3d0900\",\"gasUsed\":\"0x0\",\"timestamp\":\"0xf4240\",\"transactions\":[{\"hash\":null,\"nonce\":\"0x0\",\"blockHash\":\"0xa2a9f03b9493046696099d27b2612b99497aa1f392ec966716ab393c715a5bb6\",\"blockNumber\":\"0x0\",\"transactionIndex\":\"0x0\",\"from\":null,\"to\":\"0x0000000000000000000000000000000000000000\",\"value\":\"0x1\",\"gasPrice\":\"0x1\",\"gas\":\"0x5208\",\"data\":\"0x\"}],\"transactionHashes\":null,\"uncles\":[]}}", serialized);
        }
Example #4
0
        public ResultWrapper <UInt256?> eth_getBlockTransactionCountByHash(Keccak blockHash)
        {
            Block block = _blockchainBridge.FindBlock(blockHash);

            if (block == null)
            {
                return(ResultWrapper <UInt256?> .Fail($"Cannot find block for hash: {blockHash}", ErrorType.NotFound, null));
            }

            return(ResultWrapper <UInt256?> .Success((UInt256)block.Transactions.Length));
        }
        public static Block GetBlock(this IBlockchainBridge blockchainBridge, BlockParameter blockParameter, bool allowNulls = false, bool recoverTxSenders = false)
        {
            Block block;

            switch (blockParameter.Type)
            {
            case BlockParameterType.Pending:
            {
                block = blockchainBridge.FindPendingBlock();
                break;
            }

            case BlockParameterType.Latest:
            {
                block = blockchainBridge.FindLatestBlock();
                break;
            }

            case BlockParameterType.Earliest:
            {
                block = blockchainBridge.FindEarliestBlock();
                break;
            }

            case BlockParameterType.BlockId:
            {
                if (blockParameter.BlockId == null)
                {
                    throw new JsonRpcException(ErrorType.InvalidParams, $"Block number is required for {BlockParameterType.BlockId}");
                }

                block = blockchainBridge.FindBlock(blockParameter.BlockId.Value);
                break;
            }

            default:
                throw new Exception($"{nameof(BlockParameterType)} not supported: {blockParameter.Type}");
            }

            if (block == null && !allowNulls)
            {
                throw new JsonRpcException(ErrorType.NotFound, $"Cannot find block {blockParameter}");
            }

            if (block != null && recoverTxSenders)
            {
                blockchainBridge.RecoverTxSenders(block);
            }

            return(block);
        }
        public void Eth_get_balance()
        {
            IBlockchainBridge bridge = Substitute.For <IBlockchainBridge>();

            bridge.FindBlock(Arg.Any <long>()).Returns(Build.A.Block.TestObject);
            bridge.GetAccount(Arg.Any <Address>(), Arg.Any <Keccak>()).Returns(Build.A.Account.WithBalance(1.Ether()).TestObject);
            bridge.Head.Returns(Build.A.BlockHeader.TestObject);

            IEthModule module = new EthModule(NullLogManager.Instance, bridge);

            string serialized = RpcTest.TestSerializedRequest(module, "eth_getBalance", TestItem.AddressA.Bytes.ToHexString(true), "0x01");

            Assert.AreEqual("{\"id\":\"0x43\",\"jsonrpc\":\"2.0\",\"result\":\"0xde0b6b3a7640000\"}", serialized);
        }
        public void Eth_get_block_by_number_empty_param()
        {
            IBlockchainBridge bridge = Substitute.For <IBlockchainBridge>();

            bridge.FindBlock(Arg.Any <Keccak>(), Arg.Any <bool>()).Returns(Build.A.Block.WithTotalDifficulty(0).WithTransactions(Build.A.Transaction.TestObject).TestObject);
            bridge.RetrieveHeadBlock().Returns(Build.A.Block.WithTotalDifficulty(0).WithTransactions(Build.A.Transaction.TestObject).TestObject);
            bridge.Head.Returns(Build.A.BlockHeader.TestObject);

            IEthModule module = new EthModule(NullLogManager.Instance, bridge);

            string serialized = RpcTest.TestSerializedRequest(module, "eth_getBlockByNumber", "", "true");

            Assert.AreEqual("{\"id\":\"0x43\",\"jsonrpc\":\"2.0\",\"result\":null,\"error\":{\"code\":-32602,\"message\":\"Incorrect parameters count, expected: 2, actual: 1\",\"data\":null}}", serialized);
        }
Example #8
0
        public void Eth_get_block_by_number_with_number_bad_number()
        {
            IBlockchainBridge bridge = Substitute.For <IBlockchainBridge>();

            bridge.FindBlock(Arg.Any <UInt256>()).Returns(Build.A.Block.WithTotalDifficulty(0).WithTransactions(Build.A.Transaction.TestObject).TestObject);
            bridge.RetrieveHeadBlock().Returns(Build.A.Block.WithTotalDifficulty(0).WithTransactions(Build.A.Transaction.TestObject).TestObject);
            bridge.Head.Returns(Build.A.BlockHeader.TestObject);

            IEthModule module = new EthModule(new EthereumJsonSerializer(), Substitute.For <IConfigProvider>(), NullLogManager.Instance, bridge);

            string serialized = RpcTest.TestSerializedRequest(module, "eth_getBlockByNumber", "'0x1234567890123456789012345678901234567890123456789012345678901234567890'", "true");

            Assert.AreEqual("{\"id\":67,\"jsonrpc\":\"2.0\",\"result\":null}", serialized);
        }
Example #9
0
        public ResultWrapper <BigInteger?> eth_getBlockTransactionCountByHash(Keccak blockHash)
        {
            try
            {
                _readerWriterLockSlim.EnterReadLock();
                Block block = _blockchainBridge.FindBlock(blockHash);
                if (block == null)
                {
                    return(ResultWrapper <BigInteger?> .Fail($"Cannot find block for hash: {blockHash}", ErrorType.NotFound, null));
                }

                return(ResultWrapper <BigInteger?> .Success(block.Transactions.Length));
            }
            finally
            {
                _readerWriterLockSlim.ExitReadLock();
            }
        }
Example #10
0
        public ResultWrapper <Quantity> eth_getBlockTransactionCountByHash(Data blockHash)
        {
            var block = _blockchainBridge.FindBlock(new Keccak(blockHash.Value), false);

            if (block == null)
            {
                return(ResultWrapper <Quantity> .Fail($"Cannot find block for hash: {blockHash.Value}", ErrorType.NotFound));
            }

            if (Logger.IsTrace)
            {
                Logger.Trace($"eth_getBlockTransactionCountByHash request {blockHash.ToJson()}, result: {block.Transactions.Length}");
            }
            return(ResultWrapper <Quantity> .Success(new Quantity(block.Transactions.Length)));
        }
Example #11
0
 public Task <Block> FindBlockAsync(Keccak blockHash) => Task.FromResult(_blockchainBridge.FindBlock(blockHash));
        private async Task <(uint confirmations, bool rejected)> VerifyDepositConfirmationsAsync(DepositDetails deposit,
                                                                                                 TxReceipt receipt, Keccak headHash)
        {
            var confirmations = 0u;
            var block         = _blockchainBridge.FindBlock(headHash);

            do
            {
                if (block is null)
                {
                    if (_logger.IsWarn)
                    {
                        _logger.Warn("Block was not found.");
                    }
                    return(0, false);
                }

                var confirmationTimestamp = _depositService.VerifyDeposit(deposit.Consumer, deposit.Id, block.Header);
                if (confirmationTimestamp > 0)
                {
                    confirmations++;
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Deposit: '{deposit.Id}' has been confirmed in block number: {block.Number}, hash: '{block.Hash}', transaction hash: '{deposit.TransactionHash}', timestamp: {confirmationTimestamp}.");
                    }
                    if (deposit.ConfirmationTimestamp == 0)
                    {
                        deposit.SetConfirmationTimestamp(confirmationTimestamp);
                        await _depositRepository.UpdateAsync(deposit);
                    }
                }
                else
                {
                    if (_logger.IsInfo)
                    {
                        _logger.Info($"Deposit with id: '{deposit.Id}' has not returned confirmation timestamp from the contract call yet.'");
                    }
                    return(0, false);
                }

                if (confirmations == _requiredBlockConfirmations)
                {
                    break;
                }

                if (receipt.BlockHash == block.Hash || block.Number <= receipt.BlockNumber)
                {
                    break;
                }

                block = _blockchainBridge.FindBlock(block.ParentHash);
            } while (confirmations < _requiredBlockConfirmations);

            var blocksDifference = _blockchainBridge.Head.Number - receipt.BlockNumber;

            if (blocksDifference >= _requiredBlockConfirmations && confirmations < _requiredBlockConfirmations)
            {
                if (_logger.IsError)
                {
                    _logger.Error($"Deposit: '{deposit.Id}' has been rejected - missing confirmation in block number: {block.Number}, hash: {block.Hash}' (transaction hash: '{deposit.TransactionHash}').");
                }
                return(confirmations, true);
            }

            return(confirmations, false);
        }