示例#1
0
        }; //TODO


        public static bool Execute(out Types.Transaction transaction, ContractArgs contractArgs, bool isWitness)
        {
            try
            {
                var fileName     = HttpServerUtility.UrlTokenEncode(contractArgs.ContractHash);
                var contractCode = File.ReadAllText(Path.Combine(_OutputPath, Path.ChangeExtension(fileName, ".fs")));
                var func         = ContractExamples.Execution.compileQuotedContract(contractCode);

                var result = func.Invoke(new Tuple <byte[], byte[], FSharpFunc <Types.Outpoint, FSharpOption <Types.Output> > >(
                                             contractArgs.Message,
                                             contractArgs.ContractHash,
                                             FSharpFunc <Types.Outpoint, FSharpOption <Types.Output> > .FromConverter(t => contractArgs.tryFindUTXOFunc(t))));

                var txSkeleton = result as Tuple <FSharpList <Types.Outpoint>, FSharpList <Types.Output>, byte[]>;

                transaction = txSkeleton == null || txSkeleton.Item2.Count() == 0 ? null :
                              new Types.Transaction(
                    Tests.tx.version,
                    txSkeleton.Item1,
                    ListModule.OfSeq <byte[]>(isWitness ? new byte[][] { contractArgs.Message } : new byte[][] { }),
                    txSkeleton.Item2,
                    FSharpOption <Types.ExtendedContract> .None                           //TODO: get from txSkeleton.Item3
                    );

                return(true);
            }
            catch (Exception e)
            {
                BlockChainTrace.Error("Error executing contract", e);
            }

            transaction = null;

            return(false);
        }
示例#2
0
        void UndoBlock(Types.Block block, byte[] key)
        {
            BlockChainTrace.Information($"undoing block {block.header.blockNumber}", block);

            _BlockChain.BlockStore.SetLocation(_DbTx, key, LocationEnum.Branch);

            var blockUndoData = _BlockChain.BlockStore.GetUndoData(_DbTx, key);

            if (blockUndoData != null)
            {
                blockUndoData.AddedUTXO.ForEach(u =>
                {
                    BlockChainTrace.Information($"undo block {block.header.blockNumber}: utxo removed, amount {u.Item2.spend.amount}", block);
                    _BlockChain.UTXOStore.Remove(_DbTx, u.Item1.txHash, u.Item1.index);
                });

                blockUndoData.RemovedUTXO.ForEach(u =>
                {
                    BlockChainTrace.Information($"undo block {block.header.blockNumber}: new utxo, amount {u.Item2.spend.amount}", block);
                    _BlockChain.UTXOStore.Put(_DbTx, u.Item1.txHash, u.Item1.index, u.Item2);
                });

                foreach (var item in blockUndoData.ACSDeltas)
                {
                    if (item.Value.LastBlock.HasValue) // restore last block - undo extend
                    {
                        var current = new ActiveContractSet().Get(_DbTx, item.Key);

                        if (current != null)
                        {
                            current.Value.LastBlock = item.Value.LastBlock.Value;
                            _BlockChain.ActiveContractSet.Add(_DbTx, current.Value);
                        }
                        else
                        {
                            BlockChainTrace.Error("missing ACS item!", new Exception());
                        }
                    }
                    else if (item.Value.ACSItem != null) // restore entire item - undo expire
                    {
                        _BlockChain.ActiveContractSet.Add(_DbTx, item.Value.ACSItem);
                    }
                    else // remove item - undo activate
                    {
                        _BlockChain.ActiveContractSet.Remove(_DbTx, item.Key);
                    }
                }
            }

            block.transactions.ToList().ForEach(tx =>
            {
                var txHash             = Merkle.transactionHasher.Invoke(tx);
                UnconfirmedTxs[txHash] = tx;
            });
        }
示例#3
0
        public ContractFunction GetContractFunction(TransactionContext dbTx, byte[] contractHash)
        {
            var acsItem = Get(dbTx, contractHash);

            if (acsItem == null)
            {
                return(null);
            }

            var deserialization = FSharpOption <Tuple <ContractFunction, ContractCostFunction> > .None;

            try
            {
                deserialization = ContractExamples.FStarExecution.deserialize(acsItem.Value.Serialized);
            }
            catch
            {
                BlockChainTrace.Information("Error deserializing contract");
            }

            if (FSharpOption <Tuple <ContractFunction, ContractCostFunction> > .get_IsNone(deserialization) || deserialization == null)
            {
                BlockChainTrace.Information("Reserializing contract");

                try
                {
                    var compilation = ContractExamples.FStarExecution.compile(acsItem.Value.Extracted);

                    if (FSharpOption <byte[]> .get_IsNone(compilation))
                    {
                        return(null);
                    }

                    acsItem.Value.Serialized = compilation.Value;

                    Add(dbTx, acsItem.Value);

                    deserialization = ContractExamples.FStarExecution.deserialize(compilation.Value);

                    if (FSharpOption <Tuple <ContractFunction, ContractCostFunction> > .get_IsNone(deserialization))
                    {
                        BlockChainTrace.Error("Error deserializing contract");
                        return(null);
                    }
                }
                catch (Exception e)
                {
                    BlockChainTrace.Error("Error recompiling contract", e);
                    return(null);
                }
            }

            return(deserialization.Value.Item1);
        }
示例#4
0
        // Note: when contract uses blokchain state as context, need to pass it in.
        public static bool ExecuteContract(
            byte[] contractHash,
            ContractFunction contractFunction,
            byte[] message,
            out Types.Transaction transaction,
            UtxoLookup UtxoLookup,
            bool isWitness)
        {
            var contractFunctionInput = new ContractFunctionInput(
                message,
                contractHash,
                UtxoLookup
                );
            TransactionSkeleton transactionSkeleton = null;

            transaction = null;

            try
            {
                var serializer = new ContractExamples.FStarCompatibility.DataSerializer(Consensus.Serialization.context);
                Consensus.Serialization.context.Serializers.RegisterOverride(serializer);

                var result = contractFunction.Invoke(contractFunctionInput);

                if (result.IsError)
                {
                    BlockChainTrace.Information("Contract resulted in error: " + result.ErrorValue);
                    return(false);
                }

                transactionSkeleton = result.ResultValue;
            }
            catch (Exception e)
            {
                BlockChainTrace.Error("Error executing contract", e);
                return(false);
            }

            if (transactionSkeleton == null)
            {
                return(false);
            }

            transaction = new Types.Transaction(
                Tests.tx.version,
                transactionSkeleton.Item1,
                ListModule.OfSeq(isWitness ? new byte[][] { message } : new byte[][] { }),
                transactionSkeleton.Item2,
                FSharpOption <Types.ExtendedContract> .None //TODO: get from txSkeleton.Item3
                );

            return(true);
        }
示例#5
0
        public static bool Compile_old(String fsharpCode, out byte[] contractHash)
        {
            var tempSourceFile = Path.ChangeExtension(Path.GetTempFileName(), ".fs");
            var process        = new Process();

            contractHash = GetHash(fsharpCode);

            File.WriteAllText(tempSourceFile, fsharpCode);

            if (!Directory.Exists(_OutputPath))
            {
                Directory.CreateDirectory(_OutputPath);
            }

            if (IsRunningOnMono())
            {
                process.StartInfo.FileName  = "fsharpc";
                process.StartInfo.Arguments = $"-o { GetFileName(contractHash) } -a {tempSourceFile}{DEPENCENCY_OPTION + string.Join(DEPENCENCY_OPTION, _Dependencies)}";
            }
            else
            {
                //TODO
            }

            process.OutputDataReceived += (sender, args1) =>
            {
                Console.WriteLine("## " + args1.Data);
            };

            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.RedirectStandardOutput = true;

            process.OutputDataReceived += (sender, args1) =>
            {
                BlockChainTrace.Information(args1.Data);
            };

            try
            {
                process.Start();
                process.BeginOutputReadLine();
                process.WaitForExit();
            }
            catch (Exception e)
            {
                BlockChainTrace.Error("process", e);
            }

            File.Delete(tempSourceFile);

            return(process.ExitCode == 0);
        }
示例#6
0
        //TODO: should asset that the block came from main?
        Types.Block GetBlock(byte[] key)
        {
            using (TransactionContext context = _DBContext.GetTransactionContext())
            {
                var location = BlockStore.GetLocation(context, key);

                if (location == LocationEnum.Main)
                {
                    try
                    {
                        var bk = BlockStore.GetBlock(context, key);
                        return(bk == null ? null : bk.Value);
                    } catch (Exception e)
                    {
                        BlockChainTrace.Error("GetBlock", e);
                        return(null);
                    }
                }

                return(null);
            }
        }
示例#7
0
        public static bool Compile(String csharpCode, out byte[] contractHash)
        {
            var provider   = new CSharpCodeProvider();
            var parameters = new CompilerParameters();

            foreach (var dependency in _Dependencies)
            {
                parameters.ReferencedAssemblies.Add(dependency);
            }

            if (!Directory.Exists(_OutputPath))
            {
                Directory.CreateDirectory(_OutputPath);
            }
            contractHash = GetHash(csharpCode);

            parameters.GenerateInMemory   = false;
            parameters.GenerateExecutable = false;
            parameters.OutputAssembly     = GetFileName(contractHash);
            var results = provider.CompileAssemblyFromSource(parameters, csharpCode);

            if (results.Errors.HasErrors)
            {
                StringBuilder sb = new StringBuilder();

                foreach (CompilerError error in results.Errors)
                {
                    sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
                }

                BlockChainTrace.Error(sb.ToString(), new Exception());
                //throw new InvalidOperationException(sb.ToString());

                return(false);
            }

            return(true);
        }
示例#8
0
        //void HandleQueueAction(QueueAction action)
        async Task ConsumeAsync(ISourceBlock <QueueAction> source)
        {
            while (await source.OutputAvailableAsync())
            {
                var action = source.Receive();

                try
                {
                    //((dynamic)this).Handle((dynamic)action);

                    if (action is HandleBlockAction)
                    {
                        ((HandleBlockAction)action).SetResult(HandleBlock(action as HandleBlockAction));
                    }
                    else if (action is GetActiveContractsAction)
                    {
                        ((GetActiveContractsAction)action).SetResult(GetActiveContracts());
                    }
                    else if (action is GetContractPointedOutputsAction)
                    {
                        ((GetContractPointedOutputsAction)action).SetResult(GetContractPointedOutputs(
                                                                                ((GetContractPointedOutputsAction)action).ContractHash));
                    }
                    else if (action is HandleOrphansOfTxAction)
                    {
                        HandleOrphansOfTransaction(action as HandleOrphansOfTxAction);
                    }
                    else if (action is GetIsContractActiveAction)
                    {
                        ((GetIsContractActiveAction)action).SetResult(IsContractActive(
                                                                          ((GetIsContractActiveAction)action).ContractHash));
                    }
                    //else if (action is GetUTXOAction)
                    //((GetUTXOAction)action).SetResult(GetUTXO(((GetUTXOAction)action).Outpoint, ((GetUTXOAction)action).IsInBlock));
                    else if (action is GetIsConfirmedUTXOExistAction)
                    {
                        var outpoint = ((GetIsConfirmedUTXOExistAction)action).Outpoint;
                        ((GetIsConfirmedUTXOExistAction)action).SetResult(IsConfirmedUTXOExist(outpoint));
                    }
                    else if (action is GetContractCodeAction)
                    {
                        ((GetContractCodeAction)action).SetResult(GetContractCode(
                                                                      ((GetContractCodeAction)action).ContractHash));
                    }
                    else if (action is HandleTransactionAction)
                    {
                        ((HandleTransactionAction)action).SetResult(HandleTransaction(((HandleTransactionAction)action).Tx, ((HandleTransactionAction)action).CheckInDb));
                    }
                    else if (action is GetBlockAction)
                    {
                        ((GetBlockAction)action).SetResult(GetBlock(((GetBlockAction)action).BkHash));
                    }
                    else if (action is GetTxAction)
                    {
                        ((GetTxAction)action).SetResult(GetTransaction(((GetTxAction)action).TxHash));
                    }
                    else if (action is ExecuteContractAction)
                    {
                        var executeContractAction = ((ExecuteContractAction)action);
                        Types.Transaction tx;
                        var result = AssembleAutoTx(executeContractAction.ContractHash, executeContractAction.Message, out tx, executeContractAction.Message != null);
                        ((ExecuteContractAction)action).SetResult(new Tuple <bool, Types.Transaction>(result, tx));
                    }

                    //TODO: remove
                    else if (action is GetUTXOSetAction)
                    {
                        var getUTXOSetAction = (GetUTXOSetAction)action;
                        HashDictionary <List <Types.Output> > txOutputs;
                        HashDictionary <Types.Transaction>    txs;
                        GetUTXOSet(getUTXOSetAction.Predicate, out txOutputs, out txs);
                        getUTXOSetAction.SetResult(new Tuple <HashDictionary <List <Types.Output> >, HashDictionary <Types.Transaction> >(txOutputs, txs));
                    }
                    //TODO: rename
                    else if (action is GetUTXOSetAction2)
                    {
                        using (var dbTx = _DBContext.GetTransactionContext())
                        {
                            ((GetUTXOSetAction2)action).SetResult(UTXOStore.All(dbTx).ToList());
                        }
                    }
#if TEST
                    else if (action is GetBlockLocationAction)
                    {
                        using (var dbTx = _DBContext.GetTransactionContext())
                        {
                            ((GetBlockLocationAction)action).SetResult(BlockStore.GetLocation(dbTx, ((GetBlockLocationAction)action).Block));
                        }
                    }
#endif
                }
                catch (Exception e)
                {
#if DEBUG
                    BlockChainTrace.Error("Blockchain request handle got an exception.\n\nOriginal caller's stack:\n\n" + action.StackTrace + "\n\nException:\n\n", e);
#else
                    BlockChainTrace.Error("Blockchain request exception", e);
#endif
                }
            }
        }
示例#9
0
        public static bool Execute_old(out Types.Transaction transaction, ContractArgs contractArgs, bool isWitness)
        {
            try
            {
                var assembly = Assembly.LoadFrom(GetFileName(contractArgs.ContractHash));
                var module   = assembly.GetModules()[0];
                var type     = module.GetTypes()[0];

                //**************************************************
                // used for CSharp based contract debugging
                var matchedTypes = Assembly.GetEntryAssembly()
                                   .GetModules()[0]
                                   .GetTypes()
                                   .Where(t => t.FullName == type.FullName);

                if (matchedTypes.Any())
                {
                    type = matchedTypes.First();
                }

                //**************************************************
                // used for FSharp based contract debugging
                //var matchedTypes = Assembly.LoadFile("TestFSharpContracts.dll")
                //    .GetModules()[0]
                //    .GetTypes()
                //    .Where(t => t.FullName == type.FullName);

                //if (matchedTypes.Any())
                //{
                //    type = matchedTypes.First();
                //}

                var method = type.GetMethod("main");
                var args   = new object[] {
#if CSHARP_CONTRACTS
                    new List <byte>(contractArgs.Message),
                    contractArgs.ContractHash,
                    contractArgs.tryFindUTXOFunc,
#else
                    contractArgs.Message,
                    contractArgs.ContractHash,
                    FSharpFunc <Types.Outpoint, FSharpOption <Types.Output> > .FromConverter(t => contractArgs.tryFindUTXOFunc(t))
#endif
                };

                var result = method.Invoke(null, args);

#if CSHARP_CONTRACTS
                var txSkeleton = result as Tuple <IEnumerable <Types.Outpoint>, IEnumerable <Types.Output>, byte[]>;
#else
                var txSkeleton = result as Tuple <FSharpList <Types.Outpoint>, FSharpList <Types.Output>, byte[]>;
#endif

                transaction = txSkeleton == null || txSkeleton.Item2.Count() == 0 ? null :
                              new Types.Transaction(
                    Tests.tx.version,
#if CSHARP_CONTRACTS
                    ListModule.OfSeq(txSkeleton.Item1),
#else
                    txSkeleton.Item1,
#endif
                    ListModule.OfSeq <byte[]>(isWitness ? new byte[][] { contractArgs.Message } : new byte[][] { }),
#if CSHARP_CONTRACTS
                    ListModule.OfSeq(txSkeleton.Item2),
#else
                    txSkeleton.Item2,
#endif
                    FSharpOption <Types.ExtendedContract> .None                           //TODO: get from txSkeleton.Item3
                    );

                return(true);
            }
            catch (Exception e)
            {
                BlockChainTrace.Error("Error executing contract", e);
            }

            transaction = null;

            return(false);
        }