github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/p2pserver/common/common.go (about) 1 package common 2 3 import ( 4 "fmt" 5 "io" 6 "io/ioutil" 7 "time" 8 9 "github.com/sixexorg/magnetic-ring/common" 10 "github.com/sixexorg/magnetic-ring/rlp" 11 ) 12 13 type Msg struct { 14 Code uint64 15 Type string 16 Size uint32 // size of the paylod 17 Payload io.Reader 18 ReceivedAt time.Time 19 } 20 21 // for test ...... 22 func EncAndDec(msgcode uint64, data interface{}) error { 23 size, r, err := rlp.EncodeToReader(data) 24 if err != nil { 25 return err 26 } 27 rawmsg := Msg{Code: msgcode, Size: uint32(size), Payload: r} 28 29 codestr := TransCodeUToStr(rawmsg.Code) 30 fmt.Println(" ******** codestr:", codestr) 31 val, err := MakeEmptyMessage(codestr) 32 if err != nil { 33 return err 34 } 35 36 s := rlp.NewStream(rawmsg.Payload, uint64(rawmsg.Size)) 37 if err := s.Decode(val); err != nil { 38 return newPeerError(errInvalidMsg, "(code %x) (size %d) %v", rawmsg.Code, rawmsg.Size, err) 39 // return errors.New("(code %x) (size %d) %v") 40 } 41 return nil 42 } 43 44 // 45 func Send(w MsgWriter, msgcode uint64, data interface{}) error { 46 size, r, err := rlp.EncodeToReader(data) 47 if err != nil { 48 return err 49 } 50 return w.WriteMsg(Msg{Code: msgcode, Size: uint32(size), Payload: r}) 51 } 52 53 // Decode parses the RLP content of a message into 54 // the given value, which must be a pointer. 55 // 56 // For the decoding rules, please see package rlp. 57 func (msg Msg) Decode(val interface{}) error { 58 s := rlp.NewStream(msg.Payload, uint64(msg.Size)) 59 if err := s.Decode(val); err != nil { 60 return newPeerError(errInvalidMsg, "(code %d) (size %d) %v", msg.Code, msg.Size, err) 61 // return errors.New("(code %x) (size %d) %v") 62 } 63 return nil 64 } 65 66 func (msg Msg) String() string { 67 return fmt.Sprintf("msg #%v (%v bytes)", msg.Code, msg.Size) 68 } 69 70 // Discard reads any remaining payload data into a black hole. 71 func (msg Msg) Discard() error { 72 _, err := io.Copy(ioutil.Discard, msg.Payload) 73 return err 74 } 75 func (msg *Msg) DistinctSk() (common.Hash, error) { 76 buff, err := rlp.EncodeToBytes(msg) 77 if err != nil { 78 return common.Hash{}, err 79 } 80 return common.ParseHashFromBytes(common.Sha256(buff)) 81 } 82 83 type MsgReader interface { 84 ReadMsg() (Msg, error) 85 } 86 87 type MsgWriter interface { 88 // WriteMsg sends a message. It will block until the message's 89 // Payload has been consumed by the other end. 90 // 91 // Note that messages can be sent only once because their 92 // payload reader is drained. 93 WriteMsg(Msg) error 94 } 95 96 // MsgReadWriter provides reading and writing of encoded messages. 97 // Implementations should ensure that ReadMsg and WriteMsg can be 98 // called simultaneously from multiple goroutines. 99 type MsgReadWriter interface { 100 MsgReader 101 MsgWriter 102 Close(err ...error) 103 }