Ejemplo n.º 1
0
        public byte[] TxSignature(ImmutableArray <byte> scriptPubKey, Transaction tx, int inputIndex, byte hashType)
        {
            ///TODO
            Debug.Assert(inputIndex < tx.Inputs.Length);

            // Blank out other inputs' signatures
            var empty     = ImmutableArray.Create <byte>();
            var newInputs = new TxInput[tx.Inputs.Length];

            for (var i = 0; i < tx.Inputs.Length; i++)
            {
                var oldInput = tx.Inputs[i];
                var newInput = oldInput.With(scriptSignature: i == inputIndex ? scriptPubKey : empty);
                newInputs[i] = newInput;
            }

            //// Blank out some of the outputs
            //if ((hashType & 0x1F) == (int)ScriptHashType.SIGHASH_NONE)
            //{
            //    //TODO
            //    Debug.Assert(false);

            //    // Wildcard payee

            //    // Let the others update at will
            //}
            //else if ((hashType & 0x1F) == (int)ScriptHashType.SIGHASH_SINGLE)
            //{
            //    //TODO
            //    Debug.Assert(false);

            //    // Only lock-in the txout payee at same index as txin

            //    // Let the others update at will
            //}

            //// Blank out other inputs completely, not recommended for open transactions
            //if ((hashType & 0x80) == (int)ScriptHashType.SIGHASH_ANYONECANPAY)
            //{
            //    //TODO
            //    Debug.Assert(false);
            //}

            // create simplified transaction
            var newTx = tx.With(Inputs: newInputs.ToImmutableArray());

            // return wire-encoded simplified transaction with the 4-byte hashType tacked onto the end
            var stream = new MemoryStream();

            using (var writer = new BinaryWriter(stream))
            {
                writer.WriteBytes(DataCalculator.EncodeTransaction(newTx));
                writer.Write4Bytes(hashType);

                return(stream.ToArray());
            }
        }
Ejemplo n.º 2
0
        public void TestReadOneLoadingTx()
        {
            var coreStorageMock = new Mock <ICoreStorage>();

            // create a fake transaction with 4 inputs
            var prevTxCount   = 4;
            var txIndex       = 1;
            var chainedHeader = RandomData.RandomChainedHeader();

            // create previous transactions for 4 inputs
            var prevTxes = new Transaction[prevTxCount];
            var inputs   = new TxInput[prevTxCount];

            for (var i = 0; i < prevTxCount; i++)
            {
                var prevTx      = RandomData.RandomTransaction();
                var prevBlockTx = (BlockTx)BlockTx.Create(i, prevTx);

                prevTxes[i] = prevTx;
                inputs[i]   = new TxInput(prevTx.Hash, 0, ImmutableArray.Create <byte>(), 0);

                // mock retrieval of the previous transaction
                coreStorageMock.Setup(coreStorage => coreStorage.TryGetTransaction(UInt256.Zero, i, out prevBlockTx)).Returns(true);
            }

            // create a loading tx with the 4 inputs referencing block hash 0
            var tx = RandomData.RandomTransaction(new RandomDataOptions {
                TxOutputCount = 1
            })
                     .CreateWith(Inputs: inputs.ToImmutableArray()).Transaction;
            var prevOutputTxKeys = ImmutableArray.CreateRange(
                Enumerable.Range(0, prevTxCount).Select(x => new TxLookupKey(UInt256.Zero, x)));
            var loadingTx = new LoadingTx(txIndex, tx, chainedHeader, prevOutputTxKeys);

            // begin queuing transactions to load
            var loadingTxes = new BufferBlock <LoadingTx>();

            loadingTxes.Post(loadingTx);
            loadingTxes.Complete();

            // begin transaction loading
            var txLoader = TxLoader.LoadTxes(coreStorageMock.Object, loadingTxes);

            // verify the loaded transaction
            var loadedTxesBuffer = new BufferBlock <LoadedTx>();

            txLoader.LinkTo(loadedTxesBuffer, new DataflowLinkOptions {
                PropagateCompletion = true
            });
            txLoader.Completion.Wait();

            IList <LoadedTx> actualLoadedTxes;

            Assert.IsTrue(loadedTxesBuffer.TryReceiveAll(out actualLoadedTxes));

            var actualLoadedTx = actualLoadedTxes.Single();

            Assert.AreEqual(loadingTx.TxIndex, actualLoadedTx.TxIndex);
            Assert.AreEqual(loadingTx.Transaction, actualLoadedTx.Transaction);
            CollectionAssert.AreEqual(prevTxes.Select(x => x.Hash).ToArray(), actualLoadedTx.InputTxes.Select(x => x.Hash).ToArray());
        }