}; //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); }
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 static Types.Block AddTx(this Types.Block bk, Types.Transaction tx) { //var nonce = new byte[10]; //new Random().NextBytes(nonce); var nonce = new byte[] { }; var header = new Types.BlockHeader( 0, new byte[] { }, bk.header.blockNumber + 1, new byte[] { }, new byte[] { }, new byte[] { }, ListModule.OfSeq <byte[]>(new List <byte[]>()), DateTime.Now.ToUniversalTime().Ticks, 0, nonce ); var txs = bk.transactions.ToList(); txs.Add(tx); return(new Types.Block(bk.header, ListModule.OfSeq <Types.Transaction>(txs))); }
public bool IsDoubleSpend(TransactionContext dbTx, Types.Transaction tx, bool isBlock) { foreach (var input in tx.inputs) { if (!isBlock) { foreach (var item in memPool.TxPool) { foreach (var pInput in item.Value.pInputs) { if (input.Equals(pInput.Item1)) { return(true); } } } } if (BlockStore.TxStore.ContainsKey(dbTx, input.txHash) && BlockStore.TxStore.Get(dbTx, input.txHash).Value.InMainChain&& !UTXOStore.ContainsKey(dbTx, input.txHash, input.index)) { return(true); } } return(false); }
//demo private byte[] GetHash(Types.Transaction transaction) { // if (transaction.Transaction != null) return(Merkle.transactionHasher.Invoke(transaction)); // else // return Merkle.blockHasher.Invoke(transaction.Block); }
public void ShouldAddGenesisWithTx() { _Key = Key.Create(); _GenesisTx = Utils.GetTx().AddOutput(_Key.Address, Consensus.Tests.zhash, 100).Tag("genesis tx"); _GenesisBlock = _GenesisBlock.AddTx(_GenesisTx); Assert.That(HandleBlock(_GenesisBlock), Is.EqualTo(BlockVerificationHelper.BkResultEnum.Accepted)); }
public static Types.Transaction AddInput(this Types.Transaction tx, Types.Outpoint outpoint) { return(new Types.Transaction(tx.version, FSharpList <Types.Outpoint> .Cons(outpoint, tx.inputs), tx.witnesses, tx.outputs, tx.contract)); }
public static Types.Transaction SetContract(this Types.Transaction tx, Types.ExtendedContract extendedContract) { return(new Types.Transaction(tx.version, tx.inputs, tx.witnesses, tx.outputs, new Microsoft.FSharp.Core.FSharpOption <Types.ExtendedContract>(extendedContract))); }
public TxDelta(TxStateEnum txState, byte[] txHash, Types.Transaction transaction, AssetDeltas assetDeltas, DateTime time) { TxState = txState; TxHash = txHash; Transaction = transaction; AssetDeltas = assetDeltas; Time = time; }
protected void RegisterTxEvent(Types.Transaction tx, TxStateEnum txState) { _TxStateEvents[Merkle.transactionHasher.Invoke(tx)] = new Tuple <ManualResetEvent, TxStateEnum>( new ManualResetEvent(false), txState ); }
// 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); }
internal void OnTransactionBroadcasted(Types.Transaction tx) { var evt = TransactionBroadcasted; if (evt != null) { evt(tx); } }
internal void OnTransactionRejected(Types.Transaction tx, RejectPayload reject) { var evt = TransactionRejected; if (evt != null) { evt(tx, reject); } }
bool IsCoinbaseTxValid(Types.Transaction tx) { //TODO: check maturity return(tx.witnesses.Count() > 0 && tx.witnesses[0].Length > 0 && BitConverter.ToUInt32(tx.witnesses[0], 0) == _Bk.header.blockNumber); return(true); }
public void Put( TransactionContext transactionContext, byte[] txHash, Types.Transaction tx, bool inMainChain) { Put(transactionContext, txHash, new Transaction { Tx = tx, InMainChain = inMainChain }); }
//void _Builder_NewTransaction(Types.Transaction obj) //{ // _Transactions.AddOrReplace(obj.GetHash(), obj); // BroadcastCore(obj); //} void _BlockChain_OnAddedToMempool(Types.Transaction transaction) { foreach (var other in Nodes) { if (other != AttachedNode && other.State == NodeState.HandShaked) { other.SendMessageAsync(new InvPayload(transaction)); } } }
protected TxStateEnum?TxState(Types.Transaction tx) { var key = Merkle.transactionHasher.Invoke(tx); if (_TxStates.ContainsKey(key)) { return(_TxStates[key]); } return(null); }
internal void OnBroadcastTransaction(Types.Transaction transaction) { var nodes = Nodes .Select(n => n.Key.Behaviors.Find <BroadcastHubBehavior>()) .Where(n => n != null) .ToArray(); foreach (var node in nodes) { node.BroadcastTransactionCore(transaction); } }
public bool ContainsInputs(Types.Transaction tx) { foreach (var outpoint in tx.inputs) { if (ContainsOutpoint(outpoint)) { return(true); } } return(false); }
// 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 bool Parse(byte[] rawTxBytes, out Types.Transaction tx) { try { tx = Serialization.context.GetSerializer <Types.Transaction>().UnpackSingleObject(rawTxBytes); return(true); } catch { tx = null; return(false); } }
//demo private byte[] GetHash(Types.Transaction transaction) { try { // if (transaction.Transaction != null) return(Merkle.transactionHasher.Invoke(transaction)); // else // return Merkle.blockHasher.Invoke(transaction.Block); } catch (Exception e) { Console.WriteLine(e.Message); return(null); } }
/// <summary> /// Transmits a tx on the network. /// </summary> public Task <BlockChain.BlockChain.TxResultEnum> Transmit(Types.Transaction tx) { //TODO: refactor //TODO: if tx is known (and validated), just send it. return(new HandleTransactionAction { Tx = tx }.Publish().ContinueWith(t => { if (t.Result == BlockChain.BlockChain.TxResultEnum.Accepted && _BroadcastHubBehavior != null) { _BroadcastHubBehavior.BroadcastHub.BroadcastTransactionAsync(tx); } return t.Result; })); }
public new void OneTimeSetUp() { base.OneTimeSetUp(); block1_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block1_tx"); block2_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block2_tx"); block3_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block3_tx"); block4_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block4_tx"); block5_tx = Utils.GetTx().AddOutput(Key.Create().Address, Consensus.Tests.zhash, 1).Tag("block5_tx"); block1 = _GenesisBlock.Child().AddTx(block1_tx).Tag("block1"); block2 = _GenesisBlock.Child().AddTx(block2_tx).Tag("block2"); block3 = block2.Child().AddTx(block3_tx).Tag("block3"); block4 = block1.Child().AddTx(block4_tx).Tag("block4"); block5 = block4.Child().AddTx(block5_tx).Tag("block5"); }
bool AssembleAutoTx(byte[] contractHash, byte[] message, out Types.Transaction transaction, bool isWitness) { using (TransactionContext dbTx = _DBContext.GetTransactionContext()) { var utxoLookup = UtxoLookupFactory(dbTx, false); var contractFunction = ActiveContractSet.GetContractFunction(dbTx, contractHash); if (contractFunction != null) { return(ExecuteContract(contractHash, contractFunction, message, out transaction, utxoLookup, isWitness)); } transaction = null; return(false); } }
internal void BroadcastTransactionCore(Types.Transaction transaction) { if (transaction == null) { throw new ArgumentNullException("transaction"); } var tx = new TransactionBroadcast(); tx.Transaction = transaction; tx.State = BroadcastState.NotSent; var hash = GetHash(transaction); if (_HashToTransaction.TryAdd(hash, tx)) { Announce(tx, hash); } }
bool CheckUtxsSetContains(Types.Transaction tx) { var txHash = Merkle.transactionHasher.Invoke(tx); var utxos = new GetUTXOSetAction().Publish().Result; if (utxos.Item2.ContainsKey(txHash)) { foreach (var output in tx.outputs) { if (utxos.Item1[txHash].Contains(output)) { return(true); } } } return(false); }
internal void Put(TransactionContext dbTx, byte[] txHash, Types.Transaction tx, AssetDeltas assetDeltas, TxStateEnum txState) { var txHashRecord = dbTx.Transaction.Select <byte[], ulong>(TX_HASHES_TO_IDENTITY, txHash); var identity = txHashRecord.Exists ? txHashRecord.Value : dbTx.Transaction.Count(TX_HASHES_TO_IDENTITY); if (!txHashRecord.Exists) { dbTx.Transaction.Insert <byte[], ulong>(TX_HASHES_TO_IDENTITY, txHash, identity); } Put(dbTx, identity, new TxData() { DateTime = DateTime.Now.ToUniversalTime(), TxState = txState, Tx = tx, AssetDeltas = assetDeltas, TxHash = txHash, }); }
void CalculateCoinbase() { var reward = 1000u; var outputs = new List <Types.Output> { new Types.Output(Types.OutputLock.NewPKLock(_Address.Bytes), new Types.Spend(Tests.zhash, reward)) }; var witness = new List <byte[]> { BitConverter.GetBytes(_BlockChain.Tip.Value.header.blockNumber + 1) }; _Coinbase = new Types.Transaction( 0, ListModule.Empty <Types.Outpoint>(), ListModule.OfSeq(witness), ListModule.OfSeq(outputs), FSharpOption <Types.ExtendedContract> .None ); }
public void Render() { if (Value != null) { return; } var outputs = new List <Types.Output>(); for (var i = 0; i < Outputs; i++) { outputs.Add(Util.GetOutput()); } var inputs = new List <Types.Outpoint>(); foreach (Point point in Inputs) { point.RefTransaction.Render(); inputs.Add(new Types.Outpoint(point.RefTransaction.Value.Key, point.Index)); } var hashes = new List <byte[]>(); //hack Concensus into giving a different hash per each tx created var version = (uint)1; //_Random.Next(1000); Types.Transaction transaction = new Types.Transaction(version, ListModule.OfSeq(inputs), ListModule.OfSeq(hashes), ListModule.OfSeq(outputs), null); byte[] key = Merkle.transactionHasher.Invoke(transaction); Value = new Keyed <Types.Transaction>(key, transaction); TestTrace.Transaction(Tag, key); }