-
Notifications
You must be signed in to change notification settings - Fork 77
/
version.go
157 lines (141 loc) · 5.55 KB
/
version.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package result
import (
"encoding/json"
"fmt"
"strings"
"github.com/nspcc-dev/neo-go/pkg/config"
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
)
type (
// Version model used for reporting server version
// info.
Version struct {
TCPPort uint16 `json:"tcpport"`
WSPort uint16 `json:"wsport,omitempty"`
Nonce uint32 `json:"nonce"`
UserAgent string `json:"useragent"`
Protocol Protocol `json:"protocol"`
RPC RPC `json:"rpc"`
}
// RPC represents the RPC server configuration.
RPC struct {
MaxIteratorResultItems int `json:"maxiteratorresultitems"`
SessionEnabled bool `json:"sessionenabled"`
}
// Protocol represents network-dependent parameters.
Protocol struct {
AddressVersion byte
Network netmode.Magic
MillisecondsPerBlock int
MaxTraceableBlocks uint32
MaxValidUntilBlockIncrement uint32
MaxTransactionsPerBlock uint16
MemoryPoolMaxTransactions int
ValidatorsCount byte
InitialGasDistribution fixedn.Fixed8
// Hardforks is the map of network hardforks with the enabling height.
Hardforks map[config.Hardfork]uint32
// Below are NeoGo-specific extensions to the protocol that are
// returned by the server in case they're enabled.
// CommitteeHistory stores height:size map of the committee size.
CommitteeHistory map[uint32]uint32
// P2PSigExtensions is true when Notary subsystem is enabled on the network.
P2PSigExtensions bool
// StateRootInHeader is true if state root is contained in block header.
StateRootInHeader bool
// ValidatorsHistory stores height:size map of the validators count.
ValidatorsHistory map[uint32]uint32
}
// protocolMarshallerAux is an auxiliary struct used for Protocol JSON marshalling.
protocolMarshallerAux struct {
AddressVersion byte `json:"addressversion"`
Network netmode.Magic `json:"network"`
MillisecondsPerBlock int `json:"msperblock"`
MaxTraceableBlocks uint32 `json:"maxtraceableblocks"`
MaxValidUntilBlockIncrement uint32 `json:"maxvaliduntilblockincrement"`
MaxTransactionsPerBlock uint16 `json:"maxtransactionsperblock"`
MemoryPoolMaxTransactions int `json:"memorypoolmaxtransactions"`
ValidatorsCount byte `json:"validatorscount"`
InitialGasDistribution int64 `json:"initialgasdistribution"`
Hardforks []hardforkAux `json:"hardforks"`
CommitteeHistory map[uint32]uint32 `json:"committeehistory,omitempty"`
P2PSigExtensions bool `json:"p2psigextensions,omitempty"`
StateRootInHeader bool `json:"staterootinheader,omitempty"`
ValidatorsHistory map[uint32]uint32 `json:"validatorshistory,omitempty"`
}
// hardforkAux is an auxiliary struct used for Hardfork JSON marshalling.
hardforkAux struct {
Name string `json:"name"`
Height uint32 `json:"blockheight"`
}
)
// prefixHardfork is a prefix used for hardfork names in C# node.
const prefixHardfork = "HF_"
// MarshalJSON implements the JSON marshaler interface.
func (p Protocol) MarshalJSON() ([]byte, error) {
// Keep hardforks sorted by name in the result.
hfs := make([]hardforkAux, 0, len(p.Hardforks))
for _, hf := range config.Hardforks {
if h, ok := p.Hardforks[hf]; ok {
hfs = append(hfs, hardforkAux{
Name: hf.String(),
Height: h,
})
}
}
aux := protocolMarshallerAux{
AddressVersion: p.AddressVersion,
Network: p.Network,
MillisecondsPerBlock: p.MillisecondsPerBlock,
MaxTraceableBlocks: p.MaxTraceableBlocks,
MaxValidUntilBlockIncrement: p.MaxValidUntilBlockIncrement,
MaxTransactionsPerBlock: p.MaxTransactionsPerBlock,
MemoryPoolMaxTransactions: p.MemoryPoolMaxTransactions,
ValidatorsCount: p.ValidatorsCount,
InitialGasDistribution: int64(p.InitialGasDistribution),
Hardforks: hfs,
CommitteeHistory: p.CommitteeHistory,
P2PSigExtensions: p.P2PSigExtensions,
StateRootInHeader: p.StateRootInHeader,
ValidatorsHistory: p.ValidatorsHistory,
}
return json.Marshal(aux)
}
// UnmarshalJSON implements the JSON unmarshaler interface.
func (p *Protocol) UnmarshalJSON(data []byte) error {
var aux protocolMarshallerAux
err := json.Unmarshal(data, &aux)
if err != nil {
return err
}
p.AddressVersion = aux.AddressVersion
p.Network = aux.Network
p.MillisecondsPerBlock = aux.MillisecondsPerBlock
p.MaxTraceableBlocks = aux.MaxTraceableBlocks
p.MaxValidUntilBlockIncrement = aux.MaxValidUntilBlockIncrement
p.MaxTransactionsPerBlock = aux.MaxTransactionsPerBlock
p.MemoryPoolMaxTransactions = aux.MemoryPoolMaxTransactions
p.ValidatorsCount = aux.ValidatorsCount
p.CommitteeHistory = aux.CommitteeHistory
p.P2PSigExtensions = aux.P2PSigExtensions
p.StateRootInHeader = aux.StateRootInHeader
p.ValidatorsHistory = aux.ValidatorsHistory
p.InitialGasDistribution = fixedn.Fixed8(aux.InitialGasDistribution)
// Filter out unknown hardforks.
for i := range aux.Hardforks {
aux.Hardforks[i].Name = strings.TrimPrefix(aux.Hardforks[i].Name, prefixHardfork)
if !config.IsHardforkValid(aux.Hardforks[i].Name) {
return fmt.Errorf("unexpected hardfork: %s", aux.Hardforks[i].Name)
}
}
p.Hardforks = make(map[config.Hardfork]uint32, len(aux.Hardforks))
for _, cfgHf := range config.Hardforks {
for _, auxHf := range aux.Hardforks {
if auxHf.Name == cfgHf.String() {
p.Hardforks[cfgHf] = auxHf.Height
}
}
}
return nil
}