コード例 #1
0
 public TxMessage(byte[] txHash, TransactionValidation.PointedTransaction ptx, TxStateEnum state)
 {
     BlockChainTrace.Information("To wallet: " + state, txHash);
     TxHash = txHash;
     Ptx    = ptx;
     State  = state;
 }
コード例 #2
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
        public static IsContractGeneratedTxResult IsContractGeneratedTx(TransactionValidation.PointedTransaction ptx, out byte[] contractHash)
        {
            contractHash = null;

            foreach (var input in ptx.pInputs)
            {
                if ([email protected])
                {
                    if (contractHash == null)
                    {
                        contractHash = ((Types.OutputLock.ContractLock)input.Item2.@lock).contractHash;
                    }
                    else if (!contractHash.SequenceEqual(((Types.OutputLock.ContractLock)input.Item2.@lock).contractHash))
                    {
                        return(IsContractGeneratedTxResult.Invalid);
                    }

                    else if (!contractHash.SequenceEqual(((Types.OutputLock.ContractLock)input.Item2.@lock).contractHash))
                    {
                        BlockChainTrace.Information("Unexpected contactHash", contractHash);
                        return(IsContractGeneratedTxResult.Invalid);
                    }
                }
            }

            return(contractHash == null ? IsContractGeneratedTxResult.NotContractGenerated : IsContractGeneratedTxResult.ContractGenerated);
        }
コード例 #3
0
        // remove
        bool IsTransactionValid(Types.Transaction tx, byte[] txHash, out TransactionValidation.PointedTransaction ptx)
        {
            if (_BlockChain.BlockStore.TxStore.ContainsKey(_DbTx, txHash) && _BlockChain.BlockStore.TxStore.Get(_DbTx, txHash).Value.InMainChain)
            {
                BlockChainTrace.Information("Tx already in store", txHash);
                ptx = null;
                return(false);
            }

            switch (_BlockChain.IsOrphanTx(_DbTx, tx, true, out ptx))
            {
            case BlockChain.IsTxOrphanResult.Orphan:
                BlockChainTrace.Information("tx invalid - orphan", tx);
                return(false);

            case BlockChain.IsTxOrphanResult.Invalid:
                BlockChainTrace.Information("tx invalid - reference(s)", tx);
                return(false);
            }

            if (_BlockChain.IsDoubleSpend(_DbTx, tx, true))
            {
                return(false);
            }

            //TODO: coinbase validation + check that witness has blocknumber

            if (!BlockChain.IsValidUserGeneratedTx(_DbTx, ptx))
            {
                BlockChainTrace.Information("tx invalid - structural", ptx);
                return(false);
            }

            byte[] contractHash;
            switch (BlockChain.IsContractGeneratedTx(ptx, out contractHash))
            {
            case BlockChain.IsContractGeneratedTxResult.ContractGenerated:
                if (!_BlockChain.ActiveContractSet.IsActive(_DbTx, contractHash))
                {
                    BlockChainTrace.Information("tx invalid - contract not active", tx);
                    return(false);
                }
                var contractFunction = _BlockChain.ActiveContractSet.GetContractFunction(_DbTx, contractHash);

                if (!BlockChain.IsValidAutoTx(ptx, UtxoLookup, contractHash, contractFunction))
                {
                    BlockChainTrace.Information("auto-tx invalid", ptx);
                    return(false);
                }
                break;

            case BlockChain.IsContractGeneratedTxResult.Invalid:
                BlockChainTrace.Information("tx invalid - input locks", tx);
                return(false);
            }

            return(true);
        }
コード例 #4
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
        //Types.Output GetUTXO(Types.Outpoint outpoint, bool IsInBlock)
        //{
        //	using (TransactionContext dbTx = _DBContext.GetTransactionContext())
        //	{
        //		return GetUTXO(outpoint, dbTx, IsInBlock);
        //	}
        //}

        public UtxoLookup UtxoLookupFactory(TransactionContext dbTx, bool isInBlock, TransactionValidation.PointedTransaction ptx = null)
        {
            return(UtxoLookup.FromConverter(t =>
            {
                bool valid;
                var output = GetUTXO(t, dbTx, isInBlock, out valid, ptx);
                return output == null ? FSharpOption <Types.Output> .None : new FSharpOption <Types.Output>(output);
            }));
        }
コード例 #5
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
        public static bool IsValidAutoTx(TransactionValidation.PointedTransaction ptx, UtxoLookup UtxoLookup, byte[] contractHash, ContractFunction contractFunction)
        {
            var isWitness  = false;
            var witnessIdx = -1;

            byte[] message = null;

            for (var i = 0; i < ptx.witnesses.Length; i++)
            {
                if (ptx.witnesses[i].Length > 0)
                {
                    witnessIdx = i;
                }
            }

            if (witnessIdx == 0)
            {
                message = ptx.witnesses[0];
            }
            else if (witnessIdx == -1)
            {
                var contractLock = ptx.pInputs[0].Item2.@lock as Types.OutputLock.ContractLock;

                if (contractLock == null)
                {
                    BlockChainTrace.Information("expected ContractLock, tx invalid");
                    return(false);
                }

                message = contractLock.data;
            }

            isWitness = witnessIdx == 0;

            Types.Transaction tx;

            var isExecutionSuccessful = ExecuteContract(
                contractHash,
                contractFunction,
                message,
                out tx,
                UtxoLookup,
                isWitness
                );

            return(isExecutionSuccessful && tx != null && TransactionValidation.unpoint(ptx).Equals(tx));
        }
コード例 #6
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
        public static bool IsValidUserGeneratedTx(TransactionContext dbTx, TransactionValidation.PointedTransaction ptx)
        {
            //Verify crypto signatures for each input; reject if any are bad


            //Using the referenced output transactions to get input values, check that each input value, as well as the sum, are in legal money range
            //Reject if the sum of input values < sum of output values


            //for (var i = 0; i < ptx.pInputs.Length; i++)
            //{
            //	if (!TransactionValidation.validateAtIndex(ptx, i))
            //		return false;
            //}

            return(true);
        }
コード例 #7
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
        bool IsReferencedCoinbaseTxsValid(TransactionContext dbTx, TransactionValidation.PointedTransaction ptx)
        {
            var currentHeight = Tip == null ? 0 : Tip.Value.header.blockNumber;

            foreach (var refTx in ptx.pInputs.Select(t => t.Item1.txHash))
            {
                Types.BlockHeader refTxBk;
                if (BlockStore.IsCoinbaseTx(dbTx, refTx, out refTxBk))
                {
                    if (refTxBk.blockNumber - currentHeight < COINBASE_MATURITY)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
コード例 #8
0
        //TODO: refactore for efficiency
        bool HasUtxos(TransactionValidation.PointedTransaction ptx)
        {
            foreach (var input in ptx.pInputs)
            {
                foreach (var tx in _ValidatedTxs)
                {
                    foreach (var txInput in tx.pInputs)
                    {
                        if (input.Item1.Equals(txInput))
                        {
                            return(false);
                        }
                    }
                }
            }

            foreach (var input in ptx.pInputs)
            {
                foreach (var tx in _ValidatedTxs)
                {
                    var txHash = Merkle.transactionHasher.Invoke(TransactionValidation.unpoint(ptx));
                    for (var i = 0; i < tx.outputs.Length; i++)
                    {
                        var outpoint = new Types.Outpoint(txHash, (uint)i);

                        if (input.Item1.Equals(outpoint))
                        {
                            return(true);
                        }
                    }
                }
            }

            foreach (var input in ptx.pInputs)
            {
                if (!_UtxoSet.Any(t => t.Item1.Equals(input.Item1)))
                {
                    return(false);
                }
            }

            return(true);
        }
コード例 #9
0
        void HandleTx(TransactionContext dbTx, byte[] txHash, TransactionValidation.PointedTransaction ptx, List <TxDelta> deltas, TxStateEnum txState)
        {
            var isValid = txState != TxStateEnum.Invalid;
            var _deltas = new AssetDeltas();

            if (!isValid)
            {
                foreach (var item in _TxStore.All(dbTx).Where(t => t.Item2.TxHash.SequenceEqual(txHash)))
                {
                    item.Item2.TxState = txState;
                    //TODO: handle ui consistency
                    _TxStore.Put(dbTx, item.Item1, item.Item2);
                }
                return;
            }

            ptx.outputs.Where(IsMatch).ToList().ForEach(o =>
            {
                AddOutput(_deltas, o, !isValid);
            });

            ptx.pInputs.ToList().ForEach(pInput =>
            {
                var key = GetKey(pInput.Item2);

                if (key != null)
                {
                    AddOutput(_deltas, pInput.Item2, isValid);
                    _KeyStore.Used(dbTx, key, true);
                }
            });

            if (_deltas.Count > 0)
            {
                var tx = TransactionValidation.unpoint(ptx);

                _TxStore.Put(dbTx, txHash, tx, _deltas, txState);
                deltas.Add(new TxDelta(txState, txHash, tx, _deltas));
            }
        }
コード例 #10
0
 public override bool IsDoubleSpend(TransactionValidation.PointedTransaction t, IEnumerable <Types.Outpoint> spentOutputs)
 {
     return(t.pInputs.Select(_t => _t.Item1).Any(_t => spentOutputs.Contains(_t)));
 }
コード例 #11
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
        Types.Output GetUTXO(Types.Outpoint outpoint, TransactionContext dbTx, bool isInBlock, out bool valid, TransactionValidation.PointedTransaction validatingPtx = null)
        {
            valid = true;

            if (!isInBlock)
            {
                foreach (var item in memPool.TxPool)
                {
                    foreach (var pInput in item.Value.pInputs)
                    {
                        if (outpoint.Equals(pInput.Item1))
                        {
                            return(null);
                        }
                    }
                }
            }

            var result = UTXOStore.Get(dbTx, outpoint);

            if (result != null)
            {
                return(result.Value);
            }

            if (isInBlock)
            {
                return(null);
            }

            if (!memPool.TxPool.Contains(outpoint.txHash))
            {
                return(null);
            }

            if (validatingPtx == null)
            {
                var tx = memPool.TxPool[outpoint.txHash];

                if (tx.outputs.Count() > outpoint.index)
                {
                    return(tx.outputs[(int)outpoint.index]);
                }
                else
                {
                    valid = false;
                }
            }
            else
            {
                foreach (var pInput in validatingPtx.pInputs)
                {
                    if (outpoint.Equals(pInput.Item1))
                    {
                        return(pInput.Item2);
                    }
                }
            }

            return(null);
        }
コード例 #12
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
        public IsTxOrphanResult IsOrphanTx(TransactionContext dbTx, Types.Transaction tx, bool isBlock, out TransactionValidation.PointedTransaction ptx)
        {
            var outputs = new List <Types.Output>();

            ptx = null;

            foreach (Types.Outpoint input in tx.inputs)
            {
                bool valid;
                var  output = GetUTXO(input, dbTx, isBlock, out valid);

                if (!valid)
                {
                    return(IsTxOrphanResult.Invalid);
                }
                if (output != null)
                {
                    outputs.Add(output);
                }
                else
                {
                    return(IsTxOrphanResult.Orphan);
                }
            }

            ptx = TransactionValidation.toPointedTransaction(
                tx,
                ListModule.OfSeq(outputs)
                );

            return(IsTxOrphanResult.NotOrphan);
        }
コード例 #13
0
ファイル: BlockChain.cs プロジェクト: zenprotocol/zen-wallet
 bool IsCoinbaseTx(TransactionValidation.PointedTransaction ptx)
 {
     return(ptx.pInputs.Any(t => t.Item2.@lock is Types.OutputLock.CoinbaseLock));
 }
コード例 #14
0
        void HandleTx(TransactionValidation.PointedTransaction ptx)
        {
            //TODO: try simplify using hash from message
            var txHash = Merkle.transactionHasher.Invoke(TransactionValidation.unpoint(ptx));

            var activationSacrifice = 0UL;

            for (var i = 0; i < ptx.outputs.Length; i++)
            {
                var output = ptx.outputs[i];

                if ([email protected])
                {
                    if (!output.spend.asset.SequenceEqual(Tests.zhash))
                    {
                        continue;                         // not Zen
                    }
                    var contractSacrificeLock = (Types.OutputLock.ContractSacrificeLock)output.@lock;

                    if (contractSacrificeLock.IsHighVLock)
                    {
                        continue;                         // not current version
                    }
                    if (contractSacrificeLock.Item.lockData.Length == 0)
                    {
                        activationSacrifice += output.spend.amount;
                    }
                }

                //todo: fix  to exclude CSLocks&FLocks, instead of including by locktype
                if ([email protected] || [email protected])
                {
                    var outpoint = new Types.Outpoint(txHash, (uint)i);
                    _UtxoSet.Add(new Tuple <Types.Outpoint, Types.Output>(outpoint, output));
                }
            }

            if (FSharpOption <Types.ExtendedContract> .get_IsSome(ptx.contract) && !ptx.contract.Value.IsHighVContract)
            {
                var codeBytes    = ((Types.ExtendedContract.Contract)ptx.contract.Value).Item.code;
                var contractHash = Merkle.innerHash(codeBytes);
                var contractCode = System.Text.Encoding.ASCII.GetString(codeBytes);

                if (!_ActiveContracts.Contains(contractHash))
                {
                    if (activationSacrifice > ActiveContractSet.KalapasPerBlock(contractCode))
                    {
                        try
                        {
                            var compiledCodeOpt = ContractExamples.FStarExecution.compile(contractCode);

                            if (FSharpOption <byte[]> .get_IsSome(compiledCodeOpt))
                            {
                                _ActiveContracts.Add(contractHash);
                            }
                        }
                        catch (Exception e)
                        {
                            MinerTrace.Error("Could not compile contract " + Convert.ToBase64String(contractHash), e);
                        }
                    }
                }
            }
        }
コード例 #15
0
        bool IsTransactionValid(TransactionValidation.PointedTransaction ptx)
        {
            if (!HasUtxos(ptx))
            {
                MinerTrace.Information("could not validate tx - utxo missing");
                return(false);
            }

            var utxoLookup = UtxoLookup.FromConverter(outpoint =>
            {
                var outputs = _UtxoSet.Where(t => t.Item1.Equals(outpoint)).Select(t => t.Item2);
                return(!outputs.Any() ? FSharpOption <Types.Output> .None : new FSharpOption <Types.Output>(outputs.First()));
            });

            var contractLookup = FSharpFunc <byte[], FSharpOption <ContractFunction> > .FromConverter(contractHash =>
            {
                if (!_ActiveContracts.Contains(contractHash))
                {
                    return(FSharpOption <ContractFunction> .None);
                }

                try
                {
                    var code = new GetContractCodeAction(contractHash).Publish().Result;

                    //TODO: module name
                    var extration = ContractExamples.FStarExecution.extract(System.Text.Encoding.ASCII.GetString(code));

                    if (FSharpOption <string> .get_IsNone(extration))
                    {
                        MinerTrace.Information("Could not extract contract");
                        return(null);
                    }

                    var compilation = ContractExamples.FStarExecution.compile(extration.Value);

                    if (FSharpOption <byte[]> .get_IsNone(compilation))
                    {
                        MinerTrace.Information("Could not complie contract");
                        return(null);
                    }

                    return(ContractExamples.FStarExecution.deserialize(compilation.Value).Value.Item1);
                }
                catch (Exception e)
                {
                    MinerTrace.Error("Could not compile contract " + Convert.ToBase64String(contractHash), e);
                    return(null);
                }
            });

            if (!TransactionValidation.validateNonCoinbaseTx(
                    ptx,
                    utxoLookup,
                    contractLookup
                    ))
            {
                MinerTrace.Information("could not validate tx");
                return(false);
            }

            MinerTrace.Information("validated tx");

            //TODO: memory management issues. trying to explicitly collect DynamicMethods
            GC.Collect();
            GC.WaitForPendingFinalizers();

            return(true);
        }