Merge branch 'dev' into vm
This commit is contained in:
commit
5e26b40b5e
70 changed files with 502 additions and 258 deletions
1
go.mod
1
go.mod
|
@ -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
3
go.sum
|
@ -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=
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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{}
|
||||
|
|
|
@ -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 = []byte("TX")
|
||||
HEADER = []byte("HEADER")
|
||||
// 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 = []byte("UTXO")
|
||||
// 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!!!!
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package pubsub
|
||||
|
||||
// Publisher sends events to subscribers
|
||||
type Publisher struct {
|
||||
subs []Subscriber
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package pubsub
|
||||
|
||||
// Subscriber will listen for Events from publishers
|
||||
type Subscriber interface {
|
||||
Topics() []EventType
|
||||
Emit(Event)
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 InvType = 0x01
|
||||
InvTypeBlock InvType = 0x02
|
||||
// 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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package transaction
|
||||
|
||||
// AttrUsage represents an attribute usage on the neo network
|
||||
type AttrUsage uint8
|
||||
|
||||
// List of valid attribute usages.
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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)
|
||||
|
||||
}
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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{}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue