github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/p2p/enr/entries.go (about)

     1  package enr
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"fmt"
     6  	"io"
     7  	"net"
     8  
     9  	"github.com/quickchainproject/quickchain/crypto"
    10  	"github.com/quickchainproject/quickchain/rlp"
    11  )
    12  
    13  // Entry is implemented by known node record entry types.
    14  //
    15  // To define a new entry that is to be included in a node record,
    16  // create a Go type that satisfies this interface. The type should
    17  // also implement rlp.Decoder if additional checks are needed on the value.
    18  type Entry interface {
    19  	ENRKey() string
    20  }
    21  
    22  type generic struct {
    23  	key   string
    24  	value interface{}
    25  }
    26  
    27  func (g generic) ENRKey() string { return g.key }
    28  
    29  func (g generic) EncodeRLP(w io.Writer) error {
    30  	return rlp.Encode(w, g.value)
    31  }
    32  
    33  func (g *generic) DecodeRLP(s *rlp.Stream) error {
    34  	return s.Decode(g.value)
    35  }
    36  
    37  // WithEntry wraps any value with a key name. It can be used to set and load arbitrary values
    38  // in a record. The value v must be supported by rlp. To use WithEntry with Load, the value
    39  // must be a pointer.
    40  func WithEntry(k string, v interface{}) Entry {
    41  	return &generic{key: k, value: v}
    42  }
    43  
    44  // DiscPort is the "discv5" key, which holds the UDP port for discovery v5.
    45  type DiscPort uint16
    46  
    47  func (v DiscPort) ENRKey() string { return "discv5" }
    48  
    49  // ID is the "id" key, which holds the name of the identity scheme.
    50  type ID string
    51  
    52  func (v ID) ENRKey() string { return "id" }
    53  
    54  // IP4 is the "ip4" key, which holds a 4-byte IPv4 address.
    55  type IP4 net.IP
    56  
    57  func (v IP4) ENRKey() string { return "ip4" }
    58  
    59  // EncodeRLP implements rlp.Encoder.
    60  func (v IP4) EncodeRLP(w io.Writer) error {
    61  	ip4 := net.IP(v).To4()
    62  	if ip4 == nil {
    63  		return fmt.Errorf("invalid IPv4 address: %v", v)
    64  	}
    65  	return rlp.Encode(w, ip4)
    66  }
    67  
    68  // DecodeRLP implements rlp.Decoder.
    69  func (v *IP4) DecodeRLP(s *rlp.Stream) error {
    70  	if err := s.Decode((*net.IP)(v)); err != nil {
    71  		return err
    72  	}
    73  	if len(*v) != 4 {
    74  		return fmt.Errorf("invalid IPv4 address, want 4 bytes: %v", *v)
    75  	}
    76  	return nil
    77  }
    78  
    79  // IP6 is the "ip6" key, which holds a 16-byte IPv6 address.
    80  type IP6 net.IP
    81  
    82  func (v IP6) ENRKey() string { return "ip6" }
    83  
    84  // EncodeRLP implements rlp.Encoder.
    85  func (v IP6) EncodeRLP(w io.Writer) error {
    86  	ip6 := net.IP(v)
    87  	return rlp.Encode(w, ip6)
    88  }
    89  
    90  // DecodeRLP implements rlp.Decoder.
    91  func (v *IP6) DecodeRLP(s *rlp.Stream) error {
    92  	if err := s.Decode((*net.IP)(v)); err != nil {
    93  		return err
    94  	}
    95  	if len(*v) != 16 {
    96  		return fmt.Errorf("invalid IPv6 address, want 16 bytes: %v", *v)
    97  	}
    98  	return nil
    99  }
   100  
   101  // Secp256k1 is the "secp256k1" key, which holds a public key.
   102  type Secp256k1 ecdsa.PublicKey
   103  
   104  func (v Secp256k1) ENRKey() string { return "secp256k1" }
   105  
   106  // EncodeRLP implements rlp.Encoder.
   107  func (v Secp256k1) EncodeRLP(w io.Writer) error {
   108  	return rlp.Encode(w, crypto.CompressPubkey((*ecdsa.PublicKey)(&v)))
   109  }
   110  
   111  // DecodeRLP implements rlp.Decoder.
   112  func (v *Secp256k1) DecodeRLP(s *rlp.Stream) error {
   113  	buf, err := s.Bytes()
   114  	if err != nil {
   115  		return err
   116  	}
   117  	pk, err := crypto.DecompressPubkey(buf)
   118  	if err != nil {
   119  		return err
   120  	}
   121  	*v = (Secp256k1)(*pk)
   122  	return nil
   123  }
   124  
   125  // KeyError is an error related to a key.
   126  type KeyError struct {
   127  	Key string
   128  	Err error
   129  }
   130  
   131  // Error implements error.
   132  func (err *KeyError) Error() string {
   133  	if err.Err == errNotFound {
   134  		return fmt.Sprintf("missing ENR key %q", err.Key)
   135  	}
   136  	return fmt.Sprintf("ENR key %q: %v", err.Key, err.Err)
   137  }
   138  
   139  // IsNotFound reports whether the given error means that a key/value pair is
   140  // missing from a record.
   141  func IsNotFound(err error) bool {
   142  	kerr, ok := err.(*KeyError)
   143  	return ok && kerr.Err == errNotFound
   144  }