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); }
public TxFailureTest() { var random = new Random(); _blockHash = random.NextBlockHash(); _txid = random.NextTxId(); _fx = new TxFailure(_blockHash, _txid, new ArgumentNullException("foo")); }
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); }
/// <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); }
/// <inheritdoc cref="IStore.PutTxExecution(Libplanet.Tx.TxFailure)"/> public void PutTxExecution(TxFailure txFailure) => _store.PutTxExecution(txFailure);
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)); }
/// <inheritdoc cref="BaseStore.PutTxExecution(Libplanet.Tx.TxFailure)"/> public override void PutTxExecution(TxFailure txFailure) => _txExecutionDb.Put( TxExecutionKey(txFailure), Codec.Encode(SerializeTxExecution(txFailure)) );
public void PutTxExecution(TxFailure txFailure) { Log(nameof(PutTxExecution), txFailure); _store.PutTxExecution(txFailure); }
/// <inheritdoc cref="IStore.PutTxExecution(TxFailure)"/> public virtual void PutTxExecution(TxFailure txFailure) => Store.PutTxExecution(txFailure);
/// <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)); }