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); }
public IActionResult ProcessTransaction(TransactionValidation model, int id) { if (ModelState.IsValid) { User user = _context.Users.Where(u => u.ID == id).SingleOrDefault(); // Check if amount is a withdrawl and if there are available funds to pull if (model.Amount < 0 && ((model.Amount * -1) > user.Balance)) { TempData["errors"] = "Insufficient funds"; return(RedirectToAction("Index", new{ id = id })); } else { Transaction withdrawal = new Transaction { Amount = model.Amount, User = user }; user.Balance += model.Amount; _context.Transactions.Add(withdrawal); _context.SaveChanges(); return(RedirectToAction("Index", new{ id = id })); } } foreach (var modelState in ModelState.Values) { foreach (var error in modelState.Errors) { TempData["errors"] = error.ErrorMessage; } } return(RedirectToAction("Index", new{ id = id })); }
public async Task <ImportResultViewModel> ProcessFile(Stream stream) { var result = new ImportResultViewModel { LinesImported = 0, LinesIgnored = new List <string>() }; var linesProcessed = 1; using (var reader = new CSVTransactionReader(stream)) { var tran = new TransactionViewModel(); while (await reader.ReadTransactionAsync(tran)) { TransactionValidation.Validate(tran); if (tran.IsValid) { result.LinesImported++; _repository.Add(tran.ToTransaction()); } else { result.LinesIgnored.Add($"{linesProcessed} ignored, Reason: {tran.ValidationMessage}."); } linesProcessed++; } await _repository.SaveChangesAsync(); reader.Close(); } return(result); }
public TransactionValidationResult(TransactionResultTypes resultType, long usercode, string message, TransactionValidation nodeValidation) { Result = resultType; UserCode = usercode; Message = message; TransactionValidation = nodeValidation; }
private void Salvar(object sender, RoutedEventArgs e) { try { Client selectedClient = (Client)ClientName.SelectedValue; Card selectedCard = (Card)CardNumber.SelectedValue; ComboBoxItem selectedType = (ComboBoxItem)Type.SelectedValue; ComboBoxItem selectedNumber = (ComboBoxItem)Number.SelectedValue; string type = (string)selectedType.Content; string number = (string)selectedNumber.Tag; TransactionValidation.Validation(Amount.Text, type, Int16.Parse(number), selectedClient.IdClient, selectedCard.IdCard); Transaction t = new Transaction() { Amount = Decimal.Parse(Amount.Text), Type = type, Number = Int16.Parse(number), IdClient = selectedClient.IdClient, IdCard = selectedCard.IdCard }; string status = OldButGoldService.PostRequestTransaction(t); MessageBox.Show(status); this.NavigationService.Navigate(new Uri("Pages/Index.xaml", UriKind.Relative)); } catch (Exception ex) { MessageBox.Show(ex.Message); } }
public NodeTransactionMessagePayload(Unpacker unpacker) { if (unpacker.UnpackBool()) { Validation = new TransactionValidation(unpacker); } }
void MakeOrphan(TransactionContext dbTx) { Func <KeyValuePair <byte[], TransactionValidation.PointedTransaction>, bool> p = t => { TransactionValidation.PointedTransaction ptx; var tx = TransactionValidation.unpoint(t.Value); return(IsOrphanTx(dbTx, tx, false, out ptx) == IsTxOrphanResult.Orphan); }; memPool.TxPool.Where(p).Select(t => t.Key).ToList().ForEach(memPool.TxPool.MoveToOrphansWithDependencies); memPool.ICTxPool.Where(p).Select(t => t.Key).ToList().ForEach(memPool.ICTxPool.MoveToOrphansWithDependencies); }
public static Transaction ToTransaction(this TransactionViewModel model) { TransactionValidation.Validate(model); return(new Transaction { Account = model.Account, Amount = model.IsValid ? decimal.Parse(model.Amount) : 0, CurrencyCode = model.CurrencyCode, Description = model.Description, ID = model.ID }); }
public async Task <ActionResult> EditTransaction(TransactionViewModel model) { TransactionValidation.Validate(model); if (model.IsValid) { await _transactionService.SaveTransaction(model); return(RedirectToAction("Transactions")); } ModelState.AddModelError("", model.ValidationMessage); return(View(model)); }
public void Cadastrar(Transaction t, Card c, decimal limit) { try { CardValidation.CardValidationRules(c); TransactionValidation.TransactionValidationRules(t, limit, c.Status); repositorio.Insert(t); } catch (Exception e) { throw new Exception(e.Message); } }
public void MoveToOrphans(byte[] txHash) { if (Contains(txHash)) { var ptx = this[txHash]; Remove(txHash); var tx = TransactionValidation.unpoint(ptx); OrphanTxPool.Add(txHash, tx); } }
public bool HandleNewTransaction(Transaction transaction, TransactionValidation validation, NodeConnection connection) { if (_containers.TryGetValue(transaction.TargetChainId, out var container)) { var council = container.GetCouncil(transaction.TargetChainType, transaction.ChainIndex); if (council != null) { council.NewTransaction(transaction, connection); return(true); } } return(false); }
void UpdateMempool(TransactionContext dbTx, HashDictionary <TransactionValidation.PointedTransaction> confirmedTxs, HashDictionary <Types.Transaction> unconfirmedTxs) { lock (memPool) { dbTx.Commit(); var activeContracts = new HashSet(); foreach (var item in ActiveContractSet.All(dbTx)) { activeContracts.Add(item.Item1); } foreach (var item in memPool.ContractPool) { activeContracts.Add(item.Key); } RemoveConfirmedTxsFromMempool(confirmedTxs); MakeOrphan(dbTx); memPool.TxPool.MoveToICTxPool(activeContracts); RemoveInvalidAutoTxs(dbTx); foreach (var t in unconfirmedTxs) { new HandleTransactionAction { Tx = t.Value, CheckInDb = false }.Publish(); } memPool.ICTxPool.Where(t => { byte[] contractHash; IsContractGeneratedTx(t.Value, out contractHash); return(activeContracts.Contains(contractHash)); }) .ToList().ForEach(t => { memPool.ICTxPool.Remove(t.Key); new HandleTransactionAction { Tx = TransactionValidation.unpoint(t.Value), CheckInDb = false }.Publish(); }); } }
void ValidateTransationObject(Transaction transaction) { if (transaction == null) { throw new ArgumentNullException(); } var validator = new TransactionValidation(); var results = validator.Validate(transaction); if (!results.IsValid) { throw new ArgumentException(); } }
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)); }
Types.Transaction GetTransaction(byte[] key) //TODO: make concurrent { if (memPool.TxPool.Contains(key)) { return(TransactionValidation.unpoint(memPool.TxPool[key])); } else { using (TransactionContext context = _DBContext.GetTransactionContext()) { if (BlockStore.TxStore.ContainsKey(context, key)) { return(BlockStore.TxStore.Get(context, key).Value.Tx); } } } return(null); }
//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); }
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)); } }
public void ShouldNotOverspendUsingConfirmedTxXXXXXXXXXX() { ulong initialAmount = 11; ulong spendAmount = 10; var walletMessageEvent = new AutoResetEvent(false); // var key1 = Key.Create(); // var key2 = Key.Create(); var key1 = Key.Create("3c/oykrHM4qPmKo4sCMGT1PVfN+SXR7vNnEO7PvoWENGjVh0wy97F9bLeygidHSuejHmcXYKAVFdD7e33yPtyQ=="); var key2 = Key.Create("0PO1RfoZCeJsezF1Enk2t79W1HsYQywd9EZl7VVpRJL7z9wxs/ExZxMdh3Sx10GSx5OQNyhY2pYrw3JESFJo2w=="); // init genesis with a key from wallet var key = _WalletManager.GetUnusedKey(); var tx = Utils.GetTx().AddOutput(key.Address, Consensus.Tests.zhash, initialAmount); _GenesisBlock = _GenesisBlock.AddTx(tx); _BlockChain.HandleBlock(_GenesisBlock); Thread.Sleep(1000); //_WalletManager.Import(); Types.Transaction txNew; Assert.That(_WalletManager.Sign(key1.Address, Consensus.Tests.zhash, spendAmount, out txNew), Is.True); Assert.That(_BlockChain.HandleTransaction(txNew), Is.EqualTo(BlockChain.BlockChain.TxResultEnum.Accepted)); var mempoolPtx = _BlockChain.memPool.TxPool.ToList()[0].Value; var _tx = TransactionValidation.unpoint(mempoolPtx); _BlockChain.HandleBlock(_GenesisBlock.Child().AddTx(_tx)); Thread.Sleep(1000); _WalletManager.Import(key); Assert.That(_WalletManager.Sign(key2.Address, Consensus.Tests.zhash, spendAmount, out txNew), Is.False); // Thread.Sleep(1000); }
Types.Transaction Sign(Types.Output output, byte[] asset, ulong amount) { ulong change; var assets = new List <Asset>(); var outputs = new List <Types.Output>(); using (TransactionContext dbTx = _DBContext.GetTransactionContext()) { if (!GetAssets(dbTx, asset, amount, out change, assets)) { return(null); } else if (change > 0) { Key key; if (_KeyStore.GetUnusedKey(dbTx, out key, true)) { _Keys.Add(key); dbTx.Commit(); } outputs.Add(new Types.Output(key.Address.GetLock(), new Types.Spend(asset, change))); } } outputs.Add(output); return(TransactionValidation.signTx(new Types.Transaction( 0, ListModule.OfSeq(assets.Select(t => t.Outpoint)), ListModule.OfSeq(new List <byte[]>()), ListModule.OfSeq(outputs), null), ListModule.OfSeq(assets.Select(i => i.Key.Private)))); }
public NodeTransactionMessagePayload(TransactionValidation validation) { Validation = validation; }
bool ExtendMain(List <QueueAction> queuedActions, double totalWork, bool isGenesis = false) { if (_BlockChain.BlockStore.ContainsKey(_DbTx, _BkHash)) { _BlockChain.BlockStore.SetLocation(_DbTx, _BkHash, LocationEnum.Main); } else { _BlockChain.BlockStore.Put(_DbTx, _BkHash, _Bk, LocationEnum.Main, totalWork); } _BlockChain.Timestamps.Push(_Bk.header.timestamp); if (_Bk.header.blockNumber % 2000 == 0) { _BlockChain.BlockNumberDifficulties.Add(_DbTx.Transaction, _Bk.header.blockNumber, _BkHash); } var blockUndoData = new BlockUndoData(); var confirmedTxs = new HashDictionary <TransactionValidation.PointedTransaction>(); //TODO: lock with mempool for (var txIdx = 0; txIdx < _Bk.transactions.Count(); txIdx++) { var tx = _Bk.transactions[txIdx]; var txHash = Merkle.transactionHasher.Invoke(tx); TransactionValidation.PointedTransaction ptx; if (!isGenesis) { if ((txIdx == 0 && !IsCoinbaseTxValid(tx)) || (txIdx > 0 && IsCoinbaseTxValid(tx))) { if (txIdx == 0) { BlockChainTrace.Information("Invalid coinbase tx"); } else { BlockChainTrace.Information($"Invalid tx ({txIdx})"); } return(false); } if (!IsTransactionValid(tx, txHash, out ptx)) { return(false); } confirmedTxs[txHash] = ptx; foreach (var pInput in ptx.pInputs) { _BlockChain.UTXOStore.Remove(_DbTx, pInput.Item1); BlockChainTrace.Information($"utxo spent, amount {pInput.Item2.spend.amount}", ptx); //BlockChainTrace.Information($" of", pInput.Item1.txHash); blockUndoData.RemovedUTXO.Add(new Tuple <Types.Outpoint, Types.Output>(pInput.Item1, pInput.Item2)); } } else { ptx = TransactionValidation.toPointedTransaction( tx, ListModule.Empty <Types.Output>() ); } _BlockChain.BlockStore.TxStore.Put(_DbTx, txHash, tx, true); var contractExtendSacrifices = new HashDictionary <ulong>(); var activationSacrifice = 0UL; for (var outputIdx = 0; outputIdx < tx.outputs.Count(); outputIdx++) { var output = tx.outputs[outputIdx]; 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 && contractSacrificeLock.Item.lockData[0] != null && contractSacrificeLock.Item.lockData[0].Length > 0) { var contractKey = contractSacrificeLock.Item.lockData[0]; // output-lock-level indicated contract contractExtendSacrifices[contractKey] = (contractExtendSacrifices.ContainsKey(contractKey) ? contractExtendSacrifices[contractKey] : 0) + output.spend.amount; } else 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]) { BlockChainTrace.Information($"new utxo, amount {output.spend.amount}", tx); var outpoint = new Types.Outpoint(txHash, (uint)outputIdx); _BlockChain.UTXOStore.Put(_DbTx, outpoint, output); blockUndoData.AddedUTXO.Add(new Tuple <Types.Outpoint, Types.Output>(outpoint, output)); } } if (FSharpOption <Types.ExtendedContract> .get_IsSome(tx.contract) && !tx.contract.Value.IsHighVContract) { var codeBytes = ((Types.ExtendedContract.Contract)tx.contract.Value).Item.code; var contractHash = Merkle.innerHash(codeBytes); var contractCode = System.Text.Encoding.ASCII.GetString(codeBytes); if (_BlockChain.ActiveContractSet.TryActivate(_DbTx, contractCode, activationSacrifice, contractHash, _Bk.header.blockNumber)) { blockUndoData.ACSDeltas.Add(contractHash, new ACSUndoData()); ContractsTxsStore.Add(_DbTx.Transaction, contractHash, txHash); } } foreach (var item in contractExtendSacrifices) { var currentACSItem = _BlockChain.ActiveContractSet.Get(_DbTx, item.Key); if (currentACSItem.Value != null) { if (_BlockChain.ActiveContractSet.TryExtend(_DbTx, item.Key, item.Value)) { if (!blockUndoData.ACSDeltas.ContainsKey(item.Key)) { blockUndoData.ACSDeltas.Add(item.Key, new ACSUndoData() { LastBlock = currentACSItem.Value.LastBlock }); } } } } } var expiringContracts = _BlockChain.ActiveContractSet.GetExpiringList(_DbTx, _Bk.header.blockNumber); foreach (var acsItem in expiringContracts) { if (!blockUndoData.ACSDeltas.ContainsKey(acsItem.Key)) { blockUndoData.ACSDeltas.Add(acsItem.Key, new ACSUndoData() { ACSItem = acsItem.Value }); } } if (!isGenesis) { _BlockChain.BlockStore.SetUndoData(_DbTx, _BkHash, blockUndoData); } _BlockChain.ActiveContractSet.DeactivateContracts(_DbTx, expiringContracts.Select(t => t.Key)); ValidateACS(); _BlockChain.ChainTip.Context(_DbTx).Value = _BkHash; //TODO: only update after commit _BlockChain.Tip = new Keyed <Types.Block>(_BkHash, _Bk); queuedActions.Add(new MessageAction(new BlockMessage(confirmedTxs, _Bk.header.blockNumber))); foreach (var item in confirmedTxs) { ConfirmedTxs[item.Key] = item.Value; UnconfirmedTxs.Remove(item.Key); } return(true); }
public override bool IsValid() { ValidationResult = new TransactionValidation().Validate(this); return(ValidationResult.IsValid); }
public async Task <ResponseMessage <List <string> > > BeltLookValidation(UserInfo user, [FromBody] TransactionValidation transactionValidation) { Logger.Trace($"用户{user?.UserName ?? ""}({user?.Id ?? ""})验证带看信息(BeltLookValidation):\r\n请求参数为:\r\n" + (transactionValidation != null ? JsonHelper.ToJson(transactionValidation) : "")); var response = new ResponseMessage <List <string> >(); response.Code = ResponseCodeDefines.NotFound; response.Message = "未查询到信息"; if (!ModelState.IsValid) { var error = ""; var errors = ModelState.Values.ToList(); foreach (var item in errors) { foreach (var e in item.Errors) { error += e.ErrorMessage + " "; } } response.Code = ResponseCodeDefines.ModelStateInvalid; response.Message = error; Logger.Warn($"用户{user?.UserName ?? ""}({user?.Id ?? ""})验证带看信息(BeltLookValidation)模型验证失败:\r\n{response.Message ?? ""},\r\n请求参数为:\r\n" + (transactionValidation != null ? JsonHelper.ToJson(transactionValidation) : "")); } else { try { response.Extension = await _customerTransactionsManager.ValidationBeltLook(user.Id, transactionValidation, HttpContext.RequestAborted); response.Code = ResponseCodeDefines.SuccessCode; response.Message = "查询成功"; } catch (Exception e) { response.Code = ResponseCodeDefines.ServiceError; response.Message = "服务器错误:" + e.ToString(); Logger.Error($"用户{user?.UserName ?? ""}({user?.Id ?? ""})验证带看信息(BeltLookValidation)请求失败:\r\n{response.Message ?? ""},\r\n请求参数为:\r\n" + (transactionValidation != null ? JsonHelper.ToJson(transactionValidation) : "")); } } return(response); }
public async Task <TransactionValidationResult> ValidateDataTransaction(DataTransaction transaction) { var userCode = 0L; var result = TransactionResultTypes.Unknown; var message = string.Empty; TransactionValidation nodeValidation = null; var type = transaction.TransactionType; var chainInfo = _coreChain.GetChainInfo(ChainId); var accountId = transaction.AccountId; var service = _node.ChainManager.GetService(ChainId); if (chainInfo == null) { result = TransactionResultTypes.ChainNotFound; goto end; } if (service == null) { result = TransactionResultTypes.ChainServiceUnavailable; goto end; } if (!_chainKeyValid) { var chainKey = chainInfo.GetValidChainKey(ChainIndex, ChainKeyIndex, Time.Timestamp); if (chainKey == null || chainKey.PublicKey != ChainKey.PublicKey) { result = TransactionResultTypes.ChainNodeInvalid; goto end; } _chainKeyValid = true; } if (transaction == null) { result = TransactionResultTypes.InvalidTransaction; goto end; } if (!transaction.IsDataTransactionValid) { result = TransactionResultTypes.InvalidContent; goto end; } if (BlockStorage.History.ContainsTransactionIdentifier(transaction)) { result = TransactionResultTypes.AlreadyProcessed; goto end; } var coreAccount = _coreChain.GetCoreAccount(accountId); if (coreAccount == null) { result = TransactionResultTypes.InvalidCoreAccount; goto end; } var serviceAccount = _serviceChain.GetServiceAccount(accountId); if (transaction.SignKeyIndex == Protocol.CoreAccountSignKeyIndex) { if (!transaction.IsSignatureValid(coreAccount.AccountKey, null)) { result = TransactionResultTypes.InvalidSignature; goto end; } } else { if (serviceAccount == null) { result = TransactionResultTypes.InvalidServiceAccount; goto end; } var accountKey = serviceAccount.GetValidAccountKey(transaction.SignKeyIndex, transaction.Timestamp); if (accountKey == null) { result = TransactionResultTypes.InvalidServiceAccountKey; goto end; } if (accountKey.IsExpired()) { result = TransactionResultTypes.Expired; goto end; } if (!transaction.IsSignatureValid(coreAccount.AccountKey, accountKey)) { result = TransactionResultTypes.InvalidSignature; goto end; } } { var(featResult, featCode) = ValidateTransactionFeatures((ushort)DataTransactionTypes.FeatureRequest, transaction); if (featResult != TransactionResultTypes.Ok) { result = featResult; userCode = featCode; goto end; } } if (type == DataTransactionTypes.Attachement) { if (!Attachements.AreAttachementsUploaded(transaction as AttachementDataTransaction)) { result = TransactionResultTypes.AttachementsNotUploaded; goto end; } } var purchaseRequired = transaction.GetFeature <RequiredPurchase>(RequiredPurchase.FeatureId); if (purchaseRequired != null && purchaseRequired.RequiredPurchaseType != PurchaseTypes.None) { if (!serviceAccount.HasRequiredTransactionPurchase(transaction, purchaseRequired)) { result = TransactionResultTypes.PurchaseRequired; goto end; } } var validation = await service.IsDataTransactionValid(transaction); userCode = validation.UserCode; message = validation.Message; if (!validation.IsOK) { if (validation.Result == ServiceResultTypes.PurchaseRequired) { result = TransactionResultTypes.PurchaseRequired; } else { result = TransactionResultTypes.ChainServiceErrorResponse; } goto end; } result = TransactionResultTypes.Ok; nodeValidation = new TransactionValidation(transaction, ChainKeyIndex, ChainKey); end: return(new TransactionValidationResult(result, userCode, message, nodeValidation)); }
public static Types.Transaction Sign(this Types.Transaction tx, params byte[][] keys) { return(TransactionValidation.signTx(tx, ListModule.OfSeq(keys))); }
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); }
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); } } } } }
public bool GetContractActivationTx(byte[] code, ulong zenAmount, out Types.Transaction signedTx, byte[] secureTokenHash = null) { ulong change; var assets = new List <Asset>(); var outputs = new List <Types.Output>(); using (TransactionContext dbTx = _DBContext.GetTransactionContext()) { if (!GetAssets(dbTx, Tests.zhash, zenAmount, out change, assets)) { signedTx = null; return(false); } else if (change > 0) { Key key; if (_KeyStore.GetUnusedKey(dbTx, out key, true)) { _Keys.Add(key); dbTx.Commit(); } outputs.Add(new Types.Output(key.Address.GetLock(), new Types.Spend(Tests.zhash, change))); } if (secureTokenHash != null) { ulong secureTokenChange; // var secureTokenAssets = new Assets(); if (!GetAssets(dbTx, secureTokenHash, 1, out secureTokenChange, assets)) { signedTx = null; return(false); } else if (secureTokenChange > 0) { Key key; if (_KeyStore.GetUnusedKey(dbTx, out key, true)) { _Keys.Add(key); dbTx.Commit(); } outputs.Add(new Types.Output(key.Address.GetLock(), new Types.Spend(secureTokenHash, secureTokenChange))); } } } var output = new Types.Output( Types.OutputLock.NewContractSacrificeLock( new Types.LockCore(0, ListModule.OfSeq(new byte[][] { })) ), new Types.Spend(Tests.zhash, zenAmount) ); outputs.Add(output); if (secureTokenHash != null) { outputs.Add(new Types.Output(Types.OutputLock.NewContractLock(Merkle.innerHash(code), new byte[] { }), new Types.Spend(secureTokenHash, 1))); } signedTx = TransactionValidation.signTx(new Types.Transaction( 0, ListModule.OfSeq(assets.Select(t => t.Outpoint)), ListModule.OfSeq(new List <byte[]>()), ListModule.OfSeq(outputs), new Microsoft.FSharp.Core.FSharpOption <Types.ExtendedContract>( Types.ExtendedContract.NewContract(new Types.Contract(code, new byte[] { }, new byte[] { })) ) ), ListModule.OfSeq(assets.Select(i => i.Key.Private))); return(true); }
public async Task <TransactionValidationResult> ValidateServiceTransaction(ServiceTransaction transaction) { var userCode = 0L; var result = TransactionResultTypes.Unknown; var message = string.Empty; TransactionValidation nodeValidation = null; if (transaction == null) { result = TransactionResultTypes.InvalidTransaction; goto end; } var chainInfo = CoreChain.GetChainInfo(ChainId); var accountId = transaction.AccountId; var service = _node.ChainManager.GetService(ChainId); if (chainInfo == null) { result = TransactionResultTypes.ChainNotFound; goto end; } if (service == null) { result = TransactionResultTypes.ChainServiceUnavailable; goto end; } if (!_chainKeyValid) { var chainKey = chainInfo.GetValidChainKey(ChainIndex, _chainKeyIndex, Time.Timestamp); if (chainKey == null || chainKey.PublicKey != _chainKey.PublicKey) { result = TransactionResultTypes.ChainNodeInvalid; goto end; } _chainKeyValid = true; } if (BlockStorage.History.ContainsTransactionIdentifier(transaction)) { result = TransactionResultTypes.AlreadyProcessed; goto end; } var coreAccount = CoreChain.GetCoreAccount(accountId); if (coreAccount == null) { result = TransactionResultTypes.InvalidCoreAccount; goto end; } { var(featResult, featCode) = ValidateTransactionFeatures((ushort)ServiceTransactionTypes.FeatureRequest, transaction); if (featResult != TransactionResultTypes.Ok) { result = featResult; userCode = featCode; goto end; } } var validation = await service.IsServiceTransactionValid(transaction); userCode = validation.UserCode; message = validation.Message; if (!validation.IsOK) { if (validation.Result == ServiceResultTypes.PurchaseRequired) { result = TransactionResultTypes.PurchaseRequired; } else { result = TransactionResultTypes.ChainServiceErrorResponse; } goto end; } result = TransactionResultTypes.Ok; nodeValidation = new TransactionValidation(transaction, _chainKeyIndex, _chainKey); end: return(new TransactionValidationResult(result, userCode, message, nodeValidation)); }