added core block type
This commit is contained in:
parent
05e3a115af
commit
e9f9354b86
9 changed files with 128 additions and 7 deletions
|
@ -20,7 +20,7 @@
|
|||
### Long term project goals
|
||||
Full port of the original C# [NEO project](https://github.com/neo-project). A complete toolkit for the NEO blockchain.
|
||||
|
||||
- Full server (consensus, RPC and bookkeeping) nodes.
|
||||
- Full server (consensus and RPC) nodes.
|
||||
- RPC client
|
||||
- build, compile and deploy smart contracts with the Go vm
|
||||
|
||||
|
|
28
pkg/core/block.go
Normal file
28
pkg/core/block.go
Normal file
|
@ -0,0 +1,28 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
. "github.com/anthdm/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
// Block represents one block in the chain.
|
||||
type Block struct {
|
||||
Version uint32
|
||||
// hash of the previous block.
|
||||
PrevBlock Uint256
|
||||
// Root hash of a transaction list.
|
||||
MerkleRoot Uint256
|
||||
// timestamp
|
||||
Timestamp uint32
|
||||
// height of the block
|
||||
Height uint32
|
||||
// Random number
|
||||
Nonce uint64
|
||||
// contract addresss of the next miner
|
||||
NextMiner Uint160
|
||||
// seperator ? fixed to 1
|
||||
_sep uint8
|
||||
// Script used to validate the block
|
||||
Script []byte
|
||||
// transaction list
|
||||
Transactions []*Transaction
|
||||
}
|
4
pkg/core/transaction.go
Normal file
4
pkg/core/transaction.go
Normal file
|
@ -0,0 +1,4 @@
|
|||
package core
|
||||
|
||||
// Transaction is a process recorded in the NEO system.
|
||||
type Transaction struct{}
|
|
@ -83,6 +83,7 @@ const (
|
|||
cmdGetData = "getdata"
|
||||
cmdBlock = "block"
|
||||
cmdTX = "tx"
|
||||
cmdConsensus = "consensus"
|
||||
)
|
||||
|
||||
func newMessage(magic NetMode, cmd commandType, p payload.Payload) *Message {
|
||||
|
@ -137,6 +138,8 @@ func (m *Message) commandType() commandType {
|
|||
return cmdBlock
|
||||
case "tx":
|
||||
return cmdTX
|
||||
case "consensus":
|
||||
return cmdConsensus
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
@ -149,6 +152,8 @@ func (m *Message) decode(r io.Reader) error {
|
|||
binary.Read(r, binary.LittleEndian, &m.Length)
|
||||
binary.Read(r, binary.LittleEndian, &m.Checksum)
|
||||
|
||||
fmt.Println(cmdByteArrayToString(m.Command))
|
||||
|
||||
// return if their is no payload.
|
||||
if m.Length == 0 {
|
||||
return nil
|
||||
|
@ -164,6 +169,8 @@ func (m *Message) decodePayload(r io.Reader) error {
|
|||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("The length of the payload is %d\n", n)
|
||||
|
||||
if uint32(n) != m.Length {
|
||||
return fmt.Errorf("expected to have read exactly %d bytes got %d", m.Length, n)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,11 @@ func (i InventoryType) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
// Valid returns true if the inventory (type) is known.
|
||||
func (i InventoryType) Valid() bool {
|
||||
return i == BlockType || i == TXType || i == ConsensusType
|
||||
}
|
||||
|
||||
// List of valid InventoryTypes.
|
||||
const (
|
||||
BlockType InventoryType = 0x01 // 1
|
||||
|
@ -39,7 +44,15 @@ type Inventory struct {
|
|||
// Type if the object hash.
|
||||
Type InventoryType
|
||||
// The hash of the object (uint256).
|
||||
Hash Uint256
|
||||
Hashes []Uint256
|
||||
}
|
||||
|
||||
// NewInventory return a pointer to an Inventory.
|
||||
func NewInventory(typ InventoryType, hashes []Uint256) *Inventory {
|
||||
return &Inventory{
|
||||
Type: typ,
|
||||
Hashes: hashes,
|
||||
}
|
||||
}
|
||||
|
||||
// DecodeBinary implements the Payload interface.
|
||||
|
@ -50,15 +63,30 @@ func (p *Inventory) DecodeBinary(r io.Reader) error {
|
|||
var listLen uint8
|
||||
err := binary.Read(r, binary.LittleEndian, &p.Type)
|
||||
err = binary.Read(r, binary.LittleEndian, &listLen)
|
||||
err = binary.Read(r, binary.LittleEndian, &p.Hash)
|
||||
|
||||
p.Hashes = make([]Uint256, listLen)
|
||||
for i := 0; i < int(listLen); i++ {
|
||||
if err := binary.Read(r, binary.LittleEndian, &p.Hashes[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// EncodeBinary implements the Payload interface.
|
||||
func (p *Inventory) EncodeBinary(w io.Writer) error {
|
||||
// TODO
|
||||
return nil
|
||||
listLen := uint8(len(p.Hashes))
|
||||
err := binary.Write(w, binary.LittleEndian, p.Type)
|
||||
err = binary.Write(w, binary.LittleEndian, listLen)
|
||||
|
||||
for i := 0; i < len(p.Hashes); i++ {
|
||||
if err := binary.Write(w, binary.LittleEndian, p.Hashes[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Size implements the Payloader interface.
|
||||
|
|
32
pkg/network/payload/inventory_test.go
Normal file
32
pkg/network/payload/inventory_test.go
Normal file
|
@ -0,0 +1,32 @@
|
|||
package payload
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
. "github.com/anthdm/neo-go/pkg/util"
|
||||
)
|
||||
|
||||
func TestInventoryEncodeDecode(t *testing.T) {
|
||||
hashes := []Uint256{
|
||||
sha256.Sum256([]byte("a")),
|
||||
sha256.Sum256([]byte("b")),
|
||||
}
|
||||
inv := NewInventory(BlockType, hashes)
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
if err := inv.EncodeBinary(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
invDecode := &Inventory{}
|
||||
if err := invDecode.DecodeBinary(buf); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(inv, invDecode) {
|
||||
t.Fatalf("expected both inventories to be equal %v and %v", inv, invDecode)
|
||||
}
|
||||
}
|
|
@ -189,9 +189,11 @@ func (s *Server) processMessage(msg *Message, peer *Peer) error {
|
|||
case cmdHeaders:
|
||||
case cmdGetBlocks:
|
||||
case cmdInv:
|
||||
return s.handleInvCmd(msg.Payload.(*payload.Inventory), peer)
|
||||
case cmdGetData:
|
||||
case cmdBlock:
|
||||
case cmdTX:
|
||||
case cmdConsensus:
|
||||
default:
|
||||
return fmt.Errorf("invalid RPC command received: %s", command)
|
||||
}
|
||||
|
@ -241,6 +243,22 @@ func (s *Server) handleAddrCmd(addrList *payload.AddressList, peer *Peer) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) handleInvCmd(inv *payload.Inventory, peer *Peer) error {
|
||||
if !inv.Type.Valid() {
|
||||
return fmt.Errorf("invalid inventory type: %s", inv.Type)
|
||||
}
|
||||
if len(inv.Hashes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
payload := payload.NewInventory(inv.Type, inv.Hashes)
|
||||
msg := newMessage(s.net, cmdGetData, payload)
|
||||
|
||||
peer.send <- msg
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) peerAlreadyConnected(addr net.Addr) bool {
|
||||
// TODO: check for race conditions
|
||||
//s.mtx.RLock()
|
||||
|
|
|
@ -7,7 +7,8 @@ import (
|
|||
"fmt"
|
||||
)
|
||||
|
||||
// Uint256 ...
|
||||
// Uint256 is a 32 byte long unsigned integer.
|
||||
// Commonly used to store hashes.
|
||||
type Uint256 [32]uint8
|
||||
|
||||
// Uint256FromBytes return an Uint256 from a byte slice.
|
||||
|
@ -44,3 +45,6 @@ func (u Uint256) ToSlice() []byte {
|
|||
func (u Uint256) String() string {
|
||||
return hex.EncodeToString(u.ToSlice())
|
||||
}
|
||||
|
||||
// Uint160 is a 20 byte long unsigned integer
|
||||
type Uint160 [20]uint8
|
Loading…
Reference in a new issue