Fix lint errors (#182)

* golint and minor changes to make code readable
This commit is contained in:
decentralisedkev 2019-03-17 18:26:35 +00:00 committed by GitHub
parent 94eb16c9ca
commit f8979fe7af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 502 additions and 258 deletions

1
go.mod
View file

@ -4,5 +4,6 @@ require (
github.com/o3labs/neo-utils v0.0.0-20190129071622-8ae0bc31751f
github.com/stretchr/testify v1.3.0
github.com/syndtr/goleveldb v1.0.0
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c // indirect
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b
)

3
go.sum
View file

@ -22,6 +22,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c h1:Rx/HTKi09myZ25t1SOlDHmHOy/mKxNAcu0hP1oPX9qM=
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M=
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
@ -40,3 +42,4 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View file

@ -5,7 +5,7 @@ import (
"crypto/cipher"
)
// AESEncrypt encrypts the key with the given source.
// Encrypt encrypts the key with the given source.
func Encrypt(src, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
@ -19,7 +19,7 @@ func Encrypt(src, key []byte) ([]byte, error) {
return out, nil
}
// AESDecrypt decrypts the encrypted source with the given key.
// Decrypt decrypts the encrypted source with the given key.
func Decrypt(crypted, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {

View file

@ -22,7 +22,7 @@ var decodeMap = map[rune]int64{
'x': 55, 'y': 56, 'z': 57,
}
// Base58Decode decodes the base58 encoded string.
// Decode decodes the base58 encoded string.
func Decode(s string) ([]byte, error) {
var (
startIndex = 0
@ -58,7 +58,7 @@ func Decode(s string) ([]byte, error) {
return buf, nil
}
// Base58Encode encodes a byte slice to be a base58 encoded string.
// Encode encodes a byte slice to be a base58 encoded string.
func Encode(bytes []byte) string {
var (
lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"

View file

@ -18,10 +18,13 @@ var curve Curve
type curveType string
const (
// Secp256r1 curve type
Secp256r1 curveType = "Secp256r1"
// Secp256k1 curve type
Secp256k1 curveType = "Secp256k1"
)
// SetCurveSecp256r1 Will set the curve parameters to match Secp256r1
func (ChosenCurve *Curve) SetCurveSecp256r1() {
ChosenCurve.P, _ = new(big.Int).SetString("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16) //Q
ChosenCurve.A, _ = new(big.Int).SetString("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16)
@ -33,6 +36,7 @@ func (ChosenCurve *Curve) SetCurveSecp256r1() {
ChosenCurve.Name = "Secp256r1"
}
// SetCurveSecp256k1 Will set the curve parameters to match Secp256k1
func (ChosenCurve *Curve) SetCurveSecp256k1() {
ChosenCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
ChosenCurve.A, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000000", 16)
@ -44,6 +48,8 @@ func (ChosenCurve *Curve) SetCurveSecp256k1() {
ChosenCurve.Name = "Secp256k1"
}
//NewEllipticCurve will instantiate a new EllipticCurve
//Defaults to secp256r1
func NewEllipticCurve(ct curveType) Curve {
var curve Curve
switch ct {

View file

@ -19,8 +19,8 @@ type Point struct {
Y *big.Int
}
/* y**2 = x**3 + a*x + b % p */
// Curve represents the parameters of a short Weierstrass equation elliptic curve.
/* y**2 = x**3 + a*x + b % p */
type Curve struct {
A *big.Int
B *big.Int
@ -44,6 +44,7 @@ func (p *Point) format() string {
return fmt.Sprintf("(%s,%s)", hex.EncodeToString(p.X.Bytes()), hex.EncodeToString(p.Y.Bytes()))
}
// Params represent the paramters for the Elliptic Curve
func (ec Curve) Params() *nativeelliptic.CurveParams {
return &nativeelliptic.CurveParams{
P: ec.P,
@ -302,12 +303,13 @@ func (ec *Curve) Decompress(x *big.Int, ylsb uint) (P Point, err error) {
P.Y = y
if !ec.IsOnCurve(P.X, P.Y) {
return P, errors.New("Compressed (x, ylsb) not on curve.")
return P, errors.New("compressed (x, ylsb) not on curve")
}
return P, nil
}
// Double will return the (x1+x1,y1+y1)
func (ec Curve) Double(x1, y1 *big.Int) (x, y *big.Int) {
x = &big.Int{}
x.SetBytes([]byte{0x00})

View file

@ -8,6 +8,8 @@ import (
"golang.org/x/crypto/ripemd160"
)
// Sha256 hashes the incoming byte slice
// using the sha256 algorithm
func Sha256(data []byte) (util.Uint256, error) {
var hash util.Uint256
hasher := sha256.New()
@ -21,6 +23,7 @@ func Sha256(data []byte) (util.Uint256, error) {
return hash, nil
}
// DoubleSha256 performs sha256 twice on the given data
func DoubleSha256(data []byte) (util.Uint256, error) {
var hash util.Uint256
@ -36,6 +39,8 @@ func DoubleSha256(data []byte) (util.Uint256, error) {
return hash, nil
}
// RipeMD160 performs the RIPEMD160 hash algorithm
// on the given data
func RipeMD160(data []byte) (util.Uint160, error) {
var hash util.Uint160
hasher := ripemd160.New()
@ -49,6 +54,8 @@ func RipeMD160(data []byte) (util.Uint160, error) {
return hash, nil
}
// Hash160 performs sha256 and then ripemd160
// on the given data
func Hash160(data []byte) (util.Uint160, error) {
var hash util.Uint160
h1, err := Sha256(data)
@ -63,6 +70,8 @@ func Hash160(data []byte) (util.Uint160, error) {
return hash, nil
}
// Checksum returns the checksum for a given piece of data
// using sha256 twice as the hash algorithm
func Checksum(data []byte) ([]byte, error) {
hash, err := Sum(data)
if err != nil {
@ -71,6 +80,8 @@ func Checksum(data []byte) ([]byte, error) {
return hash[:4], nil
}
// Sum performs sha256 twice on the given data
// XXX(issue): We should remove this and just do doublesha256
func Sum(b []byte) (util.Uint256, error) {
hash, err := DoubleSha256((b))
return hash, err

View file

@ -23,6 +23,8 @@ type PrivateKey struct {
b []byte
}
// NewPrivateKey will create a new private key
// With curve as Secp256r1
func NewPrivateKey() (*PrivateKey, error) {
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
b := make([]byte, curve.N.BitLen()/8+8)
@ -38,6 +40,7 @@ func NewPrivateKey() (*PrivateKey, error) {
return p, nil
}
// NewPrivateKeyFromHex will create a new private key hex string
func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
b, err := hex.DecodeString(str)
if err != nil {
@ -56,6 +59,8 @@ func NewPrivateKeyFromBytes(b []byte) (*PrivateKey, error) {
return &PrivateKey{b}, nil
}
// PublicKey returns a the public corresponding to the private key
// For the curve secp256r1
func (p *PrivateKey) PublicKey() (*publickey.PublicKey, error) {
var (
c = elliptic.NewEllipticCurve(elliptic.Secp256r1)
@ -78,6 +83,8 @@ func (p *PrivateKey) PublicKey() (*publickey.PublicKey, error) {
}
// WIFEncode will converts a private key
// to the Wallet Import Format for NEO
func WIFEncode(key []byte) (s string) {
if len(key) != 32 {
return "invalid private key length"
@ -97,6 +104,7 @@ func WIFEncode(key []byte) (s string) {
return WIF
}
// Sign will sign the corresponding data using the private key
func (p *PrivateKey) Sign(data []byte) ([]byte, error) {
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
key := p.b

View file

@ -5,16 +5,29 @@ import (
"github.com/CityOfZion/neo-go/pkg/crypto/privatekey"
)
// SignDataWithRandomPrivateKey will sign data with
// a random private key, then verify said data
// returning true if Verify returns true
func SignDataWithRandomPrivateKey(data []byte) (bool, error) {
hashedData, _ := hash.Sha256(data)
privKey, _ := privatekey.NewPrivateKey()
signedData, err := privKey.Sign(data)
pubKey, _ := privKey.PublicKey()
result := pubKey.Verify(signedData, hashedData.Bytes())
hashedData, err := hash.Sha256(data)
if err != nil {
return false, err
}
privKey, err := privatekey.NewPrivateKey()
if err != nil {
return false, err
}
signedData, err := privKey.Sign(data)
if err != nil {
return false, err
}
pubKey, err := privKey.PublicKey()
if err != nil {
return false, err
}
result := pubKey.Verify(signedData, hashedData.Bytes())
return result, nil
}

View file

@ -77,6 +77,8 @@ func (p *PublicKey) Bytes() []byte {
return append([]byte{prefix}, paddedX...)
}
// ToAddress will convert a public key to it's neo-address
func (p *PublicKey) ToAddress() string {
publicKeyBytes := p.Bytes()
@ -145,6 +147,8 @@ func (p *PublicKey) EncodeBinary(w io.Writer) error {
return binary.Write(w, binary.LittleEndian, p.Bytes())
}
// Verify returns true if the signature is valid and corresponds
// to the hash and public key
func (p *PublicKey) Verify(signature []byte, hash []byte) bool {
publicKey := &ecdsa.PublicKey{}

View file

@ -12,27 +12,38 @@ import (
"github.com/syndtr/goleveldb/leveldb/errors"
)
// LDB represents a leveldb object
type LDB struct {
db *leveldb.DB
path string
}
// Database contains all methods needed for an object to be a database
type Database interface {
// Has checks whether the key is in the database
Has(key []byte) (bool, error)
// Put adds the key value pair into the pair
Put(key []byte, value []byte) error
// Get returns the value for the given key
Get(key []byte) ([]byte, error)
// Delete deletes the given value for the key from the database
Delete(key []byte) error
// Close closes the underlying db object
Close() error
}
var (
// TX, HEADER AND UTXO are the prefixes for the db
// TX is the prefix used when inserting a tx into the db
TX = []byte("TX")
// HEADER is the prefix used when inserting a header into the db
HEADER = []byte("HEADER")
// LATESTHEADER is the prefix used when inserting the latests header into the db
LATESTHEADER = []byte("LH")
// UTXO is the prefix used when inserting a utxo into the db
UTXO = []byte("UTXO")
)
// New will return a new leveldb instance
func New(path string) *LDB {
db, err := leveldb.OpenFile(path, nil)
@ -50,23 +61,32 @@ func New(path string) *LDB {
}
}
// Has implements the database interface
func (l *LDB) Has(key []byte) (bool, error) {
return l.db.Has(key, nil)
}
// Put implements the database interface
func (l *LDB) Put(key []byte, value []byte) error {
return l.db.Put(key, value, nil)
}
// Get implements the database interface
func (l *LDB) Get(key []byte) ([]byte, error) {
return l.db.Get(key, nil)
}
// Delete implements the database interface
func (l *LDB) Delete(key []byte) error {
return l.db.Delete(key, nil)
}
// Close implements the database interface
func (l *LDB) Close() error {
return l.db.Close()
}
// AddHeader adds a header into the database
func (l *LDB) AddHeader(header *payload.BlockBase) error {
table := NewTable(l, HEADER)
@ -102,6 +122,7 @@ func (l *LDB) AddHeader(header *payload.BlockBase) error {
return table.Put(LATESTHEADER, header.Hash.Bytes())
}
// AddTransactions adds a set of transactions into the database
func (l *LDB) AddTransactions(blockhash util.Uint256, txs []transaction.Transactioner) error {
// SHOULD BE DONE IN BATCH!!!!

View file

@ -1,12 +1,12 @@
package database
//Table is an abstract datastructure built on
// top of a db
//Table is an abstract data structure built on top of a db
type Table struct {
prefix []byte
db Database
}
//NewTable creates a new table on the given database
func NewTable(db Database, prefix []byte) *Table {
return &Table{
prefix,
@ -14,23 +14,31 @@ func NewTable(db Database, prefix []byte) *Table {
}
}
// Has implements the database interface
func (t *Table) Has(key []byte) (bool, error) {
key = append(t.prefix, key...)
return t.db.Has(key)
}
// Put implements the database interface
func (t *Table) Put(key []byte, value []byte) error {
key = append(t.prefix, key...)
return t.db.Put(key, value)
}
// Get implements the database interface
func (t *Table) Get(key []byte) ([]byte, error) {
key = append(t.prefix, key...)
return t.db.Get(key)
}
// Delete implements the database interface
func (t *Table) Delete(key []byte) error {
key = append(t.prefix, key...)
return t.db.Delete(key)
}
// Close implements the database interface
func (t *Table) Close() error {
return nil
}

View file

@ -6,7 +6,6 @@ import (
)
// LocalConfig specifies the properties that should be available for each remote peer
type LocalConfig struct {
Net protocol.Magic
UserAgent string

View file

@ -53,6 +53,7 @@ var (
errHandShakeTimeout = errors.New("Handshake timed out, peers have " + string(handshakeTimeout) + " Seconds to Complete the handshake")
)
// Peer represents a peer on the neo network
type Peer struct {
config LocalConfig
conn net.Conn
@ -81,6 +82,7 @@ type Peer struct {
quitch chan struct{}
}
// NewPeer returns a new NEO peer
func NewPeer(con net.Conn, inbound bool, cfg LocalConfig) *Peer {
p := Peer{}
p.inch = make(chan func(), inputBufferSize)
@ -108,7 +110,7 @@ func (p *Peer) Read() (wire.Messager, error) {
return wire.ReadMessage(p.conn, p.config.Net)
}
// Disconnects from a peer
// Disconnect disconnects a peer and closes the connection
func (p *Peer) Disconnect() {
// return if already disconnected
@ -126,34 +128,54 @@ func (p *Peer) Disconnect() {
}
// Exposed API functions below
// Port returns the peers port
func (p *Peer) Port() uint16 {
return p.port
}
// CreatedAt returns the time at which the connection was made
func (p *Peer) CreatedAt() time.Time {
return p.createdAt
}
// CanRelay returns true, if the peer can relay information
func (p *Peer) CanRelay() bool {
return p.relay
}
// LocalAddr returns this node's local address
func (p *Peer) LocalAddr() net.Addr {
return p.conn.LocalAddr()
}
// RemoteAddr returns the remote address of the connected peer
func (p *Peer) RemoteAddr() net.Addr {
return p.conn.RemoteAddr()
}
// Services returns the services offered by the peer
func (p *Peer) Services() protocol.ServiceFlag {
return p.config.Services
}
//Inbound returns true whether this peer is an inbound peer
func (p *Peer) Inbound() bool {
return p.inbound
}
// UserAgent returns this nodes, useragent
func (p *Peer) UserAgent() string {
return p.config.UserAgent
}
// IsVerackReceived returns true, if this node has
// received a verack from this peer
func (p *Peer) IsVerackReceived() bool {
return p.verackReceived
}
//NotifyDisconnect returns once the peer has disconnected
// Blocking
func (p *Peer) NotifyDisconnect() bool {
fmt.Println("Peer has not disconnected yet")
<-p.quitch
@ -163,7 +185,7 @@ func (p *Peer) NotifyDisconnect() bool {
//End of Exposed API functions//
// Ping not impl. in neo yet, adding it now
// PingLoop not impl. in neo yet, adding it now
// will cause this client to disconnect from all other implementations
func (p *Peer) PingLoop() { /*not implemented in other neo clients*/ }
@ -183,7 +205,7 @@ func (p *Peer) Run() error {
}
// run as a go-routine, will act as our queue for messages
// StartProtocol run as a go-routine, will act as our queue for messages
// should be ran after handshake
func (p *Peer) StartProtocol() {
loop:
@ -201,11 +223,9 @@ loop:
p.Disconnect()
}
// ReadLoop Will block on the read until a message is read
// Should only be called after handshake is complete
// on a seperate go-routine.
// ReadLoop Will block on the read until a message is
// read
func (p *Peer) ReadLoop() {
idleTimer := time.AfterFunc(idleTimeout, func() {
@ -271,8 +291,7 @@ loop:
p.Disconnect()
}
// WriteLoop will Queue all messages to be written to
// the peer.
// WriteLoop will Queue all messages to be written to the peer.
func (p *Peer) WriteLoop() {
for atomic.LoadInt32(&p.disconnected) == 0 {
select {
@ -284,17 +303,21 @@ func (p *Peer) WriteLoop() {
}
}
// OnGetData is called when a GetData message is received
func (p *Peer) OnGetData(msg *payload.GetDataMessage) {
p.inch <- func() {
// fmt.Println(msg.Hashes)
if p.config.OnInv != nil {
p.config.OnGetData(msg)
}
fmt.Println("That was an getdata Message please pass func down through config", msg.Command())
}
}
//OnTX is callwed when a TX message is received
func (p *Peer) OnTX(msg *payload.TXMessage) {
p.inch <- func() {
// fmt.Println(msg.Hashes)
getdata, err := payload.NewGetDataMessage(payload.InvTypeTx)
if err != nil {
fmt.Println("Eor", err)
@ -302,10 +325,10 @@ func (p *Peer) OnTX(msg *payload.TXMessage) {
id, err := msg.Tx.ID()
getdata.AddHash(id)
p.Write(getdata)
fmt.Println("That was an tx Message please pass func down through config", msg.Command())
}
}
// OnInv is called when a Inv message is received
func (p *Peer) OnInv(msg *payload.InvMessage) {
p.inch <- func() {
@ -316,8 +339,7 @@ func (p *Peer) OnInv(msg *payload.InvMessage) {
}
}
// OnGetHeaders Listener, outside of the anonymous func will be extra functionality
// like timing
// OnGetHeaders is called when a GetHeaders message is received
func (p *Peer) OnGetHeaders(msg *payload.GetHeadersMessage) {
p.inch <- func() {
if p.config.OnGetHeaders != nil {
@ -328,7 +350,7 @@ func (p *Peer) OnGetHeaders(msg *payload.GetHeadersMessage) {
}
}
// OnAddr Listener
// OnAddr is called when a Addr message is received
func (p *Peer) OnAddr(msg *payload.AddrMessage) {
p.inch <- func() {
if p.config.OnAddr != nil {
@ -339,7 +361,7 @@ func (p *Peer) OnAddr(msg *payload.AddrMessage) {
}
}
// OnGetAddr Listener
// OnGetAddr is called when a GetAddr message is received
func (p *Peer) OnGetAddr(msg *payload.GetAddrMessage) {
p.inch <- func() {
if p.config.OnGetAddr != nil {
@ -350,7 +372,7 @@ func (p *Peer) OnGetAddr(msg *payload.GetAddrMessage) {
}
}
// OnGetBlocks Listener
// OnGetBlocks is called when a GetBlocks message is received
func (p *Peer) OnGetBlocks(msg *payload.GetBlocksMessage) {
p.inch <- func() {
if p.config.OnGetBlocks != nil {
@ -360,7 +382,7 @@ func (p *Peer) OnGetBlocks(msg *payload.GetBlocksMessage) {
}
}
// OnBlocks Listener
// OnBlocks is called when a Blocks message is received
func (p *Peer) OnBlocks(msg *payload.BlockMessage) {
p.inch <- func() {
if p.config.OnBlock != nil {
@ -386,7 +408,7 @@ func (p *Peer) OnVersion(msg *payload.VersionMessage) error {
return nil
}
// OnHeaders Listener
// OnHeaders is called when a Headers message is received
func (p *Peer) OnHeaders(msg *payload.HeadersMessage) {
fmt.Println("We have received the headers")
p.inch <- func() {
@ -396,9 +418,8 @@ func (p *Peer) OnHeaders(msg *payload.HeadersMessage) {
}
}
// RequestHeaders will write a getheaders to peer
// RequestHeaders will write a getheaders to this peer
func (p *Peer) RequestHeaders(hash util.Uint256) error {
fmt.Println("Sending header request")
c := make(chan error, 0)
p.outch <- func() {
p.Detector.AddMessage(command.GetHeaders)
@ -406,14 +427,11 @@ func (p *Peer) RequestHeaders(hash util.Uint256) error {
err = p.Write(getHeaders)
c <- err
}
return <-c
}
// RequestBlocks will ask a peer for a block
// RequestBlocks will ask this peer for a set of blocks
func (p *Peer) RequestBlocks(hashes []util.Uint256) error {
fmt.Println("Requesting block from peer")
c := make(chan error, 0)
p.outch <- func() {

View file

@ -7,9 +7,10 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire"
"github.com/CityOfZion/neo-go/pkg/wire/payload"
"github.com/CityOfZion/neo-go/pkg/wire/util/ip"
iputils "github.com/CityOfZion/neo-go/pkg/wire/util/ip"
)
// Handshake will initiate a handshake with this peer
func (p *Peer) Handshake() error {
handshakeErr := make(chan error, 1)

View file

@ -9,10 +9,9 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// stall detector will keep track of all pendingMessages
// Detector (stall detector) will keep track of all pendingMessages
// If any message takes too long to reply
// the detector will disconnect the peer
type Detector struct {
responseTime time.Duration
tickInterval time.Duration
@ -28,6 +27,7 @@ type Detector struct {
disconnected int32
}
// NewDetector will create a new stall detector
// rT is the responseTime and signals how long
// a peer has to reply back to a sent message
// tickerInterval is how often the detector wil check for stalled messages
@ -81,9 +81,10 @@ func (d *Detector) Quit() {
close(d.Quitch)
}
//AddMessage will add a message to the responses map
// Call this function when we send a message to a peer
// The command passed through is the command that we sent
// and not the command we expect to receive
// we will then set a timer for the expected message(s)
func (d *Detector) AddMessage(cmd command.Type) {
cmds := d.addMessage(cmd)
d.lock.Lock()
@ -93,6 +94,7 @@ func (d *Detector) AddMessage(cmd command.Type) {
d.lock.Unlock()
}
// RemoveMessage remove messages from the responses map
// Call this function when we receive a message from
// peer. This will remove the pendingresponse message from the map.
// The command passed through is the command we received

View file

@ -1,13 +1,19 @@
package pubsub
// EventType is an enum
// representing the types of messages we can subscribe to
type EventType int
const (
NewBlock EventType = iota // When blockchain connects a new block, it will emit an NewBlock Event
BadBlock // When blockchain declines a block, it will emit a new block event
BadHeader // When blockchain rejects a Header, it will emit this event
// NewBlock is called When blockchain connects a new block, it will emit an NewBlock Event
NewBlock EventType = iota
// BadBlock is called When blockchain declines a block, it will emit a new block event
BadBlock
// BadHeader is called When blockchain rejects a Header, it will emit this event
BadHeader
)
// Event represents a new Event that a subscriber can listen to
type Event struct {
Type EventType // E.g. event.NewBlock
data []byte // Raw information

View file

@ -1,5 +1,6 @@
package pubsub
// Publisher sends events to subscribers
type Publisher struct {
subs []Subscriber
}

View file

@ -1,5 +1,6 @@
package pubsub
// Subscriber will listen for Events from publishers
type Subscriber interface {
Topics() []EventType
Emit(Event)

View file

@ -8,7 +8,6 @@ import (
)
// Base is everything in the message except the payload
type Base struct {
Magic uint32
CMD command.Type
@ -16,9 +15,8 @@ type Base struct {
Checksum uint32
}
// Note, That there is no EncodeBase
// As the header is implicitly inferred from
// the message on Encode To send
// DecodeBase will decode an io.Reader into a Base object
// Note, That there is no EncodeBase, As the header is implicitly inferred from the message on Encode To send
func (h *Base) DecodeBase(r io.Reader) (io.Reader, error) {
br := &util.BinReader{R: r}

View file

@ -5,11 +5,10 @@ const (
Size = 12
)
// CommandType represents the type of a message command.
// Type represents the type of a message command.
type Type string
// Valid protocol commands used to send between nodes.
// use this to get
const (
Version Type = "version"
Mempool Type = "mempool"

View file

@ -15,9 +15,15 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// Messager is implemented by any object that can
// Encode and Decode Payloads
type Messager interface {
// EncodePayload takes a message payload and encodes it
EncodePayload(w io.Writer) error
// DecodePayload takes an io.Reader and decodes it into
// a message payload
DecodePayload(r io.Reader) error
// Command returns the assosciated command type
Command() command.Type
}
@ -30,6 +36,7 @@ var (
errChecksumMismatch = errors.New("checksum mismatch")
)
// WriteMessage will write a message to a given io.Writer
func WriteMessage(w io.Writer, magic protocol.Magic, message Messager) error {
bw := &util.BinWriter{W: w}
bw.Write(magic)
@ -51,6 +58,7 @@ func WriteMessage(w io.Writer, magic protocol.Magic, message Messager) error {
return bw.Err
}
// ReadMessage will read a message from a given io.Reader
func ReadMessage(r io.Reader, magic protocol.Magic) (Messager, error) {
byt := make([]byte, minMsgSize)
@ -122,7 +130,7 @@ func ReadMessage(r io.Reader, magic protocol.Magic) (Messager, error) {
return v, err
case command.TX:
reader := bufio.NewReader(buf)
tx, err := transaction.FromBytes(reader)
tx, err := transaction.FromReader(reader)
if err != nil {
return nil, err
}

View file

@ -9,21 +9,27 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// Block representa a Block in the neo-network
type Block struct {
BlockBase
Txs []transaction.Transactioner
}
// Decode decodes an io.Reader into a Block
func (b *Block) Decode(r io.Reader) error {
br := &util.BinReader{R: r}
b.DecodePayload(br)
return br.Err
}
// Encode writes a block into a io.Writer
func (b *Block) Encode(w io.Writer) error {
bw := &util.BinWriter{W: w}
b.EncodePayload(bw)
return bw.Err
}
//EncodePayload implements Messager interface
func (b *Block) EncodePayload(bw *util.BinWriter) {
b.BlockBase.EncodePayload(bw)
bw.VarUint(uint64(len(b.Txs)))
@ -32,6 +38,7 @@ func (b *Block) EncodePayload(bw *util.BinWriter) {
}
}
// DecodePayload implements Messager interface
func (b *Block) DecodePayload(br *util.BinReader) error {
b.BlockBase.DecodePayload(br)
@ -42,7 +49,7 @@ func (b *Block) DecodePayload(br *util.BinReader) error {
reader := bufio.NewReader(br.R)
for i := 0; i < int(lenTXs); i++ {
tx, err := transaction.FromBytes(reader)
tx, err := transaction.FromReader(reader)
if err != nil {
return err
}
@ -52,6 +59,7 @@ func (b *Block) DecodePayload(br *util.BinReader) error {
return nil
}
// Bytes returns the Byte representation of Block
func (b *Block) Bytes() ([]byte, error) {
buf := new(bytes.Buffer)
err := b.Encode(buf)

View file

@ -10,9 +10,11 @@ import (
)
var (
ErrPadding = errors.New("There is a padding mismatch")
errPadding = errors.New("There is a padding mismatch")
)
//BlockBase represents the base of the block
// This is different than the block header. See HeadersMessage
type BlockBase struct {
// Version of the block.
Version uint32 `json:"version"`
@ -47,6 +49,7 @@ type BlockBase struct {
Hash util.Uint256
}
// EncodePayload implements the Messager interface
func (b *BlockBase) EncodePayload(bw *util.BinWriter) error {
b.encodeHashableFields(bw)
@ -57,11 +60,14 @@ func (b *BlockBase) EncodePayload(bw *util.BinWriter) error {
return bw.Err
}
// Decode decodes an io.Reader into a Blockbase
func (b *BlockBase) Decode(r io.Reader) error {
br := &util.BinReader{R: r}
b.DecodePayload(br)
return br.Err
}
// Encode encodes a blockbase into an io.Writer
func (b *BlockBase) Encode(w io.Writer) error {
bw := &util.BinWriter{W: w}
b.EncodePayload(bw)
@ -78,6 +84,7 @@ func (b *BlockBase) encodeHashableFields(bw *util.BinWriter) {
bw.Write(b.NextConsensus)
}
// DecodePayload implements the messager interface
func (b *BlockBase) DecodePayload(br *util.BinReader) error {
b.decodeHashableFields(br)
@ -85,7 +92,7 @@ func (b *BlockBase) DecodePayload(br *util.BinReader) error {
var padding uint8
br.Read(&padding)
if padding != 1 {
return ErrPadding
return errPadding
}
b.Witness = transaction.Witness{}
@ -117,6 +124,7 @@ func (b *BlockBase) createHash() error {
return err
}
// Bytes returns the byte representation of Blockbase
func (b *BlockBase) Bytes() ([]byte, error) {
buf := new(bytes.Buffer)
err := b.Encode(buf)

View file

@ -7,10 +7,12 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// AddrMessage represents an address message on the neo network
type AddrMessage struct {
AddrList []*Net_addr
AddrList []*NetAddr
}
// NewAddrMessage instantiates a new AddrMessage
func NewAddrMessage() (*AddrMessage, error) {
addrMess := &AddrMessage{
nil,
@ -18,22 +20,23 @@ func NewAddrMessage() (*AddrMessage, error) {
return addrMess, nil
}
func (a *AddrMessage) AddNetAddr(n *Net_addr) error {
// AddNetAddr will add a net address into the Address message
func (a *AddrMessage) AddNetAddr(n *NetAddr) error {
a.AddrList = append(a.AddrList, n)
// TODO:check if max reached, if so return err. What is max?
return nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (a *AddrMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
listLen := br.VarUint()
a.AddrList = make([]*Net_addr, listLen)
a.AddrList = make([]*NetAddr, listLen)
for i := 0; i < int(listLen); i++ {
a.AddrList[i] = &Net_addr{}
a.AddrList[i] = &NetAddr{}
a.AddrList[i].DecodePayload(br)
if br.Err != nil {
return br.Err
@ -42,20 +45,20 @@ func (a *AddrMessage) DecodePayload(r io.Reader) error {
return br.Err
}
// Implements messager interface
func (v *AddrMessage) EncodePayload(w io.Writer) error {
// EncodePayload Implements messager interface
func (a *AddrMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
listLen := uint64(len(v.AddrList))
listLen := uint64(len(a.AddrList))
bw.VarUint(listLen)
for _, addr := range v.AddrList {
for _, addr := range a.AddrList {
addr.EncodePayload(bw)
}
return bw.Err
}
// Implements messager interface
func (v *AddrMessage) Command() command.Type {
// Command Implements messager interface
func (a *AddrMessage) Command() command.Type {
return command.Addr
}

View file

@ -8,29 +8,31 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// BlockMessage represents a block message on the neo-network
type BlockMessage struct {
Block
}
// NewBlockMessage will return a block message object
func NewBlockMessage() (*BlockMessage, error) {
return &BlockMessage{}, nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (b *BlockMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
b.Block.DecodePayload(br)
return br.Err
}
// Implements messager interface
// EncodePayload Implements messager interface
func (b *BlockMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
b.Block.EncodePayload(bw)
return bw.Err
}
// Implements messager interface
func (v *BlockMessage) Command() command.Type {
// Command Implements messager interface
func (b *BlockMessage) Command() command.Type {
return command.Block
}

View file

@ -6,24 +6,25 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// No payload
//GetAddrMessage represents a GetAddress message on the neo-network
type GetAddrMessage struct{}
// NewGetAddrMessage returns a GetAddrMessage object
func NewGetAddrMessage() (*GetAddrMessage, error) {
return &GetAddrMessage{}, nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (v *GetAddrMessage) DecodePayload(r io.Reader) error {
return nil
}
// Implements messager interface
// EncodePayload Implements messager interface
func (v *GetAddrMessage) EncodePayload(w io.Writer) error {
return nil
}
// Implements messager interface
// Command Implements messager interface
func (v *GetAddrMessage) Command() command.Type {
return command.GetAddr
}

View file

@ -5,10 +5,12 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// GetBlocksMessage represnts a GetBlocks message on the neo-network
type GetBlocksMessage struct {
*GetHeadersMessage
}
// NewGetBlocksMessage returns a GetBlocksMessage object
func NewGetBlocksMessage(start []util.Uint256, stop util.Uint256) (*GetBlocksMessage, error) {
GetHeaders, err := newAbstractGetHeaders(start, stop, command.GetBlocks)

View file

@ -4,10 +4,12 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// GetDataMessage represents a GetData message on the neo-network
type GetDataMessage struct {
*InvMessage
}
//NewGetDataMessage returns a GetDataMessage object
func NewGetDataMessage(typ InvType) (*GetDataMessage, error) {
getData, err := newAbstractInv(typ, command.GetData)
return &GetDataMessage{

View file

@ -7,12 +7,14 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//GetHeadersMessage represents a GetHeaders message on the neo-network
type GetHeadersMessage struct {
cmd command.Type
hashStart []util.Uint256
hashStop util.Uint256
}
// NewGetHeadersMessage returns a NewGetHeaders object
// Start contains the list of all headers you want to fetch
// End contains the list of the highest header hash you would like to fetch
func NewGetHeadersMessage(start []util.Uint256, stop util.Uint256) (*GetHeadersMessage, error) {
@ -32,7 +34,7 @@ func newAbstractGetHeaders(start []util.Uint256, stop util.Uint256, cmd command.
return getHeaders, nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (v *GetHeadersMessage) DecodePayload(r io.Reader) error {
br := util.BinReader{R: r}
@ -44,7 +46,7 @@ func (v *GetHeadersMessage) DecodePayload(r io.Reader) error {
return br.Err
}
// Implements messager interface
// EncodePayload Implements messager interface
func (v *GetHeadersMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
bw.VarUint(uint64(len(v.hashStart)))
@ -53,7 +55,7 @@ func (v *GetHeadersMessage) EncodePayload(w io.Writer) error {
return bw.Err
}
// Implements messager interface
// Command Implements messager interface
func (v *GetHeadersMessage) Command() command.Type {
return v.cmd
}

View file

@ -8,6 +8,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// HeadersMessage represents a Header(s) Message on the neo-network
type HeadersMessage struct {
Headers []*BlockBase
@ -21,31 +22,34 @@ const (
)
var (
ErrMaxHeaders = errors.New("Maximum amount of headers allowed is 2000")
errMaxHeaders = errors.New("Maximum amount of headers allowed is 2000")
)
//NewHeadersMessage returns a HeadersMessage Object
func NewHeadersMessage() (*HeadersMessage, error) {
headers := &HeadersMessage{nil, 0}
return headers, nil
}
// AddHeader adds a header into the list of Headers.
// Since a header is just blockbase with padding, we use BlockBase
func (h *HeadersMessage) AddHeader(head *BlockBase) error {
if len(h.Headers)+1 > maxHeadersAllowed {
return ErrMaxHeaders
return errMaxHeaders
}
h.Headers = append(h.Headers, head)
return nil
}
// Implements Messager interface
func (v *HeadersMessage) DecodePayload(r io.Reader) error {
// DecodePayload Implements Messager interface
func (h *HeadersMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
lenHeaders := br.VarUint()
v.Headers = make([]*BlockBase, lenHeaders)
h.Headers = make([]*BlockBase, lenHeaders)
for i := 0; i < int(lenHeaders); i++ {
header := &BlockBase{}
@ -53,26 +57,26 @@ func (v *HeadersMessage) DecodePayload(r io.Reader) error {
var padding uint8
br.Read(&padding)
if padding != 0 {
return ErrPadding
return errPadding
}
v.Headers[i] = header
h.Headers[i] = header
}
return br.Err
}
// Implements messager interface
func (v *HeadersMessage) EncodePayload(w io.Writer) error {
// EncodePayload Implements messager interface
func (h *HeadersMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
bw.VarUint(uint64(len(v.Headers)))
for _, header := range v.Headers {
bw.VarUint(uint64(len(h.Headers)))
for _, header := range h.Headers {
header.EncodePayload(bw)
bw.Write(uint8(0))
}
return bw.Err
}
// Implements messager interface
func (v *HeadersMessage) Command() command.Type {
// Command Implements messager interface
func (h *HeadersMessage) Command() command.Type {
return command.Headers
}

View file

@ -8,29 +8,30 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//InvType represents the enum of inventory types
type InvType uint8
//Inventory types
const (
// InvTypeTx represents the transaction inventory type
InvTypeTx InvType = 0x01
// InvTypeBlock represents the block inventory type
InvTypeBlock InvType = 0x02
// InvTypeConsensus represents the consensus inventory type
InvTypeConsensus InvType = 0xe0
)
const (
maxHashes = 0x10000000
)
const maxHashes = 0x10000000
var (
MaxHashError = errors.New("Max size For Hashes reached")
)
var errMaxHash = errors.New("max size For Hashes reached")
// InvMessage represents an Inventory message on the neo-network
type InvMessage struct {
cmd command.Type
Type InvType
Hashes []util.Uint256
}
//NewInvMessage returns an InvMessage object
func NewInvMessage(typ InvType) (*InvMessage, error) {
inv := &InvMessage{
@ -53,17 +54,20 @@ func newAbstractInv(typ InvType, cmd command.Type) (*InvMessage, error) {
}
func (i *InvMessage) AddHash(h util.Uint256) error {
if len(i.Hashes)+1 > maxHashes {
return MaxHashError
// AddHash adds a hash to the list of hashes
func (inv *InvMessage) AddHash(h util.Uint256) error {
if len(inv.Hashes)+1 > maxHashes {
return errMaxHash
}
i.Hashes = append(i.Hashes, h)
inv.Hashes = append(inv.Hashes, h)
return nil
}
func (i *InvMessage) AddHashes(hashes []util.Uint256) error {
// AddHashes adds multiple hashes to the list of hashes
func (inv *InvMessage) AddHashes(hashes []util.Uint256) error {
var err error
for _, hash := range hashes {
err = i.AddHash(hash)
err = inv.AddHash(hash)
if err != nil {
break
}
@ -71,31 +75,31 @@ func (i *InvMessage) AddHashes(hashes []util.Uint256) error {
return err
}
// Implements Messager interface
func (v *InvMessage) DecodePayload(r io.Reader) error {
// DecodePayload Implements Messager interface
func (inv *InvMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
br.Read(&v.Type)
br.Read(&inv.Type)
listLen := br.VarUint()
v.Hashes = make([]util.Uint256, listLen)
inv.Hashes = make([]util.Uint256, listLen)
for i := 0; i < int(listLen); i++ {
br.Read(&v.Hashes[i])
br.Read(&inv.Hashes[i])
}
return nil
}
// Implements messager interface
func (v *InvMessage) EncodePayload(w io.Writer) error {
// EncodePayload Implements messager interface
func (inv *InvMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
bw.Write(v.Type)
bw.Write(inv.Type)
lenhashes := len(v.Hashes)
lenhashes := len(inv.Hashes)
bw.VarUint(uint64(lenhashes))
for _, hash := range v.Hashes {
for _, hash := range inv.Hashes {
bw.Write(hash)
@ -104,7 +108,7 @@ func (v *InvMessage) EncodePayload(w io.Writer) error {
return bw.Err
}
// Implements messager interface
func (v *InvMessage) Command() command.Type {
return v.cmd
// Command Implements messager interface
func (inv *InvMessage) Command() command.Type {
return inv.cmd
}

View file

@ -6,24 +6,25 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// No payload
// GetMempool represents a GetMempool message on the neo-network
type GetMempool struct{}
//NewGetMempool returns a GetMempool message
func NewGetMempool() (*GetMempool, error) {
return &GetMempool{}, nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (v *GetMempool) DecodePayload(r io.Reader) error {
return nil
}
// Implements messager interface
// EncodePayload Implements messager interface
func (v *GetMempool) EncodePayload(w io.Writer) error {
return nil
}
// Implements messager interface
// Command Implements messager interface
func (v *GetMempool) Command() command.Type {
return command.Mempool
}

View file

@ -7,28 +7,29 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction"
)
// TXMessage represents a transaction message on the neo-network
type TXMessage struct {
// w *bytes.Buffer
Tx transaction.Transactioner
}
//NewTXMessage returns a new tx object
func NewTXMessage(tx transaction.Transactioner) (*TXMessage, error) {
Tx := &TXMessage{tx}
return Tx, nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (t *TXMessage) DecodePayload(r io.Reader) error {
return t.Tx.Decode(r)
}
// Implements messager interface
// EncodePayload Implements messager interface
func (t *TXMessage) EncodePayload(w io.Writer) error {
return t.Tx.Encode(w)
}
// Implements messager interface
func (v *TXMessage) Command() command.Type {
// Command Implements messager interface
func (t *TXMessage) Command() command.Type {
return command.TX
}

View file

@ -6,24 +6,25 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/command"
)
// No payload
//VerackMessage represents a verack message on the neo-network
type VerackMessage struct{}
//NewVerackMessage returns a verack message
func NewVerackMessage() (*VerackMessage, error) {
return &VerackMessage{}, nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (v *VerackMessage) DecodePayload(r io.Reader) error {
return nil
}
// Implements messager interface
// EncodePayload Implements messager interface
func (v *VerackMessage) EncodePayload(w io.Writer) error {
return nil
}
// Implements messager interface
// Command Implements messager interface
func (v *VerackMessage) Command() command.Type {
return command.Verack
}

View file

@ -13,15 +13,12 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
const (
minMsgVersionSize = 28
)
const minMsgVersionSize = 28
// TODO: Refactor to pull out the useragent out of initialiser
// and have a seperate method to add it
var errInvalidNetAddr = errors.New("provided net.Addr is not a net.TCPAddr")
//VersionMessage represents a version message on the neo-network
type VersionMessage struct {
// w *bytes.Buffer
Version protocol.Version
Timestamp uint32
Services protocol.ServiceFlag
@ -33,13 +30,12 @@ type VersionMessage struct {
Relay bool
}
var ErrInvalidNetAddr = errors.New("provided net.Addr is not a net.TCPAddr")
//NewVersionMessage will return a VersionMessage object
func NewVersionMessage(addr net.Addr, startHeight uint32, relay bool, pver protocol.Version, userAgent string, nonce uint32, services protocol.ServiceFlag) (*VersionMessage, error) {
tcpAddr, ok := addr.(*net.TCPAddr)
if !ok {
return nil, ErrInvalidNetAddr
return nil, errInvalidNetAddr
}
version := &VersionMessage{
@ -56,13 +52,13 @@ func NewVersionMessage(addr net.Addr, startHeight uint32, relay bool, pver proto
return version, nil
}
// Implements Messager interface
// DecodePayload Implements Messager interface
func (v *VersionMessage) DecodePayload(r io.Reader) error {
br := &util.BinReader{R: r}
br.Read(&v.Version)
br.Read(&v.Services)
br.Read(&v.Timestamp)
br.Read(&v.Port) // Port is not BigEndian
br.Read(&v.Port) // Port is not BigEndian as stated in the docs
br.Read(&v.Nonce)
var lenUA uint8
@ -75,7 +71,7 @@ func (v *VersionMessage) DecodePayload(r io.Reader) error {
return br.Err
}
// Implements messager interface
// EncodePayload Implements messager interface
func (v *VersionMessage) EncodePayload(w io.Writer) error {
bw := &util.BinWriter{W: w}
@ -91,7 +87,7 @@ func (v *VersionMessage) EncodePayload(w io.Writer) error {
return bw.Err
}
// Implements messager interface
// Command Implements messager interface
func (v *VersionMessage) Command() command.Type {
return command.Version
}

View file

@ -9,21 +9,21 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// Once a VersionMessage is received, we can then store it inside of AddrMessage struct
// TODO: store this inside version message and have a bool to indicate whether to encode ip
// VersionMessage does not encodeIP
type Net_addr struct {
//NetAddr is an abstraction for the IP layer
type NetAddr struct {
Timestamp uint32
IP [16]byte
Port uint16
Service protocol.ServiceFlag
}
func NewNetAddr(time uint32, ip [16]byte, port uint16, service protocol.ServiceFlag) (*Net_addr, error) {
return &Net_addr{time, ip, port, service}, nil
//NewNetAddr returns a NetAddr object
func NewNetAddr(time uint32, ip [16]byte, port uint16, service protocol.ServiceFlag) (*NetAddr, error) {
return &NetAddr{time, ip, port, service}, nil
}
func NewAddrFromVersionMessage(version VersionMessage) (*Net_addr, error) {
//NewAddrFromVersionMessage returns a NetAddr object from a version message
func NewAddrFromVersionMessage(version VersionMessage) (*NetAddr, error) {
var ip [16]byte
@ -32,21 +32,26 @@ func NewAddrFromVersionMessage(version VersionMessage) (*Net_addr, error) {
return NewNetAddr(version.Timestamp, ip, version.Port, version.Services)
}
func (n *Net_addr) EncodePayload(bw *util.BinWriter) {
// EncodePayload Implements messager interface
func (n *NetAddr) EncodePayload(bw *util.BinWriter) {
bw.Write(uint32(time.Now().Unix()))
bw.Write(protocol.NodePeerService)
bw.WriteBigEnd(n.IP)
bw.WriteBigEnd(n.Port)
}
func (n *Net_addr) DecodePayload(br *util.BinReader) {
// DecodePayload Implements Messager interface
func (n *NetAddr) DecodePayload(br *util.BinReader) {
br.Read(&n.Timestamp)
br.Read(&n.Service)
br.ReadBigEnd(&n.IP)
br.ReadBigEnd(&n.Port)
}
func (n *Net_addr) IPPort() string {
//IPPort returns the IPPort from the NetAddr
func (n *NetAddr) IPPort() string {
ip := net.IP(n.IP[:]).String()
port := strconv.Itoa(int(n.Port))
ipport := ip + ":" + port

View file

@ -12,17 +12,14 @@ type Attribute struct {
Data []byte
}
var (
ErrMaxData = errors.New("Max Size of Attribute reached")
)
var errMaxData = errors.New("max Size of Attribute reached")
const (
maxAttrSize = 65535
)
const maxAttrSize = 65535
// Encode encodes the given Attribute into the binary writer
func (a *Attribute) Encode(bw *util.BinWriter) {
if len(a.Data) > maxAttrSize {
bw.Err = ErrMaxData
bw.Err = errMaxData
return
}
bw.Write(uint8(a.Usage))
@ -43,6 +40,7 @@ func (a *Attribute) Encode(bw *util.BinWriter) {
}
// Decode decodes the binary reader into an Attribute object
func (a *Attribute) Decode(br *util.BinReader) {
br.Read(&a.Usage)
if a.Usage == DescriptionURL || a.Usage == Vote || a.Usage >= Hash1 && a.Usage <= Hash15 {

View file

@ -11,17 +11,21 @@ type Input struct {
PrevIndex uint16
}
//NewInput returns a transaction input object
func NewInput(prevHash util.Uint256, prevIndex uint16) *Input {
return &Input{
prevHash,
prevIndex,
}
}
// Encode encodes the given input into a binary writer
func (i *Input) Encode(bw *util.BinWriter) {
bw.Write(i.PrevHash)
bw.Write(i.PrevIndex)
}
// Decode decodes a binary reader into an input object
func (i *Input) Decode(br *util.BinReader) {
br.Read(&i.PrevHash)
br.Read(&i.PrevIndex)

View file

@ -2,6 +2,7 @@ package transaction
import "github.com/CityOfZion/neo-go/pkg/wire/util"
// Output represents a transaction output in the neo-network
type Output struct {
// The NEO asset id used in the transaction.
AssetID util.Uint256
@ -13,6 +14,7 @@ type Output struct {
ScriptHash util.Uint160
}
//NewOutput returns an output object
func NewOutput(assetID util.Uint256, Amount int64, ScriptHash util.Uint160) *Output {
return &Output{
assetID,
@ -21,12 +23,14 @@ func NewOutput(assetID util.Uint256, Amount int64, ScriptHash util.Uint160) *Out
}
}
// Encode encodes the Output into a binary writer
func (o *Output) Encode(bw *util.BinWriter) {
bw.Write(o.AssetID)
bw.Write(o.Amount)
bw.Write(o.ScriptHash)
}
// Decode decodes a binary reader into an output object
func (o *Output) Decode(br *util.BinReader) {
br.Read(&o.AssetID)
br.Read(&o.Amount)

View file

@ -4,11 +4,13 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//Witness represents a Witness object in a neo transaction
type Witness struct {
InvocationScript []byte
VerificationScript []byte
}
// Encode encodes a Witness into a binary writer
func (s *Witness) Encode(bw *util.BinWriter) error {
bw.VarUint(uint64(len(s.InvocationScript)))
@ -20,6 +22,7 @@ func (s *Witness) Encode(bw *util.BinWriter) error {
return bw.Err
}
// Decode decodes a binary reader into a Witness object
func (s *Witness) Decode(br *util.BinReader) error {
lenb := br.VarUint()

View file

@ -1,5 +1,6 @@
package transaction
// AttrUsage represents an attribute usage on the neo network
type AttrUsage uint8
// List of valid attribute usages.

View file

@ -53,16 +53,20 @@ func createBaseTransaction(typ types.TX, ver version.TX) *Base {
}
// Decode implements the transactioner interface
func (b *Base) Decode(r io.Reader) error {
br := &util.BinReader{R: r}
return b.DecodePayload(br)
}
// Encode implements the transactioner interface
func (b *Base) Encode(w io.Writer) error {
bw := &util.BinWriter{W: w}
b.EncodePayload(bw)
return bw.Err
}
//EncodePayload implements the Messager interface
func (b *Base) EncodePayload(bw *util.BinWriter) {
b.encodeHashableFields(bw)
@ -74,6 +78,7 @@ func (b *Base) EncodePayload(bw *util.BinWriter) {
}
}
// DecodePayload implements the messager interface
func (b *Base) DecodePayload(br *util.BinReader) error {
b.decodeHashableFields(br)
@ -118,7 +123,6 @@ func (b *Base) encodeHashableFields(bw *util.BinWriter) {
}
}
// created for consistency
func (b *Base) decodeHashableFields(br *util.BinReader) {
b.Type.Decode(br)
@ -151,15 +155,22 @@ func (b *Base) decodeHashableFields(br *util.BinReader) {
}
// AddInput adds an input to the transaction
func (b *Base) AddInput(i *Input) {
b.Inputs = append(b.Inputs, i)
}
// AddOutput adds an output to the transaction
func (b *Base) AddOutput(o *Output) {
b.Outputs = append(b.Outputs, o)
}
// AddAttribute adds an attribute to the transaction
func (b *Base) AddAttribute(a *Attribute) {
b.Attributes = append(b.Attributes, a)
}
// AddWitness adds a witness object to the transaction
func (b *Base) AddWitness(w *Witness) {
b.Witnesses = append(b.Witnesses, w)
}

View file

@ -6,11 +6,13 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//Claim represents a claim transaction on the neo network
type Claim struct {
*Base
Claims []*Input
}
//NewClaim returns a ClaimTransaction
func NewClaim(ver version.TX) *Claim {
basicTrans := createBaseTransaction(types.Contract, ver)
@ -39,5 +41,3 @@ func (c *Claim) decodeExcl(br *util.BinReader) {
}
}
// use encode and decode exclusive to make the interface

View file

@ -6,10 +6,12 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//Contract represents a contract transaction on the neo network
type Contract struct {
*Base
}
//NewContract returns a contract transaction
func NewContract(ver version.TX) *Contract {
basicTrans := createBaseTransaction(types.Contract, ver)
@ -21,10 +23,6 @@ func NewContract(ver version.TX) *Contract {
return contract
}
func (c *Contract) encodeExcl(bw *util.BinWriter) {
return
}
func (c *Contract) encodeExcl(bw *util.BinWriter) {}
func (c *Contract) decodeExcl(br *util.BinReader) {
return
}
func (c *Contract) decodeExcl(br *util.BinReader) {}

View file

@ -6,24 +6,26 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//Enrollment represents an Enrollment transaction on the neo network
type Enrollment struct {
*Base
Key PublicKey
}
//NewEnrollment returns an Enrollment transaction
func NewEnrollment(ver version.TX) *Enrollment {
basicTrans := createBaseTransaction(types.Enrollment, ver)
Enrollment := &Enrollment{}
Enrollment.Base = basicTrans
Enrollment.encodeExclusive = Enrollment.encodeExcl
Enrollment.decodeExclusive = Enrollment.decodeExcl
return Enrollment
enrollment := &Enrollment{
Base: basicTrans,
}
enrollment.encodeExclusive = enrollment.encodeExcl
enrollment.decodeExclusive = enrollment.decodeExcl
return enrollment
}
func (e *Enrollment) encodeExcl(bw *util.BinWriter) {
e.Key.Encode(bw)
}
func (e *Enrollment) decodeExcl(br *util.BinReader) {

View file

@ -9,12 +9,14 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util/fixed8"
)
//Invocation represents an invocation transaction on the neo network
type Invocation struct {
*Base
Script []byte
Gas fixed8.Fixed8
}
//NewInvocation returns an invocation transaction
func NewInvocation(ver version.TX) *Invocation {
basicTrans := createBaseTransaction(types.Invocation, ver)
@ -53,7 +55,7 @@ func (c *Invocation) decodeExcl(br *util.BinReader) {
case 1:
br.Read(&c.Gas)
default:
br.Err = errors.New("Invalid Version Number for Invocation Transaction")
br.Err = errors.New("invalid Version Number for Invocation Transaction")
}
return
}

View file

@ -8,10 +8,12 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// Issue represents an issue transaction on the neo network
type Issue struct {
*Base
}
//NewIssue returns an issue transaction
func NewIssue(ver version.TX) *Issue {
basicTrans := createBaseTransaction(types.Issue, ver)
@ -27,9 +29,6 @@ func (c *Issue) encodeExcl(bw *util.BinWriter) {
if c.Version > 1 {
bw.Err = errors.New("Version Number Invalid, Issue cannot be more than 0")
}
return
}
func (c *Issue) decodeExcl(br *util.BinReader) {
return
}
func (c *Issue) decodeExcl(br *util.BinReader) {}

View file

@ -6,11 +6,13 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//Miner represents a miner transaction on the neo network
type Miner struct {
*Base
Nonce uint32
}
//NewMiner returns a miner transaction
func NewMiner(ver version.TX) *Miner {
basicTrans := createBaseTransaction(types.Miner, ver)
@ -22,13 +24,9 @@ func NewMiner(ver version.TX) *Miner {
}
func (c *Miner) encodeExcl(bw *util.BinWriter) {
bw.Write(c.Nonce)
return
}
func (c *Miner) decodeExcl(br *util.BinReader) {
br.Read(&c.Nonce)
}

View file

@ -6,13 +6,17 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// PublicKey represents a public key on the neo network
type PublicKey struct {
Key []byte
}
//Encode encodes a public key into a binary writer
func (p *PublicKey) Encode(bw *util.BinWriter) {
bw.Write(p.Key)
}
// Decode decodes a bianry reader into a public key
func (p *PublicKey) Decode(br *util.BinReader) {
var prefix uint8
br.Read(&prefix)
@ -30,6 +34,5 @@ func (p *PublicKey) Decode(br *util.BinReader) {
br.Err = errors.New("Prefix not recognised for public key")
return
}
p.Key = append([]byte{prefix}, p.Key...)
}

View file

@ -8,6 +8,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// Publish represents a publish transaction on the neo network
type Publish struct {
*Base
Script []byte
@ -21,6 +22,7 @@ type Publish struct {
Description string
}
//NewPublish returns a publish transaction
func NewPublish(ver version.TX) *Publish {
basicTrans := createBaseTransaction(types.Publish, ver)

View file

@ -7,6 +7,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util/fixed8"
)
// Register represents a register transaction on the neo network
type Register struct {
*Base
// The type of the asset being registered.
@ -28,6 +29,7 @@ type Register struct {
Admin util.Uint160
}
//NewRegister returns a register transaction
func NewRegister(ver version.TX) *Register {
basicTrans := createBaseTransaction(types.Register, ver)
Register := &Register{}

View file

@ -6,11 +6,14 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
//StateTX represents a state transaction on the neo network
// XXX: TX postfix here as `state` is ambiguous. We can remove it for consistency
type StateTX struct {
*Base
Descriptors []*StateDescriptor
}
//NewStateTX returns a state transaction
func NewStateTX(ver version.TX) *StateTX {
basicTrans := createBaseTransaction(types.State, ver)

View file

@ -13,7 +13,8 @@ const (
Validator DescStateType = 0x48
)
// StateDescriptor ..
// StateDescriptor represents a state descriptor on the neo network
// used in a state transaction
type StateDescriptor struct {
Type DescStateType
Key []byte
@ -21,6 +22,7 @@ type StateDescriptor struct {
Field string
}
// Decode decodes a binary reader into a state descriptor
func (s *StateDescriptor) Decode(br *util.BinReader) {
br.Read(&s.Type)
@ -38,6 +40,8 @@ func (s *StateDescriptor) Decode(br *util.BinReader) {
s.Field = string(field)
}
//Encode encodes a state descriptor into a binary writer
func (s *StateDescriptor) Encode(bw *util.BinWriter) {
bw.Write(s.Type)
@ -48,5 +52,4 @@ func (s *StateDescriptor) Encode(bw *util.BinWriter) {
bw.Write(s.Value)
bw.VarString(s.Field)
}

View file

@ -7,6 +7,7 @@ import (
// TX is the type of a transaction.
type TX uint8
// List of transaction types
const (
Miner TX = 0x00
Issue TX = 0x01
@ -21,9 +22,12 @@ const (
Invocation TX = 0xd1
)
// Encode encodes a tx type into the binary writer
func (t *TX) Encode(bw *util.BinWriter) {
bw.Write(t)
}
// Decode decodes a binary reader into a tx type
func (t *TX) Decode(br *util.BinReader) {
br.Read(t)
}

View file

@ -8,7 +8,8 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction/types"
)
func FromBytes(reader *bufio.Reader) (Transactioner, error) {
// FromReader returns a transaction from a bufio.Reader
func FromReader(reader *bufio.Reader) (Transactioner, error) {
t, err := reader.Peek(1)
@ -45,17 +46,17 @@ func FromBytes(reader *bufio.Reader) (Transactioner, error) {
err = pub.Decode(reader)
trans = pub
case types.State:
sta := NewStateTX(0)
err = sta.Decode(reader)
trans = sta
state := NewStateTX(0)
err = state.Decode(reader)
trans = state
case types.Enrollment:
enr := NewEnrollment(0)
err = enr.Decode(reader)
trans = enr
case types.Agency:
err = errors.New("Unsupported transaction type: Agency")
err = errors.New("unsupported transaction type: Agency")
default:
err = errors.New("Unsupported transaction with byte type " + hex.EncodeToString([]byte{t[0]}))
err = errors.New("unsupported transaction with byte type " + hex.EncodeToString([]byte{t[0]}))
}
return trans, err
}

View file

@ -4,16 +4,21 @@ import (
"github.com/CityOfZion/neo-go/pkg/wire/util"
)
// TX represents a tx version
type TX uint8
// List of latest tx version
const (
Contract TX = 0
Invocation TX = 1
)
// Encode encodes the tx version into the binary writer
func (v *TX) Encode(bw *util.BinWriter) {
bw.Write(v)
}
// Decode decodes the binary reader into a tx type
func (v *TX) Decode(br *util.BinReader) {
br.Read(v)
}

View file

@ -1,15 +1,19 @@
package protocol
//Version represents the latest protocol version for the neo node
type Version uint32
const (
// DefaultVersion is the nodes default protocol version
DefaultVersion Version = 0
UserAgent = "/NEO-GO/" // TODO: This may be relocated to a config file
// UserAgent is the nodes user agent or human-readable name
UserAgent = "/NEO-GO/"
)
// ServiceFlag indicates the services provided by the node. 1 = P2P Full Node
type ServiceFlag uint64
// List of Services offered by the node
const (
NodePeerService ServiceFlag = 1
// BloomFilerService ServiceFlag = 2 // Not implemented
@ -21,6 +25,7 @@ const (
// Magic is the network that NEO is running on
type Magic uint32
// List of possible networks
const (
MainNet Magic = 7630401
TestNet Magic = 0x74746e41

View file

@ -7,16 +7,20 @@ import (
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
)
// Compare calculates the checksum of b
// then compares it with the `have` checksum passed as a parameter
func Compare(have uint32, b []byte) bool {
want := FromBytes(b)
return have == want
}
// FromBuf calculates the checksum of a buffer
func FromBuf(buf *bytes.Buffer) uint32 {
return FromBytes(buf.Bytes())
}
// FromBytes calculates the checksum of a byte slice
func FromBytes(buf []byte) uint32 {
b, err := hash.DoubleSha256(buf)

View file

@ -6,6 +6,7 @@ import (
"github.com/CityOfZion/neo-go/pkg/crypto/base58"
)
// ToScriptHash converts an address to a script hash
func ToScriptHash(address string) string {
decodedAddressAsBytes, err := base58.Decode(address)

View file

@ -5,17 +5,24 @@ import (
"io"
)
//BinReader is a convenient wrapper around a io.Reader and err object
// Used to simplify error handling when reading into a struct with many fields
type BinReader struct {
R io.Reader
Err error
}
// Read reads from the underlying io.Reader
// into the interface v in LE
func (r *BinReader) Read(v interface{}) {
if r.Err != nil {
return
}
r.Err = binary.Read(r.R, binary.LittleEndian, v)
}
// ReadBigEnd reads from the underlying io.Reader
// into the interface v in BE
func (r *BinReader) ReadBigEnd(v interface{}) {
if r.Err != nil {
return
@ -23,6 +30,8 @@ func (r *BinReader) ReadBigEnd(v interface{}) {
r.Err = binary.Read(r.R, binary.BigEndian, v)
}
//VarUint reads a variable integer from the
// underlying reader
func (r *BinReader) VarUint() uint64 {
var b uint8
r.Err = binary.Read(r.R, binary.LittleEndian, &b)
@ -46,6 +55,8 @@ func (r *BinReader) VarUint() uint64 {
return uint64(b)
}
// VarBytes reads the next set of bytes from the underlying reader.
// VarUInt is used to determine how large that slice is
func (r *BinReader) VarBytes() []byte {
n := r.VarUint()
b := make([]byte, n)
@ -53,6 +64,7 @@ func (r *BinReader) VarBytes() []byte {
return b
}
// VarString calls VarBytes and casts the results as a string
func (r *BinReader) VarString() string {
b := r.VarBytes()
return string(b)

View file

@ -6,11 +6,15 @@ import (
"io"
)
//BinWriter is a convenient wrapper around a io.Writer and err object
// Used to simplify error handling when writing into a io.Writer
// from a struct with many fields
type BinWriter struct {
W io.Writer
Err error
}
// Write writes into the underlying io.Writer from an object v in LE format
func (w *BinWriter) Write(v interface{}) {
if w.Err != nil {
return
@ -18,6 +22,7 @@ func (w *BinWriter) Write(v interface{}) {
w.Err = binary.Write(w.W, binary.LittleEndian, v)
}
// WriteBigEnd writes into the underlying io.Writer from an object v in BE format
// Only used for IP and PORT. Additional method makes the default LittleEndian case clean
func (w *BinWriter) WriteBigEnd(v interface{}) {
if w.Err != nil {
@ -26,10 +31,7 @@ func (w *BinWriter) WriteBigEnd(v interface{}) {
w.Err = binary.Write(w.W, binary.BigEndian, v)
}
func (w *BinWriter) VarString(s string) {
w.VarBytes([]byte(s))
}
// VarUint writes a uint64 into the underlying writer
func (w *BinWriter) VarUint(val uint64) {
if val < 0 {
w.Err = errors.New("value out of range")
@ -61,8 +63,13 @@ func (w *BinWriter) VarUint(val uint64) {
}
// WriteVarBytes writes a variable length byte array.
// VarBytes writes a variable length byte array into the underlying io.Writer
func (w *BinWriter) VarBytes(b []byte) {
w.VarUint(uint64(len(b)))
w.Write(b)
}
//VarString casts the string as a byte slice and calls VarBytes
func (w *BinWriter) VarString(s string) {
w.VarBytes([]byte(s))
}

View file

@ -1,8 +1,11 @@
package base58
import (
"bytes"
"fmt"
"math/big"
"github.com/CityOfZion/neo-go/pkg/wire/util/crypto/hash"
)
const prefix rune = '1'
@ -22,7 +25,7 @@ var decodeMap = map[rune]int64{
'x': 55, 'y': 56, 'z': 57,
}
// Base58Decode decodes the base58 encoded string.
// Decode decodes the base58 encoded string.
func Decode(s string) ([]byte, error) {
var (
startIndex = 0
@ -58,7 +61,7 @@ func Decode(s string) ([]byte, error) {
return buf, nil
}
// Base58Encode encodes a byte slice to be a base58 encoded string.
// Encode encodes a byte slice to be a base58 encoded string.
func Encode(bytes []byte) string {
var (
lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
@ -77,47 +80,47 @@ func Encode(bytes []byte) string {
return encoded
}
// Base58CheckDecode decodes the given string.
// func CheckDecode(s string) (b []byte, err error) {
// b, err = Decode(s)
// if err != nil {
// return nil, err
// }
// CheckDecode decodes the given string.
func CheckDecode(s string) (b []byte, err error) {
b, err = Decode(s)
if err != nil {
return nil, err
}
// for i := 0; i < len(s); i++ {
// if s[i] != '1' {
// break
// }
// b = append([]byte{0x00}, b...)
// }
for i := 0; i < len(s); i++ {
if s[i] != '1' {
break
}
b = append([]byte{0x00}, b...)
}
// if len(b) < 5 {
// return nil, fmt.Errorf("Invalid base-58 check string: missing checksum. -1")
// }
if len(b) < 5 {
return nil, fmt.Errorf("Invalid base-58 check string: missing checksum. -1")
}
// hash, err := hash.DoubleSha256(b[:len(b)-4])
hash, err := hash.DoubleSha256(b[:len(b)-4])
// if err != nil {
// return nil, fmt.Errorf("Could not double sha256 data")
// }
if err != nil {
return nil, fmt.Errorf("Could not double sha256 data")
}
// if bytes.Compare(hash[0:4], b[len(b)-4:]) != 0 {
// return nil, fmt.Errorf("Invalid base-58 check string: invalid checksum. -2")
// }
if bytes.Compare(hash[0:4], b[len(b)-4:]) != 0 {
return nil, fmt.Errorf("Invalid base-58 check string: invalid checksum. -2")
}
// // Strip the 4 byte long hash.
// b = b[:len(b)-4]
// Strip the 4 byte long hash.
b = b[:len(b)-4]
// return b, nil
// }
return b, nil
}
// // Base58checkEncode encodes b into a base-58 check encoded string.
// func CheckEncode(b []byte) (string, error) {
// hash, err := hash.DoubleSha256(b)
// if err != nil {
// return "", fmt.Errorf("Could not double sha256 data")
// }
// b = append(b, hash[0:4]...)
// CheckEncode encodes b into a base-58 check encoded string.
func CheckEncode(b []byte) (string, error) {
hash, err := hash.DoubleSha256(b)
if err != nil {
return "", fmt.Errorf("Could not double sha256 data")
}
b = append(b, hash[0:4]...)
// return Encode(b), nil
// }
return Encode(b), nil
}

View file

@ -8,6 +8,7 @@ import (
"golang.org/x/crypto/ripemd160"
)
// Sha256 hashes the byte slice using sha256
func Sha256(data []byte) (util.Uint256, error) {
var hash util.Uint256
hasher := sha256.New()
@ -21,6 +22,7 @@ func Sha256(data []byte) (util.Uint256, error) {
return hash, nil
}
// DoubleSha256 hashes the underlying data twice using sha256
func DoubleSha256(data []byte) (util.Uint256, error) {
var hash util.Uint256
@ -36,6 +38,7 @@ func DoubleSha256(data []byte) (util.Uint256, error) {
return hash, nil
}
// RipeMD160 hashes the underlying data using ripemd160
func RipeMD160(data []byte) (util.Uint160, error) {
var hash util.Uint160
hasher := ripemd160.New()
@ -49,6 +52,7 @@ func RipeMD160(data []byte) (util.Uint160, error) {
return hash, nil
}
//Hash160 hashes the underlying data using sha256 then ripemd160
func Hash160(data []byte) (util.Uint160, error) {
var hash util.Uint160
h1, err := Sha256(data)
@ -63,6 +67,7 @@ func Hash160(data []byte) (util.Uint160, error) {
return hash, nil
}
// Checksum calculates the checksum of the byte slice using sha256
func Checksum(data []byte) ([]byte, error) {
hash, err := Sum(data)
if err != nil {
@ -71,6 +76,7 @@ func Checksum(data []byte) ([]byte, error) {
return hash[:4], nil
}
// Sum calculates the Sum of the data by using double sha256
func Sum(b []byte) (util.Uint256, error) {
hash, err := DoubleSha256((b))
return hash, err

View file

@ -25,12 +25,16 @@ func (f Fixed8) String() string {
func (f Fixed8) Value() float64 {
return float64(f) / float64(decimals)
}
// Add adds two Fixed8 values together
func (f Fixed8) Add(val Fixed8) Fixed8 {
a := int64(f.Value())
b := int64(val.Value())
c := a + b
return FromInt(c)
}
//Sub subtracts two fixed values from each other
func (f Fixed8) Sub(val Fixed8) Fixed8 {
a := int64(f.Value())
b := int64(val.Value())
@ -38,18 +42,21 @@ func (f Fixed8) Sub(val Fixed8) Fixed8 {
return FromInt(c)
}
//FromInt returns a Fixed8 objects from an int64
func FromInt(val int64) Fixed8 {
return Fixed8(val * decimals)
}
// FromFloat returns a Fixed8 object from a float64
func FromFloat(val float64) Fixed8 {
return Fixed8(val * decimals)
}
// FromString returns a Fixed8 object from a string
func FromString(val string) (Fixed8, error) {
res, err := strconv.ParseFloat(val, 64)
if err != nil {
return 0, fmt.Errorf("Failed at parsing string %s", val)
return 0, fmt.Errorf("failed at parsing string %s", val)
}
return FromFloat(res), nil
}

View file

@ -4,6 +4,7 @@ import (
"os"
)
// UpdateFile appends a byte slice to a file
func UpdateFile(filename string, data []byte) error {
f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)

View file

@ -5,6 +5,7 @@ import (
"net"
)
//GetLocalIP returns the ip address of the current node
// https://stackoverflow.com/a/37382208
func GetLocalIP() net.IP {
conn, err := net.Dial("udp", "8.8.8.8:80")

View file

@ -1,6 +1,6 @@
package slice
// SliceReverse return a reversed version of the given byte slice.
// Reverse return a reversed version of the given byte slice.
func Reverse(b []byte) []byte {
// Protect from big.Ints that have 1 len bytes.
if len(b) < 2 {

View file

@ -44,9 +44,11 @@ func (u Uint256) Bytes() []byte {
}
return b
}
func (u Uint256) Reverse() (res Uint256) {
res, _ = Uint256DecodeBytes(u.BytesReverse())
return
// Reverse reverses the Uint256 object
func (u Uint256) Reverse() Uint256 {
res, _ := Uint256DecodeBytes(u.BytesReverse())
return res
}
// BytesReverse return a reversed byte representation of u.

View file

@ -8,18 +8,23 @@ import (
"io/ioutil"
)
// Functions
// Convenience function
// BufferLength returns the length of a buffer as uint32
func BufferLength(buf *bytes.Buffer) uint32 {
return uint32(buf.Len())
}
// SumSHA256 returns the sha256 sum of the data
func SumSHA256(b []byte) []byte {
h := sha256.New()
h.Write(b)
return h.Sum(nil)
}
// CalculateHash takes a function with a binary writer and returns
// the double hash of the io.Writer
func CalculateHash(f func(bw *BinWriter)) (Uint256, error) {
buf := new(bytes.Buffer)
bw := &BinWriter{W: buf}
@ -33,15 +38,12 @@ func CalculateHash(f func(bw *BinWriter)) (Uint256, error) {
}
func ReaderToBuffer(r io.Reader) (buf *bytes.Buffer, err error) {
//ReaderToBuffer converts a io.Reader into a bytes.Buffer
func ReaderToBuffer(r io.Reader) (*bytes.Buffer, error) {
byt, err := ioutil.ReadAll(r)
if err != nil {
return
return nil, err
}
buf = bytes.NewBuffer(byt)
return
buf := bytes.NewBuffer(byt)
return buf, nil
}