mirror of
https://github.com/ACINQ/eclair.git
synced 2025-02-23 22:46:44 +01:00
Fix concurrent spends with Electrum (#233)
By keeping temporary spending items in history
This commit is contained in:
parent
2d5d68bf3f
commit
2ef479d38c
1 changed files with 14 additions and 4 deletions
|
@ -128,9 +128,16 @@ class ElectrumWallet(mnemonics: Seq[String], client: ActorRef, params: ElectrumW
|
||||||
|
|
||||||
goto(stateName) using data1 // goto instead of stay because we want to fire transitions
|
goto(stateName) using data1 // goto instead of stay because we want to fire transitions
|
||||||
|
|
||||||
case Event(ElectrumClient.GetScriptHashHistoryResponse(scriptHash, history), data) =>
|
case Event(ElectrumClient.GetScriptHashHistoryResponse(scriptHash, items), data) =>
|
||||||
log.debug(s"scriptHash=$scriptHash has history=$history")
|
log.debug(s"scriptHash=$scriptHash has history=$items")
|
||||||
val (heights1, pendingTransactionRequests1) = history.foldLeft((data.heights, data.pendingTransactionRequests)) {
|
val shadow_items = data.history.get(scriptHash) match {
|
||||||
|
case Some(existing_items) => existing_items.filterNot(item => items.exists(_.tx_hash == item.tx_hash))
|
||||||
|
case None => Nil
|
||||||
|
}
|
||||||
|
shadow_items.foreach(item => log.warning(s"keeping shadow item for txid=${item.tx_hash}"))
|
||||||
|
val items0 = items ++ shadow_items
|
||||||
|
|
||||||
|
val (heights1, pendingTransactionRequests1) = items0.foldLeft((data.heights, data.pendingTransactionRequests)) {
|
||||||
case ((heights, hashes), item) if !data.transactions.contains(item.tx_hash) && !data.pendingTransactionRequests.contains(item.tx_hash) =>
|
case ((heights, hashes), item) if !data.transactions.contains(item.tx_hash) && !data.pendingTransactionRequests.contains(item.tx_hash) =>
|
||||||
// we retrieve the tx if we don't have it and haven't yet requested it
|
// we retrieve the tx if we don't have it and haven't yet requested it
|
||||||
client ! GetTransaction(item.tx_hash)
|
client ! GetTransaction(item.tx_hash)
|
||||||
|
@ -157,7 +164,7 @@ class ElectrumWallet(mnemonics: Seq[String], client: ActorRef, params: ElectrumW
|
||||||
// no reorg, nothing to do
|
// no reorg, nothing to do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val data1 = data.copy(heights = heights1, history = data.history + (scriptHash -> history), pendingHistoryRequests = data.pendingHistoryRequests - scriptHash, pendingTransactionRequests = pendingTransactionRequests1)
|
val data1 = data.copy(heights = heights1, history = data.history + (scriptHash -> items0), pendingHistoryRequests = data.pendingHistoryRequests - scriptHash, pendingTransactionRequests = pendingTransactionRequests1)
|
||||||
goto(stateName) using data1 // goto instead of stay because we want to fire transitions
|
goto(stateName) using data1 // goto instead of stay because we want to fire transitions
|
||||||
|
|
||||||
case Event(GetTransactionResponse(tx), data) =>
|
case Event(GetTransactionResponse(tx), data) =>
|
||||||
|
@ -410,6 +417,9 @@ object ElectrumWallet {
|
||||||
* @param heights transactions heights
|
* @param heights transactions heights
|
||||||
* @param history script hash -> history
|
* @param history script hash -> history
|
||||||
* @param locks transactions which lock some of our utxos.
|
* @param locks transactions which lock some of our utxos.
|
||||||
|
* @param pendingHistoryRequests requests pending a response from the electrum server
|
||||||
|
* @param pendingTransactionRequests requests pending a response from the electrum server
|
||||||
|
* @param pendingTransactions transactions received but not yet connected to their parents
|
||||||
*/
|
*/
|
||||||
case class Data(tip: ElectrumClient.Header,
|
case class Data(tip: ElectrumClient.Header,
|
||||||
accountKeys: Vector[ExtendedPrivateKey],
|
accountKeys: Vector[ExtendedPrivateKey],
|
||||||
|
|
Loading…
Add table
Reference in a new issue