aboutsummaryrefslogtreecommitdiffstats
path: root/p2p/message.go
diff options
context:
space:
mode:
Diffstat (limited to 'p2p/message.go')
-rw-r--r--p2p/message.go75
1 files changed, 75 insertions, 0 deletions
diff --git a/p2p/message.go b/p2p/message.go
new file mode 100644
index 000000000..4886eaa1f
--- /dev/null
+++ b/p2p/message.go
@@ -0,0 +1,75 @@
+package p2p
+
+import (
+ // "fmt"
+ "github.com/ethereum/eth-go/ethutil"
+)
+
+type MsgCode uint8
+
+type Msg struct {
+ code MsgCode // this is the raw code as per adaptive msg code scheme
+ data *ethutil.Value
+ encoded []byte
+}
+
+func (self *Msg) Code() MsgCode {
+ return self.code
+}
+
+func (self *Msg) Data() *ethutil.Value {
+ return self.data
+}
+
+func NewMsg(code MsgCode, params ...interface{}) (msg *Msg, err error) {
+
+ // // data := [][]interface{}{}
+ // data := []interface{}{}
+ // for _, value := range params {
+ // if encodable, ok := value.(ethutil.RlpEncodeDecode); ok {
+ // data = append(data, encodable.RlpValue())
+ // } else if raw, ok := value.([]interface{}); ok {
+ // data = append(data, raw)
+ // } else {
+ // // data = append(data, interface{}(raw))
+ // err = fmt.Errorf("Unable to encode object of type %T", value)
+ // return
+ // }
+ // }
+ return &Msg{
+ code: code,
+ data: ethutil.NewValue(interface{}(params)),
+ }, nil
+}
+
+func NewMsgFromBytes(encoded []byte) (msg *Msg, err error) {
+ value := ethutil.NewValueFromBytes(encoded)
+ // Type of message
+ code := value.Get(0).Uint()
+ // Actual data
+ data := value.SliceFrom(1)
+
+ msg = &Msg{
+ code: MsgCode(code),
+ data: data,
+ // data: ethutil.NewValue(data),
+ encoded: encoded,
+ }
+ return
+}
+
+func (self *Msg) Decode(offset MsgCode) {
+ self.code = self.code - offset
+}
+
+// encode takes an offset argument to implement adaptive message coding
+// the encoded message is memoized to make msgs relayed to several peers more efficient
+func (self *Msg) Encode(offset MsgCode) (res []byte) {
+ if len(self.encoded) == 0 {
+ res = ethutil.NewValue(append([]interface{}{byte(self.code + offset)}, self.data.Slice()...)).Encode()
+ self.encoded = res
+ } else {
+ res = self.encoded
+ }
+ return
+}