github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/swarm/pss/api.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:48</date>
    10  //</624342677080510464>
    11  
    12  //
    13  //
    14  //
    15  //
    16  //
    17  //
    18  //
    19  //
    20  //
    21  //
    22  //
    23  //
    24  //
    25  //
    26  //
    27  
    28  package pss
    29  
    30  import (
    31  	"context"
    32  	"errors"
    33  	"fmt"
    34  
    35  	"github.com/ethereum/go-ethereum/common/hexutil"
    36  	"github.com/ethereum/go-ethereum/crypto"
    37  	"github.com/ethereum/go-ethereum/p2p"
    38  	"github.com/ethereum/go-ethereum/rpc"
    39  	"github.com/ethereum/go-ethereum/swarm/log"
    40  )
    41  
    42  //
    43  //
    44  type APIMsg struct {
    45  	Msg        hexutil.Bytes
    46  	Asymmetric bool
    47  	Key        string
    48  }
    49  
    50  //
    51  type API struct {
    52  	*Pss
    53  }
    54  
    55  func NewAPI(ps *Pss) *API {
    56  	return &API{Pss: ps}
    57  }
    58  
    59  //
    60  //
    61  //
    62  //
    63  //
    64  //
    65  func (pssapi *API) Receive(ctx context.Context, topic Topic) (*rpc.Subscription, error) {
    66  	notifier, supported := rpc.NotifierFromContext(ctx)
    67  	if !supported {
    68  		return nil, fmt.Errorf("Subscribe not supported")
    69  	}
    70  
    71  	psssub := notifier.CreateSubscription()
    72  
    73  	handler := func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error {
    74  		apimsg := &APIMsg{
    75  			Msg:        hexutil.Bytes(msg),
    76  			Asymmetric: asymmetric,
    77  			Key:        keyid,
    78  		}
    79  		if err := notifier.Notify(psssub.ID, apimsg); err != nil {
    80  			log.Warn(fmt.Sprintf("notification on pss sub topic rpc (sub %v) msg %v failed!", psssub.ID, msg))
    81  		}
    82  		return nil
    83  	}
    84  
    85  	deregf := pssapi.Register(&topic, handler)
    86  	go func() {
    87  		defer deregf()
    88  		select {
    89  		case err := <-psssub.Err():
    90  			log.Warn(fmt.Sprintf("caught subscription error in pss sub topic %x: %v", topic, err))
    91  		case <-notifier.Closed():
    92  			log.Warn(fmt.Sprintf("rpc sub notifier closed"))
    93  		}
    94  	}()
    95  
    96  	return psssub, nil
    97  }
    98  
    99  func (pssapi *API) GetAddress(topic Topic, asymmetric bool, key string) (PssAddress, error) {
   100  	var addr *PssAddress
   101  	if asymmetric {
   102  		peer, ok := pssapi.Pss.pubKeyPool[key][topic]
   103  		if !ok {
   104  			return nil, fmt.Errorf("pubkey/topic pair %x/%x doesn't exist", key, topic)
   105  		}
   106  		addr = peer.address
   107  	} else {
   108  		peer, ok := pssapi.Pss.symKeyPool[key][topic]
   109  		if !ok {
   110  			return nil, fmt.Errorf("symkey/topic pair %x/%x doesn't exist", key, topic)
   111  		}
   112  		addr = peer.address
   113  
   114  	}
   115  	return *addr, nil
   116  }
   117  
   118  //
   119  func (pssapi *API) BaseAddr() (PssAddress, error) {
   120  	return PssAddress(pssapi.Pss.BaseAddr()), nil
   121  }
   122  
   123  //
   124  func (pssapi *API) GetPublicKey() (keybytes hexutil.Bytes) {
   125  	key := pssapi.Pss.PublicKey()
   126  	keybytes = crypto.FromECDSAPub(key)
   127  	return keybytes
   128  }
   129  
   130  //
   131  func (pssapi *API) SetPeerPublicKey(pubkey hexutil.Bytes, topic Topic, addr PssAddress) error {
   132  	pk, err := crypto.UnmarshalPubkey(pubkey)
   133  	if err != nil {
   134  		return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkey)
   135  	}
   136  	err = pssapi.Pss.SetPeerPublicKey(pk, topic, &addr)
   137  	if err != nil {
   138  		return fmt.Errorf("Invalid key: %x", pk)
   139  	}
   140  	return nil
   141  }
   142  
   143  func (pssapi *API) GetSymmetricKey(symkeyid string) (hexutil.Bytes, error) {
   144  	symkey, err := pssapi.Pss.GetSymmetricKey(symkeyid)
   145  	return hexutil.Bytes(symkey), err
   146  }
   147  
   148  func (pssapi *API) GetSymmetricAddressHint(topic Topic, symkeyid string) (PssAddress, error) {
   149  	return *pssapi.Pss.symKeyPool[symkeyid][topic].address, nil
   150  }
   151  
   152  func (pssapi *API) GetAsymmetricAddressHint(topic Topic, pubkeyid string) (PssAddress, error) {
   153  	return *pssapi.Pss.pubKeyPool[pubkeyid][topic].address, nil
   154  }
   155  
   156  func (pssapi *API) StringToTopic(topicstring string) (Topic, error) {
   157  	topicbytes := BytesToTopic([]byte(topicstring))
   158  	if topicbytes == rawTopic {
   159  		return rawTopic, errors.New("Topic string hashes to 0x00000000 and cannot be used")
   160  	}
   161  	return topicbytes, nil
   162  }
   163  
   164  func (pssapi *API) SendAsym(pubkeyhex string, topic Topic, msg hexutil.Bytes) error {
   165  	return pssapi.Pss.SendAsym(pubkeyhex, topic, msg[:])
   166  }
   167  
   168  func (pssapi *API) SendSym(symkeyhex string, topic Topic, msg hexutil.Bytes) error {
   169  	return pssapi.Pss.SendSym(symkeyhex, topic, msg[:])
   170  }
   171  
   172  func (pssapi *API) GetPeerTopics(pubkeyhex string) ([]Topic, error) {
   173  	topics, _, err := pssapi.Pss.GetPublickeyPeers(pubkeyhex)
   174  	return topics, err
   175  
   176  }
   177  
   178  func (pssapi *API) GetPeerAddress(pubkeyhex string, topic Topic) (PssAddress, error) {
   179  	return pssapi.Pss.getPeerAddress(pubkeyhex, topic)
   180  }
   181