go-ethereum/swarm/swap/protocol.go
2018-10-12 11:18:35 -05:00

177 lines
5 KiB
Go

// Copyright 2018 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
// +build !nopssprotocol
package swap
import (
"sync"
"time"
"github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/p2p/protocols"
"github.com/ethereum/go-ethereum/rlp"
)
const (
IsActiveProtocol = true
)
// Convenience wrapper for devp2p protocol messages for transport over pss
type ProtocolMsg struct {
Code uint64
Size uint32
Payload []byte
ReceivedAt time.Time
}
// Creates a ProtocolMsg
func NewProtocolMsg(code uint64, msg interface{}) ([]byte, error) {
rlpdata, err := rlp.EncodeToBytes(msg)
if err != nil {
return nil, err
}
// TODO verify that nested structs cannot be used in rlp
smsg := &ProtocolMsg{
Code: code,
Size: uint32(len(rlpdata)),
Payload: rlpdata,
}
return rlp.EncodeToBytes(smsg)
}
// Protocol options to be passed to a new Protocol instance
//
// The parameters specify which encryption schemes to allow
type ProtocolParams struct {
}
// Convenience object for emulation devp2p over pss
type Protocol struct {
proto *p2p.Protocol
spec *protocols.Spec
RWPoolMu sync.Mutex
}
/*
// Activates devp2p emulation over a specific pss topic
//
// One or both encryption schemes must be specified. If
// only one is specified, the protocol will not be valid
// for the other, and will make the message handler
// return errors
func RegisterProtocol(ps *Pss, topic *Topic, spec *protocols.Spec, targetprotocol *p2p.Protocol, options *ProtocolParams) (*Protocol, error) {
if !options.Asymmetric && !options.Symmetric {
return nil, fmt.Errorf("specify at least one of asymmetric or symmetric messaging mode")
}
pp := &Protocol{
Pss: ps,
proto: targetprotocol,
topic: topic,
spec: spec,
pubKeyRWPool: make(map[string]p2p.MsgReadWriter),
symKeyRWPool: make(map[string]p2p.MsgReadWriter),
Asymmetric: options.Asymmetric,
Symmetric: options.Symmetric,
}
return pp, nil
}
*/
// Generic handler for incoming messages over devp2p emulation
//
// To be passed to pss.Register()
//
// Will run the protocol on a new incoming peer, provided that
// the encryption key of the message has a match in the internal
// pss keypool
//
// Fails if protocol is not valid for the message encryption scheme,
// if adding a new peer fails, or if the message is not a serialized
// p2p.Msg (which it always will be if it is sent from this object).
func (p *Protocol) Handle(msg []byte, peer *p2p.Peer, asymmetric bool, keyid string) error {
return nil
}
/*
// Runs an emulated pss Protocol on the specified peer,
// linked to a specific topic
// `key` and `asymmetric` specifies what encryption key
// to link the peer to.
// The key must exist in the pss store prior to adding the peer.
func (p *Protocol) AddPeer(peer *p2p.Peer, topic Topic, asymmetric bool, key string) (p2p.MsgReadWriter, error) {
rw := &PssReadWriter{
Pss: p.Pss,
rw: make(chan p2p.Msg),
spec: p.spec,
topic: p.topic,
key: key,
}
if asymmetric {
rw.sendFunc = p.Pss.SendAsym
} else {
rw.sendFunc = p.Pss.SendSym
}
if asymmetric {
p.Pss.pubKeyPoolMu.Lock()
if _, ok := p.Pss.pubKeyPool[key]; !ok {
return nil, fmt.Errorf("asym key does not exist: %s", key)
}
p.Pss.pubKeyPoolMu.Unlock()
p.RWPoolMu.Lock()
p.pubKeyRWPool[key] = rw
p.RWPoolMu.Unlock()
} else {
p.Pss.symKeyPoolMu.Lock()
if _, ok := p.Pss.symKeyPool[key]; !ok {
return nil, fmt.Errorf("symkey does not exist: %s", key)
}
p.Pss.symKeyPoolMu.Unlock()
p.RWPoolMu.Lock()
p.symKeyRWPool[key] = rw
p.RWPoolMu.Unlock()
}
go func() {
err := p.proto.Run(peer, rw)
log.Warn(fmt.Sprintf("pss vprotocol quit on %v topic %v: %v", peer, topic, err))
}()
return rw, nil
}
func (p *Protocol) RemovePeer(asymmetric bool, key string) {
log.Debug("closing pss peer", "asym", asymmetric, "key", key)
p.RWPoolMu.Lock()
defer p.RWPoolMu.Unlock()
if asymmetric {
rw := p.pubKeyRWPool[key].(*PssReadWriter)
rw.closed = true
delete(p.pubKeyRWPool, key)
} else {
rw := p.symKeyRWPool[key].(*PssReadWriter)
rw.closed = true
delete(p.symKeyRWPool, key)
}
}
// Uniform translation of protocol specifiers to topic
func ProtocolTopic(spec *protocols.Spec) Topic {
return BytesToTopic([]byte(fmt.Sprintf("%s:%d", spec.Name, spec.Version)))
}
*/