Пример #1
0
 public Signature Sign(BlockHeader block, EcdsaKeyPair keyPair)
 {
     return(Crypto.SignHashed(
                block.Keccak().ToBytes(), keyPair.PrivateKey.Encode(),
                HardforkHeights.IsHardfork_9Active(block.Index)
                ).ToSignature(HardforkHeights.IsHardfork_9Active(block.Index)));
 }
Пример #2
0
        private JObject VerifyRawTransaction(string rawTransaction, string signature)
        {
            var transaction = Transaction.Parser.ParseFrom(rawTransaction.HexToBytes());

            if (!transaction.ToByteArray().SequenceEqual(rawTransaction.HexToBytes()))
            {
                throw new Exception("Failed to validate serialized and deserialized transactions");
            }
            var useNewChainId =
                HardforkHeights.IsHardfork_9Active(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight() + 1);
            var s      = signature.HexToBytes().ToSignature(useNewChainId);
            var txHash = transaction.FullHash(s, useNewChainId);
            var json   = new JObject {
                ["hash"] = txHash.ToHex()
            };
            var accepted = new TransactionReceipt
            {
                Transaction = transaction,
                Hash        = txHash,
                Signature   = s
            };
            var result = _transactionManager.Verify(accepted, useNewChainId);

            json["result"] = result.ToString();
            if (result != OperatingError.Ok)
            {
                json["status"] = false;
            }
            else
            {
                json["status"] = true;
            }
            return(json);
        }
Пример #3
0
        public ExecutionStatus GetDeployHeight(UInt160 contractAddress, SystemContractExecutionFrame frame)
        {
            frame.ReturnValue = new byte[64];
            try
            {
                if (HardforkHeights.IsHardfork_3Active(frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight()))
                {
                    if (HardforkHeights.IsHardfork_6Active(
                            frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight()))
                    {
                        frame.ReturnValue = _deployHeight.GetValue(contractAddress.ToBytes()) ?? new byte[64];
                    }
                    else
                    {
                        frame.ReturnValue = _deployHeight.GetValue(contractAddress.ToBytes());
                    }
                }
            }
            catch (Exception e)
            {
                Logger.LogInformation($"Exception while get deploy height: {e}");
            }

            return(ExecutionStatus.Ok);
        }
Пример #4
0
        // changed from private to public: GetBlockByNumber() , GetBlockRawByNumber(), GetBlockByHash()
        public void Test_Web3Block()
        {
            ulong total = 1;

            GenerateBlocksWithGenesis(total);
            bool fullTx = false;
            var  tx     = GiveMeSomeMoney(Money.Parse("100000").ToUInt256(), HardforkHeights.IsHardfork_9Active(1));
            var  txList = new List <TransactionReceipt> ();

            txList.Add(tx);
            AddBatchTransactionToPool(txList, false);
            total++;
            GenerateBlocks(1, total);
            CheckBlockWeb3Format("latest", (ulong)total, fullTx);
            var randomTxList = GetRandomTransactionBatch(10, HardforkHeights.IsHardfork_9Active(2));
            var topUpTxList  = TopUpBalanceTxBatch(randomTxList, "10", HardforkHeights.IsHardfork_9Active(2));

            AddBatchTransactionToPool(topUpTxList, false);
            total++;
            GenerateBlocks(1, total);
            CheckBlockWeb3Format("latest", (ulong)total, fullTx);
            AddBatchTransactionToPool(randomTxList, false);
            total++;
            GenerateBlocks(1, total);
            CheckBlockWeb3Format("latest", (ulong)total, fullTx);
            CheckBlockWeb3Format("earliest", 0, fullTx);
            CheckBlockWeb3Format("pending", (ulong)total + 1, fullTx);
            ulong someBlockNumber = 100;

            CheckBlockWeb3Format(someBlockNumber.ToHex(), someBlockNumber, fullTx);
        }
Пример #5
0
        private void Check_Random_Address_Storage_Changing()
        {
            var randomTx  = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1));
            var balance   = randomTx.Transaction.Value;
            var allowance = balance;
            var receiver  = randomTx.Transaction.From;

            var tx1 = TopUpBalanceTx(receiver, balance, 0,
                                     HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1));
            var tx2 = ApproveTx(receiver, allowance, 0,
                                HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1));

            var owner = tx2.Transaction.From;

            var blockTxs = new[] { tx1, tx2 };

            var topUpBlock = BuildNextBlock(blockTxs);

            ExecuteBlock(topUpBlock, blockTxs);

            var storedBalance = _stateManager.LastApprovedSnapshot.Balances.GetBalance(receiver);

            Assert.AreEqual(balance.ToMoney(), storedBalance);

            var storedAllowance = _stateManager.LastApprovedSnapshot.Storage.GetRawValue(
                ContractRegisterer.LatokenContract,
                UInt256Utils.Zero.Buffer.Concat(owner.ToBytes().Concat(receiver.ToBytes()))
                ).ToUInt256().ToMoney();

            Assert.AreEqual(allowance.ToMoney(), storedAllowance);
        }
Пример #6
0
        public void Test_Block_Execution()
        {
            _blockManager.TryBuildGenesisBlock();
            var block  = BuildNextBlock();
            var result = ExecuteBlock(block);

            Assert.AreEqual(OperatingError.Ok, result);

            // using new chain id
            Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()));
            while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()))
            {
                block  = BuildNextBlock();
                result = ExecuteBlock(block);
                Assert.AreEqual(OperatingError.Ok, result);
            }

            int total = 100;

            for (var it = 0; it < total; it++)
            {
                block  = BuildNextBlock();
                result = ExecuteBlock(block);
                Assert.AreEqual(OperatingError.Ok, result);
            }
        }
Пример #7
0
        private TransactionReceipt BuildSystemContractTxReceipt(ulong blockIndex, UInt160 contractAddress, string methodSignature)
        {
            var nonce = _stateManager.LastApprovedSnapshot.Transactions.GetTotalTransactionCount(UInt160Utils.Zero);
            var abi   = ContractEncoder.Encode(methodSignature);
            var tx    = new Transaction
            {
                To       = contractAddress,
                Value    = UInt256Utils.Zero,
                From     = UInt160Utils.Zero,
                Nonce    = nonce,
                GasPrice = 0,
                /* TODO: gas estimation */
                GasLimit   = 100000000,
                Invocation = ByteString.CopyFrom(abi),
            };

            return(HardforkHeights.IsHardfork_9Active(blockIndex) ?
                   new TransactionReceipt
            {
                Hash = tx.FullHash(SignatureUtils.ZeroNew, true),
                Status = TransactionStatus.Pool,
                Transaction = tx,
                Signature = SignatureUtils.ZeroNew,
            }
                :
                   new TransactionReceipt
            {
                Hash = tx.FullHash(SignatureUtils.ZeroOld, false),
                Status = TransactionStatus.Pool,
                Transaction = tx,
                Signature = SignatureUtils.ZeroOld,
            });
        }
Пример #8
0
        public void Test_StakeWithdraw()
        {
            _blockManager.TryBuildGenesisBlock();
            GenerateBlocks(1, 1);

            _validatorStatusManager.Start(false);
            Assert.IsTrue(_validatorStatusManager.IsStarted());
            Assert.IsFalse(_validatorStatusManager.IsWithdrawTriggered());

            int blockNum = (int)_blockManager.GetHeight();

            Assert.IsFalse(HardforkHeights.IsHardfork_9Active((ulong)blockNum));
            while (!HardforkHeights.IsHardfork_9Active((ulong)blockNum))
            {
                blockNum++;
                GenerateBlocks(blockNum, blockNum);
            }

            var systemContractReader = _container?.Resolve <ISystemContractReader>() ?? throw new Exception("Container is not loaded");
            var stake = new Money(systemContractReader.GetStake());

            Console.WriteLine($"Current stake is {stake}");
            Assert.That(stake > Money.Zero, "Stake is zero");

            _validatorStatusManager.WithdrawStakeAndStop();
            Assert.IsTrue(_validatorStatusManager.IsStarted());
            Assert.IsTrue(_validatorStatusManager.IsWithdrawTriggered());

            // Test node is the only validator, so it is a next validator always
            // and it can't withdraw its stake. TODO: test to check withdraw is working
            //GenerateBlocks(50);
            //Assert.IsFalse(_validatorStatusManager.IsStarted());
        }
Пример #9
0
        public void TestTxPoolAdding()
        {
            bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1);
            var  tx            = TestUtils.GetRandomTransaction(useNewChainId);
            var  result        = _transactionPool.Add(tx);

            Assert.AreEqual(OperatingError.InsufficientBalance, result);

            _stateManager.LastApprovedSnapshot.Balances.AddBalance(tx.Transaction.From, Money.Parse("1000"));
            result = _transactionPool.Add(tx);
            Assert.AreEqual(OperatingError.Ok, result);

            result = _transactionPool.Add(tx);
            Assert.AreEqual(OperatingError.AlreadyExists, result);

            var tx2 = TestUtils.GetRandomTransaction(useNewChainId);

            tx2.Transaction.Nonce++;
            result = _transactionPool.Add(tx2);
            Assert.AreEqual(OperatingError.InvalidNonce, result);

            /* TODO: maybe we should fix this strange behaviour */
            var tx3 = TestUtils.GetRandomTransaction(useNewChainId);

            tx3.Transaction.From  = UInt160Utils.Zero;
            tx3.Transaction.Nonce = _transactionPool.GetNextNonceForAddress(UInt160Utils.Zero);
            result = _transactionPool.Add(tx3);
            Assert.AreEqual(OperatingError.Ok, result);
        }
Пример #10
0
        private TransactionReceipt FinishCycleTxReceipt(ulong blockIndex)
        {
            var tx = _transactionBuilder.InvokeTransactionWithGasPrice(
                UInt160Utils.Zero,
                ContractRegisterer.GovernanceContract,
                Utility.Money.Zero,
                GovernanceInterface.MethodFinishCycle,
                0,
                UInt256Utils.ToUInt256(GovernanceContract.GetCycleByBlockNumber(_blockManager.GetHeight()))
                );

            return(HardforkHeights.IsHardfork_9Active(blockIndex) ?
                   new TransactionReceipt
            {
                Hash = tx.FullHash(SignatureUtils.ZeroNew, true),
                Status = TransactionStatus.Pool,
                Transaction = tx,
                Signature = SignatureUtils.ZeroNew,
            }
                :
                   new TransactionReceipt
            {
                Hash = tx.FullHash(SignatureUtils.ZeroOld, false),
                Status = TransactionStatus.Pool,
                Transaction = tx,
                Signature = SignatureUtils.ZeroOld,
            });
        }
Пример #11
0
        // Changed GetTransactionCount to public
        public void Test_GetTransactionCount_latest()
        {
            _blockManager.TryBuildGenesisBlock();
            var tx = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(1));

            // adding balance so that it's transaction is added to the pool
            _stateManager.LastApprovedSnapshot.Balances.AddBalance(tx.Transaction.From, Money.Parse("1000"));



            var txCountBefore = _apiService !.GetTransactionCount(tx.Transaction.From.ToHex(), "latest").HexToUlong();


            Assert.AreEqual(txCountBefore, 0);

            var result = _transactionPool.Add(tx);

            Assert.AreEqual(OperatingError.Ok, result);


            GenerateBlocks(1);


            var txCountAfter = _apiService !.GetTransactionCount(tx.Transaction.From.ToHex(), "latest").HexToUlong();

            Assert.AreEqual(txCountAfter, 1);
        }
Пример #12
0
 public ExecutionStatus Deploy(byte[] byteCode, SystemContractExecutionFrame frame)
 {
     if (HardforkHeights.IsHardfork_2Active(frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight()))
     {
         return(DeployV2(byteCode, frame));
     }
     return(DeployV1(byteCode, frame));
 }
Пример #13
0
        public OperatingError VerifySignature(BlockHeader blockHeader, Signature signature, ECDSAPublicKey publicKey)
        {
            var result = Crypto.VerifySignatureHashed(
                blockHeader.Keccak().ToBytes(), signature.Encode(), publicKey.EncodeCompressed(),
                HardforkHeights.IsHardfork_9Active(blockHeader.Index)
                );

            return(result ? OperatingError.Ok : OperatingError.InvalidSignature);
        }
Пример #14
0
        public string SignTransaction(string[] arguments)
        {
            var to       = arguments[1].HexToUInt160();
            var value    = Money.Parse(arguments[2]);
            var from     = _keyPair.PublicKey.GetAddress();
            var tx       = _transactionBuilder.TransferTransaction(from, to, value);
            var signedTx = _transactionSigner.Sign(tx, _keyPair, HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1));

            return(signedTx.Signature.ToString());
        }
Пример #15
0
 public void Test_EventFormat()
 {
     _blockManager.TryBuildGenesisBlock();
     TestEventFormat();
     Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()));
     while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()))
     {
         GenerateBlocks(1);
     }
     TestEventFormat();
 }
Пример #16
0
        public void Test_MessageSender()
        {
            TestMessageSender(1);
            int blockNum = (int)_blockManager.GetHeight();

            Assert.IsFalse(HardforkHeights.IsHardfork_9Active((ulong)blockNum));
            while (!HardforkHeights.IsHardfork_9Active((ulong)blockNum))
            {
                GenerateBlock(blockNum + 1);
                blockNum++;
            }
            TestMessageSender(blockNum + 1);
        }
Пример #17
0
        //changed GetTransactionReceipt from private to public
        public void Test_GetTransactionReceipt()
        {
            _blockManager.TryBuildGenesisBlock();
            var tx = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(1));

            _stateManager.LastApprovedSnapshot.Balances.AddBalance(tx.Transaction.From, Money.Parse("1000"));
            var result = _transactionPool.Add(tx);

            Assert.AreEqual(OperatingError.Ok, result);
            GenerateBlocks(1, 1);
            var txHashSent     = tx.Hash.ToHex();
            var txReceipt      = _apiService.GetTransactionReceipt(txHashSent);
            var txHashReceived = txReceipt !["transactionHash"] !.ToString();
Пример #18
0
 public void Test_Tx_Pool_Adding()
 {
     TestTxPoolAdding();
     _blockManager.TryBuildGenesisBlock();
     Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()));
     while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()))
     {
         var block  = BuildNextBlock();
         var result = ExecuteBlock(block);
         Assert.AreEqual(OperatingError.Ok, result);
     }
     TestTxPoolAdding();
 }
Пример #19
0
        private void AddTxToPool(Transaction tx)
        {
            var useNewChainId =
                HardforkHeights.IsHardfork_9Active(_stateManager.LastApprovedSnapshot.Blocks.GetTotalBlockHeight() + 1);
            var receipt = _transactionSigner.Sign(tx, _privateWallet.EcdsaKeyPair, useNewChainId);

            _sendingTxHash = tx.FullHash(receipt.Signature, useNewChainId);
            var result = _transactionPool.Add(receipt);

            Logger.LogDebug(result == OperatingError.Ok
                ? $"Transaction successfully submitted: {receipt.Hash.ToHex()}"
                : $"Cannot add tx to pool: {result}");
        }
Пример #20
0
        public BlockWithTransactions Build()
        {
            if (_genesisBlock != null)
            {
                return(_genesisBlock);
            }

            var genesisConfig = _configManager.GetConfig <GenesisConfig>("genesis") ??
                                throw new InvalidOperationException("No genesis config found");

            var fromAddress = UInt160Utils.Zero; // mint initial tokens from zero address
            var balances    = genesisConfig !.Balances
                              .OrderBy(x => x.Key)
                              .ToArray();
            var genesisTransactions = balances.Select((t, i) => new Transaction
            {
                From     = fromAddress,
                Nonce    = (ulong)i,
                Value    = Money.Parse(t.Value).ToUInt256(),
                To       = t.Key.HexToUInt160(),
                GasPrice = 0,
            })
                                      .Select(tx => new TransactionReceipt
            {
                Transaction = tx,
                Hash        = HardforkHeights.IsHardfork_9Active(0) ? tx.FullHash(SignatureUtils.ZeroNew, true) : tx.FullHash(SignatureUtils.ZeroOld, false),
                Signature   = HardforkHeights.IsHardfork_9Active(0) ? SignatureUtils.ZeroNew : SignatureUtils.ZeroOld,
            })
                                      .ToList();

            var txHashes = genesisTransactions.Select(tx => tx.Hash).ToArray();

            var header = new BlockHeader
            {
                PrevBlockHash = UInt256Utils.Zero,
                MerkleRoot    = MerkleTree.ComputeRoot(txHashes) ?? UInt256Utils.Zero,
                Index         = 0,
                StateHash     = UInt256Utils.Zero,
                Nonce         = GenesisConsensusData
            };

            var result = new Block
            {
                Hash = header.Keccak(),
                TransactionHashes = { txHashes },
                Header            = header
            };

            _genesisBlock = new BlockWithTransactions(result, genesisTransactions.ToArray());
            return(_genesisBlock);
        }
Пример #21
0
        // Changed GetCode to public
        public void Test_GetCode_blockId()
        {
            _blockManager.TryBuildGenesisBlock();

            var rawTx2 = MakeDummyTx(HardforkHeights.IsHardfork_9Active(1));

            ExecuteDummyTransaction(true, rawTx2);

            var address = "0x9210567c1f79e9e9c3634331158d3143e572c001";

            var adCode = _apiService !.GetCode(address, "0x1");

            Assert.AreEqual(adCode, "");
        }
Пример #22
0
        public void Test_Tx_Pool_Replacement()
        {
            _blockManager.TryBuildGenesisBlock();
            TestTxPoolAdding();

            var privateKey = Crypto.GeneratePrivateKey().ToPrivateKey();
            var keyPair    = new EcdsaKeyPair(privateKey);

            AddRandomTxesToPool(keyPair, out var randomTxes);
            var rnd = new Random();

            randomTxes = randomTxes.OrderBy(item => rnd.Next()).ToList();
            bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1);
            var  signer        = new TransactionSigner();

            foreach (var tx in randomTxes)
            {
                Console.WriteLine($"nonce: {tx.Transaction.Nonce}");
                var newTx = new Transaction(tx.Transaction);
                // lower price
                newTx.GasPrice = tx.Transaction.GasPrice - 1;
                var randomTx = TestUtils.GetRandomTransaction(useNewChainId).Transaction;
                newTx.To       = randomTx.To;
                newTx.Value    = randomTx.Value;
                newTx.GasLimit = randomTx.GasLimit;
                var newTxReceipt = signer.Sign(newTx, keyPair, useNewChainId);
                var result       = _transactionPool.Add(newTxReceipt);
                Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}");
                Assert.AreEqual(OperatingError.Underpriced, result);
                // equal price
                newTx.GasPrice = tx.Transaction.GasPrice;
                newTxReceipt   = signer.Sign(newTx, keyPair, useNewChainId);
                result         = _transactionPool.Add(newTxReceipt);
                Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}");
                Assert.AreEqual(OperatingError.Underpriced, result);
                // higher price
                newTx.GasPrice = tx.Transaction.GasPrice + 1;
                newTxReceipt   = signer.Sign(newTx, keyPair, useNewChainId);
                result         = _transactionPool.Add(newTxReceipt);
                Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}");
                Assert.AreEqual(OperatingError.DuplicatedTransaction, result);
                // higher price and all fields same
                newTx          = new Transaction(tx.Transaction);
                newTx.GasPrice = tx.Transaction.GasPrice + 1;
                newTxReceipt   = signer.Sign(newTx, keyPair, useNewChainId);
                result         = _transactionPool.Add(newTxReceipt);
                Console.WriteLine($"old gas price: {tx.Transaction.GasPrice}, new gas price: {newTxReceipt.Transaction.GasPrice}");
                Assert.AreEqual(OperatingError.Ok, result);
            }
        }
Пример #23
0
        public OperatingError Add(Transaction transaction, Signature signature, bool notify = true)
        {
            var acceptedTx = new TransactionReceipt
            {
                Transaction = transaction,
                // we use next height here because block header should be signed with the same chainId
                // and this txes will go to the next block
                Hash = transaction.FullHash(signature,
                                            HardforkHeights.IsHardfork_9Active(BlockHeight() + 1)),
                Signature = signature,
                Status    = TransactionStatus.Pool
            };

            return(Add(acceptedTx, notify));
        }
Пример #24
0
        public string?SendRawTransaction(string[] arguments)
        {
            if (arguments.Length != 3)
            {
                return(null);
            }
            bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1);
            var  rawTx         = arguments[1].HexToBytes();
            var  tx            = Transaction.Parser.ParseFrom(rawTx);
            var  sig           = arguments[2].HexToBytes().ToSignature(useNewChainId);
            var  result        = _transactionPool.Add(tx, sig);

            Console.WriteLine($"Status: {result}");
            return($"{tx.FullHash(sig, useNewChainId).ToHex()}");
        }
Пример #25
0
        public void Test_Storage_Changing()
        {
            _blockManager.TryBuildGenesisBlock();
            Check_Random_Address_Storage_Changing();

            // using new chain id
            Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()));
            while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()))
            {
                var block  = BuildNextBlock();
                var result = ExecuteBlock(block);
                Assert.AreEqual(OperatingError.Ok, result);
            }
            Check_Random_Address_Storage_Changing();
        }
Пример #26
0
        public void AddRandomTxesToPool(EcdsaKeyPair keyPair, out List <TransactionReceipt> txes)
        {
            bool useNewChainId = HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1);
            var  txCount       = 100;

            txes = new List <TransactionReceipt>();
            _stateManager.LastApprovedSnapshot.Balances.AddBalance(keyPair.PublicKey.GetAddress(), Money.Parse("1000"));
            for (var i = 0; i < txCount; i++)
            {
                var tx     = TestUtils.GetRandomTransactionFromAddress(keyPair, (ulong)i, useNewChainId);
                var result = _transactionPool.Add(tx);
                Assert.AreEqual(OperatingError.Ok, result);
                txes.Add(tx);
            }
        }
Пример #27
0
 public OperatingError VerifySignatures(Block block, bool checkValidatorSet)
 {
     if (!block.Header.Keccak().Equals(block.Hash))
     {
         return(OperatingError.HashMismatched);
     }
     if (_IsGenesisBlock(block))
     {
         return(OperatingError.Ok);
     }
     if (checkValidatorSet && !VerifyValidatorSet(block.Multisig.Validators, block.Header.Index - 1))
     {
         return(OperatingError.InvalidMultisig);
     }
     return(_multisigVerifier.VerifyMultisig(block.Multisig, block.Hash, HardforkHeights.IsHardfork_9Active(block.Header.Index)));
 }
Пример #28
0
        private ExecutionStatus DeployV1(byte[] byteCode, SystemContractExecutionFrame frame)
        {
            Logger.LogInformation($"Deploy({byteCode.ToHex()})");
            frame.ReturnValue = Array.Empty <byte>();
            frame.UseGas(checked (GasMetering.DeployCost + GasMetering.DeployCostPerByte * (ulong)byteCode.Length));
            var receipt = _context.Receipt ?? throw new InvalidOperationException();
            // calculate contract hash and register it
            // the contractAddress at which the bytecode will be stored as calculated
            // from the sender address (To) and its nonce.
            var hash = UInt160Utils.Zero.ToBytes().Ripemd();

            if (receipt.Transaction?.From != null)
            {
                hash = receipt.Transaction.From.ToBytes()
                       .Concat(receipt.Transaction.Nonce.ToBytes())
                       .Ripemd();
            }

            var contract = new Contract(hash, byteCode);

            if (!VirtualMachine.VerifyContract(contract.ByteCode, false))
            {
                Logger.LogInformation("Failed to verify contract");
                return(ExecutionStatus.ExecutionHalted);
            }

            try
            {
                _context.Snapshot.Contracts.AddContract(_context.Sender, new Contract(hash, contract.ByteCode));
                Logger.LogInformation($"New contract with address {hash.ToHex()} deployed");

                if (HardforkHeights.IsHardfork_3Active(frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight()))
                {
                    _deployHeight.SetValue(hash.ToBytes(),
                                           frame.InvocationContext.Snapshot.Blocks.GetTotalBlockHeight().ToBytes().ToArray());
                }
            }
            catch (OutOfGasException e)
            {
                Logger.LogInformation("Out of gas");
                frame.UseGas(e.GasUsed);
                return(ExecutionStatus.GasOverflow);
            }

            return(ExecutionStatus.Ok);
        }
Пример #29
0
        public void Test_Block_With_Txs_Execution()
        {
            _blockManager.TryBuildGenesisBlock();
            var topUpReceipts  = new List <TransactionReceipt>();
            var randomReceipts = new List <TransactionReceipt>();
            var txCount        = 50;

            var coverTxFeeAmount = Money.Parse("10.0");

            for (var i = 0; i < txCount; i++)
            {
                var tx = TestUtils.GetRandomTransaction(HardforkHeights.IsHardfork_9Active(2));
                randomReceipts.Add(tx);
                topUpReceipts.Add(TopUpBalanceTx(tx.Transaction.From,
                                                 (tx.Transaction.Value.ToMoney() + coverTxFeeAmount).ToUInt256(), i,
                                                 HardforkHeights.IsHardfork_9Active(1)));
            }

            ExecuteTxesInSeveralBlocks(topUpReceipts);
            ExecuteTxesInSeveralBlocks(randomReceipts);

            // building random txes for new chain id. will send TopUpTx right now.
            Assert.IsFalse(HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()));
            txCount          = 50;
            topUpReceipts    = new List <TransactionReceipt>();
            randomReceipts   = new List <TransactionReceipt>();
            coverTxFeeAmount = Money.Parse("0.0000000001");
            Console.WriteLine(Money.Wei.ToString());
            for (var i = 0; i < txCount; i++)
            {
                var tx = TestUtils.GetCustomTransaction("0", Money.Wei.ToString(), true);
                randomReceipts.Add(tx);
                topUpReceipts.Add(TopUpBalanceTx(tx.Transaction.From,
                                                 (tx.Transaction.Value.ToMoney() + coverTxFeeAmount).ToUInt256(), i,
                                                 HardforkHeights.IsHardfork_9Active(3)));
            }
            ExecuteTxesInSeveralBlocks(topUpReceipts);

            while (!HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight()))
            {
                var block  = BuildNextBlock();
                var result = ExecuteBlock(block);
                Assert.AreEqual(OperatingError.Ok, result);
            }
            ExecuteTxesInSeveralBlocks(randomReceipts);
        }
Пример #30
0
        public uint HandleTransactionsFromPeer(IEnumerable <TransactionReceipt> transactions, ECDSAPublicKey publicKey)
        {
            lock (_txLock)
            {
                var txs = transactions.ToArray();
                Logger.LogTrace($"Received {txs.Length} transactions from peer {publicKey.ToHex()}");
                var persisted = 0u;
                foreach (var tx in txs)
                {
                    if (tx.Signature.IsZero())
                    {
                        Logger.LogTrace($"Received zero-signature transaction: {tx.Hash.ToHex()}");
                        if (_transactionPool.Add(tx, false) == OperatingError.Ok)
                        {
                            persisted++;
                        }
                        continue;
                    }

                    var error = _transactionManager.Verify(tx, HardforkHeights.IsHardfork_9Active(_blockManager.GetHeight() + 1));
                    if (error != OperatingError.Ok)
                    {
                        Logger.LogTrace($"Unable to verify transaction: {tx.Hash.ToHex()} ({error})");
                        continue;
                    }

                    error = _transactionPool.Add(tx, false);
                    if (error == OperatingError.Ok)
                    {
                        persisted++;
                    }
                    else
                    {
                        Logger.LogTrace($"Transaction {tx.Hash.ToHex()} not persisted: {error}");
                    }
                }

                lock (_peerHasTransactions)
                    Monitor.PulseAll(_peerHasTransactions);
                Logger.LogTrace($"Persisted {persisted} transactions from peer {publicKey.ToHex()}");
                return(persisted);
            }
        }