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), &nothing)
   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), &nothing)
   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  }