@ -82,7 +82,8 @@ func EthProtocol(txPool txPool, chainManager chainManager, blockPool blockPool)
}
// main entrypoint, wrappers starting a server running the eth protocol
// use this constructor to attach the protocol (class) to server caps
// use this constructor to attach the protocol ("class") to server caps
// the Dev p2p layer then runs the protocol instance on each peer
func EthProtocol ( eth backend ) * p2p . Protocol {
return & p2p . Protocol {
>> >> >> > initial commit for eth - p2p integration
@ -99,6 +100,7 @@ func EthProtocol(eth backend) *p2p.Protocol {
}
}
<< << << < HEAD
<< << << < HEAD
// the main loop that handles incoming messages
// note RemovePeer in the post-disconnect hook
@ -111,12 +113,20 @@ func runEthProtocol(txPool txPool, chainManager chainManager, blockPool blockPoo
peer : peer ,
id : ( string ) ( peer . Identity ( ) . Pubkey ( ) ) ,
== == == =
== == == =
// the main loop that handles incoming messages
// note RemovePeer in the post-disconnect hook
>> >> >> > eth protocol changes
func runEthProtocol ( eth backend , peer * p2p . Peer , rw p2p . MsgReadWriter ) ( err error ) {
self := & ethProtocol {
eth : eth ,
rw : rw ,
peer : peer ,
<< << << < HEAD
>> >> >> > initial commit for eth - p2p integration
== == == =
id : ( string ) ( peer . Identity ( ) . Pubkey ( ) ) ,
>> >> >> > eth protocol changes
}
err = self . handleStatus ( )
if err == nil {
@ -124,10 +134,14 @@ func runEthProtocol(eth backend, peer *p2p.Peer, rw p2p.MsgReadWriter) (err erro
for {
err = self . handle ( )
if err != nil {
<< << << < HEAD
<< << << < HEAD
self . blockPool . RemovePeer ( self . id )
== == == =
>> >> >> > initial commit for eth - p2p integration
== == == =
self . eth . RemovePeer ( self . id )
>> >> >> > eth protocol changes
break
}
}
@ -166,7 +180,11 @@ func (self *ethProtocol) handle() error {
return self . rw . EncodeMsg ( TxMsg , txsInterface ... )
case TxMsg :
<< << << < HEAD
>> >> >> > initial commit for eth - p2p integration
== == == =
// TODO: rework using lazy RLP stream
>> >> >> > eth protocol changes
var txs [ ] * types . Transaction
if err := msg . Decode ( & txs ) ; err != nil {
return ProtocolError ( ErrDecode , "%v" , err )
@ -192,12 +210,16 @@ func (self *ethProtocol) handle() error {
case BlockHashesMsg :
// TODO: redo using lazy decode , this way very inefficient on known chains
<< << << < HEAD
<< << << < HEAD
== == == =
>> >> >> > eth protocol changes
msgStream := rlp . NewListStream ( msg . Payload , uint64 ( msg . Size ) )
var err error
iter := func ( ) ( hash [ ] byte , ok bool ) {
hash , err = msgStream . Bytes ( )
if err == nil {
ok = true
<< << << < HEAD
}
return
}
@ -218,24 +240,35 @@ func (self *ethProtocol) handle() error {
fetchMore = self . eth . AddHash ( hash , self . peer )
if ! fetchMore {
break
== == == =
>> >> >> > eth protocol changes
}
return
}
if fetchMore {
return self . FetchHashes ( blockHashes [ len ( blockHashes ) - 1 ] )
self . eth . AddBlockHashes ( iter , self . id )
if err != nil && err != rlp . EOL {
return ProtocolError ( ErrDecode , "%v" , err )
}
case GetBlocksMsg :
<< << << < HEAD
// Limit to max 300 blocks
>> >> >> > initial commit for eth - p2p integration
== == == =
>> >> >> > eth protocol changes
var blockHashes [ ] [ ] byte
if err := msg . Decode ( & blockHashes ) ; err != nil {
return ProtocolError ( ErrDecode , "%v" , err )
}
<< << << < HEAD
<< << << < HEAD
max := int ( math . Min ( float64 ( len ( blockHashes ) ) , blockHashesBatchSize ) )
== == == =
max := int ( math . Min ( float64 ( len ( blockHashes ) ) , 300.0 ) )
>> >> >> > initial commit for eth - p2p integration
== == == =
max := int ( math . Min ( float64 ( len ( blockHashes ) ) , blockHashesBatchSize ) )
>> >> >> > eth protocol changes
var blocks [ ] interface { }
for i , hash := range blockHashes {
if i >= max {
@ -254,6 +287,9 @@ func (self *ethProtocol) handle() error {
case BlocksMsg :
<< << << < HEAD
<< << << < HEAD
== == == =
>> >> >> > eth protocol changes
msgStream := rlp . NewListStream ( msg . Payload , uint64 ( msg . Size ) )
for {
var block * types . Block
@ -262,6 +298,7 @@ func (self *ethProtocol) handle() error {
break
} else {
return ProtocolError ( ErrDecode , "%v" , err )
<< << << < HEAD
}
}
self . blockPool . AddBlock ( block , self . id )
@ -281,6 +318,13 @@ func (self *ethProtocol) handle() error {
}
}
>> >> >> > initial commit for eth - p2p integration
== == == =
}
}
if err := self . eth . AddBlock ( block , self . id ) ; err != nil {
return ProtocolError ( ErrInvalidBlock , "%v" , err )
}
>> >> >> > eth protocol changes
}
case NewBlockMsg :
@ -289,11 +333,18 @@ func (self *ethProtocol) handle() error {
return ProtocolError ( ErrDecode , "%v" , err )
}
<< << << < HEAD
<< << << < HEAD
== == == =
>> >> >> > eth protocol changes
hash := request . Block . Hash ( )
// to simplify backend interface adding a new block
// uses AddPeer followed by AddHashes, AddBlock only if peer is the best peer
// (or selected as new best peer)
<< << << < HEAD
if self . blockPool . AddPeer ( request . TD , hash , self . id , self . requestBlockHashes , self . requestBlocks , self . protoErrorDisconnect ) {
== == == =
if self . eth . AddPeer ( request . TD , hash , self . id , self . requestBlockHashes , self . requestBlocks , self . invalidBlock ) {
>> >> >> > eth protocol changes
called := true
iter := func ( ) ( hash [ ] byte , ok bool ) {
if called {
@ -303,6 +354,7 @@ func (self *ethProtocol) handle() error {
return
}
}
<< << << < HEAD
self . blockPool . AddBlockHashes ( iter , self . id )
self . blockPool . AddBlock ( request . Block , self . id )
== == == =
@ -314,6 +366,12 @@ func (self *ethProtocol) handle() error {
if fetchHashes {
return self . FetchHashes ( request . Block . Hash ( ) )
>> >> >> > initial commit for eth - p2p integration
== == == =
self . eth . AddBlockHashes ( iter , self . id )
if err := self . eth . AddBlock ( request . Block , self . id ) ; err != nil {
return ProtocolError ( ErrInvalidBlock , "%v" , err )
}
>> >> >> > eth protocol changes
}
default :
@ -389,6 +447,7 @@ func (self *ethProtocol) handleStatus() error {
return ProtocolError ( ErrProtocolVersionMismatch , "%d (!= %d)" , status . ProtocolVersion , ProtocolVersion )
}
<< << << < HEAD
<< << << < HEAD
self . peer . Infof ( "Peer is [eth] capable (%d/%d). TD = %v ~ %x" , status . ProtocolVersion , status . NetworkId , status . CurrentBlock )
@ -400,10 +459,16 @@ func (self *ethProtocol) handleStatus() error {
return self . FetchHashes ( status . CurrentBlock )
}
>> >> >> > initial commit for eth - p2p integration
== == == =
self . peer . Infof ( "Peer is [eth] capable (%d/%d). TD = %v ~ %x" , status . ProtocolVersion , status . NetworkId , status . CurrentBlock )
self . eth . AddPeer ( status . TD , status . CurrentBlock , self . id , self . requestBlockHashes , self . requestBlocks , self . invalidBlock )
>> >> >> > eth protocol changes
return nil
}
<< << << < HEAD
<< << << < HEAD
func ( self * ethProtocol ) requestBlockHashes ( from [ ] byte ) error {
self . peer . Debugf ( "fetching hashes (%d) %x...\n" , blockHashesBatchSize , from [ 0 : 4 ] )
@ -441,3 +506,29 @@ func (self *ethProtocol) FetchHashes(from []byte) error {
return self . rw . EncodeMsg ( GetBlockHashesMsg , from , blockHashesBatchSize )
}
>> >> >> > initial commit for eth - p2p integration
== == == =
func ( self * ethProtocol ) requestBlockHashes ( from [ ] byte ) error {
self . peer . Debugf ( "fetching hashes (%d) %x...\n" , blockHashesBatchSize , from [ 0 : 4 ] )
return self . rw . EncodeMsg ( GetBlockHashesMsg , from , blockHashesBatchSize )
}
func ( self * ethProtocol ) requestBlocks ( hashes [ ] [ ] byte ) error {
self . peer . Debugf ( "fetching %v blocks" , len ( hashes ) )
return self . rw . EncodeMsg ( GetBlocksMsg , ethutil . ByteSliceToInterface ( hashes ) )
}
func ( self * ethProtocol ) invalidBlock ( err error ) {
ProtocolError ( ErrInvalidBlock , "%v" , err )
self . peer . Disconnect ( p2p . DiscSubprotocolError )
}
func ( self * ethProtocol ) protoError ( code int , format string , params ... interface { } ) ( err * protocolError ) {
err = ProtocolError ( code , format , params ... )
if err . Fatal ( ) {
self . peer . Errorln ( err )
} else {
self . peer . Debugln ( err )
}
return
}
>> >> >> > eth protocol changes