}; //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); }
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; }); }
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); }
// 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); }
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); }
//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); } }
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); }
//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 } } }
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); }