mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 20:56:42 +00:00
Felix' changes from PR https://github.com/ethereum/go-ethereum/pull/303
This commit is contained in:
parent
6ef20e84cf
commit
52be0fb2c2
3 changed files with 73 additions and 2 deletions
|
|
@ -174,6 +174,7 @@ func runBzzProtocol(netStore *NetStore, p *p2p.Peer, rw p2p.MsgReadWriter) (err
|
||||||
|
|
||||||
func (self *bzzProtocol) handle() error {
|
func (self *bzzProtocol) handle() error {
|
||||||
msg, err := self.rw.ReadMsg()
|
msg, err := self.rw.ReadMsg()
|
||||||
|
dpaLogger.Debugf("Incoming MSG: %v", msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,48 @@ type Encoder interface {
|
||||||
EncodeRLP(io.Writer) error
|
EncodeRLP(io.Writer) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flat wraps a value (which must encode as a list) so
|
||||||
|
// it encodes as the list's elements.
|
||||||
|
//
|
||||||
|
// Example: suppose you have defined a type
|
||||||
|
//
|
||||||
|
// type foo struct { A, B uint }
|
||||||
|
//
|
||||||
|
// Under normal encoding rules,
|
||||||
|
//
|
||||||
|
// rlp.Encode(foo{1, 2}) --> 0xC20102
|
||||||
|
//
|
||||||
|
// This function can help you achieve the following encoding:
|
||||||
|
//
|
||||||
|
// rlp.Encode(rlp.Flat(foo{1, 2})) --> 0x0102
|
||||||
|
func Flat(val interface{}) Encoder {
|
||||||
|
return flatenc{val}
|
||||||
|
}
|
||||||
|
|
||||||
|
type flatenc struct{ val interface{} }
|
||||||
|
|
||||||
|
func (e flatenc) EncodeRLP(out io.Writer) error {
|
||||||
|
// record current output position
|
||||||
|
var (
|
||||||
|
eb = out.(*encbuf)
|
||||||
|
prevstrsize = len(eb.str)
|
||||||
|
prevnheads = len(eb.lheads)
|
||||||
|
)
|
||||||
|
if err := eb.encode(e.val); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// check that a new list header has appeared
|
||||||
|
if len(eb.lheads) == prevnheads || eb.lheads[prevnheads].offset == prevstrsize-1 {
|
||||||
|
return fmt.Errorf("rlp.Flat: %T did not encode as list", e.val)
|
||||||
|
}
|
||||||
|
// remove the new list header
|
||||||
|
newhead := eb.lheads[prevnheads]
|
||||||
|
copy(eb.lheads[prevnheads:], eb.lheads[prevnheads+1:])
|
||||||
|
eb.lheads = eb.lheads[:len(eb.lheads)-1]
|
||||||
|
eb.lhsize -= newhead.tagsize()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Encode writes the RLP encoding of val to w. Note that Encode may
|
// Encode writes the RLP encoding of val to w. Note that Encode may
|
||||||
// perform many small writes in some cases. Consider making w
|
// perform many small writes in some cases. Consider making w
|
||||||
// buffered.
|
// buffered.
|
||||||
|
|
@ -123,6 +165,13 @@ func (head *listhead) encode(buf []byte) []byte {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (head *listhead) tagsize() int {
|
||||||
|
if head.size < 56 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return 1 + intsize(uint64(head.size))
|
||||||
|
}
|
||||||
|
|
||||||
func newencbuf() *encbuf {
|
func newencbuf() *encbuf {
|
||||||
return &encbuf{sizebuf: make([]byte, 9)}
|
return &encbuf{sizebuf: make([]byte, 9)}
|
||||||
}
|
}
|
||||||
|
|
@ -280,7 +329,6 @@ func (r *encReader) next() []byte {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
encoderInterface = reflect.TypeOf(new(Encoder)).Elem()
|
encoderInterface = reflect.TypeOf(new(Encoder)).Elem()
|
||||||
emptyInterface = reflect.TypeOf(new(interface{})).Elem()
|
|
||||||
big0 = big.NewInt(0)
|
big0 = big.NewInt(0)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -292,7 +340,7 @@ func makeWriter(typ reflect.Type) (writer, error) {
|
||||||
return writeEncoder, nil
|
return writeEncoder, nil
|
||||||
case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface):
|
case kind != reflect.Ptr && reflect.PtrTo(typ).Implements(encoderInterface):
|
||||||
return writeEncoderNoPtr, nil
|
return writeEncoderNoPtr, nil
|
||||||
case typ == emptyInterface:
|
case kind == reflect.Interface:
|
||||||
return writeInterface, nil
|
return writeInterface, nil
|
||||||
case typ.AssignableTo(reflect.PtrTo(bigInt)):
|
case typ.AssignableTo(reflect.PtrTo(bigInt)):
|
||||||
return writeBigIntPtr, nil
|
return writeBigIntPtr, nil
|
||||||
|
|
|
||||||
|
|
@ -32,9 +32,19 @@ func (e byteEncoder) EncodeRLP(w io.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type encodableReader struct {
|
||||||
|
A, B uint
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *encodableReader) Read(b []byte) (int, error) {
|
||||||
|
panic("called")
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_ = Encoder(&testEncoder{})
|
_ = Encoder(&testEncoder{})
|
||||||
_ = Encoder(byteEncoder(0))
|
_ = Encoder(byteEncoder(0))
|
||||||
|
|
||||||
|
reader io.Reader = &encodableReader{1, 2}
|
||||||
)
|
)
|
||||||
|
|
||||||
type encTest struct {
|
type encTest struct {
|
||||||
|
|
@ -167,6 +177,15 @@ var encTests = []encTest{
|
||||||
{val: &recstruct{5, nil}, output: "C205C0"},
|
{val: &recstruct{5, nil}, output: "C205C0"},
|
||||||
{val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"},
|
{val: &recstruct{5, &recstruct{4, &recstruct{3, nil}}}, output: "C605C404C203C0"},
|
||||||
|
|
||||||
|
// flat
|
||||||
|
{val: Flat(uint(1)), error: "rlp.Flat: uint did not encode as list"},
|
||||||
|
{val: Flat(simplestruct{A: 3, B: "foo"}), output: "0383666F6F"},
|
||||||
|
{
|
||||||
|
// value generates more list headers after the Flat
|
||||||
|
val: []interface{}{"foo", []uint{1, 2}, Flat([]uint{3, 4}), []uint{5, 6}, "bar"},
|
||||||
|
output: "D083666F6FC201020304C2050683626172",
|
||||||
|
},
|
||||||
|
|
||||||
// nil
|
// nil
|
||||||
{val: (*uint)(nil), output: "80"},
|
{val: (*uint)(nil), output: "80"},
|
||||||
{val: (*string)(nil), output: "80"},
|
{val: (*string)(nil), output: "80"},
|
||||||
|
|
@ -176,6 +195,9 @@ var encTests = []encTest{
|
||||||
{val: (*[]struct{ uint })(nil), output: "C0"},
|
{val: (*[]struct{ uint })(nil), output: "C0"},
|
||||||
{val: (*interface{})(nil), output: "C0"},
|
{val: (*interface{})(nil), output: "C0"},
|
||||||
|
|
||||||
|
// interfaces
|
||||||
|
{val: []io.Reader{reader}, output: "C3C20102"}, // the contained value is a struct
|
||||||
|
|
||||||
// Encoder
|
// Encoder
|
||||||
{val: (*testEncoder)(nil), output: "00000000"},
|
{val: (*testEncoder)(nil), output: "00000000"},
|
||||||
{val: &testEncoder{}, output: "00010001000100010001"},
|
{val: &testEncoder{}, output: "00010001000100010001"},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue