Beispiel #1
0
        public TransactionCapsule GetTransaction(byte[] hash)
        {
            TransactionCapsule transaction = null;
            Key key = new Key(hash);

            if (this.transaction_cache.ContainsKey(key))
            {
                transaction = this.transaction_cache[key].ToCapsule <TransactionCapsule, Protocol.Transaction>();
            }
            else
            {
                if (this.parent != null)
                {
                    transaction = this.parent.GetTransaction(hash);
                }
                else
                {
                    try
                    {
                        transaction = this.db_manager.Transaction.Get(hash);
                    }
                    catch
                    {
                        transaction = null;
                    }
                }

                if (transaction != null)
                {
                    this.transaction_cache.Add(key, Value.Create(transaction.Data));
                }
            }

            return(transaction);
        }
Beispiel #2
0
        public static TransactionExtention CreateTransactionExtention(TransactionCapsule transaction)
        {
            TransactionExtention extention = new TransactionExtention();

            extention.Result = new Return();

            try
            {
                extention.Transaction   = transaction.Instance;
                extention.Txid          = ByteString.CopyFrom(transaction.Id.Hash);
                extention.Result.Result = true;
                extention.Result.Code   = Return.Types.response_code.Success;
            }
            catch (ContractValidateException e)
            {
                extention.Result.Result  = false;
                extention.Result.Code    = Return.Types.response_code.ContractValidateError;
                extention.Result.Message = ByteString.CopyFromUtf8("Contract validate error " + e.Message);
                Logger.Debug(
                    string.Format("ContractValidateException: {0}", e.Message));
            }
            catch (System.Exception e)
            {
                extention.Result.Result  = false;
                extention.Result.Code    = Return.Types.response_code.ContractValidateError;
                extention.Result.Message = ByteString.CopyFromUtf8(e.Message);
                Logger.Debug("Exception caught" + e.Message);
            }

            return(extention);
        }
Beispiel #3
0
 public void PushTransaction(TransactionCapsule trx)
 {
     try
     {
         Manager.Instance.DBManager.PushTransaction(trx);
     }
     catch (System.Exception e)
     {
         if (e is ContractSizeNotEqualToOneException ||
             e is VMIllegalException)
         {
             throw new P2pException(P2pException.ErrorType.BAD_TRX, e.Message, e);
         }
         else if (e is ContractValidateException ||
                  e is ValidateSignatureException ||
                  e is ContractExeException ||
                  e is DupTransactionException ||
                  e is TaposException ||
                  e is TooBigTransactionException ||
                  e is TransactionExpirationException ||
                  e is ReceiptCheckErrorException ||
                  e is TooBigTransactionResultException ||
                  e is AccountResourceInsufficientException)
         {
             throw new P2pException(P2pException.ErrorType.TRX_EXE_FAILED, e.Message, e);
         }
     }
 }
Beispiel #4
0
 public BlockMessage(byte[] raw_data)
     : base(raw_data)
 {
     this.type  = (byte)MessageTypes.MsgType.BLOCK;
     this.block = new BlockCapsule(GetCodedInputStream(data));
     if (Message.IsFilter)
     {
         Message.CompareBytes(data, block.Data);
         TransactionCapsule.ValidContractProto(new List <Protocol.Transaction>(block.Instance.Transactions));
     }
 }
Beispiel #5
0
        private void Precompiled()
        {
            TransactionCapsule tx        = new TransactionCapsule(this.transaction);
            List <IActuator>   actuators = ActuatorFactory.CreateActuator(tx, this.deposit.DBManager);

            foreach (IActuator actuator in actuators)
            {
                actuator.Validate();
                actuator.Execute(this.result.TransactionResult);
            }
        }
Beispiel #6
0
 public TransactionMessage(byte[] raw_data)
     : base(raw_data)
 {
     this.transaction = new TransactionCapsule(GetCodedInputStream(data));
     this.type        = (byte)MessageTypes.MsgType.TX;
     if (Message.IsFilter)
     {
         CompareBytes(data, this.transaction.Data);
         TransactionCapsule.ValidContractProto(this.transaction.Instance.RawData.Contract[0]);
     }
 }
Beispiel #7
0
 public TransactionsMessage(byte[] data)
     : base(data)
 {
     this.type         = (byte)MessageTypes.MsgType.TXS;
     this.transactions = Transactions.Parser.ParseFrom(data);
     if (IsFilter)
     {
         CompareBytes(data, this.transactions.ToByteArray());
         TransactionCapsule.ValidContractProto(new List <Transaction>(this.transactions.Transactions_));
     }
 }
Beispiel #8
0
        public static byte[] GenerateContractAddress(Transaction tx)
        {
            CreateSmartContract contract = ContractCapsule.GetSmartContractFromTransaction(tx);

            byte[]             owner_address = contract.OwnerAddress.ToByteArray();
            TransactionCapsule transaction   = new TransactionCapsule(tx);

            byte[] tx_hash = transaction.Id.Hash;

            byte[] combined = new byte[tx_hash.Length + owner_address.Length];
            Array.Copy(tx_hash, 0, combined, 0, tx_hash.Length);
            Array.Copy(owner_address, 0, combined, tx_hash.Length, owner_address.Length);

            return(Hash.ToAddress(combined));
        }
Beispiel #9
0
        public Transaction GetTransactionById(SHA256Hash hash)
        {
            Transaction transaction = null;

            try
            {
                TransactionCapsule result = this.transaction_store.Get(hash.Hash);
                if (result != null)
                {
                    transaction = result.Instance;
                }
            }
            catch
            {
            }

            return(transaction);
        }
Beispiel #10
0
        public static TransactionCapsule CreateTransactionCapsule(IMessage message, ContractType type)
        {
            DatabaseManager    db_manager  = Manager.Instance.DBManager;
            TransactionCapsule transaction = new TransactionCapsule(message, type);

            if (type != ContractType.CreateSmartContract &&
                type != ContractType.TriggerSmartContract)
            {
                List <IActuator> actuators = ActuatorFactory.CreateActuator(transaction, db_manager);
                foreach (IActuator actuator in actuators)
                {
                    actuator.Validate();
                }
            }

            if (type == ContractType.CreateSmartContract)
            {
                CreateSmartContract contract = ContractCapsule.GetSmartContractFromTransaction(transaction.Instance);
                long percent = contract.NewContract.ConsumeUserResourcePercent;
                if (percent < 0 || percent > 100)
                {
                    throw new ContractValidateException("percent must be >= 0 and <= 100");
                }
            }

            try
            {
                BlockId id = db_manager.HeadBlockId;
                if (Args.Instance.Transaction.ReferenceBlock.Equals("solid"))
                {
                    id = db_manager.SolidBlockId;
                }

                transaction.SetReference(id.Num, id.Hash);
                transaction.Expiration = db_manager.GetHeadBlockTimestamp() + (long)Args.Instance.Transaction.ExpireTimeInMillis;
                transaction.Timestamp  = Helper.CurrentTimeMillis();
            }
            catch (System.Exception e)
            {
                Logger.Error("Create transaction capsule failed.", e);
            }

            return(transaction);
        }
Beispiel #11
0
        public InternalTransaction(Transaction tx, InternalTransaction.TransactionType tx_type)
        {
            this.transaction = tx;
            TransactionCapsule transaction = new TransactionCapsule(tx);

            this.proto_encoded = transaction.Data;
            this.nonce         = 0;
            this.deep          = -1;

            if (tx_type == TransactionType.TX_CONTRACT_CREATION_TYPE)
            {
                CreateSmartContract contract = ContractCapsule.GetSmartContractFromTransaction(tx);
                if (contract == null)
                {
                    throw new ContractValidateException("Invalid CreateSmartContract protocol");
                }

                this.send_address        = contract.OwnerAddress.ToByteArray();
                this.receive_address     = new byte[0];
                this.transfer_to_address = Wallet.GenerateContractAddress(tx);
                this.note  = "create";
                this.value = contract.NewContract.CallValue;
                this.data  = contract.NewContract.Bytecode.ToByteArray();
                this.token_info.Add(contract.TokenId.ToString(), contract.CallTokenValue);
            }
            else if (tx_type == TransactionType.TX_CONTRACT_CALL_TYPE)
            {
                TriggerSmartContract contract = ContractCapsule.GetTriggerContractFromTransaction(tx);
                if (contract == null)
                {
                    throw new ContractValidateException("Invalid TriggerSmartContract protocol");
                }

                this.send_address        = contract.OwnerAddress.ToByteArray();
                this.receive_address     = contract.ContractAddress.ToByteArray();
                this.transfer_to_address = (byte[])this.receive_address.Clone();
                this.note  = "call";
                this.value = contract.CallValue;
                this.data  = contract.Data.ToByteArray();
                this.token_info.Add(contract.TokenId.ToString(), contract.CallTokenValue);
            }
            this.hash = transaction.Id.Hash;
        }
Beispiel #12
0
        public void Pay()
        {
            byte[] origin_account      = null;
            byte[] caller_account      = null;
            long   percent             = 0;
            long   origin_energy_limit = 0;

            switch (this.transaction_type)
            {
            case TransactionType.TX_CONTRACT_CREATION_TYPE:
            {
                caller_account = TransactionCapsule.GetOwner(this.transaction.Instance.RawData.Contract[0]);
                origin_account = caller_account;
            }
            break;

            case TransactionType.TX_CONTRACT_CALL_TYPE:
            {
                TriggerSmartContract trigger_contract = ContractCapsule.GetTriggerContractFromTransaction(this.transaction.Instance);
                ContractCapsule      contract         = this.db_manager.Contract.Get(trigger_contract.ContractAddress.ToByteArray());

                caller_account      = trigger_contract.OwnerAddress.ToByteArray();
                origin_account      = contract.OriginAddress;
                percent             = Math.Max(DefineParameter.ONE_HUNDRED - contract.GetConsumeUserResourcePercent(), 0);
                percent             = Math.Min(percent, DefineParameter.ONE_HUNDRED);
                origin_energy_limit = contract.GetOriginEnergyLimit();
            }
            break;

            default:
                return;
            }

            this.receipt.PayEnergyBill(this.db_manager,
                                       this.db_manager.Account.Get(origin_account),
                                       this.db_manager.Account.Get(caller_account),
                                       percent,
                                       origin_energy_limit,
                                       energy_processor,
                                       this.db_manager.WitnessController.GetHeadSlot());
        }
Beispiel #13
0
        public Message GetData(SHA256Hash hash, InventoryType type)
        {
            Message result = null;

            try
            {
                switch (type)
                {
                case InventoryType.Block:
                {
                    result = new BlockMessage(Manager.Instance.DBManager.GetBlockById(hash));
                }
                break;

                case InventoryType.Trx:
                {
                    TransactionCapsule tx = Manager.Instance.DBManager.Transaction.Get(hash.Hash);
                    if (tx == null)
                    {
                        throw new StoreException();
                    }

                    result = new TransactionMessage(tx.Instance);
                }
                break;

                default:
                {
                    throw new StoreException();
                }
                }
            }
            catch (StoreException e)
            {
                throw new P2pException(Exception.P2pException.ErrorType.DB_ITEM_NOT_FOUND,
                                       "type: " + type + ", hash: " + hash.Hash.ToHexString(),
                                       e);
            }

            return(result);
        }
Beispiel #14
0
        public BlocksMessage(byte[] data)
            : base(data)
        {
            this.type = (byte)MessageTypes.MsgType.BLOCKS;

            Items items = Items.Parser.ParseFrom(GetCodedInputStream(data));

            if (items.Type == Items.Types.ItemType.Block)
            {
                blocks = new List <Protocol.Block>(items.Blocks);
            }

            if (IsFilter && blocks.IsNotNullOrEmpty())
            {
                CompareBytes(data, items.ToByteArray());
                foreach (Block block in blocks)
                {
                    TransactionCapsule.ValidContractProto(new List <Protocol.Transaction>(block.Transactions));
                }
            }
        }
Beispiel #15
0
        public static List <IActuator> CreateActuator(TransactionCapsule transaction, DatabaseManager db_manager)
        {
            List <IActuator> actuators = new List <IActuator>();

            if (transaction == null || transaction.Instance == null)
            {
                Logger.Info("Transaction capsule or Transaction is null");
                return(actuators);
            }

            if (db_manager == null)
            {
                throw new NullReferenceException("Manager is null.");
            }

            Protocol.Transaction.Types.raw raw = transaction.Instance.RawData;

            foreach (Contract contract in raw.Contract)
            {
                actuators.Add(GetActuatorByContract(contract, db_manager));
            }

            return(actuators);
        }
Beispiel #16
0
        public TransactionTrace(TransactionCapsule tx, DatabaseManager db_manager)
        {
            this.transaction      = tx;
            this.db_manager       = db_manager;
            this.receipt          = new ReceiptCapsule(SHA256Hash.ZERO_HASH);
            this.energy_processor = new EnergyProcessor(this.db_manager);

            ContractType contract_type = this.transaction.Instance.RawData.Contract[0].Type;

            switch (contract_type)
            {
            case ContractType.TriggerSmartContract:
                this.transaction_type = InternalTransaction.TransactionType.TX_CONTRACT_CALL_TYPE;
                break;

            case ContractType.CreateSmartContract:
                this.transaction_type = InternalTransaction.TransactionType.TX_CONTRACT_CREATION_TYPE;
                break;

            default:
                this.transaction_type = InternalTransaction.TransactionType.TX_PRECOMPILED_TYPE;
                break;
            }
        }
Beispiel #17
0
 public abstract void Consume(TransactionCapsule tx, TransactionTrace tx_trace);
Beispiel #18
0
 public TransactionMessage(Protocol.Transaction tx)
 {
     this.transaction = new TransactionCapsule(tx);
     this.type        = (byte)MessageTypes.MsgType.TX;
     this.data        = tx.ToByteArray();
 }
Beispiel #19
0
 public override void Consume(TransactionCapsule tx, TransactionTrace tx_trace)
 {
     throw new System.Exception("Not support");
 }
Beispiel #20
0
        public static TransactionExtention CreateTransactionExtention(IMessage message, ContractType type)
        {
            TransactionCapsule transaction = CreateTransactionCapsule(message, type);

            return(CreateTransactionExtention(transaction));
        }
Beispiel #21
0
        public void Go()
        {
            try
            {
                if (this.vm != null)
                {
                    TransactionCapsule tx = new TransactionCapsule(this.transaction);
                    if (null != this.block &&
                        this.block.IsGenerateMyself &&
                        tx.ContractResult != contractResult.Unknown &&
                        tx.ContractResult == contractResult.OutOfTime)
                    {
                        this.result = this.program.Result;
                        this.program.SpendAllEnergy();

                        OutOfTimeException e = VMExceptions.AlreadyTimeOut();
                        this.runtime_error    = e.Message;
                        this.result.Exception = e;
                        throw e;
                    }

                    vm.Play(program);
                    this.result = this.program.Result;

                    if (this.is_static_call)
                    {
                        long call_value       = TransactionCapsule.GetCallValue(this.transaction.RawData.Contract[0]);
                        long call_token_value = TransactionCapsule.GetCallTokenValue(this.transaction.RawData.Contract[0]);
                        if (call_value > 0 || call_token_value > 0)
                        {
                            this.runtime_error = "constant cannot set call value or call token value.";
                            this.result.RejectInternalTransaction();
                        }

                        return;
                    }

                    if (this.transaction_type == TransactionType.TX_CONTRACT_CREATION_TYPE &&
                        !this.result.IsRevert)
                    {
                        byte[] code             = this.program.Result.HReturn;
                        long   save_code_energy = (long)code.Length * EnergyCost.CREATE_DATA;
                        long   after_Spend      = this.program.EnergyLimitLeft.ToLong() - save_code_energy;
                        if (after_Spend < 0)
                        {
                            if (this.result.Exception == null)
                            {
                                this.result.Exception = VMExceptions.NotEnoughSpendEnergy(
                                    "save just created contract code",
                                    save_code_energy,
                                    this.program.EnergyLimitLeft.ToLong());
                            }
                        }
                        else
                        {
                            this.result.SpendEnergy(save_code_energy);
                            if (VMConfig.AllowTvmConstantinople)
                            {
                                this.deposit.SaveCode(this.program.ContractAddress.GetNoLeadZeroesData(), code);
                            }
                        }
                    }

                    if (this.result.Exception != null || this.result.IsRevert)
                    {
                        this.result.DeleteAccount.Clear();
                        this.result.LogInfos.Clear();
                        this.result.ResetFutureRefund();
                        this.result.RejectInternalTransaction();

                        if (this.result.Exception != null)
                        {
                            if (!(this.result.Exception is TransferException))
                            {
                                this.program.SpendAllEnergy();
                            }
                            this.runtime_error = this.result.Exception.Message;
                            throw this.result.Exception;
                        }
                        else
                        {
                            this.runtime_error = "REVERT opcode executed";
                        }
                    }
                    else
                    {
                        this.deposit.Commit();

                        if (this.log_info_parser != null)
                        {
                            List <ContractTrigger> triggers = this.log_info_parser.ParseLogInfos(this.program.Result.LogInfos, this.deposit);
                            this.program.Result.Triggers = triggers;
                        }
                    }
                }
                else
                {
                    this.deposit.Commit();
                }
            }
            catch (VMStackOverFlowException e)
            {
                this.program.SpendAllEnergy();
                this.result           = this.program.Result;
                this.result.Exception = e;
                this.result.RejectInternalTransaction();
                this.runtime_error = this.result.Exception.Message;
                Logger.Info("JVMStackOverFlowException : " + this.result.Exception.Message);
            }
            catch (OutOfTimeException e)
            {
                this.program.SpendAllEnergy();
                this.result           = this.program.Result;
                this.result.Exception = e;
                this.result.RejectInternalTransaction();
                this.runtime_error = result.Exception.Message;
                Logger.Info("timeout : " + this.result.Exception.Message);
            }
            catch (System.Exception e)
            {
                if (!(e is TransferException))
                {
                    this.program.SpendAllEnergy();
                }
                this.result = this.program.Result;
                this.result.RejectInternalTransaction();
                if (this.result.Exception == null)
                {
                    Logger.Error(e.Message);
                    this.result.Exception = new System.Exception("Unknown exception");
                }

                if (this.runtime_error == null || this.runtime_error.Length == 0)
                {
                    this.runtime_error = this.result.Exception.Message;
                }
                Logger.Info("runtime result is : " + this.result.Exception.Message);
            }

            this.trace.SetBill(this.result.EnergyUsed);
        }
Beispiel #22
0
        public static TransactionApprovedList GetTransactionApprovedList(Transaction transaction)
        {
            TransactionExtention transaction_extention = new TransactionExtention()
            {
                Transaction = transaction,
                Txid        = ByteString.CopyFrom(SHA256Hash.ToHash(transaction.RawData.ToByteArray())),
                Result      = new Return()
                {
                    Result = true,
                    Code   = Return.Types.response_code.Success
                }
            };

            TransactionApprovedList approved = new TransactionApprovedList()
            {
                Transaction = transaction_extention
            };

            try
            {
                Contract       contract      = transaction.RawData.Contract[0];
                byte[]         owner_address = TransactionCapsule.GetOwner(contract);
                AccountCapsule account       = Manager.Instance.DBManager.Account.Get(owner_address);
                if (account == null)
                {
                    throw new PermissionException("Account is not exist.");
                }

                if (transaction.Signature.Count > 0)
                {
                    byte[] hash = SHA256Hash.ToHash(transaction.RawData.ToByteArray());
                    foreach (var signature in transaction.Signature)
                    {
                        if (signature.Count() < 65)
                        {
                            throw new SignatureFormatException("Signature size is " + signature.Count());
                        }

                        byte[] signature_address = ECKey.SignatureToAddress(hash, ECDSASignature.ExtractECDSASignature(signature.ToByteArray()));
                        approved.ApprovedList.Add(ByteString.CopyFrom(signature_address));
                    }
                }
                approved.Result = new TransactionApprovedList.Types.Result()
                {
                    Code = TransactionApprovedList.Types.Result.Types.response_code.Success
                };
            }
            catch (SignatureFormatException e)
            {
                approved.Result = new TransactionApprovedList.Types.Result()
                {
                    Code    = TransactionApprovedList.Types.Result.Types.response_code.SignatureFormatError,
                    Message = e.Message
                };
            }
            catch (SignatureException e)
            {
                approved.Result = new TransactionApprovedList.Types.Result()
                {
                    Code    = TransactionApprovedList.Types.Result.Types.response_code.ComputeAddressError,
                    Message = e.Message
                };
            }
            catch (System.Exception e)
            {
                approved.Result = new TransactionApprovedList.Types.Result()
                {
                    Code    = TransactionApprovedList.Types.Result.Types.response_code.OtherError,
                    Message = e.Message
                };
            }

            return(approved);
        }
Beispiel #23
0
        private void Call()
        {
            if (!this.deposit.DBManager.DynamicProperties.SupportVM())
            {
                Logger.Info("vm work is off, need to be opened by the committee");
                throw new ContractValidateException("VM work is off, need to be opened by the committee");
            }

            TriggerSmartContract contract = ContractCapsule.GetTriggerContractFromTransaction(this.transaction);

            if (contract == null)
            {
                return;
            }

            if (contract.ContractAddress == null)
            {
                throw new ContractValidateException("Cannot get contract address from TriggerContract");
            }

            byte[] contract_address = contract.ContractAddress.ToByteArray();

            ContractCapsule deployed_contract = this.deposit.GetContract(contract_address);

            if (null == deployed_contract)
            {
                Logger.Info("No contract or not a smart contract");
                throw new ContractValidateException("No contract or not a smart contract");
            }

            long call_value  = contract.CallValue;
            long token_value = 0;
            long token_id    = 0;

            if (VMConfig.AllowTvmTransferTrc10)
            {
                token_value = contract.CallTokenValue;
                token_id    = contract.TokenId;
            }

            if (VMConfig.EnergyLimitHardFork)
            {
                if (call_value < 0)
                {
                    throw new ContractValidateException("callValue must >= 0");
                }
                if (token_value < 0)
                {
                    throw new ContractValidateException("tokenValue must >= 0");
                }
            }

            byte[] caller_address = contract.OwnerAddress.ToByteArray();
            CheckTokenValueAndId(token_value, token_id);

            byte[] code = this.deposit.GetCode(contract_address);
            if (code != null && code.Length > 0)
            {
                long fee_limit = this.transaction.RawData.FeeLimit;
                if (fee_limit < 0 || fee_limit > VMConfig.MAX_FEE_LIMIT)
                {
                    Logger.Info(string.Format("invalid feeLimit {0}", fee_limit));
                    throw new ContractValidateException(
                              "feeLimit must be >= 0 and <= " + VMConfig.MAX_FEE_LIMIT);
                }

                AccountCapsule caller       = this.deposit.GetAccount(caller_address);
                long           energy_limit = 0;
                if (this.is_static_call)
                {
                    energy_limit = DefineParameter.ENERGY_LIMIT_IN_CONSTANT_TX;
                }
                else
                {
                    AccountCapsule creator = this.deposit.GetAccount(deployed_contract.Instance.OriginAddress.ToByteArray());
                    energy_limit = GetTotalEnergyLimit(creator, caller, contract, fee_limit, call_value);
                }

                long max_cpu_time_tx = this.deposit.DBManager.DynamicProperties.GetMaxCpuTimeOfOneTx() * DefineParameter.ONE_THOUSAND;
                long tx_cpu_limit    =
                    (long)(max_cpu_time_tx * GetCpuLimitInUsRatio());
                long           vm_start      = Helper.NanoTime() / DefineParameter.ONE_THOUSAND;
                long           vm_should_end = vm_start + tx_cpu_limit;
                IProgramInvoke invoke        = this.invoke_factory.CreateProgramInvoke(TransactionType.TX_CONTRACT_CALL_TYPE,
                                                                                       this.executor_type,
                                                                                       this.transaction,
                                                                                       token_value,
                                                                                       token_id,
                                                                                       this.block.Instance,
                                                                                       this.deposit,
                                                                                       vm_start,
                                                                                       vm_should_end,
                                                                                       energy_limit);

                if (this.is_static_call)
                {
                    invoke.IsStaticCall = true;
                }

                this.vm = new Vm();
                this.root_internal_transaction = new InternalTransaction(this.transaction, this.transaction_type);
                this.program = new Program(code, invoke, this.root_internal_transaction, this.block);
                byte[] tx_id = new TransactionCapsule(this.transaction).Id.Hash;
                this.program.RootTransactionId = tx_id;

                // // TODO: EventPluginLoader is not Implementation
                //if (enableEventLinstener &&
                //    (EventPluginLoader.getInstance().isContractEventTriggerEnable()
                //        || EventPluginLoader.getInstance().isContractLogTriggerEnable())
                //    && isCheckTransaction())
                //{
                //    logInfoTriggerParser = new LogInfoTriggerParser(this.block.getNum(), this.block.getTimeStamp(), txId, callerAddress);
                //}
            }

            this.program.Result.ContractAddress = contract_address;
            if (call_value > 0)
            {
                MUtil.Transfer(this.deposit, caller_address, contract_address, call_value);
            }

            if (VMConfig.AllowTvmTransferTrc10)
            {
                if (token_value > 0)
                {
                    MUtil.TransferToken(this.deposit, caller_address, contract_address, token_id.ToString(), token_value);
                }
            }
        }
Beispiel #24
0
        private void Create()
        {
            if (!this.deposit.DBManager.DynamicProperties.SupportVM())
            {
                throw new ContractValidateException("vm work is off, need to be opened by the committee");
            }

            CreateSmartContract contract = ContractCapsule.GetSmartContractFromTransaction(this.transaction);

            if (contract == null)
            {
                throw new ContractValidateException("Cannot get CreateSmartContract from transaction");
            }

            SmartContract new_contract = contract.NewContract;

            if (!contract.OwnerAddress.Equals(new_contract.OriginAddress))
            {
                Logger.Info("OwnerAddress not equals OriginAddress");
                throw new VMIllegalException("OwnerAddress is not equals OriginAddress");
            }

            byte[] contract_name = Encoding.UTF8.GetBytes(new_contract.Name);

            if (contract_name.Length > VMParameter.CONTRACT_NAME_LENGTH)
            {
                throw new ContractValidateException("contractName's length cannot be greater than 32");
            }

            long percent = contract.NewContract.ConsumeUserResourcePercent;

            if (percent < 0 || percent > DefineParameter.ONE_HUNDRED)
            {
                throw new ContractValidateException("percent must be >= 0 and <= 100");
            }

            byte[] contract_address = Wallet.GenerateContractAddress(this.transaction);
            if (this.deposit.GetAccount(contract_address) != null)
            {
                throw new ContractValidateException(
                          "Trying to create a contract with existing contract address: " + Wallet.AddressToBase58(contract_address));
            }

            new_contract.ContractAddress = ByteString.CopyFrom(contract_address);

            long call_value  = new_contract.CallValue;
            long token_value = 0;
            long token_id    = 0;

            if (VMConfig.AllowTvmTransferTrc10)
            {
                token_value = contract.CallTokenValue;
                token_id    = contract.TokenId;
            }

            byte[] caller_address = contract.OwnerAddress.ToByteArray();
            try
            {
                long fee_limit = this.transaction.RawData.FeeLimit;
                if (fee_limit < 0 || fee_limit > VMConfig.MAX_FEE_LIMIT)
                {
                    Logger.Info(string.Format("invalid feeLimit {0}", fee_limit));
                    throw new ContractValidateException(
                              "feeLimit must be >= 0 and <= " + VMConfig.MAX_FEE_LIMIT);
                }

                AccountCapsule creator      = this.deposit.GetAccount(new_contract.OriginAddress.ToByteArray());
                long           energy_limit = 0;
                if (VMConfig.EnergyLimitHardFork)
                {
                    if (call_value < 0)
                    {
                        throw new ContractValidateException("callValue must >= 0");
                    }
                    if (token_value < 0)
                    {
                        throw new ContractValidateException("tokenValue must >= 0");
                    }
                    if (new_contract.OriginEnergyLimit <= 0)
                    {
                        throw new ContractValidateException("The originEnergyLimit must be > 0");
                    }
                    energy_limit = GetAccountEnergyLimitWithFixRatio(creator, fee_limit, call_value);
                }
                else
                {
                    energy_limit = GetAccountEnergyLimitWithFloatRatio(creator, fee_limit, call_value);
                }

                CheckTokenValueAndId(token_value, token_id);

                byte[] ops = new_contract.Bytecode.ToByteArray();
                this.root_internal_transaction = new InternalTransaction(this.transaction, this.transaction_type);

                long max_cpu_time_tx = this.deposit.DBManager.DynamicProperties.GetMaxCpuTimeOfOneTx() * DefineParameter.ONE_THOUSAND;
                long tx_cpu_limit    = (long)(max_cpu_time_tx * GetCpuLimitInUsRatio());
                long vm_start        = Helper.NanoTime() / DefineParameter.ONE_THOUSAND;
                long vm_should_end   = vm_start + tx_cpu_limit;

                IProgramInvoke invoke = this.invoke_factory.CreateProgramInvoke(TransactionType.TX_CONTRACT_CREATION_TYPE,
                                                                                this.executor_type,
                                                                                this.transaction,
                                                                                token_value,
                                                                                token_id,
                                                                                this.block.Instance,
                                                                                this.deposit,
                                                                                vm_start,
                                                                                vm_should_end,
                                                                                energy_limit);

                this.vm      = new Vm();
                this.program = new Program(ops, invoke, this.root_internal_transaction, this.block);
                byte[] tx_id = new TransactionCapsule(this.transaction).Id.Hash;
                this.program.RootTransactionId = tx_id;

                // TODO: EventPluginLoader is not Implementation
                //if (this.enable_listener
                //    && (EventPluginLoader.getInstance().isContractEventTriggerEnable()
                //    || EventPluginLoader.getInstance().isContractLogTriggerEnable())
                //    && IsCheckTransaction)
                //{
                //    logInfoTriggerParser = new LogInfoTriggerParser(this.block.getNum(), this.block.getTimeStamp(), txId, callerAddress);
                //}
            }
            catch (Exception e)
            {
                Logger.Info(e.Message);
                throw new ContractValidateException(e.Message);
            }
            this.program.Result.ContractAddress = contract_address;
            this.deposit.CreateAccount(contract_address, new_contract.Name, AccountType.Contract);
            this.deposit.CreateContract(contract_address, new ContractCapsule(new_contract));
            byte[] code = new_contract.Bytecode.ToByteArray();

            if (!VMConfig.AllowTvmConstantinople)
            {
                deposit.SaveCode(contract_address, ProgramPrecompile.GetCode(code));
            }

            if (call_value > 0)
            {
                MUtil.Transfer(this.deposit, caller_address, contract_address, call_value);
            }
            if (VMConfig.AllowTvmTransferTrc10)
            {
                if (token_value > 0)
                {
                    MUtil.TransferToken(this.deposit, caller_address, contract_address, token_id.ToString(), token_value);
                }
            }
        }
Beispiel #25
0
        public static TransactionSignWeight GetTransactionSignWeight(Transaction transaction)
        {
            TransactionSignWeight weight    = new TransactionSignWeight();
            TransactionExtention  extention = new TransactionExtention();

            weight.Result    = new TransactionSignWeight.Types.Result();
            extention.Result = new Return();

            extention.Transaction   = transaction;
            extention.Txid          = ByteString.CopyFrom(SHA256Hash.ToHash(transaction.RawData.ToByteArray()));
            extention.Result.Result = true;
            extention.Result.Code   = Return.Types.response_code.Success;

            weight.Transaction = extention;

            try
            {
                Contract contract = transaction.RawData.Contract[0];
                byte[]   owner    = TransactionCapsule.GetOwner(contract);

                AccountCapsule account = Manager.Instance.DBManager.Account.Get(owner);
                if (account == null)
                {
                    throw new PermissionException("Account is not exist!");
                }

                int        permission_id = contract.PermissionId;
                Permission permission    = account.GetPermissionById(permission_id);
                if (permission == null)
                {
                    throw new PermissionException("permission isn't exit");
                }

                if (permission_id != 0)
                {
                    if (permission.Type != Permission.Types.PermissionType.Active)
                    {
                        throw new PermissionException("Permission type is error");
                    }

                    if (!CheckPermissionOprations(permission, contract))
                    {
                        throw new PermissionException("Permission denied");
                    }
                }

                weight.Permission = permission;
                if (transaction.Signature.Count > 0)
                {
                    List <ByteString> approves = new List <ByteString>();

                    weight.ApprovedList.AddRange(approves);
                    weight.CurrentWeight = TransactionCapsule.CheckWeight(permission,
                                                                          new List <ByteString>(transaction.Signature),
                                                                          SHA256Hash.ToHash(transaction.RawData.ToByteArray()),
                                                                          approves);
                }

                if (weight.CurrentWeight >= permission.Threshold)
                {
                    weight.Result.Code = TransactionSignWeight.Types.Result.Types.response_code.EnoughPermission;
                }
                else
                {
                    weight.Result.Code = TransactionSignWeight.Types.Result.Types.response_code.NotEnoughPermission;
                }
            }
            catch (SignatureFormatException e)
            {
                weight.Result.Code    = TransactionSignWeight.Types.Result.Types.response_code.SignatureFormatError;
                weight.Result.Message = e.Message;
            }
            catch (SignatureException e)
            {
                weight.Result.Code    = TransactionSignWeight.Types.Result.Types.response_code.ComputeAddressError;
                weight.Result.Message = e.Message;
            }
            catch (PermissionException e)
            {
                weight.Result.Code    = TransactionSignWeight.Types.Result.Types.response_code.PermissionError;
                weight.Result.Message = e.Message;
            }
            catch (System.Exception e)
            {
                weight.Result.Code    = TransactionSignWeight.Types.Result.Types.response_code.OtherError;
                weight.Result.Message = e.Message;
            }

            return(weight);
        }
Beispiel #26
0
        public static Return BroadcastTransaction(Transaction signed_transaction)
        {
            Return             ret         = new Return();
            TransactionCapsule transaction = new TransactionCapsule(signed_transaction);

            try
            {
                int     min_effective_connection = (int)Args.Instance.Node.RPC.MinEffectiveConnection;
                Message message = (Message) new TransactionMessage(signed_transaction);

                if (min_effective_connection != 0)
                {
                    if (Manager.Instance.NetDelegate.ActivePeers.Count == 0)
                    {
                        Logger.Warning(
                            string.Format("Broadcast transaction {0} failed, no connection", transaction.Id));

                        ret.Result  = false;
                        ret.Code    = Return.Types.response_code.NoConnection;
                        ret.Message = ByteString.CopyFromUtf8("no connection");
                        return(ret);
                    }

                    int count = (Manager.Instance.NetDelegate.ActivePeers.Where(peer =>
                    {
                        return(!peer.IsNeedSyncUs && !peer.IsNeedSyncFromPeer);
                    })).Count();

                    if (count < min_effective_connection)
                    {
                        string info = "effective connection:" + count + " lt min_effective_connection:" + min_effective_connection;
                        Logger.Warning(
                            string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, info));

                        ret.Result  = false;
                        ret.Code    = Return.Types.response_code.NotEnoughEffectiveConnection;
                        ret.Message = ByteString.CopyFromUtf8(info);
                        return(ret);
                    }
                }

                if (Manager.Instance.DBManager.IsTooManyPending)
                {
                    ret.Result = false;
                    ret.Code   = Return.Types.response_code.ServerBusy;
                    return(ret);
                }

                if (Manager.Instance.DBManager.IsGeneratingBlock)
                {
                    Logger.Warning(
                        string.Format("Broadcast transaction {0} failed, is generating block.", transaction.Id));

                    ret.Result = false;
                    ret.Code   = Return.Types.response_code.ServerBusy;
                    return(ret);
                }

                if (Manager.Instance.DBManager.TransactionIdCache.Get(transaction.Id.ToString()) != null)
                {
                    Logger.Warning(
                        string.Format("Broadcast transaction {0} failed, is already exist.", transaction.Id));

                    ret.Result = false;
                    ret.Code   = Return.Types.response_code.DupTransactionError;
                    return(ret);
                }
                else
                {
                    Manager.Instance.DBManager.TransactionIdCache.Add(transaction.Id.ToString(), true);
                }

                if (Manager.Instance.DBManager.DynamicProperties.SupportVM())
                {
                    transaction.ClearTransactionResult();
                }

                if (!Manager.Instance.DBManager.PushTransaction(transaction))
                {
                    ret.Result  = false;
                    ret.Code    = Return.Types.response_code.ContractValidateError;
                    ret.Message = ByteString.CopyFromUtf8("Push transaction error");
                    return(ret);
                }

                Manager.Instance.NetService.Broadcast(message);
                Logger.Info(
                    string.Format("Broadcast transaction {0} successfully.", transaction.Id));

                ret.Result = true;
                ret.Code   = Return.Types.response_code.Success;
            }
            catch (ValidateSignatureException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.Sigerror;
                ret.Message = ByteString.CopyFromUtf8("validate signature error : " + e.Message);
            }
            catch (ContractValidateException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.ContractValidateError;
                ret.Message = ByteString.CopyFromUtf8("contract validate error : " + e.Message);
            }
            catch (ContractExeException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.ContractExeError;
                ret.Message = ByteString.CopyFromUtf8("contract execute error : " + e.Message);
            }
            catch (AccountResourceInsufficientException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.BandwithError;
                ret.Message = ByteString.CopyFromUtf8("AccountResourceInsufficient error");
            }
            catch (DupTransactionException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.DupTransactionError;
                ret.Message = ByteString.CopyFromUtf8("dup transaction");
            }
            catch (TaposException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.TaposError;
                ret.Message = ByteString.CopyFromUtf8("Tapos check error");
            }
            catch (TooBigTransactionException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.TooBigTransactionError;
                ret.Message = ByteString.CopyFromUtf8("Transaction size is too big");
            }
            catch (TransactionExpirationException e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.TransactionExpirationError;
                ret.Message = ByteString.CopyFromUtf8("Transaction expired");
            }
            catch (System.Exception e)
            {
                Logger.Error(
                    string.Format("Broadcast transaction {0} failed, {1}.", transaction.Id, e.Message));

                ret.Result  = false;
                ret.Code    = Return.Types.response_code.OtherError;
                ret.Message = ByteString.CopyFromUtf8("Other error : " + e.Message);
            }

            return(ret);
        }
Beispiel #27
0
        public override void Consume(TransactionCapsule tx, TransactionTrace tx_trace)
        {
            List <Contract> contracts = new List <Contract>(tx.Instance.RawData.Contract);

            if (tx.ResultSize > DefineParameter.MAX_RESULT_SIZE_IN_TX * contracts.Count)
            {
                throw new TooBigTransactionResultException();
            }

            long size = 0;

            if (this.db_manager.DynamicProperties.SupportVM())
            {
                tx.Instance.Ret.Clear();
                size += tx.Instance.CalculateSize();
            }
            else
            {
                size += tx.Size;
            }

            foreach (Contract contract in contracts)
            {
                if (this.db_manager.DynamicProperties.SupportVM())
                {
                    size += DefineParameter.MAX_RESULT_SIZE_IN_TX;
                }

                Logger.Debug(string.Format("tx id {0}, bandwidth cost {1}",
                                           tx.Id,
                                           size));

                tx_trace.SetNetBill(size, 0);
                byte[]         address = TransactionCapsule.GetOwner(contract);
                AccountCapsule account = this.db_manager.Account.Get(address);

                if (account == null)
                {
                    throw new ContractValidateException("account not exists");
                }

                long now = this.db_manager.WitnessController.GetHeadSlot();
                if (ContractCreateNewAccount(contract))
                {
                    ConsumeForCreateNewAccount(account, size, now, tx_trace);
                    continue;
                }

                if (contract.Type == ContractType.TransferAssetContract &&
                    UseAssetAccountNet(contract, account, now, size))
                {
                    continue;
                }

                if (UseAccountNet(account, size, now))
                {
                    continue;
                }

                if (UseFreeNet(account, size, now))
                {
                    continue;
                }

                if (UseTransactionFee(account, size, tx_trace))
                {
                    continue;
                }

                long fee = this.db_manager.DynamicProperties.GetTransactionFee() * size;


                throw new AccountResourceInsufficientException(
                          "Account Insufficient bandwidth[" + size + "] and balance[" + fee + "] to create new account");
            }
        }