forked from TrueCloudLab/neoneo-go
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/o3labs/neo-utils v0.0.0-20190129071622-8ae0bc31751f
|
||||||
github.com/stretchr/testify v1.3.0
|
github.com/stretchr/testify v1.3.0
|
||||||
github.com/syndtr/goleveldb v1.0.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
|
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/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 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
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 h1:+/WWzjwW6gidDJnMKWLKLX1gxn7irUTF1fLpQovfQ5M=
|
||||||
golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
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=
|
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/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 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
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"
|
"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) {
|
func Encrypt(src, key []byte) ([]byte, error) {
|
||||||
block, err := aes.NewCipher(key)
|
block, err := aes.NewCipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -19,7 +19,7 @@ func Encrypt(src, key []byte) ([]byte, error) {
|
||||||
return out, nil
|
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) {
|
func Decrypt(crypted, key []byte) ([]byte, error) {
|
||||||
block, err := aes.NewCipher(key)
|
block, err := aes.NewCipher(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -22,7 +22,7 @@ var decodeMap = map[rune]int64{
|
||||||
'x': 55, 'y': 56, 'z': 57,
|
'x': 55, 'y': 56, 'z': 57,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base58Decode decodes the base58 encoded string.
|
// Decode decodes the base58 encoded string.
|
||||||
func Decode(s string) ([]byte, error) {
|
func Decode(s string) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
startIndex = 0
|
startIndex = 0
|
||||||
|
@ -58,7 +58,7 @@ func Decode(s string) ([]byte, error) {
|
||||||
return buf, nil
|
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 {
|
func Encode(bytes []byte) string {
|
||||||
var (
|
var (
|
||||||
lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||||
|
|
|
@ -18,10 +18,13 @@ var curve Curve
|
||||||
type curveType string
|
type curveType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// Secp256r1 curve type
|
||||||
Secp256r1 curveType = "Secp256r1"
|
Secp256r1 curveType = "Secp256r1"
|
||||||
|
// Secp256k1 curve type
|
||||||
Secp256k1 curveType = "Secp256k1"
|
Secp256k1 curveType = "Secp256k1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SetCurveSecp256r1 Will set the curve parameters to match Secp256r1
|
||||||
func (ChosenCurve *Curve) SetCurveSecp256r1() {
|
func (ChosenCurve *Curve) SetCurveSecp256r1() {
|
||||||
ChosenCurve.P, _ = new(big.Int).SetString("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16) //Q
|
ChosenCurve.P, _ = new(big.Int).SetString("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", 16) //Q
|
||||||
ChosenCurve.A, _ = new(big.Int).SetString("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16)
|
ChosenCurve.A, _ = new(big.Int).SetString("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", 16)
|
||||||
|
@ -33,6 +36,7 @@ func (ChosenCurve *Curve) SetCurveSecp256r1() {
|
||||||
ChosenCurve.Name = "Secp256r1"
|
ChosenCurve.Name = "Secp256r1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetCurveSecp256k1 Will set the curve parameters to match Secp256k1
|
||||||
func (ChosenCurve *Curve) SetCurveSecp256k1() {
|
func (ChosenCurve *Curve) SetCurveSecp256k1() {
|
||||||
ChosenCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
|
ChosenCurve.P, _ = new(big.Int).SetString("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16)
|
||||||
ChosenCurve.A, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000000", 16)
|
ChosenCurve.A, _ = new(big.Int).SetString("0000000000000000000000000000000000000000000000000000000000000000", 16)
|
||||||
|
@ -44,6 +48,8 @@ func (ChosenCurve *Curve) SetCurveSecp256k1() {
|
||||||
ChosenCurve.Name = "Secp256k1"
|
ChosenCurve.Name = "Secp256k1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewEllipticCurve will instantiate a new EllipticCurve
|
||||||
|
//Defaults to secp256r1
|
||||||
func NewEllipticCurve(ct curveType) Curve {
|
func NewEllipticCurve(ct curveType) Curve {
|
||||||
var curve Curve
|
var curve Curve
|
||||||
switch ct {
|
switch ct {
|
||||||
|
|
|
@ -19,8 +19,8 @@ type Point struct {
|
||||||
Y *big.Int
|
Y *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* y**2 = x**3 + a*x + b % p */
|
|
||||||
// Curve represents the parameters of a short Weierstrass equation elliptic curve.
|
// Curve represents the parameters of a short Weierstrass equation elliptic curve.
|
||||||
|
/* y**2 = x**3 + a*x + b % p */
|
||||||
type Curve struct {
|
type Curve struct {
|
||||||
A *big.Int
|
A *big.Int
|
||||||
B *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()))
|
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 {
|
func (ec Curve) Params() *nativeelliptic.CurveParams {
|
||||||
return &nativeelliptic.CurveParams{
|
return &nativeelliptic.CurveParams{
|
||||||
P: ec.P,
|
P: ec.P,
|
||||||
|
@ -302,12 +303,13 @@ func (ec *Curve) Decompress(x *big.Int, ylsb uint) (P Point, err error) {
|
||||||
P.Y = y
|
P.Y = y
|
||||||
|
|
||||||
if !ec.IsOnCurve(P.X, P.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
|
return P, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Double will return the (x1+x1,y1+y1)
|
||||||
func (ec Curve) Double(x1, y1 *big.Int) (x, y *big.Int) {
|
func (ec Curve) Double(x1, y1 *big.Int) (x, y *big.Int) {
|
||||||
x = &big.Int{}
|
x = &big.Int{}
|
||||||
x.SetBytes([]byte{0x00})
|
x.SetBytes([]byte{0x00})
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Sha256 hashes the incoming byte slice
|
||||||
|
// using the sha256 algorithm
|
||||||
func Sha256(data []byte) (util.Uint256, error) {
|
func Sha256(data []byte) (util.Uint256, error) {
|
||||||
var hash util.Uint256
|
var hash util.Uint256
|
||||||
hasher := sha256.New()
|
hasher := sha256.New()
|
||||||
|
@ -21,6 +23,7 @@ func Sha256(data []byte) (util.Uint256, error) {
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DoubleSha256 performs sha256 twice on the given data
|
||||||
func DoubleSha256(data []byte) (util.Uint256, error) {
|
func DoubleSha256(data []byte) (util.Uint256, error) {
|
||||||
var hash util.Uint256
|
var hash util.Uint256
|
||||||
|
|
||||||
|
@ -36,6 +39,8 @@ func DoubleSha256(data []byte) (util.Uint256, error) {
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RipeMD160 performs the RIPEMD160 hash algorithm
|
||||||
|
// on the given data
|
||||||
func RipeMD160(data []byte) (util.Uint160, error) {
|
func RipeMD160(data []byte) (util.Uint160, error) {
|
||||||
var hash util.Uint160
|
var hash util.Uint160
|
||||||
hasher := ripemd160.New()
|
hasher := ripemd160.New()
|
||||||
|
@ -49,6 +54,8 @@ func RipeMD160(data []byte) (util.Uint160, error) {
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hash160 performs sha256 and then ripemd160
|
||||||
|
// on the given data
|
||||||
func Hash160(data []byte) (util.Uint160, error) {
|
func Hash160(data []byte) (util.Uint160, error) {
|
||||||
var hash util.Uint160
|
var hash util.Uint160
|
||||||
h1, err := Sha256(data)
|
h1, err := Sha256(data)
|
||||||
|
@ -63,6 +70,8 @@ func Hash160(data []byte) (util.Uint160, error) {
|
||||||
return hash, nil
|
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) {
|
func Checksum(data []byte) ([]byte, error) {
|
||||||
hash, err := Sum(data)
|
hash, err := Sum(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -71,6 +80,8 @@ func Checksum(data []byte) ([]byte, error) {
|
||||||
return hash[:4], nil
|
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) {
|
func Sum(b []byte) (util.Uint256, error) {
|
||||||
hash, err := DoubleSha256((b))
|
hash, err := DoubleSha256((b))
|
||||||
return hash, err
|
return hash, err
|
||||||
|
|
|
@ -23,6 +23,8 @@ type PrivateKey struct {
|
||||||
b []byte
|
b []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPrivateKey will create a new private key
|
||||||
|
// With curve as Secp256r1
|
||||||
func NewPrivateKey() (*PrivateKey, error) {
|
func NewPrivateKey() (*PrivateKey, error) {
|
||||||
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
|
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
|
||||||
b := make([]byte, curve.N.BitLen()/8+8)
|
b := make([]byte, curve.N.BitLen()/8+8)
|
||||||
|
@ -38,6 +40,7 @@ func NewPrivateKey() (*PrivateKey, error) {
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPrivateKeyFromHex will create a new private key hex string
|
||||||
func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
|
func NewPrivateKeyFromHex(str string) (*PrivateKey, error) {
|
||||||
b, err := hex.DecodeString(str)
|
b, err := hex.DecodeString(str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -56,6 +59,8 @@ func NewPrivateKeyFromBytes(b []byte) (*PrivateKey, error) {
|
||||||
return &PrivateKey{b}, nil
|
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) {
|
func (p *PrivateKey) PublicKey() (*publickey.PublicKey, error) {
|
||||||
var (
|
var (
|
||||||
c = elliptic.NewEllipticCurve(elliptic.Secp256r1)
|
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) {
|
func WIFEncode(key []byte) (s string) {
|
||||||
if len(key) != 32 {
|
if len(key) != 32 {
|
||||||
return "invalid private key length"
|
return "invalid private key length"
|
||||||
|
@ -97,6 +104,7 @@ func WIFEncode(key []byte) (s string) {
|
||||||
return WIF
|
return WIF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sign will sign the corresponding data using the private key
|
||||||
func (p *PrivateKey) Sign(data []byte) ([]byte, error) {
|
func (p *PrivateKey) Sign(data []byte) ([]byte, error) {
|
||||||
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
|
curve := elliptic.NewEllipticCurve(elliptic.Secp256r1)
|
||||||
key := p.b
|
key := p.b
|
||||||
|
|
|
@ -5,16 +5,29 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/crypto/privatekey"
|
"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) {
|
func SignDataWithRandomPrivateKey(data []byte) (bool, error) {
|
||||||
|
|
||||||
hashedData, _ := hash.Sha256(data)
|
hashedData, err := hash.Sha256(data)
|
||||||
|
|
||||||
privKey, _ := privatekey.NewPrivateKey()
|
|
||||||
signedData, err := privKey.Sign(data)
|
|
||||||
pubKey, _ := privKey.PublicKey()
|
|
||||||
result := pubKey.Verify(signedData, hashedData.Bytes())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
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
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ func (p *PublicKey) Bytes() []byte {
|
||||||
|
|
||||||
return append([]byte{prefix}, paddedX...)
|
return append([]byte{prefix}, paddedX...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToAddress will convert a public key to it's neo-address
|
||||||
func (p *PublicKey) ToAddress() string {
|
func (p *PublicKey) ToAddress() string {
|
||||||
|
|
||||||
publicKeyBytes := p.Bytes()
|
publicKeyBytes := p.Bytes()
|
||||||
|
@ -145,6 +147,8 @@ func (p *PublicKey) EncodeBinary(w io.Writer) error {
|
||||||
return binary.Write(w, binary.LittleEndian, p.Bytes())
|
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 {
|
func (p *PublicKey) Verify(signature []byte, hash []byte) bool {
|
||||||
|
|
||||||
publicKey := &ecdsa.PublicKey{}
|
publicKey := &ecdsa.PublicKey{}
|
||||||
|
|
|
@ -12,27 +12,38 @@ import (
|
||||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// LDB represents a leveldb object
|
||||||
type LDB struct {
|
type LDB struct {
|
||||||
db *leveldb.DB
|
db *leveldb.DB
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Database contains all methods needed for an object to be a database
|
||||||
type Database interface {
|
type Database interface {
|
||||||
|
// Has checks whether the key is in the database
|
||||||
Has(key []byte) (bool, error)
|
Has(key []byte) (bool, error)
|
||||||
|
// Put adds the key value pair into the pair
|
||||||
Put(key []byte, value []byte) error
|
Put(key []byte, value []byte) error
|
||||||
|
// Get returns the value for the given key
|
||||||
Get(key []byte) ([]byte, error)
|
Get(key []byte) ([]byte, error)
|
||||||
|
// Delete deletes the given value for the key from the database
|
||||||
Delete(key []byte) error
|
Delete(key []byte) error
|
||||||
|
// Close closes the underlying db object
|
||||||
Close() error
|
Close() error
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
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")
|
TX = []byte("TX")
|
||||||
|
// HEADER is the prefix used when inserting a header into the db
|
||||||
HEADER = []byte("HEADER")
|
HEADER = []byte("HEADER")
|
||||||
|
// LATESTHEADER is the prefix used when inserting the latests header into the db
|
||||||
LATESTHEADER = []byte("LH")
|
LATESTHEADER = []byte("LH")
|
||||||
|
// UTXO is the prefix used when inserting a utxo into the db
|
||||||
UTXO = []byte("UTXO")
|
UTXO = []byte("UTXO")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// New will return a new leveldb instance
|
||||||
func New(path string) *LDB {
|
func New(path string) *LDB {
|
||||||
db, err := leveldb.OpenFile(path, nil)
|
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) {
|
func (l *LDB) Has(key []byte) (bool, error) {
|
||||||
return l.db.Has(key, nil)
|
return l.db.Has(key, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put implements the database interface
|
||||||
func (l *LDB) Put(key []byte, value []byte) error {
|
func (l *LDB) Put(key []byte, value []byte) error {
|
||||||
return l.db.Put(key, value, nil)
|
return l.db.Put(key, value, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get implements the database interface
|
||||||
func (l *LDB) Get(key []byte) ([]byte, error) {
|
func (l *LDB) Get(key []byte) ([]byte, error) {
|
||||||
return l.db.Get(key, nil)
|
return l.db.Get(key, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete implements the database interface
|
||||||
func (l *LDB) Delete(key []byte) error {
|
func (l *LDB) Delete(key []byte) error {
|
||||||
return l.db.Delete(key, nil)
|
return l.db.Delete(key, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close implements the database interface
|
||||||
func (l *LDB) Close() error {
|
func (l *LDB) Close() error {
|
||||||
return l.db.Close()
|
return l.db.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddHeader adds a header into the database
|
||||||
func (l *LDB) AddHeader(header *payload.BlockBase) error {
|
func (l *LDB) AddHeader(header *payload.BlockBase) error {
|
||||||
|
|
||||||
table := NewTable(l, HEADER)
|
table := NewTable(l, HEADER)
|
||||||
|
@ -102,6 +122,7 @@ func (l *LDB) AddHeader(header *payload.BlockBase) error {
|
||||||
return table.Put(LATESTHEADER, header.Hash.Bytes())
|
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 {
|
func (l *LDB) AddTransactions(blockhash util.Uint256, txs []transaction.Transactioner) error {
|
||||||
|
|
||||||
// SHOULD BE DONE IN BATCH!!!!
|
// SHOULD BE DONE IN BATCH!!!!
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package database
|
package database
|
||||||
|
|
||||||
//Table is an abstract datastructure built on
|
//Table is an abstract data structure built on top of a db
|
||||||
// top of a db
|
|
||||||
type Table struct {
|
type Table struct {
|
||||||
prefix []byte
|
prefix []byte
|
||||||
db Database
|
db Database
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewTable creates a new table on the given database
|
||||||
func NewTable(db Database, prefix []byte) *Table {
|
func NewTable(db Database, prefix []byte) *Table {
|
||||||
return &Table{
|
return &Table{
|
||||||
prefix,
|
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) {
|
func (t *Table) Has(key []byte) (bool, error) {
|
||||||
key = append(t.prefix, key...)
|
key = append(t.prefix, key...)
|
||||||
return t.db.Has(key)
|
return t.db.Has(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put implements the database interface
|
||||||
func (t *Table) Put(key []byte, value []byte) error {
|
func (t *Table) Put(key []byte, value []byte) error {
|
||||||
key = append(t.prefix, key...)
|
key = append(t.prefix, key...)
|
||||||
return t.db.Put(key, value)
|
return t.db.Put(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get implements the database interface
|
||||||
func (t *Table) Get(key []byte) ([]byte, error) {
|
func (t *Table) Get(key []byte) ([]byte, error) {
|
||||||
key = append(t.prefix, key...)
|
key = append(t.prefix, key...)
|
||||||
return t.db.Get(key)
|
return t.db.Get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete implements the database interface
|
||||||
func (t *Table) Delete(key []byte) error {
|
func (t *Table) Delete(key []byte) error {
|
||||||
key = append(t.prefix, key...)
|
key = append(t.prefix, key...)
|
||||||
return t.db.Delete(key)
|
return t.db.Delete(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close implements the database interface
|
||||||
func (t *Table) Close() error {
|
func (t *Table) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// LocalConfig specifies the properties that should be available for each remote peer
|
// LocalConfig specifies the properties that should be available for each remote peer
|
||||||
|
|
||||||
type LocalConfig struct {
|
type LocalConfig struct {
|
||||||
Net protocol.Magic
|
Net protocol.Magic
|
||||||
UserAgent string
|
UserAgent string
|
||||||
|
|
|
@ -53,6 +53,7 @@ var (
|
||||||
errHandShakeTimeout = errors.New("Handshake timed out, peers have " + string(handshakeTimeout) + " Seconds to Complete the handshake")
|
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 {
|
type Peer struct {
|
||||||
config LocalConfig
|
config LocalConfig
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
|
@ -81,6 +82,7 @@ type Peer struct {
|
||||||
quitch chan struct{}
|
quitch chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewPeer returns a new NEO peer
|
||||||
func NewPeer(con net.Conn, inbound bool, cfg LocalConfig) *Peer {
|
func NewPeer(con net.Conn, inbound bool, cfg LocalConfig) *Peer {
|
||||||
p := Peer{}
|
p := Peer{}
|
||||||
p.inch = make(chan func(), inputBufferSize)
|
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)
|
return wire.ReadMessage(p.conn, p.config.Net)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnects from a peer
|
// Disconnect disconnects a peer and closes the connection
|
||||||
func (p *Peer) Disconnect() {
|
func (p *Peer) Disconnect() {
|
||||||
|
|
||||||
// return if already disconnected
|
// 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 {
|
func (p *Peer) Port() uint16 {
|
||||||
return p.port
|
return p.port
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreatedAt returns the time at which the connection was made
|
||||||
func (p *Peer) CreatedAt() time.Time {
|
func (p *Peer) CreatedAt() time.Time {
|
||||||
return p.createdAt
|
return p.createdAt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CanRelay returns true, if the peer can relay information
|
||||||
func (p *Peer) CanRelay() bool {
|
func (p *Peer) CanRelay() bool {
|
||||||
return p.relay
|
return p.relay
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LocalAddr returns this node's local address
|
||||||
func (p *Peer) LocalAddr() net.Addr {
|
func (p *Peer) LocalAddr() net.Addr {
|
||||||
return p.conn.LocalAddr()
|
return p.conn.LocalAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoteAddr returns the remote address of the connected peer
|
||||||
func (p *Peer) RemoteAddr() net.Addr {
|
func (p *Peer) RemoteAddr() net.Addr {
|
||||||
return p.conn.RemoteAddr()
|
return p.conn.RemoteAddr()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Services returns the services offered by the peer
|
||||||
func (p *Peer) Services() protocol.ServiceFlag {
|
func (p *Peer) Services() protocol.ServiceFlag {
|
||||||
return p.config.Services
|
return p.config.Services
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Inbound returns true whether this peer is an inbound peer
|
||||||
func (p *Peer) Inbound() bool {
|
func (p *Peer) Inbound() bool {
|
||||||
return p.inbound
|
return p.inbound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UserAgent returns this nodes, useragent
|
||||||
func (p *Peer) UserAgent() string {
|
func (p *Peer) UserAgent() string {
|
||||||
return p.config.UserAgent
|
return p.config.UserAgent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsVerackReceived returns true, if this node has
|
||||||
|
// received a verack from this peer
|
||||||
func (p *Peer) IsVerackReceived() bool {
|
func (p *Peer) IsVerackReceived() bool {
|
||||||
return p.verackReceived
|
return p.verackReceived
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NotifyDisconnect returns once the peer has disconnected
|
||||||
|
// Blocking
|
||||||
func (p *Peer) NotifyDisconnect() bool {
|
func (p *Peer) NotifyDisconnect() bool {
|
||||||
fmt.Println("Peer has not disconnected yet")
|
fmt.Println("Peer has not disconnected yet")
|
||||||
<-p.quitch
|
<-p.quitch
|
||||||
|
@ -163,7 +185,7 @@ func (p *Peer) NotifyDisconnect() bool {
|
||||||
|
|
||||||
//End of Exposed API functions//
|
//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
|
// will cause this client to disconnect from all other implementations
|
||||||
func (p *Peer) PingLoop() { /*not implemented in other neo clients*/ }
|
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
|
// should be ran after handshake
|
||||||
func (p *Peer) StartProtocol() {
|
func (p *Peer) StartProtocol() {
|
||||||
loop:
|
loop:
|
||||||
|
@ -201,11 +223,9 @@ loop:
|
||||||
p.Disconnect()
|
p.Disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadLoop Will block on the read until a message is read
|
||||||
// Should only be called after handshake is complete
|
// Should only be called after handshake is complete
|
||||||
// on a seperate go-routine.
|
// on a seperate go-routine.
|
||||||
// ReadLoop Will block on the read until a message is
|
|
||||||
// read
|
|
||||||
|
|
||||||
func (p *Peer) ReadLoop() {
|
func (p *Peer) ReadLoop() {
|
||||||
|
|
||||||
idleTimer := time.AfterFunc(idleTimeout, func() {
|
idleTimer := time.AfterFunc(idleTimeout, func() {
|
||||||
|
@ -271,8 +291,7 @@ loop:
|
||||||
p.Disconnect()
|
p.Disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteLoop will Queue all messages to be written to
|
// WriteLoop will Queue all messages to be written to the peer.
|
||||||
// the peer.
|
|
||||||
func (p *Peer) WriteLoop() {
|
func (p *Peer) WriteLoop() {
|
||||||
for atomic.LoadInt32(&p.disconnected) == 0 {
|
for atomic.LoadInt32(&p.disconnected) == 0 {
|
||||||
select {
|
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) {
|
func (p *Peer) OnGetData(msg *payload.GetDataMessage) {
|
||||||
|
|
||||||
p.inch <- func() {
|
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())
|
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) {
|
func (p *Peer) OnTX(msg *payload.TXMessage) {
|
||||||
|
|
||||||
p.inch <- func() {
|
p.inch <- func() {
|
||||||
// fmt.Println(msg.Hashes)
|
|
||||||
getdata, err := payload.NewGetDataMessage(payload.InvTypeTx)
|
getdata, err := payload.NewGetDataMessage(payload.InvTypeTx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Eor", err)
|
fmt.Println("Eor", err)
|
||||||
|
@ -302,10 +325,10 @@ func (p *Peer) OnTX(msg *payload.TXMessage) {
|
||||||
id, err := msg.Tx.ID()
|
id, err := msg.Tx.ID()
|
||||||
getdata.AddHash(id)
|
getdata.AddHash(id)
|
||||||
p.Write(getdata)
|
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) {
|
func (p *Peer) OnInv(msg *payload.InvMessage) {
|
||||||
|
|
||||||
p.inch <- func() {
|
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
|
// OnGetHeaders is called when a GetHeaders message is received
|
||||||
// like timing
|
|
||||||
func (p *Peer) OnGetHeaders(msg *payload.GetHeadersMessage) {
|
func (p *Peer) OnGetHeaders(msg *payload.GetHeadersMessage) {
|
||||||
p.inch <- func() {
|
p.inch <- func() {
|
||||||
if p.config.OnGetHeaders != nil {
|
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) {
|
func (p *Peer) OnAddr(msg *payload.AddrMessage) {
|
||||||
p.inch <- func() {
|
p.inch <- func() {
|
||||||
if p.config.OnAddr != nil {
|
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) {
|
func (p *Peer) OnGetAddr(msg *payload.GetAddrMessage) {
|
||||||
p.inch <- func() {
|
p.inch <- func() {
|
||||||
if p.config.OnGetAddr != nil {
|
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) {
|
func (p *Peer) OnGetBlocks(msg *payload.GetBlocksMessage) {
|
||||||
p.inch <- func() {
|
p.inch <- func() {
|
||||||
if p.config.OnGetBlocks != nil {
|
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) {
|
func (p *Peer) OnBlocks(msg *payload.BlockMessage) {
|
||||||
p.inch <- func() {
|
p.inch <- func() {
|
||||||
if p.config.OnBlock != nil {
|
if p.config.OnBlock != nil {
|
||||||
|
@ -386,7 +408,7 @@ func (p *Peer) OnVersion(msg *payload.VersionMessage) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnHeaders Listener
|
// OnHeaders is called when a Headers message is received
|
||||||
func (p *Peer) OnHeaders(msg *payload.HeadersMessage) {
|
func (p *Peer) OnHeaders(msg *payload.HeadersMessage) {
|
||||||
fmt.Println("We have received the headers")
|
fmt.Println("We have received the headers")
|
||||||
p.inch <- func() {
|
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 {
|
func (p *Peer) RequestHeaders(hash util.Uint256) error {
|
||||||
fmt.Println("Sending header request")
|
|
||||||
c := make(chan error, 0)
|
c := make(chan error, 0)
|
||||||
p.outch <- func() {
|
p.outch <- func() {
|
||||||
p.Detector.AddMessage(command.GetHeaders)
|
p.Detector.AddMessage(command.GetHeaders)
|
||||||
|
@ -406,14 +427,11 @@ func (p *Peer) RequestHeaders(hash util.Uint256) error {
|
||||||
err = p.Write(getHeaders)
|
err = p.Write(getHeaders)
|
||||||
c <- err
|
c <- err
|
||||||
}
|
}
|
||||||
|
|
||||||
return <-c
|
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 {
|
func (p *Peer) RequestBlocks(hashes []util.Uint256) error {
|
||||||
fmt.Println("Requesting block from peer")
|
|
||||||
c := make(chan error, 0)
|
c := make(chan error, 0)
|
||||||
|
|
||||||
p.outch <- func() {
|
p.outch <- func() {
|
||||||
|
|
|
@ -7,9 +7,10 @@ import (
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire"
|
"github.com/CityOfZion/neo-go/pkg/wire"
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/payload"
|
"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 {
|
func (p *Peer) Handshake() error {
|
||||||
|
|
||||||
handshakeErr := make(chan error, 1)
|
handshakeErr := make(chan error, 1)
|
||||||
|
|
|
@ -9,10 +9,9 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
"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
|
// If any message takes too long to reply
|
||||||
// the detector will disconnect the peer
|
// the detector will disconnect the peer
|
||||||
|
|
||||||
type Detector struct {
|
type Detector struct {
|
||||||
responseTime time.Duration
|
responseTime time.Duration
|
||||||
tickInterval time.Duration
|
tickInterval time.Duration
|
||||||
|
@ -28,6 +27,7 @@ type Detector struct {
|
||||||
disconnected int32
|
disconnected int32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewDetector will create a new stall detector
|
||||||
// rT is the responseTime and signals how long
|
// rT is the responseTime and signals how long
|
||||||
// a peer has to reply back to a sent message
|
// a peer has to reply back to a sent message
|
||||||
// tickerInterval is how often the detector wil check for stalled messages
|
// tickerInterval is how often the detector wil check for stalled messages
|
||||||
|
@ -81,9 +81,10 @@ func (d *Detector) Quit() {
|
||||||
close(d.Quitch)
|
close(d.Quitch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AddMessage will add a message to the responses map
|
||||||
// Call this function when we send a message to a peer
|
// Call this function when we send a message to a peer
|
||||||
// The command passed through is the command that we sent
|
// 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) {
|
func (d *Detector) AddMessage(cmd command.Type) {
|
||||||
cmds := d.addMessage(cmd)
|
cmds := d.addMessage(cmd)
|
||||||
d.lock.Lock()
|
d.lock.Lock()
|
||||||
|
@ -93,6 +94,7 @@ func (d *Detector) AddMessage(cmd command.Type) {
|
||||||
d.lock.Unlock()
|
d.lock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveMessage remove messages from the responses map
|
||||||
// Call this function when we receive a message from
|
// Call this function when we receive a message from
|
||||||
// peer. This will remove the pendingresponse message from the map.
|
// peer. This will remove the pendingresponse message from the map.
|
||||||
// The command passed through is the command we received
|
// The command passed through is the command we received
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
package pubsub
|
package pubsub
|
||||||
|
|
||||||
|
// EventType is an enum
|
||||||
|
// representing the types of messages we can subscribe to
|
||||||
type EventType int
|
type EventType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NewBlock EventType = iota // When blockchain connects a new block, it will emit an NewBlock Event
|
// NewBlock is called 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
|
NewBlock EventType = iota
|
||||||
BadHeader // When blockchain rejects a Header, it will emit this event
|
// 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 Event struct {
|
||||||
Type EventType // E.g. event.NewBlock
|
Type EventType // E.g. event.NewBlock
|
||||||
data []byte // Raw information
|
data []byte // Raw information
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package pubsub
|
package pubsub
|
||||||
|
|
||||||
|
// Publisher sends events to subscribers
|
||||||
type Publisher struct {
|
type Publisher struct {
|
||||||
subs []Subscriber
|
subs []Subscriber
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package pubsub
|
package pubsub
|
||||||
|
|
||||||
|
// Subscriber will listen for Events from publishers
|
||||||
type Subscriber interface {
|
type Subscriber interface {
|
||||||
Topics() []EventType
|
Topics() []EventType
|
||||||
Emit(Event)
|
Emit(Event)
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Base is everything in the message except the payload
|
// Base is everything in the message except the payload
|
||||||
|
|
||||||
type Base struct {
|
type Base struct {
|
||||||
Magic uint32
|
Magic uint32
|
||||||
CMD command.Type
|
CMD command.Type
|
||||||
|
@ -16,9 +15,8 @@ type Base struct {
|
||||||
Checksum uint32
|
Checksum uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note, That there is no EncodeBase
|
// DecodeBase will decode an io.Reader into a Base object
|
||||||
// As the header is implicitly inferred from
|
// Note, That there is no EncodeBase, As the header is implicitly inferred from the message on Encode To send
|
||||||
// the message on Encode To send
|
|
||||||
func (h *Base) DecodeBase(r io.Reader) (io.Reader, error) {
|
func (h *Base) DecodeBase(r io.Reader) (io.Reader, error) {
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
|
|
||||||
|
|
|
@ -5,11 +5,10 @@ const (
|
||||||
Size = 12
|
Size = 12
|
||||||
)
|
)
|
||||||
|
|
||||||
// CommandType represents the type of a message command.
|
// Type represents the type of a message command.
|
||||||
type Type string
|
type Type string
|
||||||
|
|
||||||
// Valid protocol commands used to send between nodes.
|
// Valid protocol commands used to send between nodes.
|
||||||
// use this to get
|
|
||||||
const (
|
const (
|
||||||
Version Type = "version"
|
Version Type = "version"
|
||||||
Mempool Type = "mempool"
|
Mempool Type = "mempool"
|
||||||
|
|
|
@ -15,9 +15,15 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Messager is implemented by any object that can
|
||||||
|
// Encode and Decode Payloads
|
||||||
type Messager interface {
|
type Messager interface {
|
||||||
|
// EncodePayload takes a message payload and encodes it
|
||||||
EncodePayload(w io.Writer) error
|
EncodePayload(w io.Writer) error
|
||||||
|
// DecodePayload takes an io.Reader and decodes it into
|
||||||
|
// a message payload
|
||||||
DecodePayload(r io.Reader) error
|
DecodePayload(r io.Reader) error
|
||||||
|
// Command returns the assosciated command type
|
||||||
Command() command.Type
|
Command() command.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +36,7 @@ var (
|
||||||
errChecksumMismatch = errors.New("checksum mismatch")
|
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 {
|
func WriteMessage(w io.Writer, magic protocol.Magic, message Messager) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
bw.Write(magic)
|
bw.Write(magic)
|
||||||
|
@ -51,6 +58,7 @@ func WriteMessage(w io.Writer, magic protocol.Magic, message Messager) error {
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadMessage will read a message from a given io.Reader
|
||||||
func ReadMessage(r io.Reader, magic protocol.Magic) (Messager, error) {
|
func ReadMessage(r io.Reader, magic protocol.Magic) (Messager, error) {
|
||||||
|
|
||||||
byt := make([]byte, minMsgSize)
|
byt := make([]byte, minMsgSize)
|
||||||
|
@ -122,7 +130,7 @@ func ReadMessage(r io.Reader, magic protocol.Magic) (Messager, error) {
|
||||||
return v, err
|
return v, err
|
||||||
case command.TX:
|
case command.TX:
|
||||||
reader := bufio.NewReader(buf)
|
reader := bufio.NewReader(buf)
|
||||||
tx, err := transaction.FromBytes(reader)
|
tx, err := transaction.FromReader(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,21 +9,27 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Block representa a Block in the neo-network
|
||||||
type Block struct {
|
type Block struct {
|
||||||
BlockBase
|
BlockBase
|
||||||
Txs []transaction.Transactioner
|
Txs []transaction.Transactioner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes an io.Reader into a Block
|
||||||
func (b *Block) Decode(r io.Reader) error {
|
func (b *Block) Decode(r io.Reader) error {
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
b.DecodePayload(br)
|
b.DecodePayload(br)
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode writes a block into a io.Writer
|
||||||
func (b *Block) Encode(w io.Writer) error {
|
func (b *Block) Encode(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
b.EncodePayload(bw)
|
b.EncodePayload(bw)
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//EncodePayload implements Messager interface
|
||||||
func (b *Block) EncodePayload(bw *util.BinWriter) {
|
func (b *Block) EncodePayload(bw *util.BinWriter) {
|
||||||
b.BlockBase.EncodePayload(bw)
|
b.BlockBase.EncodePayload(bw)
|
||||||
bw.VarUint(uint64(len(b.Txs)))
|
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 {
|
func (b *Block) DecodePayload(br *util.BinReader) error {
|
||||||
|
|
||||||
b.BlockBase.DecodePayload(br)
|
b.BlockBase.DecodePayload(br)
|
||||||
|
@ -42,7 +49,7 @@ func (b *Block) DecodePayload(br *util.BinReader) error {
|
||||||
reader := bufio.NewReader(br.R)
|
reader := bufio.NewReader(br.R)
|
||||||
for i := 0; i < int(lenTXs); i++ {
|
for i := 0; i < int(lenTXs); i++ {
|
||||||
|
|
||||||
tx, err := transaction.FromBytes(reader)
|
tx, err := transaction.FromReader(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -52,6 +59,7 @@ func (b *Block) DecodePayload(br *util.BinReader) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bytes returns the Byte representation of Block
|
||||||
func (b *Block) Bytes() ([]byte, error) {
|
func (b *Block) Bytes() ([]byte, error) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := b.Encode(buf)
|
err := b.Encode(buf)
|
||||||
|
|
|
@ -10,9 +10,11 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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 {
|
type BlockBase struct {
|
||||||
// Version of the block.
|
// Version of the block.
|
||||||
Version uint32 `json:"version"`
|
Version uint32 `json:"version"`
|
||||||
|
@ -47,6 +49,7 @@ type BlockBase struct {
|
||||||
Hash util.Uint256
|
Hash util.Uint256
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncodePayload implements the Messager interface
|
||||||
func (b *BlockBase) EncodePayload(bw *util.BinWriter) error {
|
func (b *BlockBase) EncodePayload(bw *util.BinWriter) error {
|
||||||
|
|
||||||
b.encodeHashableFields(bw)
|
b.encodeHashableFields(bw)
|
||||||
|
@ -57,11 +60,14 @@ func (b *BlockBase) EncodePayload(bw *util.BinWriter) error {
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes an io.Reader into a Blockbase
|
||||||
func (b *BlockBase) Decode(r io.Reader) error {
|
func (b *BlockBase) Decode(r io.Reader) error {
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
b.DecodePayload(br)
|
b.DecodePayload(br)
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode encodes a blockbase into an io.Writer
|
||||||
func (b *BlockBase) Encode(w io.Writer) error {
|
func (b *BlockBase) Encode(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
b.EncodePayload(bw)
|
b.EncodePayload(bw)
|
||||||
|
@ -78,6 +84,7 @@ func (b *BlockBase) encodeHashableFields(bw *util.BinWriter) {
|
||||||
bw.Write(b.NextConsensus)
|
bw.Write(b.NextConsensus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodePayload implements the messager interface
|
||||||
func (b *BlockBase) DecodePayload(br *util.BinReader) error {
|
func (b *BlockBase) DecodePayload(br *util.BinReader) error {
|
||||||
|
|
||||||
b.decodeHashableFields(br)
|
b.decodeHashableFields(br)
|
||||||
|
@ -85,7 +92,7 @@ func (b *BlockBase) DecodePayload(br *util.BinReader) error {
|
||||||
var padding uint8
|
var padding uint8
|
||||||
br.Read(&padding)
|
br.Read(&padding)
|
||||||
if padding != 1 {
|
if padding != 1 {
|
||||||
return ErrPadding
|
return errPadding
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Witness = transaction.Witness{}
|
b.Witness = transaction.Witness{}
|
||||||
|
@ -117,6 +124,7 @@ func (b *BlockBase) createHash() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bytes returns the byte representation of Blockbase
|
||||||
func (b *BlockBase) Bytes() ([]byte, error) {
|
func (b *BlockBase) Bytes() ([]byte, error) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
err := b.Encode(buf)
|
err := b.Encode(buf)
|
||||||
|
|
|
@ -7,10 +7,12 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AddrMessage represents an address message on the neo network
|
||||||
type AddrMessage struct {
|
type AddrMessage struct {
|
||||||
AddrList []*Net_addr
|
AddrList []*NetAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewAddrMessage instantiates a new AddrMessage
|
||||||
func NewAddrMessage() (*AddrMessage, error) {
|
func NewAddrMessage() (*AddrMessage, error) {
|
||||||
addrMess := &AddrMessage{
|
addrMess := &AddrMessage{
|
||||||
nil,
|
nil,
|
||||||
|
@ -18,22 +20,23 @@ func NewAddrMessage() (*AddrMessage, error) {
|
||||||
return addrMess, nil
|
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)
|
a.AddrList = append(a.AddrList, n)
|
||||||
// TODO:check if max reached, if so return err. What is max?
|
// TODO:check if max reached, if so return err. What is max?
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (a *AddrMessage) DecodePayload(r io.Reader) error {
|
func (a *AddrMessage) DecodePayload(r io.Reader) error {
|
||||||
|
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
listLen := br.VarUint()
|
listLen := br.VarUint()
|
||||||
|
|
||||||
a.AddrList = make([]*Net_addr, listLen)
|
a.AddrList = make([]*NetAddr, listLen)
|
||||||
for i := 0; i < int(listLen); i++ {
|
for i := 0; i < int(listLen); i++ {
|
||||||
a.AddrList[i] = &Net_addr{}
|
a.AddrList[i] = &NetAddr{}
|
||||||
a.AddrList[i].DecodePayload(br)
|
a.AddrList[i].DecodePayload(br)
|
||||||
if br.Err != nil {
|
if br.Err != nil {
|
||||||
return br.Err
|
return br.Err
|
||||||
|
@ -42,20 +45,20 @@ func (a *AddrMessage) DecodePayload(r io.Reader) error {
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *AddrMessage) EncodePayload(w io.Writer) error {
|
func (a *AddrMessage) EncodePayload(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
|
|
||||||
listLen := uint64(len(v.AddrList))
|
listLen := uint64(len(a.AddrList))
|
||||||
bw.VarUint(listLen)
|
bw.VarUint(listLen)
|
||||||
|
|
||||||
for _, addr := range v.AddrList {
|
for _, addr := range a.AddrList {
|
||||||
addr.EncodePayload(bw)
|
addr.EncodePayload(bw)
|
||||||
}
|
}
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *AddrMessage) Command() command.Type {
|
func (a *AddrMessage) Command() command.Type {
|
||||||
return command.Addr
|
return command.Addr
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,29 +8,31 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// BlockMessage represents a block message on the neo-network
|
||||||
type BlockMessage struct {
|
type BlockMessage struct {
|
||||||
Block
|
Block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewBlockMessage will return a block message object
|
||||||
func NewBlockMessage() (*BlockMessage, error) {
|
func NewBlockMessage() (*BlockMessage, error) {
|
||||||
return &BlockMessage{}, nil
|
return &BlockMessage{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (b *BlockMessage) DecodePayload(r io.Reader) error {
|
func (b *BlockMessage) DecodePayload(r io.Reader) error {
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
b.Block.DecodePayload(br)
|
b.Block.DecodePayload(br)
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (b *BlockMessage) EncodePayload(w io.Writer) error {
|
func (b *BlockMessage) EncodePayload(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
b.Block.EncodePayload(bw)
|
b.Block.EncodePayload(bw)
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *BlockMessage) Command() command.Type {
|
func (b *BlockMessage) Command() command.Type {
|
||||||
return command.Block
|
return command.Block
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,25 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
// No payload
|
//GetAddrMessage represents a GetAddress message on the neo-network
|
||||||
type GetAddrMessage struct{}
|
type GetAddrMessage struct{}
|
||||||
|
|
||||||
|
// NewGetAddrMessage returns a GetAddrMessage object
|
||||||
func NewGetAddrMessage() (*GetAddrMessage, error) {
|
func NewGetAddrMessage() (*GetAddrMessage, error) {
|
||||||
return &GetAddrMessage{}, nil
|
return &GetAddrMessage{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (v *GetAddrMessage) DecodePayload(r io.Reader) error {
|
func (v *GetAddrMessage) DecodePayload(r io.Reader) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *GetAddrMessage) EncodePayload(w io.Writer) error {
|
func (v *GetAddrMessage) EncodePayload(w io.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *GetAddrMessage) Command() command.Type {
|
func (v *GetAddrMessage) Command() command.Type {
|
||||||
return command.GetAddr
|
return command.GetAddr
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,12 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetBlocksMessage represnts a GetBlocks message on the neo-network
|
||||||
type GetBlocksMessage struct {
|
type GetBlocksMessage struct {
|
||||||
*GetHeadersMessage
|
*GetHeadersMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGetBlocksMessage returns a GetBlocksMessage object
|
||||||
func NewGetBlocksMessage(start []util.Uint256, stop util.Uint256) (*GetBlocksMessage, error) {
|
func NewGetBlocksMessage(start []util.Uint256, stop util.Uint256) (*GetBlocksMessage, error) {
|
||||||
GetHeaders, err := newAbstractGetHeaders(start, stop, command.GetBlocks)
|
GetHeaders, err := newAbstractGetHeaders(start, stop, command.GetBlocks)
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,12 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetDataMessage represents a GetData message on the neo-network
|
||||||
type GetDataMessage struct {
|
type GetDataMessage struct {
|
||||||
*InvMessage
|
*InvMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewGetDataMessage returns a GetDataMessage object
|
||||||
func NewGetDataMessage(typ InvType) (*GetDataMessage, error) {
|
func NewGetDataMessage(typ InvType) (*GetDataMessage, error) {
|
||||||
getData, err := newAbstractInv(typ, command.GetData)
|
getData, err := newAbstractInv(typ, command.GetData)
|
||||||
return &GetDataMessage{
|
return &GetDataMessage{
|
||||||
|
|
|
@ -7,12 +7,14 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//GetHeadersMessage represents a GetHeaders message on the neo-network
|
||||||
type GetHeadersMessage struct {
|
type GetHeadersMessage struct {
|
||||||
cmd command.Type
|
cmd command.Type
|
||||||
hashStart []util.Uint256
|
hashStart []util.Uint256
|
||||||
hashStop util.Uint256
|
hashStop util.Uint256
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewGetHeadersMessage returns a NewGetHeaders object
|
||||||
// Start contains the list of all headers you want to fetch
|
// 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
|
// End contains the list of the highest header hash you would like to fetch
|
||||||
func NewGetHeadersMessage(start []util.Uint256, stop util.Uint256) (*GetHeadersMessage, error) {
|
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
|
return getHeaders, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (v *GetHeadersMessage) DecodePayload(r io.Reader) error {
|
func (v *GetHeadersMessage) DecodePayload(r io.Reader) error {
|
||||||
|
|
||||||
br := util.BinReader{R: r}
|
br := util.BinReader{R: r}
|
||||||
|
@ -44,7 +46,7 @@ func (v *GetHeadersMessage) DecodePayload(r io.Reader) error {
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *GetHeadersMessage) EncodePayload(w io.Writer) error {
|
func (v *GetHeadersMessage) EncodePayload(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
bw.VarUint(uint64(len(v.hashStart)))
|
bw.VarUint(uint64(len(v.hashStart)))
|
||||||
|
@ -53,7 +55,7 @@ func (v *GetHeadersMessage) EncodePayload(w io.Writer) error {
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *GetHeadersMessage) Command() command.Type {
|
func (v *GetHeadersMessage) Command() command.Type {
|
||||||
return v.cmd
|
return v.cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HeadersMessage represents a Header(s) Message on the neo-network
|
||||||
type HeadersMessage struct {
|
type HeadersMessage struct {
|
||||||
Headers []*BlockBase
|
Headers []*BlockBase
|
||||||
|
|
||||||
|
@ -21,31 +22,34 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
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) {
|
func NewHeadersMessage() (*HeadersMessage, error) {
|
||||||
|
|
||||||
headers := &HeadersMessage{nil, 0}
|
headers := &HeadersMessage{nil, 0}
|
||||||
return headers, nil
|
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 {
|
func (h *HeadersMessage) AddHeader(head *BlockBase) error {
|
||||||
if len(h.Headers)+1 > maxHeadersAllowed {
|
if len(h.Headers)+1 > maxHeadersAllowed {
|
||||||
return ErrMaxHeaders
|
return errMaxHeaders
|
||||||
}
|
}
|
||||||
h.Headers = append(h.Headers, head)
|
h.Headers = append(h.Headers, head)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (v *HeadersMessage) DecodePayload(r io.Reader) error {
|
func (h *HeadersMessage) DecodePayload(r io.Reader) error {
|
||||||
|
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
|
|
||||||
lenHeaders := br.VarUint()
|
lenHeaders := br.VarUint()
|
||||||
v.Headers = make([]*BlockBase, lenHeaders)
|
h.Headers = make([]*BlockBase, lenHeaders)
|
||||||
|
|
||||||
for i := 0; i < int(lenHeaders); i++ {
|
for i := 0; i < int(lenHeaders); i++ {
|
||||||
header := &BlockBase{}
|
header := &BlockBase{}
|
||||||
|
@ -53,26 +57,26 @@ func (v *HeadersMessage) DecodePayload(r io.Reader) error {
|
||||||
var padding uint8
|
var padding uint8
|
||||||
br.Read(&padding)
|
br.Read(&padding)
|
||||||
if padding != 0 {
|
if padding != 0 {
|
||||||
return ErrPadding
|
return errPadding
|
||||||
}
|
}
|
||||||
v.Headers[i] = header
|
h.Headers[i] = header
|
||||||
}
|
}
|
||||||
|
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *HeadersMessage) EncodePayload(w io.Writer) error {
|
func (h *HeadersMessage) EncodePayload(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
bw.VarUint(uint64(len(v.Headers)))
|
bw.VarUint(uint64(len(h.Headers)))
|
||||||
for _, header := range v.Headers {
|
for _, header := range h.Headers {
|
||||||
header.EncodePayload(bw)
|
header.EncodePayload(bw)
|
||||||
bw.Write(uint8(0))
|
bw.Write(uint8(0))
|
||||||
}
|
}
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *HeadersMessage) Command() command.Type {
|
func (h *HeadersMessage) Command() command.Type {
|
||||||
return command.Headers
|
return command.Headers
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,29 +8,30 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//InvType represents the enum of inventory types
|
||||||
type InvType uint8
|
type InvType uint8
|
||||||
|
|
||||||
//Inventory types
|
|
||||||
const (
|
const (
|
||||||
|
// InvTypeTx represents the transaction inventory type
|
||||||
InvTypeTx InvType = 0x01
|
InvTypeTx InvType = 0x01
|
||||||
|
// InvTypeBlock represents the block inventory type
|
||||||
InvTypeBlock InvType = 0x02
|
InvTypeBlock InvType = 0x02
|
||||||
|
// InvTypeConsensus represents the consensus inventory type
|
||||||
InvTypeConsensus InvType = 0xe0
|
InvTypeConsensus InvType = 0xe0
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const maxHashes = 0x10000000
|
||||||
maxHashes = 0x10000000
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
var errMaxHash = errors.New("max size For Hashes reached")
|
||||||
MaxHashError = errors.New("Max size For Hashes reached")
|
|
||||||
)
|
|
||||||
|
|
||||||
|
// InvMessage represents an Inventory message on the neo-network
|
||||||
type InvMessage struct {
|
type InvMessage struct {
|
||||||
cmd command.Type
|
cmd command.Type
|
||||||
Type InvType
|
Type InvType
|
||||||
Hashes []util.Uint256
|
Hashes []util.Uint256
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewInvMessage returns an InvMessage object
|
||||||
func NewInvMessage(typ InvType) (*InvMessage, error) {
|
func NewInvMessage(typ InvType) (*InvMessage, error) {
|
||||||
|
|
||||||
inv := &InvMessage{
|
inv := &InvMessage{
|
||||||
|
@ -53,17 +54,20 @@ func newAbstractInv(typ InvType, cmd command.Type) (*InvMessage, error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *InvMessage) AddHash(h util.Uint256) error {
|
// AddHash adds a hash to the list of hashes
|
||||||
if len(i.Hashes)+1 > maxHashes {
|
func (inv *InvMessage) AddHash(h util.Uint256) error {
|
||||||
return MaxHashError
|
if len(inv.Hashes)+1 > maxHashes {
|
||||||
|
return errMaxHash
|
||||||
}
|
}
|
||||||
i.Hashes = append(i.Hashes, h)
|
inv.Hashes = append(inv.Hashes, h)
|
||||||
return nil
|
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
|
var err error
|
||||||
for _, hash := range hashes {
|
for _, hash := range hashes {
|
||||||
err = i.AddHash(hash)
|
err = inv.AddHash(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -71,31 +75,31 @@ func (i *InvMessage) AddHashes(hashes []util.Uint256) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (v *InvMessage) DecodePayload(r io.Reader) error {
|
func (inv *InvMessage) DecodePayload(r io.Reader) error {
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
|
|
||||||
br.Read(&v.Type)
|
br.Read(&inv.Type)
|
||||||
|
|
||||||
listLen := br.VarUint()
|
listLen := br.VarUint()
|
||||||
v.Hashes = make([]util.Uint256, listLen)
|
inv.Hashes = make([]util.Uint256, listLen)
|
||||||
|
|
||||||
for i := 0; i < int(listLen); i++ {
|
for i := 0; i < int(listLen); i++ {
|
||||||
br.Read(&v.Hashes[i])
|
br.Read(&inv.Hashes[i])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *InvMessage) EncodePayload(w io.Writer) error {
|
func (inv *InvMessage) EncodePayload(w io.Writer) error {
|
||||||
|
|
||||||
bw := &util.BinWriter{W: w}
|
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))
|
bw.VarUint(uint64(lenhashes))
|
||||||
|
|
||||||
for _, hash := range v.Hashes {
|
for _, hash := range inv.Hashes {
|
||||||
|
|
||||||
bw.Write(hash)
|
bw.Write(hash)
|
||||||
|
|
||||||
|
@ -104,7 +108,7 @@ func (v *InvMessage) EncodePayload(w io.Writer) error {
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *InvMessage) Command() command.Type {
|
func (inv *InvMessage) Command() command.Type {
|
||||||
return v.cmd
|
return inv.cmd
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,25 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
// No payload
|
// GetMempool represents a GetMempool message on the neo-network
|
||||||
type GetMempool struct{}
|
type GetMempool struct{}
|
||||||
|
|
||||||
|
//NewGetMempool returns a GetMempool message
|
||||||
func NewGetMempool() (*GetMempool, error) {
|
func NewGetMempool() (*GetMempool, error) {
|
||||||
return &GetMempool{}, nil
|
return &GetMempool{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (v *GetMempool) DecodePayload(r io.Reader) error {
|
func (v *GetMempool) DecodePayload(r io.Reader) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *GetMempool) EncodePayload(w io.Writer) error {
|
func (v *GetMempool) EncodePayload(w io.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *GetMempool) Command() command.Type {
|
func (v *GetMempool) Command() command.Type {
|
||||||
return command.Mempool
|
return command.Mempool
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,28 +7,29 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction"
|
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TXMessage represents a transaction message on the neo-network
|
||||||
type TXMessage struct {
|
type TXMessage struct {
|
||||||
// w *bytes.Buffer
|
|
||||||
Tx transaction.Transactioner
|
Tx transaction.Transactioner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewTXMessage returns a new tx object
|
||||||
func NewTXMessage(tx transaction.Transactioner) (*TXMessage, error) {
|
func NewTXMessage(tx transaction.Transactioner) (*TXMessage, error) {
|
||||||
|
|
||||||
Tx := &TXMessage{tx}
|
Tx := &TXMessage{tx}
|
||||||
return Tx, nil
|
return Tx, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (t *TXMessage) DecodePayload(r io.Reader) error {
|
func (t *TXMessage) DecodePayload(r io.Reader) error {
|
||||||
return t.Tx.Decode(r)
|
return t.Tx.Decode(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (t *TXMessage) EncodePayload(w io.Writer) error {
|
func (t *TXMessage) EncodePayload(w io.Writer) error {
|
||||||
return t.Tx.Encode(w)
|
return t.Tx.Encode(w)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *TXMessage) Command() command.Type {
|
func (t *TXMessage) Command() command.Type {
|
||||||
return command.TX
|
return command.TX
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,24 +6,25 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
"github.com/CityOfZion/neo-go/pkg/wire/command"
|
||||||
)
|
)
|
||||||
|
|
||||||
// No payload
|
//VerackMessage represents a verack message on the neo-network
|
||||||
type VerackMessage struct{}
|
type VerackMessage struct{}
|
||||||
|
|
||||||
|
//NewVerackMessage returns a verack message
|
||||||
func NewVerackMessage() (*VerackMessage, error) {
|
func NewVerackMessage() (*VerackMessage, error) {
|
||||||
return &VerackMessage{}, nil
|
return &VerackMessage{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (v *VerackMessage) DecodePayload(r io.Reader) error {
|
func (v *VerackMessage) DecodePayload(r io.Reader) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *VerackMessage) EncodePayload(w io.Writer) error {
|
func (v *VerackMessage) EncodePayload(w io.Writer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *VerackMessage) Command() command.Type {
|
func (v *VerackMessage) Command() command.Type {
|
||||||
return command.Verack
|
return command.Verack
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,12 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const minMsgVersionSize = 28
|
||||||
minMsgVersionSize = 28
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: Refactor to pull out the useragent out of initialiser
|
var errInvalidNetAddr = errors.New("provided net.Addr is not a net.TCPAddr")
|
||||||
// and have a seperate method to add it
|
|
||||||
|
|
||||||
|
//VersionMessage represents a version message on the neo-network
|
||||||
type VersionMessage struct {
|
type VersionMessage struct {
|
||||||
// w *bytes.Buffer
|
|
||||||
Version protocol.Version
|
Version protocol.Version
|
||||||
Timestamp uint32
|
Timestamp uint32
|
||||||
Services protocol.ServiceFlag
|
Services protocol.ServiceFlag
|
||||||
|
@ -33,13 +30,12 @@ type VersionMessage struct {
|
||||||
Relay bool
|
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) {
|
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)
|
tcpAddr, ok := addr.(*net.TCPAddr)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ErrInvalidNetAddr
|
return nil, errInvalidNetAddr
|
||||||
}
|
}
|
||||||
|
|
||||||
version := &VersionMessage{
|
version := &VersionMessage{
|
||||||
|
@ -56,13 +52,13 @@ func NewVersionMessage(addr net.Addr, startHeight uint32, relay bool, pver proto
|
||||||
return version, nil
|
return version, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements Messager interface
|
// DecodePayload Implements Messager interface
|
||||||
func (v *VersionMessage) DecodePayload(r io.Reader) error {
|
func (v *VersionMessage) DecodePayload(r io.Reader) error {
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
br.Read(&v.Version)
|
br.Read(&v.Version)
|
||||||
br.Read(&v.Services)
|
br.Read(&v.Services)
|
||||||
br.Read(&v.Timestamp)
|
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)
|
br.Read(&v.Nonce)
|
||||||
|
|
||||||
var lenUA uint8
|
var lenUA uint8
|
||||||
|
@ -75,7 +71,7 @@ func (v *VersionMessage) DecodePayload(r io.Reader) error {
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// EncodePayload Implements messager interface
|
||||||
func (v *VersionMessage) EncodePayload(w io.Writer) error {
|
func (v *VersionMessage) EncodePayload(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
|
|
||||||
|
@ -91,7 +87,7 @@ func (v *VersionMessage) EncodePayload(w io.Writer) error {
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements messager interface
|
// Command Implements messager interface
|
||||||
func (v *VersionMessage) Command() command.Type {
|
func (v *VersionMessage) Command() command.Type {
|
||||||
return command.Version
|
return command.Version
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,21 +9,21 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Once a VersionMessage is received, we can then store it inside of AddrMessage struct
|
//NetAddr is an abstraction for the IP layer
|
||||||
// TODO: store this inside version message and have a bool to indicate whether to encode ip
|
type NetAddr struct {
|
||||||
// VersionMessage does not encodeIP
|
|
||||||
type Net_addr struct {
|
|
||||||
Timestamp uint32
|
Timestamp uint32
|
||||||
IP [16]byte
|
IP [16]byte
|
||||||
Port uint16
|
Port uint16
|
||||||
Service protocol.ServiceFlag
|
Service protocol.ServiceFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNetAddr(time uint32, ip [16]byte, port uint16, service protocol.ServiceFlag) (*Net_addr, error) {
|
//NewNetAddr returns a NetAddr object
|
||||||
return &Net_addr{time, ip, port, service}, nil
|
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
|
var ip [16]byte
|
||||||
|
|
||||||
|
@ -32,21 +32,26 @@ func NewAddrFromVersionMessage(version VersionMessage) (*Net_addr, error) {
|
||||||
return NewNetAddr(version.Timestamp, ip, version.Port, version.Services)
|
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(uint32(time.Now().Unix()))
|
||||||
bw.Write(protocol.NodePeerService)
|
bw.Write(protocol.NodePeerService)
|
||||||
bw.WriteBigEnd(n.IP)
|
bw.WriteBigEnd(n.IP)
|
||||||
bw.WriteBigEnd(n.Port)
|
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.Timestamp)
|
||||||
br.Read(&n.Service)
|
br.Read(&n.Service)
|
||||||
br.ReadBigEnd(&n.IP)
|
br.ReadBigEnd(&n.IP)
|
||||||
br.ReadBigEnd(&n.Port)
|
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()
|
ip := net.IP(n.IP[:]).String()
|
||||||
port := strconv.Itoa(int(n.Port))
|
port := strconv.Itoa(int(n.Port))
|
||||||
ipport := ip + ":" + port
|
ipport := ip + ":" + port
|
||||||
|
|
|
@ -12,17 +12,14 @@ type Attribute struct {
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var errMaxData = errors.New("max Size of Attribute reached")
|
||||||
ErrMaxData = errors.New("Max Size of Attribute reached")
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const maxAttrSize = 65535
|
||||||
maxAttrSize = 65535
|
|
||||||
)
|
|
||||||
|
|
||||||
|
// Encode encodes the given Attribute into the binary writer
|
||||||
func (a *Attribute) Encode(bw *util.BinWriter) {
|
func (a *Attribute) Encode(bw *util.BinWriter) {
|
||||||
if len(a.Data) > maxAttrSize {
|
if len(a.Data) > maxAttrSize {
|
||||||
bw.Err = ErrMaxData
|
bw.Err = errMaxData
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
bw.Write(uint8(a.Usage))
|
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) {
|
func (a *Attribute) Decode(br *util.BinReader) {
|
||||||
br.Read(&a.Usage)
|
br.Read(&a.Usage)
|
||||||
if a.Usage == DescriptionURL || a.Usage == Vote || a.Usage >= Hash1 && a.Usage <= Hash15 {
|
if a.Usage == DescriptionURL || a.Usage == Vote || a.Usage >= Hash1 && a.Usage <= Hash15 {
|
||||||
|
|
|
@ -11,17 +11,21 @@ type Input struct {
|
||||||
PrevIndex uint16
|
PrevIndex uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewInput returns a transaction input object
|
||||||
func NewInput(prevHash util.Uint256, prevIndex uint16) *Input {
|
func NewInput(prevHash util.Uint256, prevIndex uint16) *Input {
|
||||||
return &Input{
|
return &Input{
|
||||||
prevHash,
|
prevHash,
|
||||||
prevIndex,
|
prevIndex,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode encodes the given input into a binary writer
|
||||||
func (i *Input) Encode(bw *util.BinWriter) {
|
func (i *Input) Encode(bw *util.BinWriter) {
|
||||||
bw.Write(i.PrevHash)
|
bw.Write(i.PrevHash)
|
||||||
bw.Write(i.PrevIndex)
|
bw.Write(i.PrevIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes a binary reader into an input object
|
||||||
func (i *Input) Decode(br *util.BinReader) {
|
func (i *Input) Decode(br *util.BinReader) {
|
||||||
br.Read(&i.PrevHash)
|
br.Read(&i.PrevHash)
|
||||||
br.Read(&i.PrevIndex)
|
br.Read(&i.PrevIndex)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package transaction
|
||||||
|
|
||||||
import "github.com/CityOfZion/neo-go/pkg/wire/util"
|
import "github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
|
|
||||||
|
// Output represents a transaction output in the neo-network
|
||||||
type Output struct {
|
type Output struct {
|
||||||
// The NEO asset id used in the transaction.
|
// The NEO asset id used in the transaction.
|
||||||
AssetID util.Uint256
|
AssetID util.Uint256
|
||||||
|
@ -13,6 +14,7 @@ type Output struct {
|
||||||
ScriptHash util.Uint160
|
ScriptHash util.Uint160
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewOutput returns an output object
|
||||||
func NewOutput(assetID util.Uint256, Amount int64, ScriptHash util.Uint160) *Output {
|
func NewOutput(assetID util.Uint256, Amount int64, ScriptHash util.Uint160) *Output {
|
||||||
return &Output{
|
return &Output{
|
||||||
assetID,
|
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) {
|
func (o *Output) Encode(bw *util.BinWriter) {
|
||||||
bw.Write(o.AssetID)
|
bw.Write(o.AssetID)
|
||||||
bw.Write(o.Amount)
|
bw.Write(o.Amount)
|
||||||
bw.Write(o.ScriptHash)
|
bw.Write(o.ScriptHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes a binary reader into an output object
|
||||||
func (o *Output) Decode(br *util.BinReader) {
|
func (o *Output) Decode(br *util.BinReader) {
|
||||||
br.Read(&o.AssetID)
|
br.Read(&o.AssetID)
|
||||||
br.Read(&o.Amount)
|
br.Read(&o.Amount)
|
||||||
|
|
|
@ -4,11 +4,13 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Witness represents a Witness object in a neo transaction
|
||||||
type Witness struct {
|
type Witness struct {
|
||||||
InvocationScript []byte
|
InvocationScript []byte
|
||||||
VerificationScript []byte
|
VerificationScript []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode encodes a Witness into a binary writer
|
||||||
func (s *Witness) Encode(bw *util.BinWriter) error {
|
func (s *Witness) Encode(bw *util.BinWriter) error {
|
||||||
|
|
||||||
bw.VarUint(uint64(len(s.InvocationScript)))
|
bw.VarUint(uint64(len(s.InvocationScript)))
|
||||||
|
@ -20,6 +22,7 @@ func (s *Witness) Encode(bw *util.BinWriter) error {
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes a binary reader into a Witness object
|
||||||
func (s *Witness) Decode(br *util.BinReader) error {
|
func (s *Witness) Decode(br *util.BinReader) error {
|
||||||
|
|
||||||
lenb := br.VarUint()
|
lenb := br.VarUint()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package transaction
|
package transaction
|
||||||
|
|
||||||
|
// AttrUsage represents an attribute usage on the neo network
|
||||||
type AttrUsage uint8
|
type AttrUsage uint8
|
||||||
|
|
||||||
// List of valid attribute usages.
|
// 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 {
|
func (b *Base) Decode(r io.Reader) error {
|
||||||
br := &util.BinReader{R: r}
|
br := &util.BinReader{R: r}
|
||||||
return b.DecodePayload(br)
|
return b.DecodePayload(br)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode implements the transactioner interface
|
||||||
func (b *Base) Encode(w io.Writer) error {
|
func (b *Base) Encode(w io.Writer) error {
|
||||||
bw := &util.BinWriter{W: w}
|
bw := &util.BinWriter{W: w}
|
||||||
b.EncodePayload(bw)
|
b.EncodePayload(bw)
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//EncodePayload implements the Messager interface
|
||||||
func (b *Base) EncodePayload(bw *util.BinWriter) {
|
func (b *Base) EncodePayload(bw *util.BinWriter) {
|
||||||
b.encodeHashableFields(bw)
|
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 {
|
func (b *Base) DecodePayload(br *util.BinReader) error {
|
||||||
b.decodeHashableFields(br)
|
b.decodeHashableFields(br)
|
||||||
|
|
||||||
|
@ -118,7 +123,6 @@ func (b *Base) encodeHashableFields(bw *util.BinWriter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// created for consistency
|
|
||||||
func (b *Base) decodeHashableFields(br *util.BinReader) {
|
func (b *Base) decodeHashableFields(br *util.BinReader) {
|
||||||
b.Type.Decode(br)
|
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) {
|
func (b *Base) AddInput(i *Input) {
|
||||||
b.Inputs = append(b.Inputs, i)
|
b.Inputs = append(b.Inputs, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddOutput adds an output to the transaction
|
||||||
func (b *Base) AddOutput(o *Output) {
|
func (b *Base) AddOutput(o *Output) {
|
||||||
b.Outputs = append(b.Outputs, o)
|
b.Outputs = append(b.Outputs, o)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddAttribute adds an attribute to the transaction
|
||||||
func (b *Base) AddAttribute(a *Attribute) {
|
func (b *Base) AddAttribute(a *Attribute) {
|
||||||
b.Attributes = append(b.Attributes, a)
|
b.Attributes = append(b.Attributes, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddWitness adds a witness object to the transaction
|
||||||
func (b *Base) AddWitness(w *Witness) {
|
func (b *Base) AddWitness(w *Witness) {
|
||||||
b.Witnesses = append(b.Witnesses, w)
|
b.Witnesses = append(b.Witnesses, w)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Claim represents a claim transaction on the neo network
|
||||||
type Claim struct {
|
type Claim struct {
|
||||||
*Base
|
*Base
|
||||||
Claims []*Input
|
Claims []*Input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewClaim returns a ClaimTransaction
|
||||||
func NewClaim(ver version.TX) *Claim {
|
func NewClaim(ver version.TX) *Claim {
|
||||||
basicTrans := createBaseTransaction(types.Contract, ver)
|
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"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Contract represents a contract transaction on the neo network
|
||||||
type Contract struct {
|
type Contract struct {
|
||||||
*Base
|
*Base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewContract returns a contract transaction
|
||||||
func NewContract(ver version.TX) *Contract {
|
func NewContract(ver version.TX) *Contract {
|
||||||
basicTrans := createBaseTransaction(types.Contract, ver)
|
basicTrans := createBaseTransaction(types.Contract, ver)
|
||||||
|
|
||||||
|
@ -21,10 +23,6 @@ func NewContract(ver version.TX) *Contract {
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Contract) encodeExcl(bw *util.BinWriter) {
|
func (c *Contract) encodeExcl(bw *util.BinWriter) {}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Contract) decodeExcl(br *util.BinReader) {
|
func (c *Contract) decodeExcl(br *util.BinReader) {}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,24 +6,26 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Enrollment represents an Enrollment transaction on the neo network
|
||||||
type Enrollment struct {
|
type Enrollment struct {
|
||||||
*Base
|
*Base
|
||||||
Key PublicKey
|
Key PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewEnrollment returns an Enrollment transaction
|
||||||
func NewEnrollment(ver version.TX) *Enrollment {
|
func NewEnrollment(ver version.TX) *Enrollment {
|
||||||
basicTrans := createBaseTransaction(types.Enrollment, ver)
|
basicTrans := createBaseTransaction(types.Enrollment, ver)
|
||||||
|
|
||||||
Enrollment := &Enrollment{}
|
enrollment := &Enrollment{
|
||||||
Enrollment.Base = basicTrans
|
Base: basicTrans,
|
||||||
Enrollment.encodeExclusive = Enrollment.encodeExcl
|
}
|
||||||
Enrollment.decodeExclusive = Enrollment.decodeExcl
|
enrollment.encodeExclusive = enrollment.encodeExcl
|
||||||
return Enrollment
|
enrollment.decodeExclusive = enrollment.decodeExcl
|
||||||
|
return enrollment
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Enrollment) encodeExcl(bw *util.BinWriter) {
|
func (e *Enrollment) encodeExcl(bw *util.BinWriter) {
|
||||||
e.Key.Encode(bw)
|
e.Key.Encode(bw)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Enrollment) decodeExcl(br *util.BinReader) {
|
func (e *Enrollment) decodeExcl(br *util.BinReader) {
|
||||||
|
|
|
@ -9,12 +9,14 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util/fixed8"
|
"github.com/CityOfZion/neo-go/pkg/wire/util/fixed8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Invocation represents an invocation transaction on the neo network
|
||||||
type Invocation struct {
|
type Invocation struct {
|
||||||
*Base
|
*Base
|
||||||
Script []byte
|
Script []byte
|
||||||
Gas fixed8.Fixed8
|
Gas fixed8.Fixed8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewInvocation returns an invocation transaction
|
||||||
func NewInvocation(ver version.TX) *Invocation {
|
func NewInvocation(ver version.TX) *Invocation {
|
||||||
basicTrans := createBaseTransaction(types.Invocation, ver)
|
basicTrans := createBaseTransaction(types.Invocation, ver)
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ func (c *Invocation) decodeExcl(br *util.BinReader) {
|
||||||
case 1:
|
case 1:
|
||||||
br.Read(&c.Gas)
|
br.Read(&c.Gas)
|
||||||
default:
|
default:
|
||||||
br.Err = errors.New("Invalid Version Number for Invocation Transaction")
|
br.Err = errors.New("invalid Version Number for Invocation Transaction")
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,12 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Issue represents an issue transaction on the neo network
|
||||||
type Issue struct {
|
type Issue struct {
|
||||||
*Base
|
*Base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewIssue returns an issue transaction
|
||||||
func NewIssue(ver version.TX) *Issue {
|
func NewIssue(ver version.TX) *Issue {
|
||||||
basicTrans := createBaseTransaction(types.Issue, ver)
|
basicTrans := createBaseTransaction(types.Issue, ver)
|
||||||
|
|
||||||
|
@ -27,9 +29,6 @@ func (c *Issue) encodeExcl(bw *util.BinWriter) {
|
||||||
if c.Version > 1 {
|
if c.Version > 1 {
|
||||||
bw.Err = errors.New("Version Number Invalid, Issue cannot be more than 0")
|
bw.Err = errors.New("Version Number Invalid, Issue cannot be more than 0")
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Issue) decodeExcl(br *util.BinReader) {
|
func (c *Issue) decodeExcl(br *util.BinReader) {}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,11 +6,13 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Miner represents a miner transaction on the neo network
|
||||||
type Miner struct {
|
type Miner struct {
|
||||||
*Base
|
*Base
|
||||||
Nonce uint32
|
Nonce uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewMiner returns a miner transaction
|
||||||
func NewMiner(ver version.TX) *Miner {
|
func NewMiner(ver version.TX) *Miner {
|
||||||
basicTrans := createBaseTransaction(types.Miner, ver)
|
basicTrans := createBaseTransaction(types.Miner, ver)
|
||||||
|
|
||||||
|
@ -22,13 +24,9 @@ func NewMiner(ver version.TX) *Miner {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Miner) encodeExcl(bw *util.BinWriter) {
|
func (c *Miner) encodeExcl(bw *util.BinWriter) {
|
||||||
|
|
||||||
bw.Write(c.Nonce)
|
bw.Write(c.Nonce)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Miner) decodeExcl(br *util.BinReader) {
|
func (c *Miner) decodeExcl(br *util.BinReader) {
|
||||||
|
|
||||||
br.Read(&c.Nonce)
|
br.Read(&c.Nonce)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,17 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PublicKey represents a public key on the neo network
|
||||||
type PublicKey struct {
|
type PublicKey struct {
|
||||||
Key []byte
|
Key []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Encode encodes a public key into a binary writer
|
||||||
func (p *PublicKey) Encode(bw *util.BinWriter) {
|
func (p *PublicKey) Encode(bw *util.BinWriter) {
|
||||||
bw.Write(p.Key)
|
bw.Write(p.Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes a bianry reader into a public key
|
||||||
func (p *PublicKey) Decode(br *util.BinReader) {
|
func (p *PublicKey) Decode(br *util.BinReader) {
|
||||||
var prefix uint8
|
var prefix uint8
|
||||||
br.Read(&prefix)
|
br.Read(&prefix)
|
||||||
|
@ -30,6 +34,5 @@ func (p *PublicKey) Decode(br *util.BinReader) {
|
||||||
br.Err = errors.New("Prefix not recognised for public key")
|
br.Err = errors.New("Prefix not recognised for public key")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Key = append([]byte{prefix}, p.Key...)
|
p.Key = append([]byte{prefix}, p.Key...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Publish represents a publish transaction on the neo network
|
||||||
type Publish struct {
|
type Publish struct {
|
||||||
*Base
|
*Base
|
||||||
Script []byte
|
Script []byte
|
||||||
|
@ -21,6 +22,7 @@ type Publish struct {
|
||||||
Description string
|
Description string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewPublish returns a publish transaction
|
||||||
func NewPublish(ver version.TX) *Publish {
|
func NewPublish(ver version.TX) *Publish {
|
||||||
basicTrans := createBaseTransaction(types.Publish, ver)
|
basicTrans := createBaseTransaction(types.Publish, ver)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util/fixed8"
|
"github.com/CityOfZion/neo-go/pkg/wire/util/fixed8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Register represents a register transaction on the neo network
|
||||||
type Register struct {
|
type Register struct {
|
||||||
*Base
|
*Base
|
||||||
// The type of the asset being registered.
|
// The type of the asset being registered.
|
||||||
|
@ -28,6 +29,7 @@ type Register struct {
|
||||||
Admin util.Uint160
|
Admin util.Uint160
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewRegister returns a register transaction
|
||||||
func NewRegister(ver version.TX) *Register {
|
func NewRegister(ver version.TX) *Register {
|
||||||
basicTrans := createBaseTransaction(types.Register, ver)
|
basicTrans := createBaseTransaction(types.Register, ver)
|
||||||
Register := &Register{}
|
Register := &Register{}
|
||||||
|
|
|
@ -6,11 +6,14 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"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 {
|
type StateTX struct {
|
||||||
*Base
|
*Base
|
||||||
Descriptors []*StateDescriptor
|
Descriptors []*StateDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//NewStateTX returns a state transaction
|
||||||
func NewStateTX(ver version.TX) *StateTX {
|
func NewStateTX(ver version.TX) *StateTX {
|
||||||
basicTrans := createBaseTransaction(types.State, ver)
|
basicTrans := createBaseTransaction(types.State, ver)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,8 @@ const (
|
||||||
Validator DescStateType = 0x48
|
Validator DescStateType = 0x48
|
||||||
)
|
)
|
||||||
|
|
||||||
// StateDescriptor ..
|
// StateDescriptor represents a state descriptor on the neo network
|
||||||
|
// used in a state transaction
|
||||||
type StateDescriptor struct {
|
type StateDescriptor struct {
|
||||||
Type DescStateType
|
Type DescStateType
|
||||||
Key []byte
|
Key []byte
|
||||||
|
@ -21,6 +22,7 @@ type StateDescriptor struct {
|
||||||
Field string
|
Field string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes a binary reader into a state descriptor
|
||||||
func (s *StateDescriptor) Decode(br *util.BinReader) {
|
func (s *StateDescriptor) Decode(br *util.BinReader) {
|
||||||
br.Read(&s.Type)
|
br.Read(&s.Type)
|
||||||
|
|
||||||
|
@ -38,6 +40,8 @@ func (s *StateDescriptor) Decode(br *util.BinReader) {
|
||||||
|
|
||||||
s.Field = string(field)
|
s.Field = string(field)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Encode encodes a state descriptor into a binary writer
|
||||||
func (s *StateDescriptor) Encode(bw *util.BinWriter) {
|
func (s *StateDescriptor) Encode(bw *util.BinWriter) {
|
||||||
bw.Write(s.Type)
|
bw.Write(s.Type)
|
||||||
|
|
||||||
|
@ -48,5 +52,4 @@ func (s *StateDescriptor) Encode(bw *util.BinWriter) {
|
||||||
bw.Write(s.Value)
|
bw.Write(s.Value)
|
||||||
|
|
||||||
bw.VarString(s.Field)
|
bw.VarString(s.Field)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
// TX is the type of a transaction.
|
// TX is the type of a transaction.
|
||||||
type TX uint8
|
type TX uint8
|
||||||
|
|
||||||
|
// List of transaction types
|
||||||
const (
|
const (
|
||||||
Miner TX = 0x00
|
Miner TX = 0x00
|
||||||
Issue TX = 0x01
|
Issue TX = 0x01
|
||||||
|
@ -21,9 +22,12 @@ const (
|
||||||
Invocation TX = 0xd1
|
Invocation TX = 0xd1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Encode encodes a tx type into the binary writer
|
||||||
func (t *TX) Encode(bw *util.BinWriter) {
|
func (t *TX) Encode(bw *util.BinWriter) {
|
||||||
bw.Write(t)
|
bw.Write(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes a binary reader into a tx type
|
||||||
func (t *TX) Decode(br *util.BinReader) {
|
func (t *TX) Decode(br *util.BinReader) {
|
||||||
br.Read(t)
|
br.Read(t)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,8 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/payload/transaction/types"
|
"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)
|
t, err := reader.Peek(1)
|
||||||
|
|
||||||
|
@ -45,17 +46,17 @@ func FromBytes(reader *bufio.Reader) (Transactioner, error) {
|
||||||
err = pub.Decode(reader)
|
err = pub.Decode(reader)
|
||||||
trans = pub
|
trans = pub
|
||||||
case types.State:
|
case types.State:
|
||||||
sta := NewStateTX(0)
|
state := NewStateTX(0)
|
||||||
err = sta.Decode(reader)
|
err = state.Decode(reader)
|
||||||
trans = sta
|
trans = state
|
||||||
case types.Enrollment:
|
case types.Enrollment:
|
||||||
enr := NewEnrollment(0)
|
enr := NewEnrollment(0)
|
||||||
err = enr.Decode(reader)
|
err = enr.Decode(reader)
|
||||||
trans = enr
|
trans = enr
|
||||||
case types.Agency:
|
case types.Agency:
|
||||||
err = errors.New("Unsupported transaction type: Agency")
|
err = errors.New("unsupported transaction type: Agency")
|
||||||
default:
|
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
|
return trans, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,21 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
"github.com/CityOfZion/neo-go/pkg/wire/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TX represents a tx version
|
||||||
type TX uint8
|
type TX uint8
|
||||||
|
|
||||||
|
// List of latest tx version
|
||||||
const (
|
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) {
|
func (v *TX) Encode(bw *util.BinWriter) {
|
||||||
bw.Write(v)
|
bw.Write(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decode decodes the binary reader into a tx type
|
||||||
func (v *TX) Decode(br *util.BinReader) {
|
func (v *TX) Decode(br *util.BinReader) {
|
||||||
br.Read(v)
|
br.Read(v)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
package protocol
|
package protocol
|
||||||
|
|
||||||
|
//Version represents the latest protocol version for the neo node
|
||||||
type Version uint32
|
type Version uint32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// DefaultVersion is the nodes default protocol version
|
||||||
DefaultVersion Version = 0
|
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
|
// ServiceFlag indicates the services provided by the node. 1 = P2P Full Node
|
||||||
type ServiceFlag uint64
|
type ServiceFlag uint64
|
||||||
|
|
||||||
|
// List of Services offered by the node
|
||||||
const (
|
const (
|
||||||
NodePeerService ServiceFlag = 1
|
NodePeerService ServiceFlag = 1
|
||||||
// BloomFilerService ServiceFlag = 2 // Not implemented
|
// BloomFilerService ServiceFlag = 2 // Not implemented
|
||||||
|
@ -21,6 +25,7 @@ const (
|
||||||
// Magic is the network that NEO is running on
|
// Magic is the network that NEO is running on
|
||||||
type Magic uint32
|
type Magic uint32
|
||||||
|
|
||||||
|
// List of possible networks
|
||||||
const (
|
const (
|
||||||
MainNet Magic = 7630401
|
MainNet Magic = 7630401
|
||||||
TestNet Magic = 0x74746e41
|
TestNet Magic = 0x74746e41
|
||||||
|
|
|
@ -7,16 +7,20 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/crypto/hash"
|
"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 {
|
func Compare(have uint32, b []byte) bool {
|
||||||
want := FromBytes(b)
|
want := FromBytes(b)
|
||||||
return have == want
|
return have == want
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromBuf calculates the checksum of a buffer
|
||||||
func FromBuf(buf *bytes.Buffer) uint32 {
|
func FromBuf(buf *bytes.Buffer) uint32 {
|
||||||
|
|
||||||
return FromBytes(buf.Bytes())
|
return FromBytes(buf.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromBytes calculates the checksum of a byte slice
|
||||||
func FromBytes(buf []byte) uint32 {
|
func FromBytes(buf []byte) uint32 {
|
||||||
b, err := hash.DoubleSha256(buf)
|
b, err := hash.DoubleSha256(buf)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/CityOfZion/neo-go/pkg/crypto/base58"
|
"github.com/CityOfZion/neo-go/pkg/crypto/base58"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// ToScriptHash converts an address to a script hash
|
||||||
func ToScriptHash(address string) string {
|
func ToScriptHash(address string) string {
|
||||||
|
|
||||||
decodedAddressAsBytes, err := base58.Decode(address)
|
decodedAddressAsBytes, err := base58.Decode(address)
|
||||||
|
|
|
@ -5,17 +5,24 @@ import (
|
||||||
"io"
|
"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 {
|
type BinReader struct {
|
||||||
R io.Reader
|
R io.Reader
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read reads from the underlying io.Reader
|
||||||
|
// into the interface v in LE
|
||||||
func (r *BinReader) Read(v interface{}) {
|
func (r *BinReader) Read(v interface{}) {
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r.Err = binary.Read(r.R, binary.LittleEndian, v)
|
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{}) {
|
func (r *BinReader) ReadBigEnd(v interface{}) {
|
||||||
if r.Err != nil {
|
if r.Err != nil {
|
||||||
return
|
return
|
||||||
|
@ -23,6 +30,8 @@ func (r *BinReader) ReadBigEnd(v interface{}) {
|
||||||
r.Err = binary.Read(r.R, binary.BigEndian, v)
|
r.Err = binary.Read(r.R, binary.BigEndian, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//VarUint reads a variable integer from the
|
||||||
|
// underlying reader
|
||||||
func (r *BinReader) VarUint() uint64 {
|
func (r *BinReader) VarUint() uint64 {
|
||||||
var b uint8
|
var b uint8
|
||||||
r.Err = binary.Read(r.R, binary.LittleEndian, &b)
|
r.Err = binary.Read(r.R, binary.LittleEndian, &b)
|
||||||
|
@ -46,6 +55,8 @@ func (r *BinReader) VarUint() uint64 {
|
||||||
return uint64(b)
|
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 {
|
func (r *BinReader) VarBytes() []byte {
|
||||||
n := r.VarUint()
|
n := r.VarUint()
|
||||||
b := make([]byte, n)
|
b := make([]byte, n)
|
||||||
|
@ -53,6 +64,7 @@ func (r *BinReader) VarBytes() []byte {
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VarString calls VarBytes and casts the results as a string
|
||||||
func (r *BinReader) VarString() string {
|
func (r *BinReader) VarString() string {
|
||||||
b := r.VarBytes()
|
b := r.VarBytes()
|
||||||
return string(b)
|
return string(b)
|
||||||
|
|
|
@ -6,11 +6,15 @@ import (
|
||||||
"io"
|
"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 {
|
type BinWriter struct {
|
||||||
W io.Writer
|
W io.Writer
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write writes into the underlying io.Writer from an object v in LE format
|
||||||
func (w *BinWriter) Write(v interface{}) {
|
func (w *BinWriter) Write(v interface{}) {
|
||||||
if w.Err != nil {
|
if w.Err != nil {
|
||||||
return
|
return
|
||||||
|
@ -18,6 +22,7 @@ func (w *BinWriter) Write(v interface{}) {
|
||||||
w.Err = binary.Write(w.W, binary.LittleEndian, v)
|
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
|
// Only used for IP and PORT. Additional method makes the default LittleEndian case clean
|
||||||
func (w *BinWriter) WriteBigEnd(v interface{}) {
|
func (w *BinWriter) WriteBigEnd(v interface{}) {
|
||||||
if w.Err != nil {
|
if w.Err != nil {
|
||||||
|
@ -26,10 +31,7 @@ func (w *BinWriter) WriteBigEnd(v interface{}) {
|
||||||
w.Err = binary.Write(w.W, binary.BigEndian, v)
|
w.Err = binary.Write(w.W, binary.BigEndian, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *BinWriter) VarString(s string) {
|
// VarUint writes a uint64 into the underlying writer
|
||||||
w.VarBytes([]byte(s))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *BinWriter) VarUint(val uint64) {
|
func (w *BinWriter) VarUint(val uint64) {
|
||||||
if val < 0 {
|
if val < 0 {
|
||||||
w.Err = errors.New("value out of range")
|
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) {
|
func (w *BinWriter) VarBytes(b []byte) {
|
||||||
w.VarUint(uint64(len(b)))
|
w.VarUint(uint64(len(b)))
|
||||||
w.Write(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
|
package base58
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/CityOfZion/neo-go/pkg/wire/util/crypto/hash"
|
||||||
)
|
)
|
||||||
|
|
||||||
const prefix rune = '1'
|
const prefix rune = '1'
|
||||||
|
@ -22,7 +25,7 @@ var decodeMap = map[rune]int64{
|
||||||
'x': 55, 'y': 56, 'z': 57,
|
'x': 55, 'y': 56, 'z': 57,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base58Decode decodes the base58 encoded string.
|
// Decode decodes the base58 encoded string.
|
||||||
func Decode(s string) ([]byte, error) {
|
func Decode(s string) ([]byte, error) {
|
||||||
var (
|
var (
|
||||||
startIndex = 0
|
startIndex = 0
|
||||||
|
@ -58,7 +61,7 @@ func Decode(s string) ([]byte, error) {
|
||||||
return buf, nil
|
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 {
|
func Encode(bytes []byte) string {
|
||||||
var (
|
var (
|
||||||
lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||||
|
@ -77,47 +80,47 @@ func Encode(bytes []byte) string {
|
||||||
return encoded
|
return encoded
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base58CheckDecode decodes the given string.
|
// CheckDecode decodes the given string.
|
||||||
// func CheckDecode(s string) (b []byte, err error) {
|
func CheckDecode(s string) (b []byte, err error) {
|
||||||
// b, err = Decode(s)
|
b, err = Decode(s)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// return nil, err
|
return nil, err
|
||||||
// }
|
}
|
||||||
|
|
||||||
// for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
// if s[i] != '1' {
|
if s[i] != '1' {
|
||||||
// break
|
break
|
||||||
// }
|
}
|
||||||
// b = append([]byte{0x00}, b...)
|
b = append([]byte{0x00}, b...)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if len(b) < 5 {
|
if len(b) < 5 {
|
||||||
// return nil, fmt.Errorf("Invalid base-58 check string: missing checksum. -1")
|
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 {
|
if err != nil {
|
||||||
// return nil, fmt.Errorf("Could not double sha256 data")
|
return nil, fmt.Errorf("Could not double sha256 data")
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if bytes.Compare(hash[0:4], b[len(b)-4:]) != 0 {
|
if bytes.Compare(hash[0:4], b[len(b)-4:]) != 0 {
|
||||||
// return nil, fmt.Errorf("Invalid base-58 check string: invalid checksum. -2")
|
return nil, fmt.Errorf("Invalid base-58 check string: invalid checksum. -2")
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Strip the 4 byte long hash.
|
// Strip the 4 byte long hash.
|
||||||
// b = b[:len(b)-4]
|
b = b[:len(b)-4]
|
||||||
|
|
||||||
// return b, nil
|
return b, nil
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // Base58checkEncode encodes b into a base-58 check encoded string.
|
// CheckEncode encodes b into a base-58 check encoded string.
|
||||||
// func CheckEncode(b []byte) (string, error) {
|
func CheckEncode(b []byte) (string, error) {
|
||||||
// hash, err := hash.DoubleSha256(b)
|
hash, err := hash.DoubleSha256(b)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// return "", fmt.Errorf("Could not double sha256 data")
|
return "", fmt.Errorf("Could not double sha256 data")
|
||||||
// }
|
}
|
||||||
// b = append(b, hash[0:4]...)
|
b = append(b, hash[0:4]...)
|
||||||
|
|
||||||
// return Encode(b), nil
|
return Encode(b), nil
|
||||||
// }
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"golang.org/x/crypto/ripemd160"
|
"golang.org/x/crypto/ripemd160"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Sha256 hashes the byte slice using sha256
|
||||||
func Sha256(data []byte) (util.Uint256, error) {
|
func Sha256(data []byte) (util.Uint256, error) {
|
||||||
var hash util.Uint256
|
var hash util.Uint256
|
||||||
hasher := sha256.New()
|
hasher := sha256.New()
|
||||||
|
@ -21,6 +22,7 @@ func Sha256(data []byte) (util.Uint256, error) {
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DoubleSha256 hashes the underlying data twice using sha256
|
||||||
func DoubleSha256(data []byte) (util.Uint256, error) {
|
func DoubleSha256(data []byte) (util.Uint256, error) {
|
||||||
var hash util.Uint256
|
var hash util.Uint256
|
||||||
|
|
||||||
|
@ -36,6 +38,7 @@ func DoubleSha256(data []byte) (util.Uint256, error) {
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RipeMD160 hashes the underlying data using ripemd160
|
||||||
func RipeMD160(data []byte) (util.Uint160, error) {
|
func RipeMD160(data []byte) (util.Uint160, error) {
|
||||||
var hash util.Uint160
|
var hash util.Uint160
|
||||||
hasher := ripemd160.New()
|
hasher := ripemd160.New()
|
||||||
|
@ -49,6 +52,7 @@ func RipeMD160(data []byte) (util.Uint160, error) {
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Hash160 hashes the underlying data using sha256 then ripemd160
|
||||||
func Hash160(data []byte) (util.Uint160, error) {
|
func Hash160(data []byte) (util.Uint160, error) {
|
||||||
var hash util.Uint160
|
var hash util.Uint160
|
||||||
h1, err := Sha256(data)
|
h1, err := Sha256(data)
|
||||||
|
@ -63,6 +67,7 @@ func Hash160(data []byte) (util.Uint160, error) {
|
||||||
return hash, nil
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checksum calculates the checksum of the byte slice using sha256
|
||||||
func Checksum(data []byte) ([]byte, error) {
|
func Checksum(data []byte) ([]byte, error) {
|
||||||
hash, err := Sum(data)
|
hash, err := Sum(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -71,6 +76,7 @@ func Checksum(data []byte) ([]byte, error) {
|
||||||
return hash[:4], nil
|
return hash[:4], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sum calculates the Sum of the data by using double sha256
|
||||||
func Sum(b []byte) (util.Uint256, error) {
|
func Sum(b []byte) (util.Uint256, error) {
|
||||||
hash, err := DoubleSha256((b))
|
hash, err := DoubleSha256((b))
|
||||||
return hash, err
|
return hash, err
|
||||||
|
|
|
@ -25,12 +25,16 @@ func (f Fixed8) String() string {
|
||||||
func (f Fixed8) Value() float64 {
|
func (f Fixed8) Value() float64 {
|
||||||
return float64(f) / float64(decimals)
|
return float64(f) / float64(decimals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add adds two Fixed8 values together
|
||||||
func (f Fixed8) Add(val Fixed8) Fixed8 {
|
func (f Fixed8) Add(val Fixed8) Fixed8 {
|
||||||
a := int64(f.Value())
|
a := int64(f.Value())
|
||||||
b := int64(val.Value())
|
b := int64(val.Value())
|
||||||
c := a + b
|
c := a + b
|
||||||
return FromInt(c)
|
return FromInt(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Sub subtracts two fixed values from each other
|
||||||
func (f Fixed8) Sub(val Fixed8) Fixed8 {
|
func (f Fixed8) Sub(val Fixed8) Fixed8 {
|
||||||
a := int64(f.Value())
|
a := int64(f.Value())
|
||||||
b := int64(val.Value())
|
b := int64(val.Value())
|
||||||
|
@ -38,18 +42,21 @@ func (f Fixed8) Sub(val Fixed8) Fixed8 {
|
||||||
return FromInt(c)
|
return FromInt(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//FromInt returns a Fixed8 objects from an int64
|
||||||
func FromInt(val int64) Fixed8 {
|
func FromInt(val int64) Fixed8 {
|
||||||
return Fixed8(val * decimals)
|
return Fixed8(val * decimals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromFloat returns a Fixed8 object from a float64
|
||||||
func FromFloat(val float64) Fixed8 {
|
func FromFloat(val float64) Fixed8 {
|
||||||
return Fixed8(val * decimals)
|
return Fixed8(val * decimals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromString returns a Fixed8 object from a string
|
||||||
func FromString(val string) (Fixed8, error) {
|
func FromString(val string) (Fixed8, error) {
|
||||||
res, err := strconv.ParseFloat(val, 64)
|
res, err := strconv.ParseFloat(val, 64)
|
||||||
if err != nil {
|
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
|
return FromFloat(res), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// UpdateFile appends a byte slice to a file
|
||||||
func UpdateFile(filename string, data []byte) error {
|
func UpdateFile(filename string, data []byte) error {
|
||||||
|
|
||||||
f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//GetLocalIP returns the ip address of the current node
|
||||||
// https://stackoverflow.com/a/37382208
|
// https://stackoverflow.com/a/37382208
|
||||||
func GetLocalIP() net.IP {
|
func GetLocalIP() net.IP {
|
||||||
conn, err := net.Dial("udp", "8.8.8.8:80")
|
conn, err := net.Dial("udp", "8.8.8.8:80")
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package slice
|
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 {
|
func Reverse(b []byte) []byte {
|
||||||
// Protect from big.Ints that have 1 len bytes.
|
// Protect from big.Ints that have 1 len bytes.
|
||||||
if len(b) < 2 {
|
if len(b) < 2 {
|
||||||
|
|
|
@ -44,9 +44,11 @@ func (u Uint256) Bytes() []byte {
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
func (u Uint256) Reverse() (res Uint256) {
|
|
||||||
res, _ = Uint256DecodeBytes(u.BytesReverse())
|
// Reverse reverses the Uint256 object
|
||||||
return
|
func (u Uint256) Reverse() Uint256 {
|
||||||
|
res, _ := Uint256DecodeBytes(u.BytesReverse())
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// BytesReverse return a reversed byte representation of u.
|
// BytesReverse return a reversed byte representation of u.
|
||||||
|
|
|
@ -8,18 +8,23 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Functions
|
// Convenience function
|
||||||
|
|
||||||
|
// BufferLength returns the length of a buffer as uint32
|
||||||
func BufferLength(buf *bytes.Buffer) uint32 {
|
func BufferLength(buf *bytes.Buffer) uint32 {
|
||||||
|
|
||||||
return uint32(buf.Len())
|
return uint32(buf.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SumSHA256 returns the sha256 sum of the data
|
||||||
func SumSHA256(b []byte) []byte {
|
func SumSHA256(b []byte) []byte {
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
h.Write(b)
|
h.Write(b)
|
||||||
return h.Sum(nil)
|
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) {
|
func CalculateHash(f func(bw *BinWriter)) (Uint256, error) {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
bw := &BinWriter{W: buf}
|
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)
|
byt, err := ioutil.ReadAll(r)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
buf := bytes.NewBuffer(byt)
|
||||||
buf = bytes.NewBuffer(byt)
|
return buf, nil
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue