github.com/oskarth/go-ethereum@v1.6.8-0.20191013093314-dac24a9d3494/swarm/pss/types.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package pss
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"sync"
    23  
    24  	"github.com/ethereum/go-ethereum/common"
    25  	"github.com/ethereum/go-ethereum/common/hexutil"
    26  	"github.com/ethereum/go-ethereum/p2p"
    27  	"github.com/ethereum/go-ethereum/rlp"
    28  	"github.com/ethereum/go-ethereum/swarm/storage"
    29  	whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
    30  )
    31  
    32  const (
    33  	defaultWhisperTTL = 6000
    34  )
    35  
    36  const (
    37  	pssControlSym = 1
    38  	pssControlRaw = 1 << 1
    39  )
    40  
    41  var (
    42  	topicHashMutex = sync.Mutex{}
    43  	topicHashFunc  = storage.MakeHashFunc("SHA256")()
    44  	rawTopic       = Topic{}
    45  )
    46  
    47  // Topic is the PSS encapsulation of the Whisper topic type
    48  type Topic whisper.TopicType
    49  
    50  func (t *Topic) String() string {
    51  	return hexutil.Encode(t[:])
    52  }
    53  
    54  // MarshalJSON implements the json.Marshaler interface
    55  func (t Topic) MarshalJSON() (b []byte, err error) {
    56  	return json.Marshal(t.String())
    57  }
    58  
    59  // MarshalJSON implements the json.Marshaler interface
    60  func (t *Topic) UnmarshalJSON(input []byte) error {
    61  	topicbytes, err := hexutil.Decode(string(input[1 : len(input)-1]))
    62  	if err != nil {
    63  		return err
    64  	}
    65  	copy(t[:], topicbytes)
    66  	return nil
    67  }
    68  
    69  // PssAddress is an alias for []byte. It represents a variable length address
    70  type PssAddress []byte
    71  
    72  // MarshalJSON implements the json.Marshaler interface
    73  func (a PssAddress) MarshalJSON() ([]byte, error) {
    74  	return json.Marshal(hexutil.Encode(a[:]))
    75  }
    76  
    77  // UnmarshalJSON implements the json.Marshaler interface
    78  func (a *PssAddress) UnmarshalJSON(input []byte) error {
    79  	b, err := hexutil.Decode(string(input[1 : len(input)-1]))
    80  	if err != nil {
    81  		return err
    82  	}
    83  	for _, bb := range b {
    84  		*a = append(*a, bb)
    85  	}
    86  	return nil
    87  }
    88  
    89  // holds the digest of a message used for caching
    90  type pssDigest [digestLength]byte
    91  
    92  // conceals bitwise operations on the control flags byte
    93  type msgParams struct {
    94  	raw bool
    95  	sym bool
    96  }
    97  
    98  func newMsgParamsFromBytes(paramBytes []byte) *msgParams {
    99  	if len(paramBytes) != 1 {
   100  		return nil
   101  	}
   102  	return &msgParams{
   103  		raw: paramBytes[0]&pssControlRaw > 0,
   104  		sym: paramBytes[0]&pssControlSym > 0,
   105  	}
   106  }
   107  
   108  func (m *msgParams) Bytes() (paramBytes []byte) {
   109  	var b byte
   110  	if m.raw {
   111  		b |= pssControlRaw
   112  	}
   113  	if m.sym {
   114  		b |= pssControlSym
   115  	}
   116  	paramBytes = append(paramBytes, b)
   117  	return paramBytes
   118  }
   119  
   120  // PssMsg encapsulates messages transported over pss.
   121  type PssMsg struct {
   122  	To      []byte
   123  	Control []byte
   124  	Expire  uint32
   125  	Payload *whisper.Envelope
   126  }
   127  
   128  func newPssMsg(param *msgParams) *PssMsg {
   129  	return &PssMsg{
   130  		Control: param.Bytes(),
   131  	}
   132  }
   133  
   134  // message is flagged as raw / external encryption
   135  func (msg *PssMsg) isRaw() bool {
   136  	return msg.Control[0]&pssControlRaw > 0
   137  }
   138  
   139  // message is flagged as symmetrically encrypted
   140  func (msg *PssMsg) isSym() bool {
   141  	return msg.Control[0]&pssControlSym > 0
   142  }
   143  
   144  // serializes the message for use in cache
   145  func (msg *PssMsg) serialize() []byte {
   146  	rlpdata, _ := rlp.EncodeToBytes(struct {
   147  		To      []byte
   148  		Payload *whisper.Envelope
   149  	}{
   150  		To:      msg.To,
   151  		Payload: msg.Payload,
   152  	})
   153  	return rlpdata
   154  }
   155  
   156  // String representation of PssMsg
   157  func (msg *PssMsg) String() string {
   158  	return fmt.Sprintf("PssMsg: Recipient: %x", common.ToHex(msg.To))
   159  }
   160  
   161  // Signature for a message handler function for a PssMsg
   162  //
   163  // Implementations of this type are passed to Pss.Register together with a topic,
   164  type Handler func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error
   165  
   166  // the stateStore handles saving and loading PSS peers and their corresponding keys
   167  // it is currently unimplemented
   168  type stateStore struct {
   169  	values map[string][]byte
   170  }
   171  
   172  func (store *stateStore) Load(key string) ([]byte, error) {
   173  	return nil, nil
   174  }
   175  
   176  func (store *stateStore) Save(key string, v []byte) error {
   177  	return nil
   178  }
   179  
   180  // BytesToTopic hashes an arbitrary length byte slice and truncates it to the length of a topic, using only the first bytes of the digest
   181  func BytesToTopic(b []byte) Topic {
   182  	topicHashMutex.Lock()
   183  	defer topicHashMutex.Unlock()
   184  	topicHashFunc.Reset()
   185  	topicHashFunc.Write(b)
   186  	return Topic(whisper.BytesToTopic(topicHashFunc.Sum(nil)))
   187  }