forked from TrueCloudLab/neoneo-go
Merge pull request #529 from nspcc-dev/peer-communication-fixes
A set of fixes to make neo-go privnet more usable.
This commit is contained in:
commit
65332f5e7f
14 changed files with 127 additions and 68 deletions
BIN
.docker/6000-privnet-blocks.acc.gz
Normal file
BIN
.docker/6000-privnet-blocks.acc.gz
Normal file
Binary file not shown.
|
@ -24,9 +24,9 @@ services:
|
|||
neo_go_network:
|
||||
ipv4_address: 172.200.0.1
|
||||
ports:
|
||||
- 20331:20331
|
||||
- 20341:20341
|
||||
- 20351:20351
|
||||
- 20333:20333
|
||||
- 30333:30333
|
||||
- 20001:20001
|
||||
node_two:
|
||||
container_name: neo_go_node_two
|
||||
image: env_neo_go_image
|
||||
|
@ -38,9 +38,9 @@ services:
|
|||
neo_go_network:
|
||||
ipv4_address: 172.200.0.2
|
||||
ports:
|
||||
- 20332:20332
|
||||
- 20342:20342
|
||||
- 20352:20352
|
||||
- 20334:20334
|
||||
- 30334:30334
|
||||
- 20002:20002
|
||||
node_three:
|
||||
container_name: neo_go_node_three
|
||||
image: env_neo_go_image
|
||||
|
@ -52,9 +52,9 @@ services:
|
|||
neo_go_network:
|
||||
ipv4_address: 172.200.0.3
|
||||
ports:
|
||||
- 20333:20333
|
||||
- 20343:20343
|
||||
- 20353:20353
|
||||
- 20335:20335
|
||||
- 30335:30335
|
||||
- 20003:20003
|
||||
node_four:
|
||||
container_name: neo_go_node_four
|
||||
image: env_neo_go_image
|
||||
|
@ -66,6 +66,6 @@ services:
|
|||
neo_go_network:
|
||||
ipv4_address: 172.200.0.4
|
||||
ports:
|
||||
- 20334:20334
|
||||
- 20344:20344
|
||||
- 20354:20354
|
||||
- 20336:20336
|
||||
- 30336:30336
|
||||
- 20004:20004
|
||||
|
|
6
.docker/privnet-entrypoint.sh
Executable file
6
.docker/privnet-entrypoint.sh
Executable file
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
if test -f /6000-privnet-blocks.acc.gz; then
|
||||
gunzip /6000-privnet-blocks.acc.gz
|
||||
/usr/bin/neo-go db restore -i /6000-privnet-blocks.acc
|
||||
fi
|
||||
/usr/bin/neo-go "$@"
|
|
@ -22,7 +22,7 @@ RUN set -x \
|
|||
&& go build -v -mod=vendor -ldflags "${LDFLAGS}" -o /go/bin/neo-go ./cli
|
||||
|
||||
# Executable image
|
||||
FROM scratch
|
||||
FROM alpine
|
||||
|
||||
ARG VERSION
|
||||
LABEL version=$VERSION
|
||||
|
@ -30,9 +30,11 @@ LABEL version=$VERSION
|
|||
WORKDIR /
|
||||
|
||||
COPY --from=builder /neo-go/config /config
|
||||
COPY --from=builder /neo-go/.docker/6000-privnet-blocks.acc.gz /
|
||||
COPY --from=builder /neo-go/.docker/privnet-entrypoint.sh /usr/bin/privnet-entrypoint.sh
|
||||
COPY --from=builder /go/bin/neo-go /usr/bin/neo-go
|
||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
|
||||
ENTRYPOINT ["/usr/bin/neo-go"]
|
||||
ENTRYPOINT ["/usr/bin/privnet-entrypoint.sh"]
|
||||
|
||||
CMD ["node", "--config-path", "/config", "--testnet"]
|
||||
CMD ["node", "--config-path", "/config", "--privnet"]
|
||||
|
|
7
Makefile
7
Makefile
|
@ -108,10 +108,13 @@ env_up:
|
|||
@docker-compose -f $(DC_FILE) up -d node_one node_two node_three node_four
|
||||
|
||||
env_down:
|
||||
@echo "=> Stop and cleanup environment"
|
||||
@echo "=> Stop environment"
|
||||
@docker-compose -f $(DC_FILE) down
|
||||
|
||||
env_restart:
|
||||
@echo "=> Stop and cleanup environment"
|
||||
@echo "=> Stop and start environment"
|
||||
@docker-compose -f $(DC_FILE) restart
|
||||
|
||||
env_clean: env_down
|
||||
@echo "=> Cleanup environment"
|
||||
@docker volume rm docker_volume_chain
|
||||
|
|
|
@ -9,10 +9,10 @@ ProtocolConfiguration:
|
|||
- 03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699
|
||||
- 02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62
|
||||
SeedList:
|
||||
- 172.200.0.1:20331
|
||||
- 172.200.0.2:20332
|
||||
- 172.200.0.3:20333
|
||||
- 172.200.0.4:20334
|
||||
- 172.200.0.1:20333
|
||||
- 172.200.0.2:20334
|
||||
- 172.200.0.3:20335
|
||||
- 172.200.0.4:20336
|
||||
SystemFee:
|
||||
EnrollmentTransaction: 1000
|
||||
IssueTransaction: 500
|
||||
|
@ -37,7 +37,7 @@ ApplicationConfiguration:
|
|||
# FilePath: "./chains/privnet.bolt"
|
||||
# Uncomment in order to set up custom address for node.
|
||||
# Address: 127.0.0.1
|
||||
NodePort: 20334
|
||||
NodePort: 20336
|
||||
Relay: true
|
||||
DialTimeout: 3
|
||||
ProtoTickInterval: 2
|
||||
|
@ -47,10 +47,10 @@ ApplicationConfiguration:
|
|||
RPC:
|
||||
Enabled: true
|
||||
EnableCORSWorkaround: false
|
||||
Port: 20344
|
||||
Port: 30336
|
||||
Monitoring:
|
||||
Enabled: true
|
||||
Port: 20354
|
||||
Port: 20004
|
||||
UnlockWallet:
|
||||
Path: "6PYRXVwHSqFSukL3CuXxdQ75VmsKpjeLgQLEjt83FrtHf1gCVphHzdD4nc"
|
||||
Password: "four"
|
||||
|
|
|
@ -9,10 +9,10 @@ ProtocolConfiguration:
|
|||
- 03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699
|
||||
- 02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62
|
||||
SeedList:
|
||||
- 172.200.0.1:20331
|
||||
- 172.200.0.2:20332
|
||||
- 172.200.0.3:20333
|
||||
- 172.200.0.4:20334
|
||||
- 172.200.0.1:20333
|
||||
- 172.200.0.2:20334
|
||||
- 172.200.0.3:20335
|
||||
- 172.200.0.4:20336
|
||||
SystemFee:
|
||||
EnrollmentTransaction: 1000
|
||||
IssueTransaction: 500
|
||||
|
@ -37,7 +37,7 @@ ApplicationConfiguration:
|
|||
# FilePath: "./chains/privnet.bolt"
|
||||
# Uncomment in order to set up custom address for node.
|
||||
# Address: 127.0.0.1
|
||||
NodePort: 20331
|
||||
NodePort: 20333
|
||||
Relay: true
|
||||
DialTimeout: 3
|
||||
ProtoTickInterval: 2
|
||||
|
@ -47,10 +47,10 @@ ApplicationConfiguration:
|
|||
RPC:
|
||||
Enabled: true
|
||||
EnableCORSWorkaround: false
|
||||
Port: 20341
|
||||
Port: 30333
|
||||
Monitoring:
|
||||
Enabled: true
|
||||
Port: 20351
|
||||
Port: 20001
|
||||
UnlockWallet:
|
||||
Path: "6PYLmjBYJ4wQTCEfqvnznGJwZeW9pfUcV5m5oreHxqryUgqKpTRAFt9L8Y"
|
||||
Password: "one"
|
||||
|
|
|
@ -9,10 +9,10 @@ ProtocolConfiguration:
|
|||
- 03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699
|
||||
- 02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62
|
||||
SeedList:
|
||||
- 172.200.0.1:20331
|
||||
- 172.200.0.2:20332
|
||||
- 172.200.0.3:20333
|
||||
- 172.200.0.4:20334
|
||||
- 172.200.0.1:20333
|
||||
- 172.200.0.2:20334
|
||||
- 172.200.0.3:20335
|
||||
- 172.200.0.4:20336
|
||||
SystemFee:
|
||||
EnrollmentTransaction: 1000
|
||||
IssueTransaction: 500
|
||||
|
@ -37,7 +37,7 @@ ApplicationConfiguration:
|
|||
# FilePath: "./chains/privnet.bolt"
|
||||
# Uncomment in order to set up custom address for node.
|
||||
# Address: 127.0.0.1
|
||||
NodePort: 20333
|
||||
NodePort: 20335
|
||||
Relay: true
|
||||
DialTimeout: 3
|
||||
ProtoTickInterval: 2
|
||||
|
@ -47,10 +47,10 @@ ApplicationConfiguration:
|
|||
RPC:
|
||||
Enabled: true
|
||||
EnableCORSWorkaround: false
|
||||
Port: 20343
|
||||
Port: 30335
|
||||
Monitoring:
|
||||
Enabled: true
|
||||
Port: 20353
|
||||
Port: 20003
|
||||
UnlockWallet:
|
||||
Path: "6PYX86vYiHfUbpD95hfN1xgnvcSxy5skxfWYKu3ztjecxk6ikYs2kcWbeh"
|
||||
Password: "three"
|
||||
|
|
|
@ -9,10 +9,10 @@ ProtocolConfiguration:
|
|||
- 03d90c07df63e690ce77912e10ab51acc944b66860237b608c4f8f8309e71ee699
|
||||
- 02a7bc55fe8684e0119768d104ba30795bdcc86619e864add26156723ed185cd62
|
||||
SeedList:
|
||||
- 172.200.0.1:20331
|
||||
- 172.200.0.2:20332
|
||||
- 172.200.0.3:20333
|
||||
- 172.200.0.4:20334
|
||||
- 172.200.0.1:20333
|
||||
- 172.200.0.2:20334
|
||||
- 172.200.0.3:20335
|
||||
- 172.200.0.4:20336
|
||||
SystemFee:
|
||||
EnrollmentTransaction: 1000
|
||||
IssueTransaction: 500
|
||||
|
@ -37,7 +37,7 @@ ApplicationConfiguration:
|
|||
# FilePath: "./chains/privnet.bolt"
|
||||
# Uncomment in order to set up custom address for node.
|
||||
# Address: 127.0.0.1
|
||||
NodePort: 20332
|
||||
NodePort: 20334
|
||||
Relay: true
|
||||
DialTimeout: 3
|
||||
ProtoTickInterval: 2
|
||||
|
@ -47,10 +47,10 @@ ApplicationConfiguration:
|
|||
RPC:
|
||||
Enabled: true
|
||||
EnableCORSWorkaround: false
|
||||
Port: 20342
|
||||
Port: 30334
|
||||
Monitoring:
|
||||
Enabled: true
|
||||
Port: 20352
|
||||
Port: 20002
|
||||
UnlockWallet:
|
||||
Path: "6PYXHjPaNvW8YknSXaKsTWjf9FRxo1s4naV2jdmSQEgzaqKGX368rndN3L"
|
||||
Password: "two"
|
||||
|
|
|
@ -62,6 +62,9 @@ type Config struct {
|
|||
// Broadcast is a callback which is called to notify server
|
||||
// about new consensus payload to sent.
|
||||
Broadcast func(p *Payload)
|
||||
// RelayBlock is a callback that is called to notify server
|
||||
// about the new block that needs to be broadcasted.
|
||||
RelayBlock func(b *core.Block)
|
||||
// Chain is a core.Blockchainer instance.
|
||||
Chain core.Blockchainer
|
||||
// RequestTx is a callback to which will be called
|
||||
|
@ -252,6 +255,8 @@ func (s *service) processBlock(b block.Block) {
|
|||
|
||||
if err := s.Chain.AddBlock(bb); err != nil {
|
||||
s.log.Warnf("error on add block: %v", err)
|
||||
} else {
|
||||
s.Config.RelayBlock(bb)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ func (bc *Blockchain) init() error {
|
|||
// There is a high chance that the Node is stopped before the next
|
||||
// batch of 2000 headers was stored. Via the currentHeaders stored we can sync
|
||||
// that with stored blocks.
|
||||
if currHeaderHeight > bc.storedHeaderCount {
|
||||
if currHeaderHeight >= bc.storedHeaderCount {
|
||||
hash := currHeaderHash
|
||||
var targetHash util.Uint256
|
||||
if bc.headerList.Len() > 0 {
|
||||
|
|
|
@ -13,7 +13,7 @@ type Headers struct {
|
|||
|
||||
// Users can at most request 2k header.
|
||||
const (
|
||||
maxHeadersAllowed = 2000
|
||||
MaxHeadersAllowed = 2000
|
||||
)
|
||||
|
||||
// DecodeBinary implements Serializable interface.
|
||||
|
@ -21,9 +21,9 @@ func (p *Headers) DecodeBinary(br *io.BinReader) {
|
|||
lenHeaders := br.ReadVarUint()
|
||||
|
||||
// C# node does it silently
|
||||
if lenHeaders > maxHeadersAllowed {
|
||||
log.Warnf("received %d headers, capping to %d", lenHeaders, maxHeadersAllowed)
|
||||
lenHeaders = maxHeadersAllowed
|
||||
if lenHeaders > MaxHeadersAllowed {
|
||||
log.Warnf("received %d headers, capping to %d", lenHeaders, MaxHeadersAllowed)
|
||||
lenHeaders = MaxHeadersAllowed
|
||||
}
|
||||
|
||||
p.Hdrs = make([]*core.Header, lenHeaders)
|
||||
|
|
|
@ -37,6 +37,7 @@ var (
|
|||
errMaxPeers = errors.New("max peers reached")
|
||||
errServerShutdown = errors.New("server shutdown")
|
||||
errInvalidInvType = errors.New("invalid inventory type")
|
||||
errInvalidHashStart = errors.New("invalid requested HashStart")
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -94,10 +95,11 @@ func NewServer(config ServerConfig, chain core.Blockchainer) *Server {
|
|||
}
|
||||
|
||||
srv, err := consensus.NewService(consensus.Config{
|
||||
Broadcast: s.handleNewPayload,
|
||||
Chain: chain,
|
||||
RequestTx: s.requestTx,
|
||||
Wallet: config.Wallet,
|
||||
Broadcast: s.handleNewPayload,
|
||||
RelayBlock: s.relayBlock,
|
||||
Chain: chain,
|
||||
RequestTx: s.requestTx,
|
||||
Wallet: config.Wallet,
|
||||
})
|
||||
if err != nil {
|
||||
return nil
|
||||
|
@ -200,12 +202,6 @@ func (s *Server) run() {
|
|||
}
|
||||
return
|
||||
case p := <-s.register:
|
||||
// When a new peer is connected we send out our version immediately.
|
||||
if err := s.sendVersion(p); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"addr": p.RemoteAddr(),
|
||||
}).Error(err)
|
||||
}
|
||||
s.lock.Lock()
|
||||
s.peers[p] = true
|
||||
s.lock.Unlock()
|
||||
|
@ -289,6 +285,8 @@ func (s *Server) PeerCount() int {
|
|||
// startProtocol starts a long running background loop that interacts
|
||||
// every ProtoTickInterval with the peer.
|
||||
func (s *Server) startProtocol(p Peer) {
|
||||
var err error
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"addr": p.RemoteAddr(),
|
||||
"userAgent": string(p.Version().UserAgent),
|
||||
|
@ -297,10 +295,12 @@ func (s *Server) startProtocol(p Peer) {
|
|||
}).Info("started protocol")
|
||||
|
||||
s.discovery.RegisterGoodAddr(p.PeerAddr().String())
|
||||
err := s.requestHeaders(p)
|
||||
if err != nil {
|
||||
p.Disconnect(err)
|
||||
return
|
||||
if s.chain.HeaderHeight() < p.Version().StartHeight {
|
||||
err = s.requestHeaders(p)
|
||||
if err != nil {
|
||||
p.Disconnect(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
timer := time.NewTimer(s.ProtoTickInterval)
|
||||
|
@ -427,6 +427,35 @@ func (s *Server) handleGetDataCmd(p Peer, inv *payload.Inventory) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// handleGetHeadersCmd processes the getheaders request.
|
||||
func (s *Server) handleGetHeadersCmd(p Peer, gh *payload.GetBlocks) error {
|
||||
if len(gh.HashStart) < 1 {
|
||||
return errInvalidHashStart
|
||||
}
|
||||
startHash := gh.HashStart[0]
|
||||
start, err := s.chain.GetHeader(startHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp := payload.Headers{}
|
||||
resp.Hdrs = make([]*core.Header, 0, payload.MaxHeadersAllowed)
|
||||
for i := start.Index + 1; i < start.Index+1+payload.MaxHeadersAllowed; i++ {
|
||||
hash := s.chain.GetHeaderHash(int(i))
|
||||
if hash.Equals(util.Uint256{}) || hash.Equals(gh.HashStop) {
|
||||
break
|
||||
}
|
||||
header, err := s.chain.GetHeader(hash)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
resp.Hdrs = append(resp.Hdrs, header)
|
||||
}
|
||||
if len(resp.Hdrs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return p.WriteMsg(NewMessage(s.Net, CMDHeaders, &resp))
|
||||
}
|
||||
|
||||
// handleConsensusCmd processes received consensus payload.
|
||||
// It never returns an error.
|
||||
func (s *Server) handleConsensusCmd(cp *consensus.Payload) error {
|
||||
|
@ -438,6 +467,9 @@ func (s *Server) handleConsensusCmd(cp *consensus.Payload) error {
|
|||
// It never returns an error.
|
||||
func (s *Server) handleTxCmd(tx *transaction.Transaction) error {
|
||||
s.consensus.OnTransaction(tx)
|
||||
// It's OK for it to fail for various reasons like tx already existing
|
||||
// in the pool.
|
||||
_ = s.RelayTxn(tx)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -520,6 +552,9 @@ func (s *Server) handleMessage(peer Peer, msg *Message) error {
|
|||
case CMDGetData:
|
||||
inv := msg.Payload.(*payload.Inventory)
|
||||
return s.handleGetDataCmd(peer, inv)
|
||||
case CMDGetHeaders:
|
||||
gh := msg.Payload.(*payload.GetBlocks)
|
||||
return s.handleGetHeadersCmd(peer, gh)
|
||||
case CMDHeaders:
|
||||
headers := msg.Payload.(*payload.Headers)
|
||||
go s.handleHeadersCmd(peer, headers)
|
||||
|
@ -580,6 +615,11 @@ func (s *Server) relayInventory(t payload.InventoryType, hashes ...util.Uint256)
|
|||
}
|
||||
}
|
||||
|
||||
// relayBlock tells all the other connected nodes about the given block.
|
||||
func (s *Server) relayBlock(b *core.Block) {
|
||||
s.relayInventory(payload.BlockType, b.Hash())
|
||||
}
|
||||
|
||||
// RelayTxn a new transaction to the local node and the connected peers.
|
||||
// Reference: the method OnRelay in C#: https://github.com/neo-project/neo/blob/master/neo/Network/P2P/LocalNode.cs#L159
|
||||
func (s *Server) RelayTxn(t *transaction.Transaction) RelayReason {
|
||||
|
@ -599,10 +639,7 @@ func (s *Server) RelayTxn(t *transaction.Transaction) RelayReason {
|
|||
return RelayOutOfMemory
|
||||
}
|
||||
|
||||
for p := range s.Peers() {
|
||||
payload := payload.NewInventory(payload.TXType, []util.Uint256{t.Hash()})
|
||||
s.RelayDirectly(p, payload)
|
||||
}
|
||||
s.relayInventory(payload.TXType, t.Hash())
|
||||
|
||||
return RelaySucceed
|
||||
}
|
||||
|
|
|
@ -78,6 +78,12 @@ func (t *TCPTransport) handleConn(conn net.Conn) {
|
|||
|
||||
t.server.register <- p
|
||||
|
||||
// When a new peer is connected we send out our version immediately.
|
||||
if err := t.server.sendVersion(p); err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"addr": p.RemoteAddr(),
|
||||
}).Error(err)
|
||||
}
|
||||
r := io.NewBinReaderFromIO(p.conn)
|
||||
for {
|
||||
msg := &Message{}
|
||||
|
|
Loading…
Reference in a new issue