Closed ryan-lingle closed 5 years ago
that's a very good point. I haven't looked into that yet. I currently don't have an lnd behind a "trusted" cert.
actually initializing the GRPC::Core::ChannelCredentials
with no parameter/nil should do the trick to load the root certs from the environment/server.
Do you have the full trace of your error?
full trace:
/Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/active_call.rb:31:in `check_status': 2:unmarshal v1: packet size too big (GRPC::Unknown)
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/active_call.rb:181:in `attach_status_results_and_complete_call'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/active_call.rb:377:in `request_response'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/client_stub.rb:178:in `block in request_response'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/interceptors.rb:181:in `block in intercept!'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/lnrpc-0.5.2/lib/lnrpc/macaroon_interceptor.rb:13:in `inject_macaroon_metadata'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/interceptors.rb:175:in `intercept!'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/client_stub.rb:177:in `request_response'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/grpc-1.19.0-universal-darwin/src/ruby/lib/grpc/generic/service.rb:170:in `block (3 levels) in rpc_stub_class'
from /Users/Ryan/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/gems/lnrpc-0.5.2/lib/lnrpc/client.rb:60:in `method_missing'
from rpc.rb:6:in `<main>'
hmmm, that's strange... and how exactly does your code look like?
require 'lnrpc'
macaroon = "[my macaroon here]".each_byte.map { |b| b.to_s(16).rjust(2,'0') }.join
lnd = Lnrpc::Client.new({macaroon: macaroon, channel: 'btcpay399208.lndyn.com:443'})
lnd.get_info
with this adjustment to gem:
self.address = options[:address] || DEFAULT_ADDRESS
self.credentials = options[:credentials_path] ? ::File.read(::File.expand_path(options[:credentials_path] || DEFAULT_CREDENTIALS_PATH)) : options[:credentials]
options[:macaroon] ||= begin
macaroon_binary = ::File.read(::File.expand_path(options[:macaroon_path] || DEFAULT_MACAROON_PATH))
macaroon_binary.unpack("H*")
end
self.macaroon = options[:macaroon]
channelcredentials = self.credentials ? GRPC::Core::ChannelCredentials.new(self.credentials) : GRPC::Core::ChannelCredentials.new
self.grpc_client = Lnrpc::Lightning::Stub.new(self.address,
channelcredentials,
interceptors: [Lnrpc::MacaroonInterceptor.new(self.macaroon)]
)
ok,
"[my macaroon here]"
is what you're loading from the macaroon file? (binary?)
and I think in the options the address should be passed as address
not channel
:
lnd = Lnrpc::Client.new({macaroon: macaroon, address: 'btcpay399208.lndyn.com:443'})
and is your lnd node really reachable through that address and port?
Good catch on the channel mistype (luckily I had the default address constant set to btcpay399208.lndyn.com:443).
The macaroon is the actual admin macaroon for the lnd instance as a string (just trying to get it up and running at this point).
The node should be reachable through that port. The node is a BTC Pay Server running on a lunanode VM. BTC Pay Server exposes an LND grpc service on that endpoint:
sadly I don't know btc pay server, how do you get the macaroon from btcpay server? if it is already a hex value (which I assume) then you should not need the .each_byte.map { |b| b.to_s(16).rjust(2,'0') }.join
Yep, that was the problem! Thanks a ton!
For the pr:
I can assume trusted cert when no credentials and credentials_path (instead of assuming DEFAULT_CREDENTIALS_PATH):
def initialize(options={})
self.address = options[:address] || DEFAULT_ADDRESS
self.credentials = options[:credentials_path] ? ::File.read(::File.expand_path(options[:credentials_path])) : options[:credentials]
options[:macaroon] ||= begin
macaroon_binary = ::File.read(::File.expand_path(options[:macaroon_path] || DEFAULT_MACAROON_PATH))
macaroon_binary.unpack("H*")
end
self.macaroon = options[:macaroon]
channel_credentials = self.credentials ? GRPC::Core::ChannelCredentials.new(self.credentials) : GRPC::Core::ChannelCredentials.new
self.grpc_client = Lnrpc::Lightning::Stub.new(self.address,
channel_credentials,
interceptors: [Lnrpc::MacaroonInterceptor.new(self.macaroon)]
)
end
or continue to assume the DEFAULT_CREDENTIALS_PATH in that case and make user pass in additional argument (trusted_certificated: true) :
def initialize(options={})
self.address = options[:address] || DEFAULT_ADDRESS
options[:credentials] ||= ::File.read(::File.expand_path(options[:credentials_path] || DEFAULT_CREDENTIALS_PATH))
self.credentials = options[:credentials]
options[:macaroon] ||= begin
macaroon_binary = ::File.read(::File.expand_path(options[:macaroon_path] || DEFAULT_MACAROON_PATH))
macaroon_binary.unpack("H*")
end
self.macaroon = options[:macaroon]
channel_credentials = options[:trusted_certification] ? GRPC::Core::ChannelCredentials.new : GRPC::Core::ChannelCredentials.new(self.credentials)
self.grpc_client = Lnrpc::Lightning::Stub.new(self.address,
channel_credentials,
interceptors: [Lnrpc::MacaroonInterceptor.new(self.macaroon)]
)
end
yay, great! happy to hear that.
I was just experimenting with something like this:
def initialize(options={})
self.address = options[:address] || DEFAULT_ADDRESS
unless options.has_key?(:credentials)
options[:credentials] = ::File.read(::File.expand_path(options[:credentials_path] || DEFAULT_CREDENTIALS_PATH))
end
self.credentials = options[:credentials]
unless options.has_key?(:macaroon)
options[:macaroon] = ::File.read(::File.expand_path(options[:macaroon_path] || DEFAULT_MACAROON_PATH)).unpack("H*")
end
self.macaroon = options[:macaroon]
self.grpc_client = Lnrpc::Lightning::Stub.new(self.address,
GRPC::Core::ChannelCredentials.new(self.credentials),
interceptors: [Lnrpc::MacaroonInterceptor.new(self.macaroon)]
)
end
so it could be used like:
lnd = Lnrpc::Client.new({credentials: nil, macaroon: macaroon, address: 'btcpay399208.lndyn.com:443'})
meaning if nil
is passed as credentials then the default/trusted system certs are used?
what do you think?
I like it!
I've just pushed a branch PR #5 if you want to test it. let me know if it works for you. still in the testing phrase and I need to write some specs for it.
Works great!
ok, great!! as I don't have any btc pay server running... do you want to add a section to the readme or in some docs folder or wiki a HowTo connect to it? that could be super helpful for others.
Yes, I will do that!
Trying to adapt gem to use with btc pay server which utilizes trusted certificates.
Changed
GRPC::Core::ChannelCredentials.new(self.credentials)
toGRPC::Core::ChannelCredentials.new
Following the pattern that Nicolas Dorier used with Alex Bosworth's ln-service: https://github.com/alexbosworth/ln-service/pull/71
Continue to get this error: rails aborted! GRPC::Unknown: 2:unmarshal v1: packet size too big
Wondering if you might have some insight as to why and if we can add this functionality to lnrpc? If I get it to work properly on my machine and can create a pr.