76 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			76 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
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
 | 
						|
}
 |