Skip to content

Commit

Permalink
feat: backwards compatible with old channels
Browse files Browse the repository at this point in the history
  • Loading branch information
Jasonvdb committed Jan 3, 2024
1 parent a939cfa commit 29aeb0c
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 30 deletions.
33 changes: 21 additions & 12 deletions lib/android/src/main/java/com/reactnativeldk/LdkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
private val channelManagerPersister: LdkChannelManagerPersister by lazy { LdkChannelManagerPersister() }

//Config required to setup below objects
private var keysManager: KeysManager? = null
private var keysManager: CustomKeysManager? = null
private var channelManager: ChannelManager? = null
private var userConfig: UserConfig? = null
private var networkGraph: NetworkGraph? = null
Expand Down Expand Up @@ -230,7 +230,7 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
}

@ReactMethod
fun initKeysManager(seed: String, promise: Promise) {
fun initKeysManager(seed: String, destinationScriptPublicKey: String, witnessProgram: String, witnessProgramVersion: Double, promise: Promise) {
if (keysManager !== null) {
return handleResolve(promise, LdkCallbackResponses.keys_manager_init_success)
}
Expand All @@ -243,7 +243,15 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
return handleReject(promise, LdkErrors.invalid_seed_hex)
}

keysManager = KeysManager.of(seedBytes, seconds, nanoSeconds.toInt())
keysManager = CustomKeysManager(
seedBytes,
seconds,
nanoSeconds.toInt(),
destinationScriptPublicKey.hexa(),
witnessProgram.hexa(),
witnessProgramVersion.toInt().toByte()
)
//keysManager = KeysManager.of(seedBytes, seconds, nanoSeconds.toInt())

handleResolve(promise, LdkCallbackResponses.keys_manager_init_success)
}
Expand Down Expand Up @@ -439,9 +447,9 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
channelManagerSerialized,
channelMonitors.toTypedArray(),
userConfig!!,
keysManager!!.as_EntropySource(),
keysManager!!.as_NodeSigner(),
keysManager!!.as_SignerProvider(),
keysManager!!.inner.as_EntropySource(),
keysManager!!.inner.as_NodeSigner(),
SignerProvider.new_impl(keysManager!!.signerProvider),
feeEstimator.feeEstimator,
chainMonitor!!,
filter.filter,
Expand All @@ -461,9 +469,9 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
userConfig,
blockHash.hexa().reversedArray(),
blockHeight.toInt(),
keysManager!!.as_EntropySource(),
keysManager!!.as_NodeSigner(),
keysManager!!.as_SignerProvider(),
keysManager!!.inner.as_EntropySource(),
keysManager!!.inner.as_NodeSigner(),
SignerProvider.new_impl(keysManager!!.signerProvider),
feeEstimator.feeEstimator,
chainMonitor,
networkGraph!!,
Expand Down Expand Up @@ -826,7 +834,7 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod

val res = UtilMethods.create_invoice_from_channelmanager(
channelManager,
keysManager!!.as_NodeSigner(),
keysManager!!.inner.as_NodeSigner(),
logger.logger,
ldkCurrency,
if (amountSats == 0.0) Option_u64Z.none() else Option_u64Z.some((amountSats * 1000).toLong()),
Expand Down Expand Up @@ -1101,7 +1109,7 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
fun nodeSign(message: String, promise: Promise) {
keysManager ?: return handleReject(promise, LdkErrors.init_keys_manager)

val res = UtilMethods.sign(message.toByteArray(Charsets.UTF_8), keysManager!!._node_secret_key)
val res = UtilMethods.sign(message.toByteArray(Charsets.UTF_8), keysManager!!.inner._node_secret_key)

if (!res.is_ok) {
return handleReject(promise, LdkErrors.failed_signing_request)
Expand All @@ -1114,7 +1122,8 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
fun nodeStateDump(promise: Promise) {
val logDump: MutableList<String> = mutableListOf()

keysManager?.as_NodeSigner()?.get_node_id(Recipient.LDKRecipient_Node)?.let { pubKeyRes ->
keysManager?.inner?.as_NodeSigner()
?.get_node_id(Recipient.LDKRecipient_Node)?.let { pubKeyRes ->
if (pubKeyRes.is_ok) {
logDump.add("NodeID: ${(pubKeyRes as Result_PublicKeyNoneZ_OK).res.hexEncodedString()}")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,12 @@ class CustomKeysManager(
seed: ByteArray,
startingTimeSecs: Long,
startingTimeNanos: Int,
destinationScriptPublicKey: ByteArray,
witnessProgram: ByteArray,
witnessProgramVersion: Byte
val destinationScriptPublicKey: ByteArray,
val witnessProgram: ByteArray,
val witnessProgramVersion: Byte
) {
val inner: KeysManager = KeysManager.of(seed, startingTimeSecs, startingTimeNanos)
val signerProvider: CustomSignerProvider = CustomSignerProvider()
val destinationScriptPublicKey: ByteArray = destinationScriptPublicKey
val witnessProgram: ByteArray = witnessProgram
val witnessProgramVersion: Byte = witnessProgramVersion
val signerProvider = CustomSignerProvider()

init {
signerProvider.customKeysManager = this
Expand All @@ -41,23 +38,20 @@ class CustomKeysManager(
feerateSatPer1000Weight: Int,
locktime: Option_u32Z
): Result_TransactionNoneZ {
//TODO filter out static outputs
val onlyNonStatic: Array<SpendableOutputDescriptor> = descriptors.filter {
true //TODO
it as? SpendableOutputDescriptor.StaticOutput == null
}.toTypedArray()

val res = inner.spend_spendable_outputs(
return inner.spend_spendable_outputs(
onlyNonStatic,
outputs,
changeDestinationScript,
feerateSatPer1000Weight,
locktime
)
return res
}
}


class CustomSignerProvider : SignerProviderInterface {
lateinit var customKeysManager: CustomKeysManager

Expand All @@ -82,17 +76,14 @@ class CustomSignerProvider : SignerProviderInterface {
channel_value_satoshis: Long,
channel_keys_id: ByteArray?
): WriteableEcdsaChannelSigner {
return customKeysManager.signerProvider.derive_channel_signer(
channel_value_satoshis,
channel_keys_id
)
return customKeysManager.inner.as_SignerProvider().derive_channel_signer(channel_value_satoshis, channel_keys_id)
}

override fun generate_channel_keys_id(p0: Boolean, p1: Long, p2: UInt128?): ByteArray {
return customKeysManager.signerProvider.generate_channel_keys_id(p0, p1, p2)
return customKeysManager.inner.as_SignerProvider().generate_channel_keys_id(p0, p1, p2)
}

override fun read_chan_signer(p0: ByteArray?): Result_WriteableEcdsaChannelSignerDecodeErrorZ {
return customKeysManager.signerProvider.read_chan_signer(p0!!)
return customKeysManager.inner.as_SignerProvider().read_chan_signer(p0!!)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
}

(event as? Event.SpendableOutputs)?.let { spendableOutputs ->
if (channelWasOpenedWithNewCustomKeysManager((spendableOutputs.channel_id as Option_ThirtyTwoBytesZ.Some).some)) {
return
}

val body = Arguments.createMap()
val outputs = Arguments.createArray()
spendableOutputs.outputs.iterator().forEach {
Expand Down Expand Up @@ -169,6 +173,14 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {
persistPaymentClaimed(body)
return LdkEventEmitter.send(EventTypes.channel_manager_payment_claimed, body)
}

(event as? Event.ChannelReady)?.let { channelReady ->
persistChannelOpenedWithNewCustomKeysManager(channelReady.channel_id)
}

(event as? Event.ChannelPending)?.let { channelPending ->
persistChannelOpenedWithNewCustomKeysManager(channelPending.channel_id)
}
}

override fun persist_manager(channel_manager_bytes: ByteArray?) {
Expand Down Expand Up @@ -284,4 +296,56 @@ class LdkChannelManagerPersister: ChannelManagerConstructor.EventHandler {

File(LdkModule.accountStoragePath + "/" + LdkFileNames.paymentsSent.fileName).writeText(JSONArray(payments).toString())
}

private fun persistChannelOpenedWithNewCustomKeysManager(channelId: ByteArray) {
if (LdkModule.accountStoragePath == "") {
LdkEventEmitter.send(EventTypes.native_log, "Error. Failed to persist channel opened with new custom keys manager to disk (No set storage)")
return
}

val id = channelId.hexEncodedString()
val existingIds = ArrayList<String>()
try {
if (File(LdkModule.accountStoragePath + "/" + LdkFileNames.channelsOpenedWithCustomKeysManager.fileName).exists()) {
val data = File(LdkModule.accountStoragePath + "/" + LdkFileNames.channelsOpenedWithCustomKeysManager.fileName).readBytes()
val existingIdsArray = JSONArray(String(data))
for (i in 0 until existingIdsArray.length()) {
existingIds.add(existingIdsArray.getString(i))
}
}

if (!existingIds.contains(id)) {
existingIds.add(id)

File(LdkModule.accountStoragePath + "/" + LdkFileNames.channelsOpenedWithCustomKeysManager.fileName).writeText(JSONArray(existingIds).toString())
}
} catch (e: Exception) {
LdkEventEmitter.send(EventTypes.native_log, "Error could not read existing ChannelOpenedWithNewCustomKeysManager")
}

println("**** existingIds: $existingIds")
}

private fun channelWasOpenedWithNewCustomKeysManager(channelId: ByteArray): Boolean {
if (LdkModule.accountStoragePath == "") {
LdkEventEmitter.send(EventTypes.native_log, "Error. Failed to check if channel was opened with new custom keys manager (No set storage)")
return false
}

val id = channelId.hexEncodedString()
val existingIds = ArrayList<String>()
try {
if (File(LdkModule.accountStoragePath + "/" + LdkFileNames.channelsOpenedWithCustomKeysManager.fileName).exists()) {
val data = File(LdkModule.accountStoragePath + "/" + LdkFileNames.channelsOpenedWithCustomKeysManager.fileName).readBytes()
val existingIdsArray = JSONArray(String(data))
for (i in 0 until existingIdsArray.length()) {
existingIds.add(existingIdsArray.getString(i))
}
}
} catch (e: Exception) {
LdkEventEmitter.send(EventTypes.native_log, "Error could not read existing ChannelOpenedWithNewCustomKeysManager")
}

return existingIds.contains(id)
}
}

0 comments on commit 29aeb0c

Please sign in to comment.