30e5aa8f48
* [database] - Add Prefix method to interface - Convert leveldb error to `database error` - Be explicit with prefixedKey in `Table` as slices can be pointers * [protocol] - Add stringer method to protocol * [Chaindb] - Added saveBlock() which will allow us to save a block into the database. The block is broken up into transactions and Headers. The headers are saved as is. The transactions are saved as is, then the utxos in the transactions are collected to make the utxo db. - Verification for blocks and transactions will reside in the same package. Note that the save methods are all unexported, while the Get methods are exported. Making it so that any can call a get method, but only code in this package may save to the database. The other code which will reside in this package will be code verification logic. * [chaindb] - Added saveHeader function which saveHeaders uses - Update the latest header, each time we save a header instead of after a batch. This is so that we can call saveHeader without saveHeaders. This functionality can be rolled back if the performance of updating the header after a batch is significant - small refactor in test code |
||
---|---|---|
.. | ||
stall | ||
config.go | ||
peer.go | ||
peer_test.go | ||
peerhandshake.go | ||
readme.md |
Package - Peer
Responsibility
Once a connection has been made. The connection will represent a established peer to the localNode. Since a connection and the Wire
is a golang primitive, that we cannot do much with. The peer package will encapsulate both, while adding extra functionality.
Features
-
The handshake protocol is automatically executed and handled by the peer package. If a Version/Verack is received twice, the peer will be disconnected.
-
IdleTimeouts: If a Message is not received from the peer within a set period of time, the peer will be disconnected.
-
StallTimeouts: For Example, If a GetHeaders, is sent to the Peer and a Headers Response is not received within a certain period of time, then the peer is disconnected.
-
Concurrency Model: The concurrency model used is similar to Actor model, with a few changes. Messages can be sent to a peer asynchronously or synchronously. An example of an synchornous message send is the
RequestHeaders
method, where the channel blocks until an error value is received. TheOnHeaders
message is however asynchronously called. Furthermore, all methods passed through the config, are wrapped inside of an additionalPeers
method, this is to lay the ground work to capturing statistics regarding a specific command. These are also used so that we can pass behaviour to be executed down the channel. -
Configuration: Each Peer will have a config struct passed to it, with information about the Local Peer and functions that will encapsulate the behaviour of what the peer should do, given a request. This way, the peer is not dependent on any other package.
Usage
conn, err := net.Dial("tcp", "seed2.neo.org:10333")
if err != nil {
fmt.Println("Error dialing connection", err.Error())
return
}
config := peer.LocalConfig{
Net: protocol.MainNet,
UserAgent: "NEO-G",
Services: protocol.NodePeerService,
Nonce: 1200,
ProtocolVer: 0,
Relay: false,
Port: 10332,
StartHeight: LocalHeight,
OnHeader: OnHeader,
}
p := peer.NewPeer(conn, false, config)
err = p.Run()
hash, err := util.Uint256DecodeString(chainparams.GenesisHash)
// hash2, err := util.Uint256DecodeString("ff8fe95efc5d1cc3a22b17503aecaf289cef68f94b79ddad6f613569ca2342d8")
err = p.RequestHeaders(hash)
func OnHeader(peer *peer.Peer, msg *payload.HeadersMessage) {
// This function is passed to peer
// and the peer will execute it on receiving a header
}
func LocalHeight() uint32 {
// This will be a function from the object that handles the block heights
return 10
}
Notes
Should we follow the actor model for Peers? Each Peer will have a ID, which we can take as the PID or if we launch a go-routine for each peer, then we can use that as an implicit PID.
Peer information should be stored into a database, if no db exists, we should get it from an initial peers file. We can use this to periodically store information about a peer.