-
Notifications
You must be signed in to change notification settings - Fork 103
/
odr.go
100 lines (85 loc) · 3.1 KB
/
odr.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* @file
* @copyright defined in go-seele/LICENSE
*/
package light
import (
"errors"
"github.com/seeleteam/go-seele/core/store"
)
const (
blockRequestCode uint16 = 10 + iota
blockResponseCode
addTxRequestCode
addTxResponseCode
trieRequestCode
trieResponseCode
receiptRequestCode
receiptResponseCode
txByHashRequestCode
txByHashResponseCode
debtRequestCode
debtResponseCode
protocolMsgCodeLength // protocolMsgCodeLength always defined in the end.
)
var (
odrRequestFactories = map[uint16]func() odrRequest{
blockRequestCode: func() odrRequest { return &odrBlock{} },
addTxRequestCode: func() odrRequest { return &odrAddTx{} },
trieRequestCode: func() odrRequest { return &odrTriePoof{} },
receiptRequestCode: func() odrRequest { return &odrReceiptRequest{} },
txByHashRequestCode: func() odrRequest { return &odrTxByHashRequest{} },
debtRequestCode: func() odrRequest { return &odrDebtRequest{} },
}
odrResponseFactories = map[uint16]func() odrResponse{
blockResponseCode: func() odrResponse { return &odrBlock{} },
addTxResponseCode: func() odrResponse { return &odrAddTx{} },
trieResponseCode: func() odrResponse { return &odrTriePoof{} },
receiptResponseCode: func() odrResponse { return &odrReceiptResponse{} },
txByHashResponseCode: func() odrResponse { return &odrTxByHashResponse{} },
debtResponseCode: func() odrResponse { return &odrDebtResponse{} },
}
)
type odrRequest interface {
getRequestID() uint32 // get the random request ID.
setRequestID(requestID uint32) // set the random request ID.
code() uint16 // get request code.
handle(lp *LightProtocol) (respCode uint16, resp odrResponse) // handle the request and return response to remote peer.
}
type odrResponse interface {
getRequestID() uint32 // get the random request ID.
setRequestID(requestID uint32) // set the random request ID.
getError() error // get the response error if any.
setError(err error) // set the response error.
validate(request odrRequest, bcStore store.BlockchainStore) error // validate the retrieved response.
}
// OdrItem is base struct for ODR request and response.
type OdrItem struct {
ReqID uint32 // random request ID that generated dynamically
Error string // response error
}
func (item *OdrItem) getRequestID() uint32 {
return item.ReqID
}
func (item *OdrItem) setRequestID(requestID uint32) {
item.ReqID = requestID
}
func (item *OdrItem) getError() error {
if len(item.Error) == 0 {
return nil
}
return errors.New(item.Error)
}
func (item *OdrItem) setError(err error) {
if err == nil {
item.Error = ""
} else {
item.Error = err.Error()
}
}
func newErrorResponse(respCode uint16, reqID uint32, err error) (uint16, odrResponse) {
response := odrResponseFactories[respCode]()
response.setRequestID(reqID)
response.setError(err)
return respCode, response
}