public Hashtable HandleBitcoinConfirmationPing(Hashtable request_hash) { m_log.Error("[FreeMoney] Got request for confirmation"); //string base_url = "http://beech/TODO"; string base_url = m_scenes[0].RegionInfo.ExternalHostName + ":" + m_scenes[0].RegionInfo.HttpPort; /* TODO: Recreate the ability to handle multiple services. if (!get_params.ContainsKey("service")) { //print_simple_and_exit("Error: Service name not set."); return false; } */ Hashtable error_response = new Hashtable(); error_response.Add("int_response_code", 400); //Dictionary<string, object> postvals = ServerUtils.ParseQueryString ((string)request["body"]); string post_data = (string)request_hash["body"]; m_log.Error("[FreeMoney] Confirmation body:"+post_data); BitcoinNotificationService service = new BitcoinNotificationService(m_btcconfig); if (!service.ParseRequestBody(post_data)) { m_log.Error("[FreeMoney] Could not parse post params"); return error_response; } if (!service.IsValid()) { return error_response; } string address = service.BtcAddress(); int num_confirmations_received = service.NumConfirmationsReceived(); BitcoinTransaction btc_trans = new BitcoinTransaction(m_connectionString, m_btcconfig, base_url); if (!btc_trans.PopulateByBtcAddress(address)) { m_log.Error("[FreeMoney] Could not find btc_trans"); return error_response; } // Always mark the latest number of confirmations, assuming it's more than we had last time. if (!btc_trans.MarkConfirmed(num_confirmations_received)) { m_log.Error("[FreeMoney] Could not mark confirmed in database"); //print_simple_and_exit("Could not mark btc_trans confirmed despite receiving ".htmlentities($num_confirmations_received)." confirmations."); return error_response; } // If it's less than we need, there should be nothing more to do. //if (num_confirmations_received < btc_trans.num_confirmations_required) if (!btc_trans.IsEnoughConfirmations(num_confirmations_received)) { m_log.Info("[FreeMoney] Got "+ num_confirmations_received.ToString()+" confirmations for address " + address + ", but that is not enough to complete the transaction."); return error_response; //print_simple_and_exit("Not enough confirmations, ignoring.", 200); } // If we've already notified the client about this btc_trans, no need to do anything else. if (btc_trans.IsConfirmationSent()) { //print_simple_and_exit("Already confirmed, nothing more to do.", 200); } UUID txnID = new UUID (btc_trans.GetTransactionID()); if (!m_transactionsInProgress.ContainsKey (txnID)) { Hashtable ereply = new Hashtable (); ereply["int_response_code"] = 404; // 200 OK ereply["str_response_string"] = "Invalid Transaction"; ereply["content_type"] = "text/html"; return ereply; } FreeMoneyTransaction txn = m_transactionsInProgress[txnID]; if (!btc_trans.MarkNotified()) { //print_simple_and_exit("Notified sim, but unable to record the fact that we did."); m_log.Error("[FreeMoney] Could not mark notified"); return error_response; } Util.FireAndForget (delegate { TransferSuccess (txn); }); Hashtable ok_response = new Hashtable(); ok_response.Add("int_response_code", 200); ok_response.Add("str_response_string", "OK, thanks for letting us know."); ok_response.Add("content_type", "text/html"); return ok_response; }