Merge branch 'btc_spop'

Stephen Paul Weber created

* btc_spop:
  Get new Bitcoin address from Redis set

Change summary

lib/customer.rb           |  9 ++++-----
redis_lua/spopsadd.lua    |  6 ++++++
sgx_jmp.rb                |  1 +
test/test_customer.rb     | 11 +++--------
test/test_registration.rb | 28 ++++++++++++----------------
5 files changed, 26 insertions(+), 29 deletions(-)

Detailed changes

lib/customer.rb 🔗

@@ -119,11 +119,10 @@ class Customer
 	end
 
 	def add_btc_address
-		ELECTRUM.createnewaddress.then do |addr|
-			REDIS.sadd("jmp_customer_btc_addresses-#{customer_id}", addr).then do
-				addr
-			end
-		end
+		REDIS.spopsadd([
+			"jmp_available_btc_addresses",
+			"jmp_customer_btc_addresses-#{customer_id}"
+		])
 	end
 
 	protected def_delegator :@plan, :expires_at

redis_lua/spopsadd.lua 🔗

@@ -0,0 +1,6 @@
+local addr = redis.call("spop", KEYS[1])
+if not addr then
+	return redis.error_reply("Nothing to SPOP")
+end
+redis.call("sadd", KEYS[2], addr)
+return addr

sgx_jmp.rb 🔗

@@ -45,6 +45,7 @@ require_relative "lib/web_register_manager"
 require_relative "lib/statsd"
 
 ELECTRUM = Electrum.new(**CONFIG[:electrum])
+EM::Hiredis::Client.load_scripts_from("./redis_lua")
 
 Faraday.default_adapter = :em_synchrony
 BandwidthIris::Client.global_options = {

test/test_customer.rb 🔗

@@ -295,17 +295,12 @@ class CustomerTest < Minitest::Test
 	em :test_btc_addresses
 
 	def test_add_btc_address
-		Customer::ELECTRUM.expect(
-			:createnewaddress,
-			EMPromise.resolve("testaddr")
-		)
 		Customer::REDIS.expect(
-			:sadd,
-			EMPromise.resolve(nil),
-			["jmp_customer_btc_addresses-test", "testaddr"]
+			:spopsadd,
+			EMPromise.resolve("testaddr"),
+			[["jmp_available_btc_addresses", "jmp_customer_btc_addresses-test"]]
 		)
 		assert_equal "testaddr", Customer.new("test").add_btc_address.sync
-		assert_mock Customer::ELECTRUM
 		assert_mock Customer::REDIS
 	end
 	em :test_add_btc_address

test/test_registration.rb 🔗

@@ -103,20 +103,19 @@ class RegistrationTest < Minitest::Test
 
 	class PaymentTest < Minitest::Test
 		Customer::BRAINTREE = Minitest::Mock.new
-		Registration::Payment::Bitcoin::ELECTRUM = Minitest::Mock.new
 
 		def test_for_bitcoin
-			Registration::Payment::Bitcoin::ELECTRUM.expect(:createnewaddress, "addr")
+			customer = Minitest::Mock.new(Customer.new("test"))
+			customer.expect(
+				:add_btc_address,
+				EMPromise.resolve("testaddr")
+			)
 			iq = Blather::Stanza::Iq::Command.new
 			iq.form.fields = [
 				{ var: "activation_method", value: "bitcoin" },
 				{ var: "plan_name", value: "test_usd" }
 			]
-			result = Registration::Payment.for(
-				iq,
-				Customer.new("test"),
-				"+15555550000"
-			)
+			result = Registration::Payment.for(iq, customer, "+15555550000")
 			assert_kind_of Registration::Payment::Bitcoin, result
 		end
 
@@ -164,17 +163,19 @@ class RegistrationTest < Minitest::Test
 			Registration::Payment::Bitcoin::BTC_SELL_PRICES = Minitest::Mock.new
 			Registration::Payment::Bitcoin::BLATHER = Minitest::Mock.new
 			Customer::REDIS = Minitest::Mock.new
-			Customer::ELECTRUM = Minitest::Mock.new
 
 			def setup
-				Customer::ELECTRUM.expect(
-					:createnewaddress,
+				@customer = Minitest::Mock.new(
+					Customer.new("test", plan_name: "test_usd")
+				)
+				@customer.expect(
+					:add_btc_address,
 					EMPromise.resolve("testaddr")
 				)
 				iq = Blather::Stanza::Iq::Command.new
 				@bitcoin = Registration::Payment::Bitcoin.new(
 					iq,
-					Customer.new("test", plan_name: "test_usd"),
+					@customer,
 					"+15555550000"
 				)
 			end
@@ -185,11 +186,6 @@ class RegistrationTest < Minitest::Test
 					EMPromise.resolve([]),
 					["jmp_customer_btc_addresses-test"]
 				)
-				Customer::REDIS.expect(
-					:sadd,
-					EMPromise.resolve(1),
-					["jmp_customer_btc_addresses-test", "testaddr"]
-				)
 				reply_text = <<~NOTE
 					Activate your account by sending at least 1.000000 BTC to
 					testaddr