public async Task CanMineVotingRequestTransactionAsync() { var network = new TestPoACollateralNetwork(true, Guid.NewGuid().ToString()); using (PoANodeBuilder builder = PoANodeBuilder.CreatePoANodeBuilder(this)) { string walletName = "mywallet"; string walletPassword = "******"; string walletAccount = "account 0"; Money transferAmount = Money.Coins(0.01m); Money feeAmount = Money.Coins(0.0001m); var counterchainNetwork = new StraxTest(); CoreNode nodeA = builder.CreatePoANodeWithCounterchain(network, counterchainNetwork, network.FederationKey1).WithWallet(walletPassword, walletName).Start(); CoreNode nodeB = builder.CreatePoANodeWithCounterchain(network, counterchainNetwork, network.FederationKey2).WithWallet(walletPassword, walletName).Start(); TestHelper.Connect(nodeA, nodeB); long toMineCount = network.Consensus.PremineHeight + network.Consensus.CoinbaseMaturity + 1 - nodeA.GetTip().Height; // Get coins on nodeA via the premine. await nodeA.MineBlocksAsync((int)toMineCount).ConfigureAwait(false); CoreNodePoAExtensions.WaitTillSynced(nodeA, nodeB); // Create voting-request transaction. var minerKey = new Key(); var collateralKey = new Key(); var request = new JoinFederationRequest(minerKey.PubKey, new Money(CollateralFederationMember.MinerCollateralAmount, MoneyUnit.BTC), collateralKey.PubKey.Hash); // In practice this signature will come from calling the counter-chain "signmessage" API. request.AddSignature(collateralKey.SignMessage(request.SignatureMessage)); var encoder = new JoinFederationRequestEncoder(nodeA.FullNode.NodeService <Microsoft.Extensions.Logging.ILoggerFactory>()); Transaction trx = JoinFederationRequestBuilder.BuildTransaction(nodeA.FullNode.WalletTransactionHandler(), this.network, request, encoder, walletName, walletAccount, walletPassword); await nodeA.FullNode.NodeController <WalletController>().SendTransaction(new SendTransactionRequest(trx.ToHex())); TestBase.WaitLoop(() => nodeA.CreateRPCClient().GetRawMempool().Length == 1 && nodeB.CreateRPCClient().GetRawMempool().Length == 1); await nodeB.MineBlocksAsync((int)toMineCount).ConfigureAwait(false); TestBase.WaitLoop(() => nodeA.CreateRPCClient().GetRawMempool().Length == 0 && nodeB.CreateRPCClient().GetRawMempool().Length == 0); IWalletManager walletManager = nodeB.FullNode.NodeService <IWalletManager>(); TestBase.WaitLoop(() => { long balance = walletManager.GetBalances(walletName, walletAccount).Sum(x => x.AmountConfirmed); return(balance == feeAmount); }); Assert.Single(nodeA.FullNode.NodeService <VotingManager>().GetPendingPolls()); Assert.Single(nodeB.FullNode.NodeService <VotingManager>().GetPendingPolls()); } }
// Checks that multisig fed members can't be kicked. public async Task CantKickMultiSigFedMemberAsync() { var network = new TestPoACollateralNetwork(); CoreNode node = this.builder.CreatePoANode(network, network.FederationKey1).Start(); var model = new HexPubKeyModel() { PubKeyHex = network.FederationKey2.PubKey.ToHex() }; IActionResult response = node.FullNode.NodeController <FederationVotingController>().VoteKickFedMember(model); Assert.True(response is ErrorResult errorResult && errorResult.Value is ErrorResponse errorResponse && errorResponse.Errors.First().Message == "Multisig members can't be voted on"); }