From 76ee927d608cdb9bfa792637a4a12508ba86e1d0 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Mon, 16 May 2022 11:32:25 +0800 Subject: [PATCH 1/5] Fix crash when faulty node send nil header to syncer --- protocol/skeleton.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/protocol/skeleton.go b/protocol/skeleton.go index 1a20303d9d..1af4968099 100644 --- a/protocol/skeleton.go +++ b/protocol/skeleton.go @@ -2,12 +2,17 @@ package protocol import ( "context" + "errors" "fmt" "github.com/dogechain-lab/jury/protocol/proto" "github.com/dogechain-lab/jury/types" ) +var ( + ErrNilHeaderRequest = errors.New("header request spec is nil") +) + func getHeaders(clt proto.V1Client, req *proto.GetHeadersRequest) ([]*types.Header, error) { resp, err := clt.GetHeaders(context.Background(), req) if err != nil { @@ -17,6 +22,11 @@ func getHeaders(clt proto.V1Client, req *proto.GetHeadersRequest) ([]*types.Head headers := []*types.Header{} for _, obj := range resp.Objs { + if obj.Spec == nil { + // this nil header comes from a faulty node, reject all blocks of it. + return nil, ErrNilHeaderRequest + } + header := &types.Header{} if err := header.UnmarshalRLP(obj.Spec.Value); err != nil { return nil, err From f69bdea348da8171a0458a64b22adcef5e2c4d68 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Mon, 16 May 2022 12:05:00 +0800 Subject: [PATCH 2/5] Fix crash when faulty node send single nil header to syncer --- protocol/syncer.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/protocol/syncer.go b/protocol/syncer.go index 09ec93be3e..31641c6a31 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -722,6 +722,10 @@ func getHeader(clt proto.V1Client, num *uint64, hash *types.Hash) (*types.Header return nil, fmt.Errorf("unexpected more than 1 result") } + if resp.Objs[0].Spec == nil || len(resp.Objs[0].Spec.Value) == 0 { + return nil, ErrNilHeaderRequest + } + header := &types.Header{} if err := header.UnmarshalRLP(resp.Objs[0].Spec.Value); err != nil { From d50d0bae0f350ebc294bcbdfb4f1af69e713c4d5 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Mon, 16 May 2022 12:08:26 +0800 Subject: [PATCH 3/5] Extract error constant --- protocol/syncer.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/protocol/syncer.go b/protocol/syncer.go index 31641c6a31..b8ae4c9fa2 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -37,6 +37,9 @@ var ( ErrForkNotFound = errors.New("fork not found") ErrPopTimeout = errors.New("timeout") ErrConnectionClosed = errors.New("connection closed") + ErrTooManyHeaders = errors.New("unexpected more than 1 result") + ErrDecodeDifficulty = errors.New("failed to decode difficulty") + ErrInvalidTypeAssertion = errors.New("invalid type assertion") ) // SyncPeer is a representation of the peer the node is syncing with @@ -187,7 +190,7 @@ func statusFromProto(p *proto.V1Status) (*Status, error) { diff, ok := new(big.Int).SetString(p.Difficulty, 10) if !ok { - return nil, fmt.Errorf("failed to decode difficulty") + return nil, ErrDecodeDifficulty } s.Difficulty = diff @@ -494,7 +497,7 @@ func (s *Syncer) DeletePeer(peerID peer.ID) error { if ok { syncPeer, ok := p.(*SyncPeer) if !ok { - return errors.New("invalid type assertion") + return ErrInvalidTypeAssertion } if err := syncPeer.conn.Close(); err != nil { @@ -719,7 +722,7 @@ func getHeader(clt proto.V1Client, num *uint64, hash *types.Hash) (*types.Header } if len(resp.Objs) != 1 { - return nil, fmt.Errorf("unexpected more than 1 result") + return nil, ErrTooManyHeaders } if resp.Objs[0].Spec == nil || len(resp.Objs[0].Spec.Value) == 0 { From facc45c71e134e8303c7a790a1c553b56530c6a6 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Mon, 16 May 2022 17:06:05 +0800 Subject: [PATCH 4/5] Handle protocal Response nil Objs element --- protocol/skeleton.go | 2 +- protocol/syncer.go | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/protocol/skeleton.go b/protocol/skeleton.go index 1af4968099..d2523a1934 100644 --- a/protocol/skeleton.go +++ b/protocol/skeleton.go @@ -22,7 +22,7 @@ func getHeaders(clt proto.V1Client, req *proto.GetHeadersRequest) ([]*types.Head headers := []*types.Header{} for _, obj := range resp.Objs { - if obj.Spec == nil { + if obj == nil || obj.Spec == nil { // this nil header comes from a faulty node, reject all blocks of it. return nil, ErrNilHeaderRequest } diff --git a/protocol/syncer.go b/protocol/syncer.go index b8ae4c9fa2..56b61a9bdc 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -725,13 +725,15 @@ func getHeader(clt proto.V1Client, num *uint64, hash *types.Hash) (*types.Header return nil, ErrTooManyHeaders } - if resp.Objs[0].Spec == nil || len(resp.Objs[0].Spec.Value) == 0 { + obj := resp.Objs[0] + + if obj == nil || obj.Spec == nil || len(obj.Spec.Value) == 0 { return nil, ErrNilHeaderRequest } header := &types.Header{} - if err := header.UnmarshalRLP(resp.Objs[0].Spec.Value); err != nil { + if err := header.UnmarshalRLP(obj.Spec.Value); err != nil { return nil, err } From 29fa978f675935cc674b44968671dbc64f5d6dc5 Mon Sep 17 00:00:00 2001 From: DarianShawn Date: Wed, 18 May 2022 16:38:30 +0800 Subject: [PATCH 5/5] Rename ErrNilHeaderRequest to ErrNilHeaderResponse --- protocol/skeleton.go | 4 ++-- protocol/syncer.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/protocol/skeleton.go b/protocol/skeleton.go index d2523a1934..3d1b5e2b7e 100644 --- a/protocol/skeleton.go +++ b/protocol/skeleton.go @@ -10,7 +10,7 @@ import ( ) var ( - ErrNilHeaderRequest = errors.New("header request spec is nil") + ErrNilHeaderResponse = errors.New("header response is nil") ) func getHeaders(clt proto.V1Client, req *proto.GetHeadersRequest) ([]*types.Header, error) { @@ -24,7 +24,7 @@ func getHeaders(clt proto.V1Client, req *proto.GetHeadersRequest) ([]*types.Head for _, obj := range resp.Objs { if obj == nil || obj.Spec == nil { // this nil header comes from a faulty node, reject all blocks of it. - return nil, ErrNilHeaderRequest + return nil, ErrNilHeaderResponse } header := &types.Header{} diff --git a/protocol/syncer.go b/protocol/syncer.go index 56b61a9bdc..babf3bcb21 100644 --- a/protocol/syncer.go +++ b/protocol/syncer.go @@ -728,7 +728,7 @@ func getHeader(clt proto.V1Client, num *uint64, hash *types.Hash) (*types.Header obj := resp.Objs[0] if obj == nil || obj.Spec == nil || len(obj.Spec.Value) == 0 { - return nil, ErrNilHeaderRequest + return nil, ErrNilHeaderResponse } header := &types.Header{}