public async Task CanScheduleAndCancelSuspendNetwork() { var systemAddress = await _network.GetSystemFreezeAdminAddress(); if (systemAddress is null) { _network.Output?.WriteLine("TEST SKIPPED: No access to System Freeze Administrator Account."); return; } await using var client = _network.NewClient(); var receipt = await client.SuspendNetworkAsync(DateTime.UtcNow.AddSeconds(20), ctx => ctx.Payer = systemAddress); Assert.Equal(ResponseCode.Success, receipt.Status); receipt = await client.AbortNetworkUpgrade(ctx => ctx.Payer = systemAddress); Assert.Equal(ResponseCode.Success, receipt.Status); await Task.Delay(TimeSpan.FromSeconds(30)); // Confirm network is still up and running. var info = await client.GetAccountInfoAsync(_network.Payer); Assert.Equal(_network.Payer, info.Address); }
public async Task CanSuspendNetwork() { var systemAddress = await _network.GetSystemFreezeAdminAddress(); if (systemAddress is null) { _network.Output?.WriteLine("TEST SKIPPED: No access to System Freeze Administrator Account."); return; } await using var client = _network.NewClient(); var suspendParameters = new SuspendNetworkParams { Starting = TimeSpan.FromSeconds(5), Duration = TimeSpan.FromSeconds(60) }; var receipt = await client.SuspendNetworkAsync(suspendParameters, ctx => ctx.Payer = systemAddress); Assert.Equal(ResponseCode.Success, receipt.Status); await Task.Delay(TimeSpan.FromSeconds(30)); var pex = await Assert.ThrowsAsync <PrecheckException>(async() => { await client.GetAccountInfoAsync(_network.Payer); }); Assert.Equal(ResponseCode.PlatformNotActive, pex.Status); Assert.StartsWith("Transaction Failed Pre-Check: PlatformNotActive", pex.Message); await Task.Delay(TimeSpan.FromSeconds(50)); var info = await client.GetAccountInfoAsync(_network.Payer); Assert.Equal(_network.Payer, info.Address); }
public async Task CanGetInfoForAccountAsync() { await using var client = _network.NewClient(); var account = _network.Payer; var info = await client.GetAccountInfoAsync(account); Assert.NotNull(info.Address); Assert.Equal(account.RealmNum, info.Address.RealmNum); Assert.Equal(account.ShardNum, info.Address.ShardNum); Assert.Equal(account.AccountNum, info.Address.AccountNum); Assert.NotNull(info.SmartContractId); Assert.False(info.Deleted); Assert.NotNull(info.Proxy); Assert.True(info.Proxy.RealmNum > -1); Assert.True(info.Proxy.ShardNum > -1); Assert.True(info.Proxy.AccountNum > -1); Assert.Equal(0, info.ProxiedToAccount); Assert.Equal(new Endorsement(_network.PublicKey), info.Endorsement); Assert.True(info.Balance > 0); Assert.True(info.SendThresholdCreateRecord > 0); Assert.True(info.ReceiveThresholdCreateRecord > 0); Assert.False(info.ReceiveSignatureRequired); // At the moment, it appears this is off. //Assert.True(info.Expiration > DateTime.UtcNow); Assert.True(info.AutoRenewPeriod.TotalSeconds > 0); }
public async Task CanUpdateKey() { var originalKeyPair = Generator.KeyPair(); var updatedKeyPair = Generator.KeyPair(); await using var client = _network.NewClient(); var createResult = await client.CreateAccountAsync(new CreateAccountParams { InitialBalance = 1, PublicKey = originalKeyPair.publicKey }); Assert.Equal(ResponseCode.Success, createResult.Status); var originalInfo = await client.GetAccountInfoAsync(createResult.Address); Assert.Equal(new Endorsement(originalKeyPair.publicKey), originalInfo.Endorsement); var updateResult = await client.UpdateAccountAsync(new UpdateAccountParams { Account = new Account(createResult.Address, originalKeyPair.privateKey, updatedKeyPair.privateKey), Endorsement = new Endorsement(updatedKeyPair.publicKey) }); Assert.Equal(ResponseCode.Success, updateResult.Status); var updatedInfo = await client.GetAccountInfoAsync(createResult.Address); Assert.Equal(new Endorsement(updatedKeyPair.publicKey), updatedInfo.Endorsement); }
public async Task CanGetInfoForAccountAsync() { await using var client = _network.NewClient(); var account = _network.Payer; var info = await client.GetAccountInfoAsync(account); Assert.NotNull(info.Address); Assert.Equal(account.RealmNum, info.Address.RealmNum); Assert.Equal(account.ShardNum, info.Address.ShardNum); Assert.Equal(account.AccountNum, info.Address.AccountNum); Assert.NotNull(info.SmartContractId); Assert.False(info.Deleted); Assert.NotNull(info.Proxy); Assert.Equal(new Address(0, 0, 0), info.Proxy); Assert.Equal(0, info.ProxiedToAccount); Assert.Equal(new Endorsement(_network.PublicKey), info.Endorsement); Assert.True(info.Balance > 0); Assert.False(info.ReceiveSignatureRequired); Assert.True(info.AutoRenewPeriod.TotalSeconds > 0); Assert.True(info.Expiration > DateTime.MinValue); Assert.Equal(0, info.AssetCount); Assert.Equal(0, info.AutoAssociationLimit); Assert.Equal(Alias.None, info.Alias); AssertHg.NotEmpty(info.Ledger); }
public async Task CanGetAddressBook() { var client = _network.NewClient(); var book = await client.GetAddressBookAsync(); Assert.NotNull(book); Assert.NotEmpty(book); }
public async Task CanGetExchangeRates() { var client = _network.NewClient(); var rate = await client.GetExchangeRatesAsync(); Assert.NotNull(rate); Assert.NotNull(rate.Current); Assert.NotNull(rate.Next); }
public async Task CanGetAddressBook() { var client = _network.NewClient(); var book = await client.GetAddressBookAsync(); Assert.NotNull(book); Assert.NotEmpty(book); Assert.Equal(book.Length, book.ToDictionary(n => n.Id).Count); }
public async Task MissingBalanceContractAccountThrowsException() { await using var client = _network.NewClient(); var ex = await Assert.ThrowsAsync <ArgumentNullException>(async() => { var balance = await client.GetContractBalanceAsync(null); }); Assert.StartsWith("Contract Address is missing.", ex.Message); }
public async Task EmptyTransactionIdThrowsError() { await using var client = _network.NewClient(); var ane = await Assert.ThrowsAsync <ArgumentNullException>(async() => { await client.GetTransactionRecordAsync(null); }); Assert.Equal("transaction", ane.ParamName); Assert.StartsWith("Transaction is missing. Please check that it is not null.", ane.Message); }
public async Task DeletingNonExistantClaimThrowsError() { await using var client = _network.NewClient(); var excepiton = await Assert.ThrowsAsync <PrecheckException>(async() => { await client.GetClaimAsync(_network.Payer, Generator.SHA384Hash()); }); Assert.Equal(ResponseCode.ClaimNotFound, excepiton.Status); Assert.StartsWith("Transaction Failed Pre-Check: ClaimNotFound", excepiton.Message); }
public async Task DeleteContractWithoutAdminKeyRaisesError() { await using var fxContract = await GreetingContract.CreateAsync(_network); await using var client = _network.NewClient(); var tex = await Assert.ThrowsAsync <TransactionException>(async() => { await client.DeleteContractAsync(fxContract.ContractRecord.Contract, _network.Payer); }); Assert.Equal(ResponseCode.InvalidSignature, tex.Status); Assert.StartsWith("Unable to delete contract, status: InvalidSignature", tex.Message); }
public async Task SubmitUnsafeTransaction() { await using var client = _network.NewClient(); var systemAddress = await _network.GetSystemAccountAddress(); if (systemAddress is null) { _network.Output?.WriteLine("TEST SKIPPED: No access to System Administrator Account."); return; } // Ok, lets build a TX from Scratch, Including a Signature var txid = client.CreateNewTxId(); var transfers = new Proto.TransferList(); transfers.AccountAmounts.Add(new Proto.AccountAmount { AccountID = new Proto.AccountID(_network.Payer), Amount = -1 }); transfers.AccountAmounts.Add(new Proto.AccountAmount { AccountID = new Proto.AccountID(_network.Gateway), Amount = 1 }); var body = new Proto.TransactionBody { TransactionID = new Proto.TransactionID(txid), NodeAccountID = new Proto.AccountID(_network.Gateway), TransactionFee = 30_00_000_000, TransactionValidDuration = new Proto.Duration { Seconds = 180 }, Memo = "Unsafe Test", CryptoTransfer = new Proto.CryptoTransferTransactionBody { Transfers = transfers } }; var invoice = new Invoice(body, 6); await(_network.Signatory as ISignatory).SignAsync(invoice); var transaction = new Proto.Transaction { SignedTransactionBytes = invoice.GenerateSignedTransactionFromSignatures().ToByteString() }; var receipt = await client.SubmitUnsafeTransactionAsync(transaction.ToByteArray(), ctx => ctx.Payer = systemAddress); Assert.Equal(ResponseCode.Success, receipt.Status); Assert.Equal(txid, receipt.Id); }
public async Task CanGetTinybarBalanceForAccountAsync() { await using var client = _network.NewClient(); var account = _network.Payer; var balance = await client.GetAccountBalanceAsync(account); Assert.True(balance > 0, "Account Balance should be greater than zero."); }
public async Task CanGetCreateTxId() { await using var client = _network.NewClient(); var txId = client.CreateNewTxId(); Assert.NotNull(txId); }
public async Task CanCreateATopicWithReceiptAsync() { await using var client = _network.NewClient(); var receipt = await client.CreateTopicAsync(new CreateTopicParams { Memo = "Receipt Version" }); Assert.NotNull(receipt); Assert.NotNull(receipt.Topic); Assert.True(receipt.Topic.AccountNum > 0); Assert.Equal(ResponseCode.Success, receipt.Status); var info = await client.GetTopicInfoAsync(receipt.Topic); Assert.Equal("Receipt Version", info.Memo); Assert.NotEmpty(info.RunningHash.ToArray()); Assert.Equal(0UL, info.SequenceNumber); Assert.True(info.Expiration > DateTime.MinValue); Assert.Null(info.Administrator); Assert.Null(info.Participant); Assert.True(info.AutoRenewPeriod > TimeSpan.MinValue); Assert.Null(info.RenewAccount); AssertHg.NotEmpty(info.Ledger); }
public static async Task <TestTopic> CreateAsync(NetworkCredentials networkCredentials, Action <TestTopic> customize = null) { var fx = new TestTopic(); fx.Network = networkCredentials; fx.Network.Output?.WriteLine("STARTING SETUP: Test Topic Instance"); fx.Memo = "Test Topic: " + Generator.Code(20); (fx.AdminPublicKey, fx.AdminPrivateKey) = Generator.KeyPair(); (fx.ParticipantPublicKey, fx.ParticipantPrivateKey) = Generator.KeyPair(); fx.Payer = networkCredentials.Payer; fx.Client = networkCredentials.NewClient(); fx.TestAccount = await TestAccount.CreateAsync(networkCredentials); fx.Signatory = new Signatory(fx.AdminPrivateKey, fx.ParticipantPrivateKey, fx.TestAccount.PrivateKey); fx.Params = new CreateTopicParams { Memo = fx.Memo, Administrator = fx.AdminPublicKey, Participant = fx.ParticipantPublicKey, RenewAccount = fx.TestAccount.Record.Address, Signatory = fx.Signatory }; customize?.Invoke(fx); fx.Record = await fx.Client.RetryKnownNetworkIssues(async client => { return(await fx.Client.CreateTopicWithRecordAsync(fx.Params, ctx => { ctx.Memo = "TestTopic Setup: " + fx.Memo ?? "(null memo)"; })); }); Assert.Equal(ResponseCode.Success, fx.Record.Status); networkCredentials.Output?.WriteLine("SETUP COMPLETED: Test Topic Instance"); return(fx); }
public static async Task <TestFile> CreateAsync(NetworkCredentials networkCredentials, Action <TestFile> customize = null) { var test = new TestFile(); test.Network = networkCredentials; test.Network.Output?.WriteLine("STARTING SETUP: Test File Instance"); (test.PublicKey, test.PrivateKey) = Generator.KeyPair(); test.Payer = networkCredentials.Payer; test.Client = networkCredentials.NewClient(); test.CreateParams = new CreateFileParams { Memo = Generator.Code(20), Expiration = Generator.TruncateToSeconds(DateTime.UtcNow.AddSeconds(7890000)), Endorsements = new Endorsement[] { test.PublicKey }, Contents = Encoding.Unicode.GetBytes("Hello From .NET" + Generator.Code(50)).Take(48).ToArray(), Signatory = test.PrivateKey }; customize?.Invoke(test); test.Record = await test.Client.RetryKnownNetworkIssues(async client => { return(await test.Client.CreateFileWithRecordAsync(test.CreateParams, ctx => { ctx.Memo = "TestFileInstance Setup: Creating Test File on Network"; })); }); Assert.Equal(ResponseCode.Success, test.Record.Status); networkCredentials.Output?.WriteLine("SETUP COMPLETED: Test File Instance"); return(test); }
public static async Task <TestAliasAccount> CreateAsync(NetworkCredentials networkCredentials, Action <TestAliasAccount> customize = null) { var fx = new TestAliasAccount(); networkCredentials.Output?.WriteLine("STARTING SETUP: Pay to Alias Account Instance"); (fx.PublicKey, fx.PrivateKey) = Generator.KeyPair(); fx.Network = networkCredentials; fx.Client = networkCredentials.NewClient(); fx.Alias = new Alias(fx.PublicKey); fx.InitialTransfer = Generator.Integer(1_00_000_000, 2_00_000_000); customize?.Invoke(fx); fx.TransactionRecord = await fx.Client.RetryKnownNetworkIssues(async client => { return(await fx.Client.TransferWithRecordAsync(fx.Network.Payer, fx.Alias, fx.InitialTransfer, ctx => { ctx.Memo = "Test Account Instance: Creating Test Account on Network"; })); }); var createTransactionId = new TxId(fx.TransactionRecord.Id.Address, fx.TransactionRecord.Id.ValidStartSeconds, fx.TransactionRecord.Id.ValidStartNanos, false, 1); Assert.Equal(ResponseCode.Success, fx.TransactionRecord.Status); fx.CreateRecord = await fx.Client.GetTransactionRecordAsync(createTransactionId) as CreateAccountRecord; Assert.NotNull(fx.CreateRecord); networkCredentials.Output?.WriteLine("SETUP COMPLETED: Pay to Alias Account Instance"); return(fx); }
public static async Task <TestAccount> CreateAsync(NetworkCredentials networkCredentials, Action <TestAccount> customize = null) { var fx = new TestAccount(); networkCredentials.Output?.WriteLine("STARTING SETUP: Test Account Instance"); (fx.PublicKey, fx.PrivateKey) = Generator.KeyPair(); fx.Network = networkCredentials; fx.Client = networkCredentials.NewClient(); fx.CreateParams = new CreateAccountParams { Endorsement = fx.PublicKey, InitialBalance = (ulong)Generator.Integer(10, 20), Memo = Generator.String(10, 20), AutoAssociationLimit = Generator.Integer(5, 10) }; customize?.Invoke(fx); fx.Record = await fx.Client.RetryKnownNetworkIssues(async client => { return(await fx.Client.CreateAccountWithRecordAsync(fx.CreateParams, ctx => { ctx.Memo = "Test Account Instance: Creating Test Account on Network"; })); }); Assert.Equal(ResponseCode.Success, fx.Record.Status); networkCredentials.Output?.WriteLine("SETUP COMPLETED: Test Account Instance"); return(fx); }
public async Task NetworkForcesDelayOnTransactionForwardInTime() { await using var client = _network.NewClient(); var account = _network.Payer; var startInstant = Epoch.UniqueClockNanos(); var info = await client.GetAccountBalanceAsync(account, ctx => { ctx.Transaction = Protobuf.FromTransactionId(new Proto.TransactionID { AccountID = Protobuf.ToAccountID(_network.Payer), TransactionValidStart = Protobuf.ToTimestamp(DateTime.UtcNow.AddSeconds(6)) }); }); var duration = Epoch.UniqueClockNanos() - startInstant; Assert.InRange(duration, 4_000_000_000L, 240_000_000_000L); }
public async Task CanCreateAccountAsync() { var initialBalance = (ulong)Generator.Integer(10, 200); var(publicKey1, privateKey1) = Generator.KeyPair(); var(publicKey2, privateKey2) = Generator.KeyPair(); var endorsement = new Endorsement(publicKey1, publicKey2); var signatory = new Signatory(privateKey1, privateKey2); var client = _network.NewClient(); var createResult = await client.CreateAccountAsync(new CreateAccountParams { InitialBalance = initialBalance, Endorsement = endorsement }); Assert.NotNull(createResult); Assert.NotNull(createResult.Address); Assert.Equal(_network.ServerRealm, createResult.Address.RealmNum); Assert.Equal(_network.ServerShard, createResult.Address.ShardNum); Assert.True(createResult.Address.AccountNum > 0); var info = await client.GetAccountInfoAsync(createResult.Address); Assert.Equal(initialBalance, info.Balance); Assert.Equal(createResult.Address.RealmNum, info.Address.RealmNum); Assert.Equal(createResult.Address.ShardNum, info.Address.ShardNum); Assert.Equal(createResult.Address.AccountNum, info.Address.AccountNum); Assert.Equal(endorsement, info.Endorsement); Assert.Equal(new Address(0, 0, 0), info.Proxy); Assert.False(info.Deleted); // Move remaining funds back to primary account. var from = createResult.Address; await client.TransferAsync(from, _network.Payer, (long)initialBalance, signatory); var receipt = await client.DeleteAccountAsync(createResult.Address, _network.Payer, signatory); Assert.NotNull(receipt); Assert.Equal(ResponseCode.Success, receipt.Status); var exception = await Assert.ThrowsAsync <PrecheckException>(async() => { await client.GetAccountInfoAsync(createResult.Address); }); Assert.StartsWith("Transaction Failed Pre-Check: AccountDeleted", exception.Message); }
public async Task SignatureMapNoPrefixWithTrimOfZeroAndOneSignature() { await using var client = _network.NewClient(); var(_, privateKey) = Generator.Ed25519KeyPair(); var invoice = new Invoice(new Proto.TransactionBody { TransactionID = new Proto.TransactionID(client.CreateNewTxId()), Memo = Generator.String(20, 30) }, 0); var signatory = new Signatory(CustomSigner); await(signatory as ISignatory).SignAsync(invoice); var signedTransaction = invoice.GenerateSignedTransactionFromSignatures(); var signatureMap = signedTransaction.SigMap; Assert.Single(signatureMap.SigPair); Assert.Empty(signatureMap.SigPair[0].PubKeyPrefix); Task CustomSigner(IInvoice invoice) { var signingKey = TestKeys.ImportPrivateEd25519KeyFromBytes(privateKey); var prefix = signingKey.PublicKey.Export(KeyBlobFormat.PkixPublicKey).ToArray(); var signature = SignatureAlgorithm.Ed25519.Sign(signingKey, invoice.TxBytes.Span); invoice.AddSignature(KeyType.Ed25519, prefix, signature); return(Task.CompletedTask); } }
public async Task CanGetListOfDuplicateReceipts() { for (int tries = 0; tries < 5; tries++) { var duplicates = Generator.Integer(10, 15); var passedPrecheck = duplicates; await using var client = _network.NewClient(); var txid = client.CreateNewTxId(); var tasks = new Task[duplicates]; for (var i = 0; i < duplicates; i++) { tasks[i] = client.TransferAsync(_network.Payer, _network.Gateway, 1, ctx => ctx.Transaction = txid); } for (var i = 0; i < duplicates; i++) { try { await tasks[i]; } catch { passedPrecheck--; } } if (passedPrecheck == 0) { // Start over. continue; } for (int getTries = 0; getTries < 5; getTries++) { var receipts = await client.GetAllReceiptsAsync(txid); // We still have random timing issues for this check if (passedPrecheck == receipts.Count) { Assert.Equal(1, receipts.Count(t => t.Status == ResponseCode.Success)); Assert.Equal(passedPrecheck - 1, receipts.Count(t => t.Status == ResponseCode.DuplicateTransaction)); return; } } await Task.Delay(1000); } _network.Output?.WriteLine("TEST INCONCLUSIVE, UNABLE TO CREATE DUPLICATE TRANSACTIONS THIS TIME AROUND."); }
public async Task CanGetNetworkVersionInfo() { await using var client = _network.NewClient(); var info = await client.GetVersionInfoAsync(); Assert.NotNull(info); AssertHg.SemanticVersionGreaterOrEqualThan(new SemanticVersion(0, 21, 2), info.ApiProtobufVersion); AssertHg.SemanticVersionGreaterOrEqualThan(new SemanticVersion(0, 21, 2), info.HederaServicesVersion); }
public async Task CanTransferCryptoToGatewayNode() { long fee = 0; long transferAmount = 10; await using var client = _network.NewClient(); client.Configure(ctx => fee = ctx.FeeLimit); var fromAccount = _network.Payer; var toAddress = _network.Gateway; var balanceBefore = await client.GetAccountBalanceAsync(fromAccount); var receipt = await client.TransferAsync(fromAccount, toAddress, transferAmount); var balanceAfter = await client.GetAccountBalanceAsync(fromAccount); var maxFee = (ulong)(3 * fee); Assert.InRange(balanceAfter, balanceBefore - (ulong)transferAmount - maxFee, balanceBefore - (ulong)transferAmount); }
public async Task DeleteContractWithoutAdminKeyRaisesError() { var(publicKey, privateKey) = Generator.KeyPair(); await using var fx = await GreetingContract.SetupAsync(_network); fx.ContractParams.Administrator = publicKey; // Default is to use Payor's fx.Client.Configure(ctx => ctx.Payer = _network.PayerWithKeys(privateKey)); await fx.CompleteCreateAsync(); await using (var client = _network.NewClient()) // Will not have private key { var tex = await Assert.ThrowsAsync <TransactionException>(async() => { await client.DeleteContractAsync(fx.ContractRecord.Contract, _network.Payer); }); Assert.Equal(ResponseCode.InvalidSignature, tex.Status); Assert.StartsWith("Unable to delete contract, status: InvalidSignature", tex.Message); } }
public async Task CallingDeleteWithMissingTopicIDRaisesError() { await using var client = _network.NewClient(); var ane = await Assert.ThrowsAsync <ArgumentNullException>(async() => { await client.DeleteTopicAsync(null); }); Assert.Equal("topic", ane.ParamName); Assert.StartsWith("Topic Address is missing. Please check that it is not null.", ane.Message); }
public async Task EmptyAccountRaisesError() { await using var client = _network.NewClient(); var ane = await Assert.ThrowsAsync <ArgumentNullException>(async() => { await client.GetAccountRecordsAsync(null); }); Assert.Equal("address", ane.ParamName); Assert.StartsWith("Account Address is missing. Please check that it is not null.", ane.Message); }
public async Task GetStakersIsNotImplemented() { await using var client = _network.NewClient(); var pex = await Assert.ThrowsAsync <PrecheckException>(async() => { await client.GetStakers(_network.Payer); }); Assert.Equal(ResponseCode.NotSupported, pex.Status); Assert.StartsWith("Transaction Failed Pre-Check: NotSupported", pex.Message); }