示例#1
0
        public async Task <IActionResult> JoinFederationAsync([FromBody] JoinFederationRequestModel request, CancellationToken cancellationToken = default)
        {
            Guard.NotNull(request, nameof(request));

            // Checks that the request is valid.
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            try
            {
                PubKey minerPubKey = await(this.federationManager as CollateralFederationManager).JoinFederationAsync(request, cancellationToken);

                var model = new JoinFederationResponseModel
                {
                    MinerPublicKey = minerPubKey.ToHex()
                };

                this.logger.LogTrace("(-):'{0}'", model);
                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[ERROR]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
示例#2
0
        public async Task <IActionResult> JoinFederationAsync([FromBody] JoinFederationRequestModel request, CancellationToken cancellationToken = default)
        {
            Guard.NotNull(request, nameof(request));

            // Checks that the request is valid.
            if (!this.ModelState.IsValid)
            {
                this.logger.LogTrace("(-)[MODEL_STATE_INVALID]");
                return(ModelStateErrors.BuildErrorResponse(this.ModelState));
            }

            if (!(this.network.Consensus.Options as PoAConsensusOptions).AutoKickIdleMembers)
            {
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, "Error", "This feature is currently disabled."));
            }

            try
            {
                PubKey minerPubKey = await this.joinFederationRequestService.JoinFederationAsync(request, cancellationToken);

                var model = new JoinFederationResponseModel
                {
                    MinerPublicKey = minerPubKey.ToHex()
                };

                this.logger.LogTrace("(-):'{0}'", model);
                return(this.Json(model));
            }
            catch (Exception e)
            {
                this.logger.LogError("Exception occurred: {0}", e.ToString());
                this.logger.LogTrace("(-)[ERROR]");
                return(ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()));
            }
        }
        public async Task <PubKey> JoinFederationAsync(JoinFederationRequestModel request, CancellationToken cancellationToken)
        {
            // Get the address pub key hash.
            var   address    = BitcoinAddress.Create(request.CollateralAddress, this.counterChainSettings.CounterChainNetwork);
            KeyId addressKey = PayToPubkeyHashTemplate.Instance.ExtractScriptPubKeyParameters(address.ScriptPubKey);

            // Get mining key.
            var keyTool  = new KeyTool(this.settings.DataFolder);
            Key minerKey = keyTool.LoadPrivateKey();

            if (minerKey == null)
            {
                throw new Exception($"The private key file ({KeyTool.KeyFileDefaultName}) has not been configured.");
            }

            var expectedCollateralAmount = CollateralFederationMember.GetCollateralAmountForPubKey(this.network, minerKey.PubKey);

            Money collateralAmount = new Money(expectedCollateralAmount, MoneyUnit.BTC);

            var joinRequest = new JoinFederationRequest(minerKey.PubKey, collateralAmount, addressKey);

            // Populate the RemovalEventId.
            var collateralFederationMember = new CollateralFederationMember(minerKey.PubKey, false, joinRequest.CollateralAmount, request.CollateralAddress);

            byte[] federationMemberBytes = (this.network.Consensus.ConsensusFactory as CollateralPoAConsensusFactory).SerializeFederationMember(collateralFederationMember);
            var    votingManager         = this.fullNode.NodeService <VotingManager>();
            Poll   poll = votingManager.GetFinishedPolls().FirstOrDefault(x => x.IsExecuted &&
                                                                          x.VotingData.Key == VoteKey.KickFederationMember && x.VotingData.Data.SequenceEqual(federationMemberBytes));

            joinRequest.RemovalEventId = (poll == null) ? Guid.Empty : new Guid(poll.PollExecutedBlockData.Hash.ToBytes().TakeLast(16).ToArray());

            // Get the signature by calling the counter-chain "signmessage" API.
            var signMessageRequest = new SignMessageRequest()
            {
                Message         = joinRequest.SignatureMessage,
                WalletName      = request.CollateralWalletName,
                Password        = request.CollateralWalletPassword,
                ExternalAddress = request.CollateralAddress
            };

            var    walletClient = new WalletClient(this.loggerFactory, this.httpClientFactory, $"http://{this.counterChainSettings.CounterChainApiHost}", this.counterChainSettings.CounterChainApiPort);
            string signature    = await walletClient.SignMessageAsync(signMessageRequest, cancellationToken);

            if (signature == null)
            {
                throw new Exception("Operation was cancelled during call to counter-chain to sign the collateral address.");
            }

            joinRequest.AddSignature(signature);

            var         walletTransactionHandler = this.fullNode.NodeService <IWalletTransactionHandler>();
            var         encoder = new JoinFederationRequestEncoder(this.loggerFactory);
            Transaction trx     = JoinFederationRequestBuilder.BuildTransaction(walletTransactionHandler, this.network, joinRequest, encoder, request.WalletName, request.WalletAccount, request.WalletPassword);

            var walletService = this.fullNode.NodeService <IWalletService>();
            await walletService.SendTransaction(new SendTransactionRequest(trx.ToHex()), cancellationToken);

            return(minerKey.PubKey);
        }
示例#4
0
        private async Task <bool> CallJoinFederationRequestAsync()
        {
            Console.Clear();
            Console.WriteLine($"The relevant masternode registration wallets has now been setup and verified.");
            Console.WriteLine($"Press any key to continue (this will deduct the registation fee from your Cirrus wallet)");
            Console.ReadKey();

            string collateralWallet;
            string collateralPassword;
            string collateralAddress;
            string cirrusWalletName;
            string cirrusWalletPassword;

            do
            {
                Console.WriteLine($"[Strax] Please enter the collateral wallet name:");
                collateralWallet = Console.ReadLine();
                Console.WriteLine($"[Strax] Please enter the collateral wallet password:"******"[Strax] Please enter the collateral address in which the collateral amount of {CollateralRequirement} {this.mainchainNetwork.CoinTicker} is held:");
                collateralAddress = Console.ReadLine();

                Console.WriteLine($"[Cirrus] Please enter the wallet name which holds the registration fee of {FeeRequirement} {this.sidechainNetwork.CoinTicker}:");
                cirrusWalletName = Console.ReadLine();
                Console.WriteLine($"[Cirrus] Please enter the above wallet's password:"******"ERROR: Please ensure that you enter the relevant details correctly.");
            } while (true);

            var request = new JoinFederationRequestModel()
            {
                CollateralAddress        = collateralAddress,
                CollateralWalletName     = collateralWallet,
                CollateralWalletPassword = collateralPassword,
                WalletAccount            = "account 0",
                WalletName     = cirrusWalletName,
                WalletPassword = cirrusWalletPassword
            };

            try
            {
                await $"http://localhost:{this.sidechainNetwork.DefaultAPIPort}/api".AppendPathSegment("collateral/joinfederation").PostJsonAsync(request);
                Console.WriteLine($"SUCCESS: The masternode request has now been submitted to the network,please press any key to view its progress.");
                return(true);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"ERROR: An exception occurred trying to registre your masternode: {ex}");
                return(false);
            }
        }