示例#1
0
        protected static IValue SerializeTxExecution(TxFailure txFailure)
        {
            Dictionary d = Dictionary.Empty
                           .Add("fail", true)
                           .Add("exc", txFailure.ExceptionName);

            return(txFailure.ExceptionMetadata is { } v?d.Add("excMeta", v) : d);
        }
示例#2
0
        public TxFailureTest()
        {
            var random = new Random();

            _blockHash = random.NextBlockHash();
            _txid      = random.NextTxId();
            _fx        = new TxFailure(_blockHash, _txid, new ArgumentNullException("foo"));
        }
示例#3
0
        public void Constructor()
        {
            var f = new TxFailure(_blockHash, _txid, nameof(ArgumentNullException), (Text)"foo");

            Assert.Equal(_blockHash, f.BlockHash);
            Assert.Equal(_txid, f.TxId);
            Assert.Equal(nameof(ArgumentNullException), f.ExceptionName);
            Assert.Equal((Text)"foo", f.ExceptionMetadata);
        }
示例#4
0
        /// <inheritdoc cref="BaseStore.PutTxExecution(Libplanet.Tx.TxFailure)"/>
        public override void PutTxExecution(TxFailure txFailure)
        {
            UPath path    = TxExecutionPath(txFailure);
            UPath dirPath = path.GetDirectory();

            CreateDirectoryRecursively(_txExecutions, dirPath);
            using Stream f =
                      _txExecutions.OpenFile(path, System.IO.FileMode.OpenOrCreate, FileAccess.Write);
            Codec.Encode(SerializeTxExecution(txFailure), f);
        }
示例#5
0
 /// <inheritdoc cref="IStore.PutTxExecution(Libplanet.Tx.TxFailure)"/>
 public void PutTxExecution(TxFailure txFailure) =>
 _store.PutTxExecution(txFailure);
示例#6
0
        public void TxExecution()
        {
            void AssertTxSuccessesEqual(TxSuccess expected, TxExecution actual)
            {
                Assert.IsType <TxSuccess>(actual);
                var success = (TxSuccess)actual;

                Assert.Equal(expected.TxId, success.TxId);
                Assert.Equal(expected.BlockHash, success.BlockHash);
                Assert.Equal(expected.UpdatedStates, success.UpdatedStates);
                Assert.Equal(expected.FungibleAssetsDelta, success.FungibleAssetsDelta);
                Assert.Equal(expected.UpdatedFungibleAssets, success.UpdatedFungibleAssets);
            }

            void AssertTxFailuresEqual(TxFailure expected, TxExecution actual)
            {
                Assert.IsType <TxFailure>(actual);
                var failure = (TxFailure)actual;

                Assert.Equal(expected.TxId, failure.TxId);
                Assert.Equal(expected.BlockHash, failure.BlockHash);
                Assert.Equal(expected.ExceptionName, failure.ExceptionName);
                Assert.Equal(expected.ExceptionMetadata, failure.ExceptionMetadata);
            }

            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId1));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId2));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId1));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId2));

            var random = new System.Random();
            var inputA = new TxSuccess(
                Fx.Hash1,
                Fx.TxId1,
                ImmutableDictionary <Address, IValue> .Empty.Add(
                    random.NextAddress(),
                    (Text)"state value"
                    ),
                ImmutableDictionary <Address, IImmutableDictionary <Currency, FAV> > .Empty
                .Add(
                    random.NextAddress(),
                    ImmutableDictionary <Currency, FAV> .Empty.Add(
                        DumbAction.DumbCurrency,
                        DumbAction.DumbCurrency * 5
                        )
                    ),
                ImmutableDictionary <Address, IImmutableDictionary <Currency, FAV> > .Empty
                .Add(
                    random.NextAddress(),
                    ImmutableDictionary <Currency, FAV> .Empty.Add(
                        DumbAction.DumbCurrency,
                        DumbAction.DumbCurrency * 10
                        )
                    )
                );

            Fx.Store.PutTxExecution(inputA);

            AssertTxSuccessesEqual(inputA, Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId1));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId2));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId1));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId2));

            var inputB = new TxFailure(
                Fx.Hash1,
                Fx.TxId2,
                "AnExceptionName",
                Dictionary.Empty.Add("foo", 1).Add("bar", "baz")
                );

            Fx.Store.PutTxExecution(inputB);

            AssertTxSuccessesEqual(inputA, Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId1));
            AssertTxFailuresEqual(inputB, Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId2));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId1));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId2));

            var inputC = new TxFailure(
                Fx.Hash2,
                Fx.TxId1,
                "AnotherExceptionName",
                null
                );

            Fx.Store.PutTxExecution(inputC);

            AssertTxSuccessesEqual(inputA, Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId1));
            AssertTxFailuresEqual(inputB, Fx.Store.GetTxExecution(Fx.Hash1, Fx.TxId2));
            AssertTxFailuresEqual(inputC, Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId1));
            Assert.Null(Fx.Store.GetTxExecution(Fx.Hash2, Fx.TxId2));
        }
示例#7
0
 /// <inheritdoc cref="BaseStore.PutTxExecution(Libplanet.Tx.TxFailure)"/>
 public override void PutTxExecution(TxFailure txFailure) =>
 _txExecutionDb.Put(
     TxExecutionKey(txFailure),
     Codec.Encode(SerializeTxExecution(txFailure))
     );
示例#8
0
 public void PutTxExecution(TxFailure txFailure)
 {
     Log(nameof(PutTxExecution), txFailure);
     _store.PutTxExecution(txFailure);
 }
示例#9
0
 /// <inheritdoc cref="IStore.PutTxExecution(TxFailure)"/>
 public virtual void PutTxExecution(TxFailure txFailure) =>
 Store.PutTxExecution(txFailure);
示例#10
0
 /// <inheritdoc cref="IStore.PutTxExecution(Libplanet.Tx.TxFailure)"/>
 public abstract void PutTxExecution(TxFailure txFailure);
 public void PutTxExecution(TxFailure txFailure) =>
 InternalStore.PutTxExecution(txFailure);
        public TransactionHeadlessQuery(StandaloneContext standaloneContext)
        {
            Field <NonNullGraphType <LongGraphType> >(
                name: "nextTxNonce",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <AddressType> > {
                Name = "address", Description = "Target address to query"
            }
                    ),
                resolve: context =>
            {
                if (!(standaloneContext.BlockChain is BlockChain <PolymorphicAction <ActionBase> > blockChain))
                {
                    throw new ExecutionError(
                        $"{nameof(StandaloneContext)}.{nameof(StandaloneContext.BlockChain)} was not set yet!");
                }

                Address address = context.GetArgument <Address>("address");
                return(blockChain.GetNextTxNonce(address));
            }
                );

            Field <TransactionType <NCAction> >(
                name: "getTx",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <TxIdType> >
            {
                Name = "txId", Description = "transaction id."
            }
                    ),
                resolve: context =>
            {
                if (!(standaloneContext.BlockChain is BlockChain <PolymorphicAction <ActionBase> > blockChain))
                {
                    throw new ExecutionError(
                        $"{nameof(StandaloneContext)}.{nameof(StandaloneContext.BlockChain)} was not set yet!");
                }

                var txId = context.GetArgument <TxId>("txId");
                return(blockChain.GetTransaction(txId));
            }
                );

            Field <NonNullGraphType <StringGraphType> >(
                name: "createUnsignedTx",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <StringGraphType> >
            {
                Name        = "publicKey",
                Description = "The base64-encoded public key for Transaction.",
            },
                    new QueryArgument <NonNullGraphType <StringGraphType> >
            {
                Name        = "plainValue",
                Description = "The base64-encoded plain value of action for Transaction.",
            }
                    ),
                resolve: context =>
            {
                if (!(standaloneContext.BlockChain is BlockChain <PolymorphicAction <ActionBase> > blockChain))
                {
                    throw new ExecutionError(
                        $"{nameof(StandaloneContext)}.{nameof(StandaloneContext.BlockChain)} was not set yet!");
                }

                string plainValueString = context.GetArgument <string>("plainValue");
                var plainValue          = new Bencodex.Codec().Decode(System.Convert.FromBase64String(plainValueString));
#pragma warning disable 612
                var action = new NCAction();
#pragma warning restore 612
                action.LoadPlainValue(plainValue);

                var publicKey  = new PublicKey(Convert.FromBase64String(context.GetArgument <string>("publicKey")));
                Address signer = publicKey.ToAddress();
                long nonce     = blockChain.GetNextTxNonce(signer);
                Transaction <NCAction> unsignedTransaction =
                    Transaction <NCAction> .CreateUnsigned(nonce, publicKey, blockChain.Genesis.Hash, new[] { action });
                return(Convert.ToBase64String(unsignedTransaction.Serialize(false)));
            });

            Field <NonNullGraphType <StringGraphType> >(
                name: "attachSignature",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <StringGraphType> >
            {
                Name        = "unsignedTransaction",
                Description = "The base64-encoded unsigned transaction to attach the given signature."
            },
                    new QueryArgument <NonNullGraphType <StringGraphType> >
            {
                Name        = "signature",
                Description = "The base64-encoded signature of the given unsigned transaction."
            }
                    ),
                resolve: context =>
            {
                byte[] signature = Convert.FromBase64String(context.GetArgument <string>("signature"));
                Transaction <NCAction> unsignedTransaction =
                    Transaction <NCAction> .Deserialize(
                        Convert.FromBase64String(context.GetArgument <string>("unsignedTransaction")),
                        false);
                Transaction <NCAction> signedTransaction = new Transaction <NCAction>(
                    unsignedTransaction.Nonce,
                    unsignedTransaction.Signer,
                    unsignedTransaction.PublicKey,
                    unsignedTransaction.GenesisHash,
                    unsignedTransaction.UpdatedAddresses,
                    unsignedTransaction.Timestamp,
                    unsignedTransaction.Actions,
                    signature);

                return(Convert.ToBase64String(signedTransaction.Serialize(true)));
            });

            Field <NonNullGraphType <TxResultType> >(
                name: "transactionResult",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <TxIdType> >
            {
                Name = "txId", Description = "transaction id."
            }
                    ),
                resolve: context =>
            {
                if (!(standaloneContext.BlockChain is BlockChain <PolymorphicAction <ActionBase> > blockChain))
                {
                    throw new ExecutionError(
                        $"{nameof(StandaloneContext)}.{nameof(StandaloneContext.BlockChain)} was not set yet!");
                }

                if (!(standaloneContext.Store is IStore store))
                {
                    throw new ExecutionError(
                        $"{nameof(StandaloneContext)}.{nameof(StandaloneContext.Store)} was not set yet!");
                }

                TxId txId = context.GetArgument <TxId>("txId");
                if (!(store.GetFirstTxIdBlockHashIndex(txId) is { } txExecutedBlockHash))
                {
                    return(blockChain.GetStagedTransactionIds().Contains(txId)
                            ? new TxResult(TxStatus.STAGING, null, null)
                            : new TxResult(TxStatus.INVALID, null, null));
                }

                try
                {
                    TxExecution execution = blockChain.GetTxExecution(txExecutedBlockHash, txId);
                    Block <PolymorphicAction <ActionBase> > txExecutedBlock = blockChain[txExecutedBlockHash];
                    return(execution switch
                    {
                        TxSuccess txSuccess => new TxResult(TxStatus.SUCCESS, txExecutedBlock.Index,
                                                            txExecutedBlock.Hash.ToString()),
                        TxFailure txFailure => new TxResult(TxStatus.FAILURE, txExecutedBlock.Index,
                                                            txExecutedBlock.Hash.ToString()),
                        _ => throw new NotImplementedException(
                            $"{nameof(execution)} is not expected concrete class.")
                    });
                }
                catch (Exception)
                {
                    return(new TxResult(TxStatus.INVALID, null, null));
                }
            }
        public void UpdateTxExecutions(bool getTxExecutionViaStore)
        {
            void AssertTxSuccessesEqual(TxSuccess expected, TxExecution actual)
            {
                Assert.IsType <TxSuccess>(actual);
                var success = (TxSuccess)actual;

                Assert.Equal(expected.TxId, success.TxId);
                Assert.Equal(expected.BlockHash, success.BlockHash);
                Assert.Equal(expected.UpdatedStates, success.UpdatedStates);
                Assert.Equal(expected.FungibleAssetsDelta, success.FungibleAssetsDelta);
                Assert.Equal(expected.UpdatedFungibleAssets, success.UpdatedFungibleAssets);
            }

            void AssertTxFailuresEqual(TxFailure expected, TxExecution actual)
            {
                Assert.IsType <TxFailure>(actual);
                var failure = (TxFailure)actual;

                Assert.Equal(expected.TxId, failure.TxId);
                Assert.Equal(expected.BlockHash, failure.BlockHash);
                Assert.Equal(expected.ExceptionName, failure.ExceptionName);
                Assert.Equal(expected.ExceptionMetadata, failure.ExceptionMetadata);
            }

            Func <BlockHash, TxId, TxExecution> getTxExecution
                = getTxExecutionViaStore
                ? (Func <BlockHash, TxId, TxExecution>)_blockChain.Store.GetTxExecution
                : _blockChain.GetTxExecution;

            Assert.Null(getTxExecution(_fx.Hash1, _fx.TxId1));
            Assert.Null(getTxExecution(_fx.Hash1, _fx.TxId2));
            Assert.Null(getTxExecution(_fx.Hash2, _fx.TxId1));
            Assert.Null(getTxExecution(_fx.Hash2, _fx.TxId2));

            var random = new System.Random();
            var inputA = new TxSuccess(
                _fx.Hash1,
                _fx.TxId1,
                ImmutableDictionary <Address, IValue> .Empty.Add(
                    random.NextAddress(),
                    (Text)"state value"
                    ),
                ImmutableDictionary <Address, IImmutableDictionary <Currency, FAV> > .Empty
                .Add(
                    random.NextAddress(),
                    ImmutableDictionary <Currency, FAV> .Empty.Add(
                        DumbAction.DumbCurrency,
                        DumbAction.DumbCurrency * 5
                        )
                    ),
                ImmutableDictionary <Address, IImmutableDictionary <Currency, FAV> > .Empty
                .Add(
                    random.NextAddress(),
                    ImmutableDictionary <Currency, FAV> .Empty.Add(
                        DumbAction.DumbCurrency,
                        DumbAction.DumbCurrency * 10
                        )
                    )
                );
            var inputB = new TxFailure(
                _fx.Hash1,
                _fx.TxId2,
                "AnExceptionName",
                Dictionary.Empty.Add("foo", 1).Add("bar", "baz")
                );
            var inputC = new TxFailure(
                _fx.Hash2,
                _fx.TxId1,
                "AnotherExceptionName",
                null
                );

            _blockChain.UpdateTxExecutions(new TxExecution[] { inputA, inputB, inputC });

            AssertTxSuccessesEqual(inputA, getTxExecution(_fx.Hash1, _fx.TxId1));
            AssertTxFailuresEqual(inputB, getTxExecution(_fx.Hash1, _fx.TxId2));
            AssertTxFailuresEqual(inputC, getTxExecution(_fx.Hash2, _fx.TxId1));
            Assert.Null(getTxExecution(_fx.Hash2, _fx.TxId2));
        }