You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
2.4 KiB

  1. package loopdb
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/btcsuite/btcd/chaincfg"
  6. "github.com/coreos/bbolt"
  7. )
  8. // migrateUpdates migrates the swap updates to add an additional level of
  9. // nesting, allowing for optional keys to be added.
  10. func migrateUpdates(tx *bbolt.Tx, chainParams *chaincfg.Params) error {
  11. for _, key := range [][]byte{loopInBucketKey, loopOutBucketKey} {
  12. rootBucket := tx.Bucket(key)
  13. if rootBucket == nil {
  14. return fmt.Errorf("bucket %v does not exist", key)
  15. }
  16. err := migrateSwapTypeUpdates(rootBucket)
  17. if err != nil {
  18. return err
  19. }
  20. }
  21. return nil
  22. }
  23. // migrateSwapTypeUpdates migrates updates for swaps in the specified bucket.
  24. func migrateSwapTypeUpdates(rootBucket *bbolt.Bucket) error {
  25. var swaps [][]byte
  26. // Do not modify inside the for each.
  27. err := rootBucket.ForEach(func(swapHash, v []byte) error {
  28. // Only go into things that we know are sub-bucket
  29. // keys.
  30. if rootBucket.Bucket(swapHash) != nil {
  31. swaps = append(swaps, swapHash)
  32. }
  33. return nil
  34. })
  35. if err != nil {
  36. return err
  37. }
  38. // With the swaps listed, migrate them one by one.
  39. for _, swapHash := range swaps {
  40. swapBucket := rootBucket.Bucket(swapHash)
  41. if swapBucket == nil {
  42. return fmt.Errorf("swap bucket %x not found",
  43. swapHash)
  44. }
  45. err := migrateSwapUpdates(swapBucket)
  46. if err != nil {
  47. return err
  48. }
  49. }
  50. return nil
  51. }
  52. // migrateSwapUpdates migrates updates for the swap stored in the specified
  53. // bucket.
  54. func migrateSwapUpdates(swapBucket *bbolt.Bucket) error {
  55. // With the main swap bucket obtained, we'll grab the
  56. // raw swap contract bytes.
  57. updatesBucket := swapBucket.Bucket(updatesBucketKey)
  58. if updatesBucket == nil {
  59. return errors.New("updates bucket not found")
  60. }
  61. type state struct {
  62. id, state []byte
  63. }
  64. var existingStates []state
  65. // Do not modify inside the for each.
  66. err := updatesBucket.ForEach(func(k, v []byte) error {
  67. existingStates = append(existingStates, state{id: k, state: v})
  68. return nil
  69. })
  70. if err != nil {
  71. return err
  72. }
  73. for _, existingState := range existingStates {
  74. // Delete the existing state key.
  75. err := updatesBucket.Delete(existingState.id)
  76. if err != nil {
  77. return err
  78. }
  79. // Re-create as a bucket.
  80. updateBucket, err := updatesBucket.CreateBucket(
  81. existingState.id,
  82. )
  83. if err != nil {
  84. return err
  85. }
  86. // Write back the basic state as a sub-key.
  87. err = updateBucket.Put(basicStateKey, existingState.state)
  88. if err != nil {
  89. return err
  90. }
  91. }
  92. return nil
  93. }