github.com/ethersphere/bee/v2@v2.2.0/pkg/settlement/swap/addressbook.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package swap 6 7 import ( 8 "errors" 9 "fmt" 10 11 "github.com/ethereum/go-ethereum/common" 12 "github.com/ethersphere/bee/v2/pkg/storage" 13 "github.com/ethersphere/bee/v2/pkg/swarm" 14 ) 15 16 var ( 17 peerPrefix = "swap_chequebook_peer_" 18 peerChequebookPrefix = "swap_peer_chequebook_" 19 beneficiaryPeerPrefix = "swap_beneficiary_peer_" 20 peerBeneficiaryPrefix = "swap_peer_beneficiary_" 21 deductedForPeerPrefix = "swap_deducted_for_peer_" 22 deductedByPeerPrefix = "swap_deducted_by_peer_" 23 ) 24 25 // Addressbook maps peers to beneficaries, chequebooks and in reverse. 26 type Addressbook interface { 27 // Beneficiary returns the beneficiary for the given peer. 28 Beneficiary(peer swarm.Address) (beneficiary common.Address, known bool, err error) 29 // Chequebook returns the chequebook for the given peer. 30 Chequebook(peer swarm.Address) (chequebookAddress common.Address, known bool, err error) 31 // BeneficiaryPeer returns the peer for a beneficiary. 32 BeneficiaryPeer(beneficiary common.Address) (peer swarm.Address, known bool, err error) 33 // ChequebookPeer returns the peer for a beneficiary. 34 ChequebookPeer(chequebook common.Address) (peer swarm.Address, known bool, err error) 35 // PutBeneficiary stores the beneficiary for the given peer. 36 PutBeneficiary(peer swarm.Address, beneficiary common.Address) error 37 // PutChequebook stores the chequebook for the given peer. 38 PutChequebook(peer swarm.Address, chequebook common.Address) error 39 // AddDeductionFor peer stores the flag indicating the peer have already issued a cheque that has been deducted 40 AddDeductionFor(peer swarm.Address) error 41 // AddDeductionFor peer stores the flag indicating the peer have already received a cheque that has been deducted 42 AddDeductionBy(peer swarm.Address) error 43 // GetDeductionFor returns whether a peer have already issued a cheque that has been deducted 44 GetDeductionFor(peer swarm.Address) (bool, error) 45 // GetDeductionBy returns whether a peer have already received a cheque that has been deducted 46 GetDeductionBy(peer swarm.Address) (bool, error) 47 // MigratePeer returns whether a peer have already received a cheque that has been deducted 48 MigratePeer(oldPeer, newPeer swarm.Address) error 49 } 50 51 type addressbook struct { 52 store storage.StateStorer 53 } 54 55 // NewAddressbook creates a new addressbook using the store. 56 func NewAddressbook(store storage.StateStorer) Addressbook { 57 return &addressbook{ 58 store: store, 59 } 60 } 61 62 func (a *addressbook) MigratePeer(oldPeer, newPeer swarm.Address) error { 63 ba, known, err := a.Beneficiary(oldPeer) 64 if err != nil { 65 return err 66 } 67 if !known { 68 return errors.New("old beneficiary not known") 69 } 70 71 cb, known, err := a.Chequebook(oldPeer) 72 if err != nil { 73 return err 74 } 75 76 if err := a.PutBeneficiary(newPeer, ba); err != nil { 77 return err 78 } 79 80 if err := a.store.Delete(peerBeneficiaryKey(oldPeer)); err != nil { 81 return err 82 } 83 84 if known { 85 if err := a.PutChequebook(newPeer, cb); err != nil { 86 return err 87 } 88 if err := a.store.Delete(peerKey(oldPeer)); err != nil { 89 return err 90 } 91 } 92 93 return nil 94 } 95 96 // Beneficiary returns the beneficiary for the given peer. 97 func (a *addressbook) Beneficiary(peer swarm.Address) (beneficiary common.Address, known bool, err error) { 98 err = a.store.Get(peerBeneficiaryKey(peer), &beneficiary) 99 if err != nil { 100 if !errors.Is(err, storage.ErrNotFound) { 101 return common.Address{}, false, err 102 } 103 return common.Address{}, false, nil 104 } 105 return beneficiary, true, nil 106 } 107 108 // BeneficiaryPeer returns the peer for a beneficiary. 109 func (a *addressbook) BeneficiaryPeer(beneficiary common.Address) (peer swarm.Address, known bool, err error) { 110 err = a.store.Get(beneficiaryPeerKey(beneficiary), &peer) 111 if err != nil { 112 if !errors.Is(err, storage.ErrNotFound) { 113 return swarm.Address{}, false, err 114 } 115 return swarm.Address{}, false, nil 116 } 117 return peer, true, nil 118 } 119 120 // Chequebook returns the chequebook for the given peer. 121 func (a *addressbook) Chequebook(peer swarm.Address) (chequebookAddress common.Address, known bool, err error) { 122 err = a.store.Get(peerKey(peer), &chequebookAddress) 123 if err != nil { 124 if !errors.Is(err, storage.ErrNotFound) { 125 return common.Address{}, false, err 126 } 127 return common.Address{}, false, nil 128 } 129 return chequebookAddress, true, nil 130 } 131 132 // ChequebookPeer returns the peer for a beneficiary. 133 func (a *addressbook) ChequebookPeer(chequebook common.Address) (peer swarm.Address, known bool, err error) { 134 err = a.store.Get(chequebookPeerKey(chequebook), &peer) 135 if err != nil { 136 if !errors.Is(err, storage.ErrNotFound) { 137 return swarm.Address{}, false, err 138 } 139 return swarm.Address{}, false, nil 140 } 141 return peer, true, nil 142 } 143 144 // PutBeneficiary stores the beneficiary for the given peer. 145 func (a *addressbook) PutBeneficiary(peer swarm.Address, beneficiary common.Address) error { 146 err := a.store.Put(peerBeneficiaryKey(peer), beneficiary) 147 if err != nil { 148 return err 149 } 150 return a.store.Put(beneficiaryPeerKey(beneficiary), peer) 151 } 152 153 // PutChequebook stores the chequebook for the given peer. 154 func (a *addressbook) PutChequebook(peer swarm.Address, chequebook common.Address) error { 155 err := a.store.Put(peerKey(peer), chequebook) 156 if err != nil { 157 return err 158 } 159 return a.store.Put(chequebookPeerKey(chequebook), peer) 160 } 161 162 func (a *addressbook) AddDeductionFor(peer swarm.Address) error { 163 return a.store.Put(peerDeductedForKey(peer), struct{}{}) 164 } 165 166 func (a *addressbook) AddDeductionBy(peer swarm.Address) error { 167 return a.store.Put(peerDeductedByKey(peer), struct{}{}) 168 } 169 170 func (a *addressbook) GetDeductionFor(peer swarm.Address) (bool, error) { 171 var nothing struct{} 172 err := a.store.Get(peerDeductedForKey(peer), ¬hing) 173 if err != nil { 174 if !errors.Is(err, storage.ErrNotFound) { 175 return false, err 176 } 177 return false, nil 178 } 179 return true, nil 180 } 181 182 func (a *addressbook) GetDeductionBy(peer swarm.Address) (bool, error) { 183 var nothing struct{} 184 err := a.store.Get(peerDeductedByKey(peer), ¬hing) 185 if err != nil { 186 if !errors.Is(err, storage.ErrNotFound) { 187 return false, err 188 } 189 return false, nil 190 } 191 return true, nil 192 } 193 194 // peerKey computes the key where to store the chequebook from a peer. 195 func peerKey(peer swarm.Address) string { 196 return fmt.Sprintf("%s%s", peerPrefix, peer) 197 } 198 199 // chequebookPeerKey computes the key where to store the peer for a chequebook. 200 func chequebookPeerKey(chequebook common.Address) string { 201 return fmt.Sprintf("%s%x", peerChequebookPrefix, chequebook) 202 } 203 204 // peerBeneficiaryKey computes the key where to store the beneficiary for a peer. 205 func peerBeneficiaryKey(peer swarm.Address) string { 206 return fmt.Sprintf("%s%s", peerBeneficiaryPrefix, peer) 207 } 208 209 // beneficiaryPeerKey computes the key where to store the peer for a beneficiary. 210 func beneficiaryPeerKey(peer common.Address) string { 211 return fmt.Sprintf("%s%x", beneficiaryPeerPrefix, peer) 212 } 213 214 func peerDeductedByKey(peer swarm.Address) string { 215 return fmt.Sprintf("%s%s", deductedByPeerPrefix, peer.String()) 216 } 217 218 func peerDeductedForKey(peer swarm.Address) string { 219 return fmt.Sprintf("%s%s", deductedForPeerPrefix, peer.String()) 220 }