module: run go mod tidy && go mod vendor

This commit is contained in:
George Tankersley 2019-02-14 18:56:16 +00:00
parent e910ee0475
commit 51614ecd2b
181 changed files with 41119 additions and 2 deletions

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.12
require ( require (
github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d github.com/btcsuite/btcd v0.0.0-20190115013929-ed77733ec07d
github.com/golang/protobuf v1.2.0 github.com/golang/protobuf v1.2.0
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e // indirect
github.com/jtolds/gls v4.2.1+incompatible // indirect github.com/jtolds/gls v4.2.1+incompatible // indirect
github.com/mattn/go-sqlite3 v1.10.0 github.com/mattn/go-sqlite3 v1.10.0
github.com/pebbe/zmq4 v1.0.0 github.com/pebbe/zmq4 v1.0.0

2
go.sum
View File

@ -24,6 +24,8 @@ github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=

16
vendor/github.com/btcsuite/btcd/LICENSE generated vendored Normal file
View File

@ -0,0 +1,16 @@
ISC License
Copyright (c) 2013-2017 The btcsuite developers
Copyright (c) 2015-2016 The Decred developers
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

68
vendor/github.com/btcsuite/btcd/btcec/README.md generated vendored Normal file
View File

@ -0,0 +1,68 @@
btcec
=====
[![Build Status](https://travis-ci.org/btcsuite/btcd.png?branch=master)](https://travis-ci.org/btcsuite/btcec)
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
[![GoDoc](https://godoc.org/github.com/btcsuite/btcd/btcec?status.png)](http://godoc.org/github.com/btcsuite/btcd/btcec)
Package btcec implements elliptic curve cryptography needed for working with
Bitcoin (secp256k1 only for now). It is designed so that it may be used with the
standard crypto/ecdsa packages provided with go. A comprehensive suite of test
is provided to ensure proper functionality. Package btcec was originally based
on work from ThePiachu which is licensed under the same terms as Go, but it has
signficantly diverged since then. The btcsuite developers original is licensed
under the liberal ISC license.
Although this package was primarily written for btcd, it has intentionally been
designed so it can be used as a standalone package for any projects needing to
use secp256k1 elliptic curve cryptography.
## Installation and Updating
```bash
$ go get -u github.com/btcsuite/btcd/btcec
```
## Examples
* [Sign Message](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--SignMessage)
Demonstrates signing a message with a secp256k1 private key that is first
parsed form raw bytes and serializing the generated signature.
* [Verify Signature](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--VerifySignature)
Demonstrates verifying a secp256k1 signature against a public key that is
first parsed from raw bytes. The signature is also parsed from raw bytes.
* [Encryption](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--EncryptMessage)
Demonstrates encrypting a message for a public key that is first parsed from
raw bytes, then decrypting it using the corresponding private key.
* [Decryption](http://godoc.org/github.com/btcsuite/btcd/btcec#example-package--DecryptMessage)
Demonstrates decrypting a message using a private key that is first parsed
from raw bytes.
## GPG Verification Key
All official release tags are signed by Conformal so users can ensure the code
has not been tampered with and is coming from the btcsuite developers. To
verify the signature perform the following:
- Download the public key from the Conformal website at
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
- Import the public key into your GPG keyring:
```bash
gpg --import GIT-GPG-KEY-conformal.txt
```
- Verify the release tag with the following command where `TAG_NAME` is a
placeholder for the specific tag:
```bash
git tag -v TAG_NAME
```
## License
Package btcec is licensed under the [copyfree](http://copyfree.org) ISC License
except for btcec.go and btcec_test.go which is under the same license as Go.

958
vendor/github.com/btcsuite/btcd/btcec/btcec.go generated vendored Normal file
View File

@ -0,0 +1,958 @@
// Copyright 2010 The Go Authors. All rights reserved.
// Copyright 2011 ThePiachu. All rights reserved.
// Copyright 2013-2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcec
// References:
// [SECG]: Recommended Elliptic Curve Domain Parameters
// http://www.secg.org/sec2-v2.pdf
//
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
// This package operates, internally, on Jacobian coordinates. For a given
// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1)
// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole
// calculation can be performed within the transform (as in ScalarMult and
// ScalarBaseMult). But even for Add and Double, it's faster to apply and
// reverse the transform than to operate in affine coordinates.
import (
"crypto/elliptic"
"math/big"
"sync"
)
var (
// fieldOne is simply the integer 1 in field representation. It is
// used to avoid needing to create it multiple times during the internal
// arithmetic.
fieldOne = new(fieldVal).SetInt(1)
)
// KoblitzCurve supports a koblitz curve implementation that fits the ECC Curve
// interface from crypto/elliptic.
type KoblitzCurve struct {
*elliptic.CurveParams
q *big.Int
H int // cofactor of the curve.
halfOrder *big.Int // half the order N
// byteSize is simply the bit size / 8 and is provided for convenience
// since it is calculated repeatedly.
byteSize int
// bytePoints
bytePoints *[32][256][3]fieldVal
// The next 6 values are used specifically for endomorphism
// optimizations in ScalarMult.
// lambda must fulfill lambda^3 = 1 mod N where N is the order of G.
lambda *big.Int
// beta must fulfill beta^3 = 1 mod P where P is the prime field of the
// curve.
beta *fieldVal
// See the EndomorphismVectors in gensecp256k1.go to see how these are
// derived.
a1 *big.Int
b1 *big.Int
a2 *big.Int
b2 *big.Int
}
// Params returns the parameters for the curve.
func (curve *KoblitzCurve) Params() *elliptic.CurveParams {
return curve.CurveParams
}
// bigAffineToField takes an affine point (x, y) as big integers and converts
// it to an affine point as field values.
func (curve *KoblitzCurve) bigAffineToField(x, y *big.Int) (*fieldVal, *fieldVal) {
x3, y3 := new(fieldVal), new(fieldVal)
x3.SetByteSlice(x.Bytes())
y3.SetByteSlice(y.Bytes())
return x3, y3
}
// fieldJacobianToBigAffine takes a Jacobian point (x, y, z) as field values and
// converts it to an affine point as big integers.
func (curve *KoblitzCurve) fieldJacobianToBigAffine(x, y, z *fieldVal) (*big.Int, *big.Int) {
// Inversions are expensive and both point addition and point doubling
// are faster when working with points that have a z value of one. So,
// if the point needs to be converted to affine, go ahead and normalize
// the point itself at the same time as the calculation is the same.
var zInv, tempZ fieldVal
zInv.Set(z).Inverse() // zInv = Z^-1
tempZ.SquareVal(&zInv) // tempZ = Z^-2
x.Mul(&tempZ) // X = X/Z^2 (mag: 1)
y.Mul(tempZ.Mul(&zInv)) // Y = Y/Z^3 (mag: 1)
z.SetInt(1) // Z = 1 (mag: 1)
// Normalize the x and y values.
x.Normalize()
y.Normalize()
// Convert the field values for the now affine point to big.Ints.
x3, y3 := new(big.Int), new(big.Int)
x3.SetBytes(x.Bytes()[:])
y3.SetBytes(y.Bytes()[:])
return x3, y3
}
// IsOnCurve returns boolean if the point (x,y) is on the curve.
// Part of the elliptic.Curve interface. This function differs from the
// crypto/elliptic algorithm since a = 0 not -3.
func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool {
// Convert big ints to field values for faster arithmetic.
fx, fy := curve.bigAffineToField(x, y)
// Elliptic curve equation for secp256k1 is: y^2 = x^3 + 7
y2 := new(fieldVal).SquareVal(fy).Normalize()
result := new(fieldVal).SquareVal(fx).Mul(fx).AddInt(7).Normalize()
return y2.Equals(result)
}
// addZ1AndZ2EqualsOne adds two Jacobian points that are already known to have
// z values of 1 and stores the result in (x3, y3, z3). That is to say
// (x1, y1, 1) + (x2, y2, 1) = (x3, y3, z3). It performs faster addition than
// the generic add routine since less arithmetic is needed due to the ability to
// avoid the z value multiplications.
func (curve *KoblitzCurve) addZ1AndZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3 *fieldVal) {
// To compute the point addition efficiently, this implementation splits
// the equation into intermediate elements which are used to minimize
// the number of field multiplications using the method shown at:
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl
//
// In particular it performs the calculations using the following:
// H = X2-X1, HH = H^2, I = 4*HH, J = H*I, r = 2*(Y2-Y1), V = X1*I
// X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = 2*H
//
// This results in a cost of 4 field multiplications, 2 field squarings,
// 6 field additions, and 5 integer multiplications.
// When the x coordinates are the same for two points on the curve, the
// y coordinates either must be the same, in which case it is point
// doubling, or they are opposite and the result is the point at
// infinity per the group law for elliptic curve cryptography.
x1.Normalize()
y1.Normalize()
x2.Normalize()
y2.Normalize()
if x1.Equals(x2) {
if y1.Equals(y2) {
// Since x1 == x2 and y1 == y2, point doubling must be
// done, otherwise the addition would end up dividing
// by zero.
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
return
}
// Since x1 == x2 and y1 == -y2, the sum is the point at
// infinity per the group law.
x3.SetInt(0)
y3.SetInt(0)
z3.SetInt(0)
return
}
// Calculate X3, Y3, and Z3 according to the intermediate elements
// breakdown above.
var h, i, j, r, v fieldVal
var negJ, neg2V, negX3 fieldVal
h.Set(x1).Negate(1).Add(x2) // H = X2-X1 (mag: 3)
i.SquareVal(&h).MulInt(4) // I = 4*H^2 (mag: 4)
j.Mul2(&h, &i) // J = H*I (mag: 1)
r.Set(y1).Negate(1).Add(y2).MulInt(2) // r = 2*(Y2-Y1) (mag: 6)
v.Mul2(x1, &i) // V = X1*I (mag: 1)
negJ.Set(&j).Negate(1) // negJ = -J (mag: 2)
neg2V.Set(&v).MulInt(2).Negate(2) // neg2V = -(2*V) (mag: 3)
x3.Set(&r).Square().Add(&negJ).Add(&neg2V) // X3 = r^2-J-2*V (mag: 6)
negX3.Set(x3).Negate(6) // negX3 = -X3 (mag: 7)
j.Mul(y1).MulInt(2).Negate(2) // J = -(2*Y1*J) (mag: 3)
y3.Set(&v).Add(&negX3).Mul(&r).Add(&j) // Y3 = r*(V-X3)-2*Y1*J (mag: 4)
z3.Set(&h).MulInt(2) // Z3 = 2*H (mag: 6)
// Normalize the resulting field values to a magnitude of 1 as needed.
x3.Normalize()
y3.Normalize()
z3.Normalize()
}
// addZ1EqualsZ2 adds two Jacobian points that are already known to have the
// same z value and stores the result in (x3, y3, z3). That is to say
// (x1, y1, z1) + (x2, y2, z1) = (x3, y3, z3). It performs faster addition than
// the generic add routine since less arithmetic is needed due to the known
// equivalence.
func (curve *KoblitzCurve) addZ1EqualsZ2(x1, y1, z1, x2, y2, x3, y3, z3 *fieldVal) {
// To compute the point addition efficiently, this implementation splits
// the equation into intermediate elements which are used to minimize
// the number of field multiplications using a slightly modified version
// of the method shown at:
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-mmadd-2007-bl
//
// In particular it performs the calculations using the following:
// A = X2-X1, B = A^2, C=Y2-Y1, D = C^2, E = X1*B, F = X2*B
// X3 = D-E-F, Y3 = C*(E-X3)-Y1*(F-E), Z3 = Z1*A
//
// This results in a cost of 5 field multiplications, 2 field squarings,
// 9 field additions, and 0 integer multiplications.
// When the x coordinates are the same for two points on the curve, the
// y coordinates either must be the same, in which case it is point
// doubling, or they are opposite and the result is the point at
// infinity per the group law for elliptic curve cryptography.
x1.Normalize()
y1.Normalize()
x2.Normalize()
y2.Normalize()
if x1.Equals(x2) {
if y1.Equals(y2) {
// Since x1 == x2 and y1 == y2, point doubling must be
// done, otherwise the addition would end up dividing
// by zero.
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
return
}
// Since x1 == x2 and y1 == -y2, the sum is the point at
// infinity per the group law.
x3.SetInt(0)
y3.SetInt(0)
z3.SetInt(0)
return
}
// Calculate X3, Y3, and Z3 according to the intermediate elements
// breakdown above.
var a, b, c, d, e, f fieldVal
var negX1, negY1, negE, negX3 fieldVal
negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
a.Set(&negX1).Add(x2) // A = X2-X1 (mag: 3)
b.SquareVal(&a) // B = A^2 (mag: 1)
c.Set(&negY1).Add(y2) // C = Y2-Y1 (mag: 3)
d.SquareVal(&c) // D = C^2 (mag: 1)
e.Mul2(x1, &b) // E = X1*B (mag: 1)
negE.Set(&e).Negate(1) // negE = -E (mag: 2)
f.Mul2(x2, &b) // F = X2*B (mag: 1)
x3.Add2(&e, &f).Negate(3).Add(&d) // X3 = D-E-F (mag: 5)
negX3.Set(x3).Negate(5).Normalize() // negX3 = -X3 (mag: 1)
y3.Set(y1).Mul(f.Add(&negE)).Negate(3) // Y3 = -(Y1*(F-E)) (mag: 4)
y3.Add(e.Add(&negX3).Mul(&c)) // Y3 = C*(E-X3)+Y3 (mag: 5)
z3.Mul2(z1, &a) // Z3 = Z1*A (mag: 1)
// Normalize the resulting field values to a magnitude of 1 as needed.
x3.Normalize()
y3.Normalize()
}
// addZ2EqualsOne adds two Jacobian points when the second point is already
// known to have a z value of 1 (and the z value for the first point is not 1)
// and stores the result in (x3, y3, z3). That is to say (x1, y1, z1) +
// (x2, y2, 1) = (x3, y3, z3). It performs faster addition than the generic
// add routine since less arithmetic is needed due to the ability to avoid
// multiplications by the second point's z value.
func (curve *KoblitzCurve) addZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3 *fieldVal) {
// To compute the point addition efficiently, this implementation splits
// the equation into intermediate elements which are used to minimize
// the number of field multiplications using the method shown at:
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl
//
// In particular it performs the calculations using the following:
// Z1Z1 = Z1^2, U2 = X2*Z1Z1, S2 = Y2*Z1*Z1Z1, H = U2-X1, HH = H^2,
// I = 4*HH, J = H*I, r = 2*(S2-Y1), V = X1*I
// X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*Y1*J, Z3 = (Z1+H)^2-Z1Z1-HH
//
// This results in a cost of 7 field multiplications, 4 field squarings,
// 9 field additions, and 4 integer multiplications.
// When the x coordinates are the same for two points on the curve, the
// y coordinates either must be the same, in which case it is point
// doubling, or they are opposite and the result is the point at
// infinity per the group law for elliptic curve cryptography. Since
// any number of Jacobian coordinates can represent the same affine
// point, the x and y values need to be converted to like terms. Due to
// the assumption made for this function that the second point has a z
// value of 1 (z2=1), the first point is already "converted".
var z1z1, u2, s2 fieldVal
x1.Normalize()
y1.Normalize()
z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
if x1.Equals(&u2) {
if y1.Equals(&s2) {
// Since x1 == x2 and y1 == y2, point doubling must be
// done, otherwise the addition would end up dividing
// by zero.
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
return
}
// Since x1 == x2 and y1 == -y2, the sum is the point at
// infinity per the group law.
x3.SetInt(0)
y3.SetInt(0)
z3.SetInt(0)
return
}
// Calculate X3, Y3, and Z3 according to the intermediate elements
// breakdown above.
var h, hh, i, j, r, rr, v fieldVal
var negX1, negY1, negX3 fieldVal
negX1.Set(x1).Negate(1) // negX1 = -X1 (mag: 2)
h.Add2(&u2, &negX1) // H = U2-X1 (mag: 3)
hh.SquareVal(&h) // HH = H^2 (mag: 1)
i.Set(&hh).MulInt(4) // I = 4 * HH (mag: 4)
j.Mul2(&h, &i) // J = H*I (mag: 1)
negY1.Set(y1).Negate(1) // negY1 = -Y1 (mag: 2)
r.Set(&s2).Add(&negY1).MulInt(2) // r = 2*(S2-Y1) (mag: 6)
rr.SquareVal(&r) // rr = r^2 (mag: 1)
v.Mul2(x1, &i) // V = X1*I (mag: 1)
x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
y3.Set(y1).Mul(&j).MulInt(2).Negate(2) // Y3 = -(2*Y1*J) (mag: 3)
y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
z3.Add2(z1, &h).Square() // Z3 = (Z1+H)^2 (mag: 1)
z3.Add(z1z1.Add(&hh).Negate(2)) // Z3 = Z3-(Z1Z1+HH) (mag: 4)
// Normalize the resulting field values to a magnitude of 1 as needed.
x3.Normalize()
y3.Normalize()
z3.Normalize()
}
// addGeneric adds two Jacobian points (x1, y1, z1) and (x2, y2, z2) without any
// assumptions about the z values of the two points and stores the result in
// (x3, y3, z3). That is to say (x1, y1, z1) + (x2, y2, z2) = (x3, y3, z3). It
// is the slowest of the add routines due to requiring the most arithmetic.
func (curve *KoblitzCurve) addGeneric(x1, y1, z1, x2, y2, z2, x3, y3, z3 *fieldVal) {
// To compute the point addition efficiently, this implementation splits
// the equation into intermediate elements which are used to minimize
// the number of field multiplications using the method shown at:
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl
//
// In particular it performs the calculations using the following:
// Z1Z1 = Z1^2, Z2Z2 = Z2^2, U1 = X1*Z2Z2, U2 = X2*Z1Z1, S1 = Y1*Z2*Z2Z2
// S2 = Y2*Z1*Z1Z1, H = U2-U1, I = (2*H)^2, J = H*I, r = 2*(S2-S1)
// V = U1*I
// X3 = r^2-J-2*V, Y3 = r*(V-X3)-2*S1*J, Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2)*H
//
// This results in a cost of 11 field multiplications, 5 field squarings,
// 9 field additions, and 4 integer multiplications.
// When the x coordinates are the same for two points on the curve, the
// y coordinates either must be the same, in which case it is point
// doubling, or they are opposite and the result is the point at
// infinity. Since any number of Jacobian coordinates can represent the
// same affine point, the x and y values need to be converted to like
// terms.
var z1z1, z2z2, u1, u2, s1, s2 fieldVal
z1z1.SquareVal(z1) // Z1Z1 = Z1^2 (mag: 1)
z2z2.SquareVal(z2) // Z2Z2 = Z2^2 (mag: 1)
u1.Set(x1).Mul(&z2z2).Normalize() // U1 = X1*Z2Z2 (mag: 1)
u2.Set(x2).Mul(&z1z1).Normalize() // U2 = X2*Z1Z1 (mag: 1)
s1.Set(y1).Mul(&z2z2).Mul(z2).Normalize() // S1 = Y1*Z2*Z2Z2 (mag: 1)
s2.Set(y2).Mul(&z1z1).Mul(z1).Normalize() // S2 = Y2*Z1*Z1Z1 (mag: 1)
if u1.Equals(&u2) {
if s1.Equals(&s2) {
// Since x1 == x2 and y1 == y2, point doubling must be
// done, otherwise the addition would end up dividing
// by zero.
curve.doubleJacobian(x1, y1, z1, x3, y3, z3)
return
}
// Since x1 == x2 and y1 == -y2, the sum is the point at
// infinity per the group law.
x3.SetInt(0)
y3.SetInt(0)
z3.SetInt(0)
return
}
// Calculate X3, Y3, and Z3 according to the intermediate elements
// breakdown above.
var h, i, j, r, rr, v fieldVal
var negU1, negS1, negX3 fieldVal
negU1.Set(&u1).Negate(1) // negU1 = -U1 (mag: 2)
h.Add2(&u2, &negU1) // H = U2-U1 (mag: 3)
i.Set(&h).MulInt(2).Square() // I = (2*H)^2 (mag: 2)
j.Mul2(&h, &i) // J = H*I (mag: 1)
negS1.Set(&s1).Negate(1) // negS1 = -S1 (mag: 2)
r.Set(&s2).Add(&negS1).MulInt(2) // r = 2*(S2-S1) (mag: 6)
rr.SquareVal(&r) // rr = r^2 (mag: 1)
v.Mul2(&u1, &i) // V = U1*I (mag: 1)
x3.Set(&v).MulInt(2).Add(&j).Negate(3) // X3 = -(J+2*V) (mag: 4)
x3.Add(&rr) // X3 = r^2+X3 (mag: 5)
negX3.Set(x3).Negate(5) // negX3 = -X3 (mag: 6)
y3.Mul2(&s1, &j).MulInt(2).Negate(2) // Y3 = -(2*S1*J) (mag: 3)
y3.Add(v.Add(&negX3).Mul(&r)) // Y3 = r*(V-X3)+Y3 (mag: 4)
z3.Add2(z1, z2).Square() // Z3 = (Z1+Z2)^2 (mag: 1)
z3.Add(z1z1.Add(&z2z2).Negate(2)) // Z3 = Z3-(Z1Z1+Z2Z2) (mag: 4)
z3.Mul(&h) // Z3 = Z3*H (mag: 1)
// Normalize the resulting field values to a magnitude of 1 as needed.
x3.Normalize()
y3.Normalize()
}
// addJacobian adds the passed Jacobian points (x1, y1, z1) and (x2, y2, z2)
// together and stores the result in (x3, y3, z3).
func (curve *KoblitzCurve) addJacobian(x1, y1, z1, x2, y2, z2, x3, y3, z3 *fieldVal) {
// A point at infinity is the identity according to the group law for
// elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P.
if (x1.IsZero() && y1.IsZero()) || z1.IsZero() {
x3.Set(x2)
y3.Set(y2)
z3.Set(z2)
return
}
if (x2.IsZero() && y2.IsZero()) || z2.IsZero() {
x3.Set(x1)
y3.Set(y1)
z3.Set(z1)
return
}
// Faster point addition can be achieved when certain assumptions are
// met. For example, when both points have the same z value, arithmetic
// on the z values can be avoided. This section thus checks for these
// conditions and calls an appropriate add function which is accelerated
// by using those assumptions.
z1.Normalize()
z2.Normalize()
isZ1One := z1.Equals(fieldOne)
isZ2One := z2.Equals(fieldOne)
switch {
case isZ1One && isZ2One:
curve.addZ1AndZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3)
return
case z1.Equals(z2):
curve.addZ1EqualsZ2(x1, y1, z1, x2, y2, x3, y3, z3)
return
case isZ2One:
curve.addZ2EqualsOne(x1, y1, z1, x2, y2, x3, y3, z3)
return
}
// None of the above assumptions are true, so fall back to generic
// point addition.
curve.addGeneric(x1, y1, z1, x2, y2, z2, x3, y3, z3)
}
// Add returns the sum of (x1,y1) and (x2,y2). Part of the elliptic.Curve
// interface.
func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
// A point at infinity is the identity according to the group law for
// elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P.
if x1.Sign() == 0 && y1.Sign() == 0 {
return x2, y2
}
if x2.Sign() == 0 && y2.Sign() == 0 {
return x1, y1
}
// Convert the affine coordinates from big integers to field values
// and do the point addition in Jacobian projective space.
fx1, fy1 := curve.bigAffineToField(x1, y1)
fx2, fy2 := curve.bigAffineToField(x2, y2)
fx3, fy3, fz3 := new(fieldVal), new(fieldVal), new(fieldVal)
fOne := new(fieldVal).SetInt(1)
curve.addJacobian(fx1, fy1, fOne, fx2, fy2, fOne, fx3, fy3, fz3)
// Convert the Jacobian coordinate field values back to affine big
// integers.
return curve.fieldJacobianToBigAffine(fx3, fy3, fz3)
}
// doubleZ1EqualsOne performs point doubling on the passed Jacobian point
// when the point is already known to have a z value of 1 and stores
// the result in (x3, y3, z3). That is to say (x3, y3, z3) = 2*(x1, y1, 1). It
// performs faster point doubling than the generic routine since less arithmetic
// is needed due to the ability to avoid multiplication by the z value.
func (curve *KoblitzCurve) doubleZ1EqualsOne(x1, y1, x3, y3, z3 *fieldVal) {
// This function uses the assumptions that z1 is 1, thus the point
// doubling formulas reduce to:
//
// X3 = (3*X1^2)^2 - 8*X1*Y1^2
// Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
// Z3 = 2*Y1
//
// To compute the above efficiently, this implementation splits the
// equation into intermediate elements which are used to minimize the
// number of field multiplications in favor of field squarings which
// are roughly 35% faster than field multiplications with the current
// implementation at the time this was written.
//
// This uses a slightly modified version of the method shown at:
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl
//
// In particular it performs the calculations using the following:
// A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
// E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
// Z3 = 2*Y1
//
// This results in a cost of 1 field multiplication, 5 field squarings,
// 6 field additions, and 5 integer multiplications.
var a, b, c, d, e, f fieldVal
z3.Set(y1).MulInt(2) // Z3 = 2*Y1 (mag: 2)
a.SquareVal(x1) // A = X1^2 (mag: 1)
b.SquareVal(y1) // B = Y1^2 (mag: 1)
c.SquareVal(&b) // C = B^2 (mag: 1)
b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
f.SquareVal(&e) // F = E^2 (mag: 1)
x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
x3.Add(&f) // X3 = F+X3 (mag: 18)
f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
// Normalize the field values back to a magnitude of 1.
x3.Normalize()
y3.Normalize()
z3.Normalize()
}
// doubleGeneric performs point doubling on the passed Jacobian point without
// any assumptions about the z value and stores the result in (x3, y3, z3).
// That is to say (x3, y3, z3) = 2*(x1, y1, z1). It is the slowest of the point
// doubling routines due to requiring the most arithmetic.
func (curve *KoblitzCurve) doubleGeneric(x1, y1, z1, x3, y3, z3 *fieldVal) {
// Point doubling formula for Jacobian coordinates for the secp256k1
// curve:
// X3 = (3*X1^2)^2 - 8*X1*Y1^2
// Y3 = (3*X1^2)*(4*X1*Y1^2 - X3) - 8*Y1^4
// Z3 = 2*Y1*Z1
//
// To compute the above efficiently, this implementation splits the
// equation into intermediate elements which are used to minimize the
// number of field multiplications in favor of field squarings which
// are roughly 35% faster than field multiplications with the current
// implementation at the time this was written.
//
// This uses a slightly modified version of the method shown at:
// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
//
// In particular it performs the calculations using the following:
// A = X1^2, B = Y1^2, C = B^2, D = 2*((X1+B)^2-A-C)
// E = 3*A, F = E^2, X3 = F-2*D, Y3 = E*(D-X3)-8*C
// Z3 = 2*Y1*Z1
//
// This results in a cost of 1 field multiplication, 5 field squarings,
// 6 field additions, and 5 integer multiplications.
var a, b, c, d, e, f fieldVal
z3.Mul2(y1, z1).MulInt(2) // Z3 = 2*Y1*Z1 (mag: 2)
a.SquareVal(x1) // A = X1^2 (mag: 1)
b.SquareVal(y1) // B = Y1^2 (mag: 1)
c.SquareVal(&b) // C = B^2 (mag: 1)
b.Add(x1).Square() // B = (X1+B)^2 (mag: 1)
d.Set(&a).Add(&c).Negate(2) // D = -(A+C) (mag: 3)
d.Add(&b).MulInt(2) // D = 2*(B+D)(mag: 8)
e.Set(&a).MulInt(3) // E = 3*A (mag: 3)
f.SquareVal(&e) // F = E^2 (mag: 1)
x3.Set(&d).MulInt(2).Negate(16) // X3 = -(2*D) (mag: 17)
x3.Add(&f) // X3 = F+X3 (mag: 18)
f.Set(x3).Negate(18).Add(&d).Normalize() // F = D-X3 (mag: 1)
y3.Set(&c).MulInt(8).Negate(8) // Y3 = -(8*C) (mag: 9)
y3.Add(f.Mul(&e)) // Y3 = E*F+Y3 (mag: 10)
// Normalize the field values back to a magnitude of 1.
x3.Normalize()
y3.Normalize()
z3.Normalize()
}
// doubleJacobian doubles the passed Jacobian point (x1, y1, z1) and stores the
// result in (x3, y3, z3).
func (curve *KoblitzCurve) doubleJacobian(x1, y1, z1, x3, y3, z3 *fieldVal) {
// Doubling a point at infinity is still infinity.
if y1.IsZero() || z1.IsZero() {
x3.SetInt(0)
y3.SetInt(0)
z3.SetInt(0)
return
}
// Slightly faster point doubling can be achieved when the z value is 1
// by avoiding the multiplication on the z value. This section calls
// a point doubling function which is accelerated by using that
// assumption when possible.
if z1.Normalize().Equals(fieldOne) {
curve.doubleZ1EqualsOne(x1, y1, x3, y3, z3)
return
}
// Fall back to generic point doubling which works with arbitrary z
// values.
curve.doubleGeneric(x1, y1, z1, x3, y3, z3)
}
// Double returns 2*(x1,y1). Part of the elliptic.Curve interface.
func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
if y1.Sign() == 0 {
return new(big.Int), new(big.Int)
}
// Convert the affine coordinates from big integers to field values
// and do the point doubling in Jacobian projective space.
fx1, fy1 := curve.bigAffineToField(x1, y1)
fx3, fy3, fz3 := new(fieldVal), new(fieldVal), new(fieldVal)
fOne := new(fieldVal).SetInt(1)
curve.doubleJacobian(fx1, fy1, fOne, fx3, fy3, fz3)
// Convert the Jacobian coordinate field values back to affine big
// integers.
return curve.fieldJacobianToBigAffine(fx3, fy3, fz3)
}
// splitK returns a balanced length-two representation of k and their signs.
// This is algorithm 3.74 from [GECC].
//
// One thing of note about this algorithm is that no matter what c1 and c2 are,
// the final equation of k = k1 + k2 * lambda (mod n) will hold. This is
// provable mathematically due to how a1/b1/a2/b2 are computed.
//
// c1 and c2 are chosen to minimize the max(k1,k2).
func (curve *KoblitzCurve) splitK(k []byte) ([]byte, []byte, int, int) {
// All math here is done with big.Int, which is slow.
// At some point, it might be useful to write something similar to
// fieldVal but for N instead of P as the prime field if this ends up
// being a bottleneck.
bigIntK := new(big.Int)
c1, c2 := new(big.Int), new(big.Int)
tmp1, tmp2 := new(big.Int), new(big.Int)
k1, k2 := new(big.Int), new(big.Int)
bigIntK.SetBytes(k)
// c1 = round(b2 * k / n) from step 4.
// Rounding isn't really necessary and costs too much, hence skipped
c1.Mul(curve.b2, bigIntK)
c1.Div(c1, curve.N)
// c2 = round(b1 * k / n) from step 4 (sign reversed to optimize one step)
// Rounding isn't really necessary and costs too much, hence skipped
c2.Mul(curve.b1, bigIntK)
c2.Div(c2, curve.N)
// k1 = k - c1 * a1 - c2 * a2 from step 5 (note c2's sign is reversed)
tmp1.Mul(c1, curve.a1)
tmp2.Mul(c2, curve.a2)
k1.Sub(bigIntK, tmp1)
k1.Add(k1, tmp2)
// k2 = - c1 * b1 - c2 * b2 from step 5 (note c2's sign is reversed)
tmp1.Mul(c1, curve.b1)
tmp2.Mul(c2, curve.b2)
k2.Sub(tmp2, tmp1)
// Note Bytes() throws out the sign of k1 and k2. This matters
// since k1 and/or k2 can be negative. Hence, we pass that
// back separately.
return k1.Bytes(), k2.Bytes(), k1.Sign(), k2.Sign()
}
// moduloReduce reduces k from more than 32 bytes to 32 bytes and under. This
// is done by doing a simple modulo curve.N. We can do this since G^N = 1 and
// thus any other valid point on the elliptic curve has the same order.
func (curve *KoblitzCurve) moduloReduce(k []byte) []byte {
// Since the order of G is curve.N, we can use a much smaller number
// by doing modulo curve.N
if len(k) > curve.byteSize {
// Reduce k by performing modulo curve.N.
tmpK := new(big.Int).SetBytes(k)
tmpK.Mod(tmpK, curve.N)
return tmpK.Bytes()
}
return k
}
// NAF takes a positive integer k and returns the Non-Adjacent Form (NAF) as two
// byte slices. The first is where 1s will be. The second is where -1s will
// be. NAF is convenient in that on average, only 1/3rd of its values are
// non-zero. This is algorithm 3.30 from [GECC].
//
// Essentially, this makes it possible to minimize the number of operations
// since the resulting ints returned will be at least 50% 0s.
func NAF(k []byte) ([]byte, []byte) {
// The essence of this algorithm is that whenever we have consecutive 1s
// in the binary, we want to put a -1 in the lowest bit and get a bunch
// of 0s up to the highest bit of consecutive 1s. This is due to this
// identity:
// 2^n + 2^(n-1) + 2^(n-2) + ... + 2^(n-k) = 2^(n+1) - 2^(n-k)
//
// The algorithm thus may need to go 1 more bit than the length of the
// bits we actually have, hence bits being 1 bit longer than was
// necessary. Since we need to know whether adding will cause a carry,
// we go from right-to-left in this addition.
var carry, curIsOne, nextIsOne bool
// these default to zero
retPos := make([]byte, len(k)+1)
retNeg := make([]byte, len(k)+1)
for i := len(k) - 1; i >= 0; i-- {
curByte := k[i]
for j := uint(0); j < 8; j++ {
curIsOne = curByte&1 == 1
if j == 7 {
if i == 0 {
nextIsOne = false
} else {
nextIsOne = k[i-1]&1 == 1
}
} else {
nextIsOne = curByte&2 == 2
}
if carry {
if curIsOne {
// This bit is 1, so continue to carry
// and don't need to do anything.
} else {
// We've hit a 0 after some number of
// 1s.
if nextIsOne {
// Start carrying again since
// a new sequence of 1s is
// starting.
retNeg[i+1] += 1 << j
} else {
// Stop carrying since 1s have
// stopped.
carry = false
retPos[i+1] += 1 << j
}
}
} else if curIsOne {
if nextIsOne {
// If this is the start of at least 2
// consecutive 1s, set the current one
// to -1 and start carrying.
retNeg[i+1] += 1 << j
carry = true
} else {
// This is a singleton, not consecutive
// 1s.
retPos[i+1] += 1 << j
}
}
curByte >>= 1
}
}
if carry {
retPos[0] = 1
return retPos, retNeg
}
return retPos[1:], retNeg[1:]
}
// ScalarMult returns k*(Bx, By) where k is a big endian integer.
// Part of the elliptic.Curve interface.
func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
// Point Q = ∞ (point at infinity).
qx, qy, qz := new(fieldVal), new(fieldVal), new(fieldVal)
// Decompose K into k1 and k2 in order to halve the number of EC ops.
// See Algorithm 3.74 in [GECC].
k1, k2, signK1, signK2 := curve.splitK(curve.moduloReduce(k))
// The main equation here to remember is:
// k * P = k1 * P + k2 * ϕ(P)
//
// P1 below is P in the equation, P2 below is ϕ(P) in the equation
p1x, p1y := curve.bigAffineToField(Bx, By)
p1yNeg := new(fieldVal).NegateVal(p1y, 1)
p1z := new(fieldVal).SetInt(1)
// NOTE: ϕ(x,y) = (βx,y). The Jacobian z coordinate is 1, so this math
// goes through.
p2x := new(fieldVal).Mul2(p1x, curve.beta)
p2y := new(fieldVal).Set(p1y)
p2yNeg := new(fieldVal).NegateVal(p2y, 1)
p2z := new(fieldVal).SetInt(1)
// Flip the positive and negative values of the points as needed
// depending on the signs of k1 and k2. As mentioned in the equation
// above, each of k1 and k2 are multiplied by the respective point.
// Since -k * P is the same thing as k * -P, and the group law for
// elliptic curves states that P(x, y) = -P(x, -y), it's faster and
// simplifies the code to just make the point negative.
if signK1 == -1 {
p1y, p1yNeg = p1yNeg, p1y
}
if signK2 == -1 {
p2y, p2yNeg = p2yNeg, p2y
}
// NAF versions of k1 and k2 should have a lot more zeros.
//
// The Pos version of the bytes contain the +1s and the Neg versions
// contain the -1s.
k1PosNAF, k1NegNAF := NAF(k1)
k2PosNAF, k2NegNAF := NAF(k2)
k1Len := len(k1PosNAF)
k2Len := len(k2PosNAF)
m := k1Len
if m < k2Len {
m = k2Len
}
// Add left-to-right using the NAF optimization. See algorithm 3.77
// from [GECC]. This should be faster overall since there will be a lot
// more instances of 0, hence reducing the number of Jacobian additions
// at the cost of 1 possible extra doubling.
var k1BytePos, k1ByteNeg, k2BytePos, k2ByteNeg byte
for i := 0; i < m; i++ {
// Since we're going left-to-right, pad the front with 0s.
if i < m-k1Len {
k1BytePos = 0
k1ByteNeg = 0
} else {
k1BytePos = k1PosNAF[i-(m-k1Len)]
k1ByteNeg = k1NegNAF[i-(m-k1Len)]
}
if i < m-k2Len {
k2BytePos = 0
k2ByteNeg = 0
} else {
k2BytePos = k2PosNAF[i-(m-k2Len)]
k2ByteNeg = k2NegNAF[i-(m-k2Len)]
}
for j := 7; j >= 0; j-- {
// Q = 2 * Q
curve.doubleJacobian(qx, qy, qz, qx, qy, qz)
if k1BytePos&0x80 == 0x80 {
curve.addJacobian(qx, qy, qz, p1x, p1y, p1z,
qx, qy, qz)
} else if k1ByteNeg&0x80 == 0x80 {
curve.addJacobian(qx, qy, qz, p1x, p1yNeg, p1z,
qx, qy, qz)
}
if k2BytePos&0x80 == 0x80 {
curve.addJacobian(qx, qy, qz, p2x, p2y, p2z,
qx, qy, qz)
} else if k2ByteNeg&0x80 == 0x80 {
curve.addJacobian(qx, qy, qz, p2x, p2yNeg, p2z,
qx, qy, qz)
}
k1BytePos <<= 1
k1ByteNeg <<= 1
k2BytePos <<= 1
k2ByteNeg <<= 1
}
}
// Convert the Jacobian coordinate field values back to affine big.Ints.
return curve.fieldJacobianToBigAffine(qx, qy, qz)
}
// ScalarBaseMult returns k*G where G is the base point of the group and k is a
// big endian integer.
// Part of the elliptic.Curve interface.
func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
newK := curve.moduloReduce(k)
diff := len(curve.bytePoints) - len(newK)
// Point Q = ∞ (point at infinity).
qx, qy, qz := new(fieldVal), new(fieldVal), new(fieldVal)
// curve.bytePoints has all 256 byte points for each 8-bit window. The
// strategy is to add up the byte points. This is best understood by
// expressing k in base-256 which it already sort of is.
// Each "digit" in the 8-bit window can be looked up using bytePoints
// and added together.
for i, byteVal := range newK {
p := curve.bytePoints[diff+i][byteVal]
curve.addJacobian(qx, qy, qz, &p[0], &p[1], &p[2], qx, qy, qz)
}
return curve.fieldJacobianToBigAffine(qx, qy, qz)
}
// QPlus1Div4 returns the Q+1/4 constant for the curve for use in calculating
// square roots via exponention.
func (curve *KoblitzCurve) QPlus1Div4() *big.Int {
return curve.q
}
var initonce sync.Once
var secp256k1 KoblitzCurve
func initAll() {
initS256()
}
// fromHex converts the passed hex string into a big integer pointer and will
// panic is there is an error. This is only provided for the hard-coded
// constants so errors in the source code can bet detected. It will only (and
// must only) be called for initialization purposes.
func fromHex(s string) *big.Int {
r, ok := new(big.Int).SetString(s, 16)
if !ok {
panic("invalid hex in source file: " + s)
}
return r
}
func initS256() {
// Curve parameters taken from [SECG] section 2.4.1.
secp256k1.CurveParams = new(elliptic.CurveParams)
secp256k1.P = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")
secp256k1.N = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")
secp256k1.B = fromHex("0000000000000000000000000000000000000000000000000000000000000007")
secp256k1.Gx = fromHex("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")
secp256k1.Gy = fromHex("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8")
secp256k1.BitSize = 256
secp256k1.q = new(big.Int).Div(new(big.Int).Add(secp256k1.P,
big.NewInt(1)), big.NewInt(4))
secp256k1.H = 1
secp256k1.halfOrder = new(big.Int).Rsh(secp256k1.N, 1)
// Provided for convenience since this gets computed repeatedly.
secp256k1.byteSize = secp256k1.BitSize / 8
// Deserialize and set the pre-computed table used to accelerate scalar
// base multiplication. This is hard-coded data, so any errors are
// panics because it means something is wrong in the source code.
if err := loadS256BytePoints(); err != nil {
panic(err)
}
// Next 6 constants are from Hal Finney's bitcointalk.org post:
// https://bitcointalk.org/index.php?topic=3238.msg45565#msg45565
// May he rest in peace.
//
// They have also been independently derived from the code in the
// EndomorphismVectors function in gensecp256k1.go.
secp256k1.lambda = fromHex("5363AD4CC05C30E0A5261C028812645A122E22EA20816678DF02967C1B23BD72")
secp256k1.beta = new(fieldVal).SetHex("7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE")
secp256k1.a1 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
secp256k1.b1 = fromHex("-E4437ED6010E88286F547FA90ABFE4C3")
secp256k1.a2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8")
secp256k1.b2 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
// Alternatively, we can use the parameters below, however, they seem
// to be about 8% slower.
// secp256k1.lambda = fromHex("AC9C52B33FA3CF1F5AD9E3FD77ED9BA4A880B9FC8EC739C2E0CFC810B51283CE")
// secp256k1.beta = new(fieldVal).SetHex("851695D49A83F8EF919BB86153CBCB16630FB68AED0A766A3EC693D68E6AFA40")
// secp256k1.a1 = fromHex("E4437ED6010E88286F547FA90ABFE4C3")
// secp256k1.b1 = fromHex("-3086D221A7D46BCDE86C90E49284EB15")
// secp256k1.a2 = fromHex("3086D221A7D46BCDE86C90E49284EB15")
// secp256k1.b2 = fromHex("114CA50F7A8E2F3F657C1108D9D44CFD8")
}
// S256 returns a Curve which implements secp256k1.
func S256() *KoblitzCurve {
initonce.Do(initAll)
return &secp256k1
}

216
vendor/github.com/btcsuite/btcd/btcec/ciphering.go generated vendored Normal file
View File

@ -0,0 +1,216 @@
// Copyright (c) 2015-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcec
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"crypto/sha512"
"errors"
"io"
)
var (
// ErrInvalidMAC occurs when Message Authentication Check (MAC) fails
// during decryption. This happens because of either invalid private key or
// corrupt ciphertext.
ErrInvalidMAC = errors.New("invalid mac hash")
// errInputTooShort occurs when the input ciphertext to the Decrypt
// function is less than 134 bytes long.
errInputTooShort = errors.New("ciphertext too short")
// errUnsupportedCurve occurs when the first two bytes of the encrypted
// text aren't 0x02CA (= 712 = secp256k1, from OpenSSL).
errUnsupportedCurve = errors.New("unsupported curve")
errInvalidXLength = errors.New("invalid X length, must be 32")
errInvalidYLength = errors.New("invalid Y length, must be 32")
errInvalidPadding = errors.New("invalid PKCS#7 padding")
// 0x02CA = 714
ciphCurveBytes = [2]byte{0x02, 0xCA}
// 0x20 = 32
ciphCoordLength = [2]byte{0x00, 0x20}
)
// GenerateSharedSecret generates a shared secret based on a private key and a
// public key using Diffie-Hellman key exchange (ECDH) (RFC 4753).
// RFC5903 Section 9 states we should only return x.
func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte {
x, _ := pubkey.Curve.ScalarMult(pubkey.X, pubkey.Y, privkey.D.Bytes())
return x.Bytes()
}
// Encrypt encrypts data for the target public key using AES-256-CBC. It also
// generates a private key (the pubkey of which is also in the output). The only
// supported curve is secp256k1. The `structure' that it encodes everything into
// is:
//
// struct {
// // Initialization Vector used for AES-256-CBC
// IV [16]byte
// // Public Key: curve(2) + len_of_pubkeyX(2) + pubkeyX +
// // len_of_pubkeyY(2) + pubkeyY (curve = 714)
// PublicKey [70]byte
// // Cipher text
// Data []byte
// // HMAC-SHA-256 Message Authentication Code
// HMAC [32]byte
// }
//
// The primary aim is to ensure byte compatibility with Pyelliptic. Also, refer
// to section 5.8.1 of ANSI X9.63 for rationale on this format.
func Encrypt(pubkey *PublicKey, in []byte) ([]byte, error) {
ephemeral, err := NewPrivateKey(S256())
if err != nil {
return nil, err
}
ecdhKey := GenerateSharedSecret(ephemeral, pubkey)
derivedKey := sha512.Sum512(ecdhKey)
keyE := derivedKey[:32]
keyM := derivedKey[32:]
paddedIn := addPKCSPadding(in)
// IV + Curve params/X/Y + padded plaintext/ciphertext + HMAC-256
out := make([]byte, aes.BlockSize+70+len(paddedIn)+sha256.Size)
iv := out[:aes.BlockSize]
if _, err = io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
}
// start writing public key
pb := ephemeral.PubKey().SerializeUncompressed()
offset := aes.BlockSize
// curve and X length
copy(out[offset:offset+4], append(ciphCurveBytes[:], ciphCoordLength[:]...))
offset += 4
// X
copy(out[offset:offset+32], pb[1:33])
offset += 32
// Y length
copy(out[offset:offset+2], ciphCoordLength[:])
offset += 2
// Y
copy(out[offset:offset+32], pb[33:])
offset += 32
// start encryption
block, err := aes.NewCipher(keyE)
if err != nil {
return nil, err
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(out[offset:len(out)-sha256.Size], paddedIn)
// start HMAC-SHA-256
hm := hmac.New(sha256.New, keyM)
hm.Write(out[:len(out)-sha256.Size]) // everything is hashed
copy(out[len(out)-sha256.Size:], hm.Sum(nil)) // write checksum
return out, nil
}
// Decrypt decrypts data that was encrypted using the Encrypt function.
func Decrypt(priv *PrivateKey, in []byte) ([]byte, error) {
// IV + Curve params/X/Y + 1 block + HMAC-256
if len(in) < aes.BlockSize+70+aes.BlockSize+sha256.Size {
return nil, errInputTooShort
}
// read iv
iv := in[:aes.BlockSize]
offset := aes.BlockSize
// start reading pubkey
if !bytes.Equal(in[offset:offset+2], ciphCurveBytes[:]) {
return nil, errUnsupportedCurve
}
offset += 2
if !bytes.Equal(in[offset:offset+2], ciphCoordLength[:]) {
return nil, errInvalidXLength
}
offset += 2
xBytes := in[offset : offset+32]
offset += 32
if !bytes.Equal(in[offset:offset+2], ciphCoordLength[:]) {
return nil, errInvalidYLength
}
offset += 2
yBytes := in[offset : offset+32]
offset += 32
pb := make([]byte, 65)
pb[0] = byte(0x04) // uncompressed
copy(pb[1:33], xBytes)
copy(pb[33:], yBytes)
// check if (X, Y) lies on the curve and create a Pubkey if it does
pubkey, err := ParsePubKey(pb, S256())
if err != nil {
return nil, err
}
// check for cipher text length
if (len(in)-aes.BlockSize-offset-sha256.Size)%aes.BlockSize != 0 {
return nil, errInvalidPadding // not padded to 16 bytes
}
// read hmac
messageMAC := in[len(in)-sha256.Size:]
// generate shared secret
ecdhKey := GenerateSharedSecret(priv, pubkey)
derivedKey := sha512.Sum512(ecdhKey)
keyE := derivedKey[:32]
keyM := derivedKey[32:]
// verify mac
hm := hmac.New(sha256.New, keyM)
hm.Write(in[:len(in)-sha256.Size]) // everything is hashed
expectedMAC := hm.Sum(nil)
if !hmac.Equal(messageMAC, expectedMAC) {
return nil, ErrInvalidMAC
}
// start decryption
block, err := aes.NewCipher(keyE)
if err != nil {
return nil, err
}
mode := cipher.NewCBCDecrypter(block, iv)
// same length as ciphertext
plaintext := make([]byte, len(in)-offset-sha256.Size)
mode.CryptBlocks(plaintext, in[offset:len(in)-sha256.Size])
return removePKCSPadding(plaintext)
}
// Implement PKCS#7 padding with block size of 16 (AES block size).
// addPKCSPadding adds padding to a block of data
func addPKCSPadding(src []byte) []byte {
padding := aes.BlockSize - len(src)%aes.BlockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
}
// removePKCSPadding removes padding from data that was added with addPKCSPadding
func removePKCSPadding(src []byte) ([]byte, error) {
length := len(src)
padLength := int(src[length-1])
if padLength > aes.BlockSize || length < aes.BlockSize {
return nil, errInvalidPadding
}
return src[:length-padLength], nil
}

21
vendor/github.com/btcsuite/btcd/btcec/doc.go generated vendored Normal file
View File

@ -0,0 +1,21 @@
// Copyright (c) 2013-2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
/*
Package btcec implements support for the elliptic curves needed for bitcoin.
Bitcoin uses elliptic curve cryptography using koblitz curves
(specifically secp256k1) for cryptographic functions. See
http://www.secg.org/collateral/sec2_final.pdf for details on the
standard.
This package provides the data structures and functions implementing the
crypto/elliptic Curve interface in order to permit using these curves
with the standard crypto/ecdsa package provided with go. Helper
functionality is provided to parse signatures and public keys from
standard formats. It was designed for use with btcd, but should be
general enough for other uses of elliptic curve crypto. It was originally based
on some initial work by ThePiachu, but has significantly diverged since then.
*/
package btcec

1223
vendor/github.com/btcsuite/btcd/btcec/field.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

63
vendor/github.com/btcsuite/btcd/btcec/genprecomps.go generated vendored Normal file
View File

@ -0,0 +1,63 @@
// Copyright 2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// This file is ignored during the regular build due to the following build tag.
// It is called by go generate and used to automatically generate pre-computed
// tables used to accelerate operations.
// +build ignore
package main
import (
"bytes"
"compress/zlib"
"encoding/base64"
"fmt"
"log"
"os"
"github.com/btcsuite/btcd/btcec"
)
func main() {
fi, err := os.Create("secp256k1.go")
if err != nil {
log.Fatal(err)
}
defer fi.Close()
// Compress the serialized byte points.
serialized := btcec.S256().SerializedBytePoints()
var compressed bytes.Buffer
w := zlib.NewWriter(&compressed)
if _, err := w.Write(serialized); err != nil {
fmt.Println(err)
os.Exit(1)
}
w.Close()
// Encode the compressed byte points with base64.
encoded := make([]byte, base64.StdEncoding.EncodedLen(compressed.Len()))
base64.StdEncoding.Encode(encoded, compressed.Bytes())
fmt.Fprintln(fi, "// Copyright (c) 2015 The btcsuite developers")
fmt.Fprintln(fi, "// Use of this source code is governed by an ISC")
fmt.Fprintln(fi, "// license that can be found in the LICENSE file.")
fmt.Fprintln(fi)
fmt.Fprintln(fi, "package btcec")
fmt.Fprintln(fi)
fmt.Fprintln(fi, "// Auto-generated file (see genprecomps.go)")
fmt.Fprintln(fi, "// DO NOT EDIT")
fmt.Fprintln(fi)
fmt.Fprintf(fi, "var secp256k1BytePoints = %q\n", string(encoded))
a1, b1, a2, b2 := btcec.S256().EndomorphismVectors()
fmt.Println("The following values are the computed linearly " +
"independent vectors needed to make use of the secp256k1 " +
"endomorphism:")
fmt.Printf("a1: %x\n", a1)
fmt.Printf("b1: %x\n", b1)
fmt.Printf("a2: %x\n", a2)
fmt.Printf("b2: %x\n", b2)
}

203
vendor/github.com/btcsuite/btcd/btcec/gensecp256k1.go generated vendored Normal file
View File

@ -0,0 +1,203 @@
// Copyright (c) 2014-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// This file is ignored during the regular build due to the following build tag.
// This build tag is set during go generate.
// +build gensecp256k1
package btcec
// References:
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
import (
"encoding/binary"
"math/big"
)
// secp256k1BytePoints are dummy points used so the code which generates the
// real values can compile.
var secp256k1BytePoints = ""
// getDoublingPoints returns all the possible G^(2^i) for i in
// 0..n-1 where n is the curve's bit size (256 in the case of secp256k1)
// the coordinates are recorded as Jacobian coordinates.
func (curve *KoblitzCurve) getDoublingPoints() [][3]fieldVal {
doublingPoints := make([][3]fieldVal, curve.BitSize)
// initialize px, py, pz to the Jacobian coordinates for the base point
px, py := curve.bigAffineToField(curve.Gx, curve.Gy)
pz := new(fieldVal).SetInt(1)
for i := 0; i < curve.BitSize; i++ {
doublingPoints[i] = [3]fieldVal{*px, *py, *pz}
// P = 2*P
curve.doubleJacobian(px, py, pz, px, py, pz)
}
return doublingPoints
}
// SerializedBytePoints returns a serialized byte slice which contains all of
// the possible points per 8-bit window. This is used to when generating
// secp256k1.go.
func (curve *KoblitzCurve) SerializedBytePoints() []byte {
doublingPoints := curve.getDoublingPoints()
// Segregate the bits into byte-sized windows
serialized := make([]byte, curve.byteSize*256*3*10*4)
offset := 0
for byteNum := 0; byteNum < curve.byteSize; byteNum++ {
// Grab the 8 bits that make up this byte from doublingPoints.
startingBit := 8 * (curve.byteSize - byteNum - 1)
computingPoints := doublingPoints[startingBit : startingBit+8]
// Compute all points in this window and serialize them.
for i := 0; i < 256; i++ {
px, py, pz := new(fieldVal), new(fieldVal), new(fieldVal)
for j := 0; j < 8; j++ {
if i>>uint(j)&1 == 1 {
curve.addJacobian(px, py, pz, &computingPoints[j][0],
&computingPoints[j][1], &computingPoints[j][2], px, py, pz)
}
}
for i := 0; i < 10; i++ {
binary.LittleEndian.PutUint32(serialized[offset:], px.n[i])
offset += 4
}
for i := 0; i < 10; i++ {
binary.LittleEndian.PutUint32(serialized[offset:], py.n[i])
offset += 4
}
for i := 0; i < 10; i++ {
binary.LittleEndian.PutUint32(serialized[offset:], pz.n[i])
offset += 4
}
}
}
return serialized
}
// sqrt returns the square root of the provided big integer using Newton's
// method. It's only compiled and used during generation of pre-computed
// values, so speed is not a huge concern.
func sqrt(n *big.Int) *big.Int {
// Initial guess = 2^(log_2(n)/2)
guess := big.NewInt(2)
guess.Exp(guess, big.NewInt(int64(n.BitLen()/2)), nil)
// Now refine using Newton's method.
big2 := big.NewInt(2)
prevGuess := big.NewInt(0)
for {
prevGuess.Set(guess)
guess.Add(guess, new(big.Int).Div(n, guess))
guess.Div(guess, big2)
if guess.Cmp(prevGuess) == 0 {
break
}
}
return guess
}
// EndomorphismVectors runs the first 3 steps of algorithm 3.74 from [GECC] to
// generate the linearly independent vectors needed to generate a balanced
// length-two representation of a multiplier such that k = k1 + k2λ (mod N) and
// returns them. Since the values will always be the same given the fact that N
// and λ are fixed, the final results can be accelerated by storing the
// precomputed values with the curve.
func (curve *KoblitzCurve) EndomorphismVectors() (a1, b1, a2, b2 *big.Int) {
bigMinus1 := big.NewInt(-1)
// This section uses an extended Euclidean algorithm to generate a
// sequence of equations:
// s[i] * N + t[i] * λ = r[i]
nSqrt := sqrt(curve.N)
u, v := new(big.Int).Set(curve.N), new(big.Int).Set(curve.lambda)
x1, y1 := big.NewInt(1), big.NewInt(0)
x2, y2 := big.NewInt(0), big.NewInt(1)
q, r := new(big.Int), new(big.Int)
qu, qx1, qy1 := new(big.Int), new(big.Int), new(big.Int)
s, t := new(big.Int), new(big.Int)
ri, ti := new(big.Int), new(big.Int)
a1, b1, a2, b2 = new(big.Int), new(big.Int), new(big.Int), new(big.Int)
found, oneMore := false, false
for u.Sign() != 0 {
// q = v/u
q.Div(v, u)
// r = v - q*u
qu.Mul(q, u)
r.Sub(v, qu)
// s = x2 - q*x1
qx1.Mul(q, x1)
s.Sub(x2, qx1)
// t = y2 - q*y1
qy1.Mul(q, y1)
t.Sub(y2, qy1)
// v = u, u = r, x2 = x1, x1 = s, y2 = y1, y1 = t
v.Set(u)
u.Set(r)
x2.Set(x1)
x1.Set(s)
y2.Set(y1)
y1.Set(t)
// As soon as the remainder is less than the sqrt of n, the
// values of a1 and b1 are known.
if !found && r.Cmp(nSqrt) < 0 {
// When this condition executes ri and ti represent the
// r[i] and t[i] values such that i is the greatest
// index for which r >= sqrt(n). Meanwhile, the current
// r and t values are r[i+1] and t[i+1], respectively.
// a1 = r[i+1], b1 = -t[i+1]
a1.Set(r)
b1.Mul(t, bigMinus1)
found = true
oneMore = true
// Skip to the next iteration so ri and ti are not
// modified.
continue
} else if oneMore {
// When this condition executes ri and ti still
// represent the r[i] and t[i] values while the current
// r and t are r[i+2] and t[i+2], respectively.
// sum1 = r[i]^2 + t[i]^2
rSquared := new(big.Int).Mul(ri, ri)
tSquared := new(big.Int).Mul(ti, ti)
sum1 := new(big.Int).Add(rSquared, tSquared)
// sum2 = r[i+2]^2 + t[i+2]^2
r2Squared := new(big.Int).Mul(r, r)
t2Squared := new(big.Int).Mul(t, t)
sum2 := new(big.Int).Add(r2Squared, t2Squared)
// if (r[i]^2 + t[i]^2) <= (r[i+2]^2 + t[i+2]^2)
if sum1.Cmp(sum2) <= 0 {
// a2 = r[i], b2 = -t[i]
a2.Set(ri)
b2.Mul(ti, bigMinus1)
} else {
// a2 = r[i+2], b2 = -t[i+2]
a2.Set(r)
b2.Mul(t, bigMinus1)
}
// All done.
break
}
ri.Set(r)
ti.Set(t)
}
return a1, b1, a2, b2
}

67
vendor/github.com/btcsuite/btcd/btcec/precompute.go generated vendored Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcec
import (
"compress/zlib"
"encoding/base64"
"encoding/binary"
"io/ioutil"
"strings"
)
//go:generate go run -tags gensecp256k1 genprecomps.go
// loadS256BytePoints decompresses and deserializes the pre-computed byte points
// used to accelerate scalar base multiplication for the secp256k1 curve. This
// approach is used since it allows the compile to use significantly less ram
// and be performed much faster than it is with hard-coding the final in-memory
// data structure. At the same time, it is quite fast to generate the in-memory
// data structure at init time with this approach versus computing the table.
func loadS256BytePoints() error {
// There will be no byte points to load when generating them.
bp := secp256k1BytePoints
if len(bp) == 0 {
return nil
}
// Decompress the pre-computed table used to accelerate scalar base
// multiplication.
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp))
r, err := zlib.NewReader(decoder)
if err != nil {
return err
}
serialized, err := ioutil.ReadAll(r)
if err != nil {
return err
}
// Deserialize the precomputed byte points and set the curve to them.
offset := 0
var bytePoints [32][256][3]fieldVal
for byteNum := 0; byteNum < 32; byteNum++ {
// All points in this window.
for i := 0; i < 256; i++ {
px := &bytePoints[byteNum][i][0]
py := &bytePoints[byteNum][i][1]
pz := &bytePoints[byteNum][i][2]
for i := 0; i < 10; i++ {
px.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
offset += 4
}
for i := 0; i < 10; i++ {
py.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
offset += 4
}
for i := 0; i < 10; i++ {
pz.n[i] = binary.LittleEndian.Uint32(serialized[offset:])
offset += 4
}
}
}
secp256k1.bytePoints = &bytePoints
return nil
}

73
vendor/github.com/btcsuite/btcd/btcec/privkey.go generated vendored Normal file
View File

@ -0,0 +1,73 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcec
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"math/big"
)
// PrivateKey wraps an ecdsa.PrivateKey as a convenience mainly for signing
// things with the the private key without having to directly import the ecdsa
// package.
type PrivateKey ecdsa.PrivateKey
// PrivKeyFromBytes returns a private and public key for `curve' based on the
// private key passed as an argument as a byte slice.
func PrivKeyFromBytes(curve elliptic.Curve, pk []byte) (*PrivateKey,
*PublicKey) {
x, y := curve.ScalarBaseMult(pk)
priv := &ecdsa.PrivateKey{
PublicKey: ecdsa.PublicKey{
Curve: curve,
X: x,
Y: y,
},
D: new(big.Int).SetBytes(pk),
}
return (*PrivateKey)(priv), (*PublicKey)(&priv.PublicKey)
}
// NewPrivateKey is a wrapper for ecdsa.GenerateKey that returns a PrivateKey
// instead of the normal ecdsa.PrivateKey.
func NewPrivateKey(curve elliptic.Curve) (*PrivateKey, error) {
key, err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil {
return nil, err
}
return (*PrivateKey)(key), nil
}
// PubKey returns the PublicKey corresponding to this private key.
func (p *PrivateKey) PubKey() *PublicKey {
return (*PublicKey)(&p.PublicKey)
}
// ToECDSA returns the private key as a *ecdsa.PrivateKey.
func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey {
return (*ecdsa.PrivateKey)(p)
}
// Sign generates an ECDSA signature for the provided hash (which should be the result
// of hashing a larger message) using the private key. Produced signature
// is deterministic (same message and same key yield the same signature) and canonical
// in accordance with RFC6979 and BIP0062.
func (p *PrivateKey) Sign(hash []byte) (*Signature, error) {
return signRFC6979(p, hash)
}
// PrivKeyBytesLen defines the length in bytes of a serialized private key.
const PrivKeyBytesLen = 32
// Serialize returns the private key number d as a big-endian binary-encoded
// number, padded to a length of 32 bytes.
func (p *PrivateKey) Serialize() []byte {
b := make([]byte, 0, PrivKeyBytesLen)
return paddedAppend(PrivKeyBytesLen, b, p.ToECDSA().D.Bytes())
}

192
vendor/github.com/btcsuite/btcd/btcec/pubkey.go generated vendored Normal file
View File

@ -0,0 +1,192 @@
// Copyright (c) 2013-2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcec
import (
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
)
// These constants define the lengths of serialized public keys.
const (
PubKeyBytesLenCompressed = 33
PubKeyBytesLenUncompressed = 65
PubKeyBytesLenHybrid = 65
)
func isOdd(a *big.Int) bool {
return a.Bit(0) == 1
}
// decompressPoint decompresses a point on the given curve given the X point and
// the solution to use.
func decompressPoint(curve *KoblitzCurve, x *big.Int, ybit bool) (*big.Int, error) {
// TODO: This will probably only work for secp256k1 due to
// optimizations.
// Y = +-sqrt(x^3 + B)
x3 := new(big.Int).Mul(x, x)
x3.Mul(x3, x)
x3.Add(x3, curve.Params().B)
x3.Mod(x3, curve.Params().P)
// Now calculate sqrt mod p of x^3 + B
// This code used to do a full sqrt based on tonelli/shanks,
// but this was replaced by the algorithms referenced in
// https://bitcointalk.org/index.php?topic=162805.msg1712294#msg1712294
y := new(big.Int).Exp(x3, curve.QPlus1Div4(), curve.Params().P)
if ybit != isOdd(y) {
y.Sub(curve.Params().P, y)
}
// Check that y is a square root of x^3 + B.
y2 := new(big.Int).Mul(y, y)
y2.Mod(y2, curve.Params().P)
if y2.Cmp(x3) != 0 {
return nil, fmt.Errorf("invalid square root")
}
// Verify that y-coord has expected parity.
if ybit != isOdd(y) {
return nil, fmt.Errorf("ybit doesn't match oddness")
}
return y, nil
}
const (
pubkeyCompressed byte = 0x2 // y_bit + x coord
pubkeyUncompressed byte = 0x4 // x coord + y coord
pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord
)
// IsCompressedPubKey returns true the the passed serialized public key has
// been encoded in compressed format, and false otherwise.
func IsCompressedPubKey(pubKey []byte) bool {
// The public key is only compressed if it is the correct length and
// the format (first byte) is one of the compressed pubkey values.
return len(pubKey) == PubKeyBytesLenCompressed &&
(pubKey[0]&^byte(0x1) == pubkeyCompressed)
}
// ParsePubKey parses a public key for a koblitz curve from a bytestring into a
// ecdsa.Publickey, verifying that it is valid. It supports compressed,
// uncompressed and hybrid signature formats.
func ParsePubKey(pubKeyStr []byte, curve *KoblitzCurve) (key *PublicKey, err error) {
pubkey := PublicKey{}
pubkey.Curve = curve
if len(pubKeyStr) == 0 {
return nil, errors.New("pubkey string is empty")
}
format := pubKeyStr[0]
ybit := (format & 0x1) == 0x1
format &= ^byte(0x1)
switch len(pubKeyStr) {
case PubKeyBytesLenUncompressed:
if format != pubkeyUncompressed && format != pubkeyHybrid {
return nil, fmt.Errorf("invalid magic in pubkey str: "+
"%d", pubKeyStr[0])
}
pubkey.X = new(big.Int).SetBytes(pubKeyStr[1:33])
pubkey.Y = new(big.Int).SetBytes(pubKeyStr[33:])
// hybrid keys have extra information, make use of it.
if format == pubkeyHybrid && ybit != isOdd(pubkey.Y) {
return nil, fmt.Errorf("ybit doesn't match oddness")
}
case PubKeyBytesLenCompressed:
// format is 0x2 | solution, <X coordinate>
// solution determines which solution of the curve we use.
/// y^2 = x^3 + Curve.B
if format != pubkeyCompressed {
return nil, fmt.Errorf("invalid magic in compressed "+
"pubkey string: %d", pubKeyStr[0])
}
pubkey.X = new(big.Int).SetBytes(pubKeyStr[1:33])
pubkey.Y, err = decompressPoint(curve, pubkey.X, ybit)
if err != nil {
return nil, err
}
default: // wrong!
return nil, fmt.Errorf("invalid pub key length %d",
len(pubKeyStr))
}
if pubkey.X.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey X parameter is >= to P")
}
if pubkey.Y.Cmp(pubkey.Curve.Params().P) >= 0 {
return nil, fmt.Errorf("pubkey Y parameter is >= to P")
}
if !pubkey.Curve.IsOnCurve(pubkey.X, pubkey.Y) {
return nil, fmt.Errorf("pubkey isn't on secp256k1 curve")
}
return &pubkey, nil
}
// PublicKey is an ecdsa.PublicKey with additional functions to
// serialize in uncompressed, compressed, and hybrid formats.
type PublicKey ecdsa.PublicKey
// ToECDSA returns the public key as a *ecdsa.PublicKey.
func (p *PublicKey) ToECDSA() *ecdsa.PublicKey {
return (*ecdsa.PublicKey)(p)
}
// SerializeUncompressed serializes a public key in a 65-byte uncompressed
// format.
func (p *PublicKey) SerializeUncompressed() []byte {
b := make([]byte, 0, PubKeyBytesLenUncompressed)
b = append(b, pubkeyUncompressed)
b = paddedAppend(32, b, p.X.Bytes())
return paddedAppend(32, b, p.Y.Bytes())
}
// SerializeCompressed serializes a public key in a 33-byte compressed format.
func (p *PublicKey) SerializeCompressed() []byte {
b := make([]byte, 0, PubKeyBytesLenCompressed)
format := pubkeyCompressed
if isOdd(p.Y) {
format |= 0x1
}
b = append(b, format)
return paddedAppend(32, b, p.X.Bytes())
}
// SerializeHybrid serializes a public key in a 65-byte hybrid format.
func (p *PublicKey) SerializeHybrid() []byte {
b := make([]byte, 0, PubKeyBytesLenHybrid)
format := pubkeyHybrid
if isOdd(p.Y) {
format |= 0x1
}
b = append(b, format)
b = paddedAppend(32, b, p.X.Bytes())
return paddedAppend(32, b, p.Y.Bytes())
}
// IsEqual compares this PublicKey instance to the one passed, returning true if
// both PublicKeys are equivalent. A PublicKey is equivalent to another, if they
// both have the same X and Y coordinate.
func (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool {
return p.X.Cmp(otherPubKey.X) == 0 &&
p.Y.Cmp(otherPubKey.Y) == 0
}
// paddedAppend appends the src byte slice to dst, returning the new slice.
// If the length of the source is smaller than the passed size, leading zero
// bytes are appended to the dst slice before appending src.
func paddedAppend(size uint, dst, src []byte) []byte {
for i := 0; i < int(size)-len(src); i++ {
dst = append(dst, 0)
}
return append(dst, src...)
}

10
vendor/github.com/btcsuite/btcd/btcec/secp256k1.go generated vendored Normal file

File diff suppressed because one or more lines are too long

540
vendor/github.com/btcsuite/btcd/btcec/signature.go generated vendored Normal file
View File

@ -0,0 +1,540 @@
// Copyright (c) 2013-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcec
import (
"bytes"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/hmac"
"crypto/sha256"
"errors"
"fmt"
"hash"
"math/big"
)
// Errors returned by canonicalPadding.
var (
errNegativeValue = errors.New("value may be interpreted as negative")
errExcessivelyPaddedValue = errors.New("value is excessively padded")
)
// Signature is a type representing an ecdsa signature.
type Signature struct {
R *big.Int
S *big.Int
}
var (
// Used in RFC6979 implementation when testing the nonce for correctness
one = big.NewInt(1)
// oneInitializer is used to fill a byte slice with byte 0x01. It is provided
// here to avoid the need to create it multiple times.
oneInitializer = []byte{0x01}
)
// Serialize returns the ECDSA signature in the more strict DER format. Note
// that the serialized bytes returned do not include the appended hash type
// used in Bitcoin signature scripts.
//
// encoding/asn1 is broken so we hand roll this output:
//
// 0x30 <length> 0x02 <length r> r 0x02 <length s> s
func (sig *Signature) Serialize() []byte {
// low 'S' malleability breaker
sigS := sig.S
if sigS.Cmp(S256().halfOrder) == 1 {
sigS = new(big.Int).Sub(S256().N, sigS)
}
// Ensure the encoded bytes for the r and s values are canonical and
// thus suitable for DER encoding.
rb := canonicalizeInt(sig.R)
sb := canonicalizeInt(sigS)
// total length of returned signature is 1 byte for each magic and
// length (6 total), plus lengths of r and s
length := 6 + len(rb) + len(sb)
b := make([]byte, length)
b[0] = 0x30
b[1] = byte(length - 2)
b[2] = 0x02
b[3] = byte(len(rb))
offset := copy(b[4:], rb) + 4
b[offset] = 0x02
b[offset+1] = byte(len(sb))
copy(b[offset+2:], sb)
return b
}
// Verify calls ecdsa.Verify to verify the signature of hash using the public
// key. It returns true if the signature is valid, false otherwise.
func (sig *Signature) Verify(hash []byte, pubKey *PublicKey) bool {
return ecdsa.Verify(pubKey.ToECDSA(), hash, sig.R, sig.S)
}
// IsEqual compares this Signature instance to the one passed, returning true
// if both Signatures are equivalent. A signature is equivalent to another, if
// they both have the same scalar value for R and S.
func (sig *Signature) IsEqual(otherSig *Signature) bool {
return sig.R.Cmp(otherSig.R) == 0 &&
sig.S.Cmp(otherSig.S) == 0
}
// minSigLen is the minimum length of a DER encoded signature and is
// when both R and S are 1 byte each.
// 0x30 + <1-byte> + 0x02 + 0x01 + <byte> + 0x2 + 0x01 + <byte>
const minSigLen = 8
func parseSig(sigStr []byte, curve elliptic.Curve, der bool) (*Signature, error) {
// Originally this code used encoding/asn1 in order to parse the
// signature, but a number of problems were found with this approach.
// Despite the fact that signatures are stored as DER, the difference
// between go's idea of a bignum (and that they have sign) doesn't agree
// with the openssl one (where they do not). The above is true as of
// Go 1.1. In the end it was simpler to rewrite the code to explicitly
// understand the format which is this:
// 0x30 <length of whole message> <0x02> <length of R> <R> 0x2
// <length of S> <S>.
signature := &Signature{}
if len(sigStr) < minSigLen {
return nil, errors.New("malformed signature: too short")
}
// 0x30
index := 0
if sigStr[index] != 0x30 {
return nil, errors.New("malformed signature: no header magic")
}
index++
// length of remaining message
siglen := sigStr[index]
index++
// siglen should be less than the entire message and greater than
// the minimal message size.
if int(siglen+2) > len(sigStr) || int(siglen+2) < minSigLen {
return nil, errors.New("malformed signature: bad length")
}
// trim the slice we're working on so we only look at what matters.
sigStr = sigStr[:siglen+2]
// 0x02
if sigStr[index] != 0x02 {
return nil,
errors.New("malformed signature: no 1st int marker")
}
index++
// Length of signature R.
rLen := int(sigStr[index])
// must be positive, must be able to fit in another 0x2, <len> <s>
// hence the -3. We assume that the length must be at least one byte.
index++
if rLen <= 0 || rLen > len(sigStr)-index-3 {
return nil, errors.New("malformed signature: bogus R length")
}
// Then R itself.
rBytes := sigStr[index : index+rLen]
if der {
switch err := canonicalPadding(rBytes); err {
case errNegativeValue:
return nil, errors.New("signature R is negative")
case errExcessivelyPaddedValue:
return nil, errors.New("signature R is excessively padded")
}
}
signature.R = new(big.Int).SetBytes(rBytes)
index += rLen
// 0x02. length already checked in previous if.
if sigStr[index] != 0x02 {
return nil, errors.New("malformed signature: no 2nd int marker")
}
index++
// Length of signature S.
sLen := int(sigStr[index])
index++
// S should be the rest of the string.
if sLen <= 0 || sLen > len(sigStr)-index {
return nil, errors.New("malformed signature: bogus S length")
}
// Then S itself.
sBytes := sigStr[index : index+sLen]
if der {
switch err := canonicalPadding(sBytes); err {
case errNegativeValue:
return nil, errors.New("signature S is negative")
case errExcessivelyPaddedValue:
return nil, errors.New("signature S is excessively padded")
}
}
signature.S = new(big.Int).SetBytes(sBytes)
index += sLen
// sanity check length parsing
if index != len(sigStr) {
return nil, fmt.Errorf("malformed signature: bad final length %v != %v",
index, len(sigStr))
}
// Verify also checks this, but we can be more sure that we parsed
// correctly if we verify here too.
// FWIW the ecdsa spec states that R and S must be | 1, N - 1 |
// but crypto/ecdsa only checks for Sign != 0. Mirror that.
if signature.R.Sign() != 1 {
return nil, errors.New("signature R isn't 1 or more")
}
if signature.S.Sign() != 1 {
return nil, errors.New("signature S isn't 1 or more")
}
if signature.R.Cmp(curve.Params().N) >= 0 {
return nil, errors.New("signature R is >= curve.N")
}
if signature.S.Cmp(curve.Params().N) >= 0 {
return nil, errors.New("signature S is >= curve.N")
}
return signature, nil
}
// ParseSignature parses a signature in BER format for the curve type `curve'
// into a Signature type, perfoming some basic sanity checks. If parsing
// according to the more strict DER format is needed, use ParseDERSignature.
func ParseSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) {
return parseSig(sigStr, curve, false)
}
// ParseDERSignature parses a signature in DER format for the curve type
// `curve` into a Signature type. If parsing according to the less strict
// BER format is needed, use ParseSignature.
func ParseDERSignature(sigStr []byte, curve elliptic.Curve) (*Signature, error) {
return parseSig(sigStr, curve, true)
}
// canonicalizeInt returns the bytes for the passed big integer adjusted as
// necessary to ensure that a big-endian encoded integer can't possibly be
// misinterpreted as a negative number. This can happen when the most
// significant bit is set, so it is padded by a leading zero byte in this case.
// Also, the returned bytes will have at least a single byte when the passed
// value is 0. This is required for DER encoding.
func canonicalizeInt(val *big.Int) []byte {
b := val.Bytes()
if len(b) == 0 {
b = []byte{0x00}
}
if b[0]&0x80 != 0 {
paddedBytes := make([]byte, len(b)+1)
copy(paddedBytes[1:], b)
b = paddedBytes
}
return b
}
// canonicalPadding checks whether a big-endian encoded integer could
// possibly be misinterpreted as a negative number (even though OpenSSL
// treats all numbers as unsigned), or if there is any unnecessary
// leading zero padding.
func canonicalPadding(b []byte) error {
switch {
case b[0]&0x80 == 0x80:
return errNegativeValue
case len(b) > 1 && b[0] == 0x00 && b[1]&0x80 != 0x80:
return errExcessivelyPaddedValue
default:
return nil
}
}
// hashToInt converts a hash value to an integer. There is some disagreement
// about how this is done. [NSA] suggests that this is done in the obvious
// manner, but [SECG] truncates the hash to the bit-length of the curve order
// first. We follow [SECG] because that's what OpenSSL does. Additionally,
// OpenSSL right shifts excess bits from the number if the hash is too large
// and we mirror that too.
// This is borrowed from crypto/ecdsa.
func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
orderBits := c.Params().N.BitLen()
orderBytes := (orderBits + 7) / 8
if len(hash) > orderBytes {
hash = hash[:orderBytes]
}
ret := new(big.Int).SetBytes(hash)
excess := len(hash)*8 - orderBits
if excess > 0 {
ret.Rsh(ret, uint(excess))
}
return ret
}
// recoverKeyFromSignature recovers a public key from the signature "sig" on the
// given message hash "msg". Based on the algorithm found in section 5.1.5 of
// SEC 1 Ver 2.0, page 47-48 (53 and 54 in the pdf). This performs the details
// in the inner loop in Step 1. The counter provided is actually the j parameter
// of the loop * 2 - on the first iteration of j we do the R case, else the -R
// case in step 1.6. This counter is used in the bitcoin compressed signature
// format and thus we match bitcoind's behaviour here.
func recoverKeyFromSignature(curve *KoblitzCurve, sig *Signature, msg []byte,
iter int, doChecks bool) (*PublicKey, error) {
// 1.1 x = (n * i) + r
Rx := new(big.Int).Mul(curve.Params().N,
new(big.Int).SetInt64(int64(iter/2)))
Rx.Add(Rx, sig.R)
if Rx.Cmp(curve.Params().P) != -1 {
return nil, errors.New("calculated Rx is larger than curve P")
}
// convert 02<Rx> to point R. (step 1.2 and 1.3). If we are on an odd
// iteration then 1.6 will be done with -R, so we calculate the other
// term when uncompressing the point.
Ry, err := decompressPoint(curve, Rx, iter%2 == 1)
if err != nil {
return nil, err
}
// 1.4 Check n*R is point at infinity
if doChecks {
nRx, nRy := curve.ScalarMult(Rx, Ry, curve.Params().N.Bytes())
if nRx.Sign() != 0 || nRy.Sign() != 0 {
return nil, errors.New("n*R does not equal the point at infinity")
}
}
// 1.5 calculate e from message using the same algorithm as ecdsa
// signature calculation.
e := hashToInt(msg, curve)
// Step 1.6.1:
// We calculate the two terms sR and eG separately multiplied by the
// inverse of r (from the signature). We then add them to calculate
// Q = r^-1(sR-eG)
invr := new(big.Int).ModInverse(sig.R, curve.Params().N)
// first term.
invrS := new(big.Int).Mul(invr, sig.S)
invrS.Mod(invrS, curve.Params().N)
sRx, sRy := curve.ScalarMult(Rx, Ry, invrS.Bytes())
// second term.
e.Neg(e)
e.Mod(e, curve.Params().N)
e.Mul(e, invr)
e.Mod(e, curve.Params().N)
minuseGx, minuseGy := curve.ScalarBaseMult(e.Bytes())
// TODO: this would be faster if we did a mult and add in one
// step to prevent the jacobian conversion back and forth.
Qx, Qy := curve.Add(sRx, sRy, minuseGx, minuseGy)
return &PublicKey{
Curve: curve,
X: Qx,
Y: Qy,
}, nil
}
// SignCompact produces a compact signature of the data in hash with the given
// private key on the given koblitz curve. The isCompressed parameter should
// be used to detail if the given signature should reference a compressed
// public key or not. If successful the bytes of the compact signature will be
// returned in the format:
// <(byte of 27+public key solution)+4 if compressed >< padded bytes for signature R><padded bytes for signature S>
// where the R and S parameters are padde up to the bitlengh of the curve.
func SignCompact(curve *KoblitzCurve, key *PrivateKey,
hash []byte, isCompressedKey bool) ([]byte, error) {
sig, err := key.Sign(hash)
if err != nil {
return nil, err
}
// bitcoind checks the bit length of R and S here. The ecdsa signature
// algorithm returns R and S mod N therefore they will be the bitsize of
// the curve, and thus correctly sized.
for i := 0; i < (curve.H+1)*2; i++ {
pk, err := recoverKeyFromSignature(curve, sig, hash, i, true)
if err == nil && pk.X.Cmp(key.X) == 0 && pk.Y.Cmp(key.Y) == 0 {
result := make([]byte, 1, 2*curve.byteSize+1)
result[0] = 27 + byte(i)
if isCompressedKey {
result[0] += 4
}
// Not sure this needs rounding but safer to do so.
curvelen := (curve.BitSize + 7) / 8
// Pad R and S to curvelen if needed.
bytelen := (sig.R.BitLen() + 7) / 8
if bytelen < curvelen {
result = append(result,
make([]byte, curvelen-bytelen)...)
}
result = append(result, sig.R.Bytes()...)
bytelen = (sig.S.BitLen() + 7) / 8
if bytelen < curvelen {
result = append(result,
make([]byte, curvelen-bytelen)...)
}
result = append(result, sig.S.Bytes()...)
return result, nil
}
}
return nil, errors.New("no valid solution for pubkey found")
}
// RecoverCompact verifies the compact signature "signature" of "hash" for the
// Koblitz curve in "curve". If the signature matches then the recovered public
// key will be returned as well as a boolen if the original key was compressed
// or not, else an error will be returned.
func RecoverCompact(curve *KoblitzCurve, signature,
hash []byte) (*PublicKey, bool, error) {
bitlen := (curve.BitSize + 7) / 8
if len(signature) != 1+bitlen*2 {
return nil, false, errors.New("invalid compact signature size")
}
iteration := int((signature[0] - 27) & ^byte(4))
// format is <header byte><bitlen R><bitlen S>
sig := &Signature{
R: new(big.Int).SetBytes(signature[1 : bitlen+1]),
S: new(big.Int).SetBytes(signature[bitlen+1:]),
}
// The iteration used here was encoded
key, err := recoverKeyFromSignature(curve, sig, hash, iteration, false)
if err != nil {
return nil, false, err
}
return key, ((signature[0] - 27) & 4) == 4, nil
}
// signRFC6979 generates a deterministic ECDSA signature according to RFC 6979 and BIP 62.
func signRFC6979(privateKey *PrivateKey, hash []byte) (*Signature, error) {
privkey := privateKey.ToECDSA()
N := S256().N
halfOrder := S256().halfOrder
k := nonceRFC6979(privkey.D, hash)
inv := new(big.Int).ModInverse(k, N)
r, _ := privkey.Curve.ScalarBaseMult(k.Bytes())
r.Mod(r, N)
if r.Sign() == 0 {
return nil, errors.New("calculated R is zero")
}
e := hashToInt(hash, privkey.Curve)
s := new(big.Int).Mul(privkey.D, r)
s.Add(s, e)
s.Mul(s, inv)
s.Mod(s, N)
if s.Cmp(halfOrder) == 1 {
s.Sub(N, s)
}
if s.Sign() == 0 {
return nil, errors.New("calculated S is zero")
}
return &Signature{R: r, S: s}, nil
}
// nonceRFC6979 generates an ECDSA nonce (`k`) deterministically according to RFC 6979.
// It takes a 32-byte hash as an input and returns 32-byte nonce to be used in ECDSA algorithm.
func nonceRFC6979(privkey *big.Int, hash []byte) *big.Int {
curve := S256()
q := curve.Params().N
x := privkey
alg := sha256.New
qlen := q.BitLen()
holen := alg().Size()
rolen := (qlen + 7) >> 3
bx := append(int2octets(x, rolen), bits2octets(hash, curve, rolen)...)
// Step B
v := bytes.Repeat(oneInitializer, holen)
// Step C (Go zeroes the all allocated memory)
k := make([]byte, holen)
// Step D
k = mac(alg, k, append(append(v, 0x00), bx...))
// Step E
v = mac(alg, k, v)
// Step F
k = mac(alg, k, append(append(v, 0x01), bx...))
// Step G
v = mac(alg, k, v)
// Step H
for {
// Step H1
var t []byte
// Step H2
for len(t)*8 < qlen {
v = mac(alg, k, v)
t = append(t, v...)
}
// Step H3
secret := hashToInt(t, curve)
if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 {
return secret
}
k = mac(alg, k, append(v, 0x00))
v = mac(alg, k, v)
}
}
// mac returns an HMAC of the given key and message.
func mac(alg func() hash.Hash, k, m []byte) []byte {
h := hmac.New(alg, k)
h.Write(m)
return h.Sum(nil)
}
// https://tools.ietf.org/html/rfc6979#section-2.3.3
func int2octets(v *big.Int, rolen int) []byte {
out := v.Bytes()
// left pad with zeros if it's too short
if len(out) < rolen {
out2 := make([]byte, rolen)
copy(out2[rolen-len(out):], out)
return out2
}
// drop most significant bytes if it's too long
if len(out) > rolen {
out2 := make([]byte, rolen)
copy(out2, out[len(out)-rolen:])
return out2
}
return out
}
// https://tools.ietf.org/html/rfc6979#section-2.3.4
func bits2octets(in []byte, curve elliptic.Curve, rolen int) []byte {
z1 := hashToInt(in, curve)
z2 := new(big.Int).Sub(z1, curve.Params().N)
if z2.Sign() < 0 {
return int2octets(z1, rolen)
}
return int2octets(z2, rolen)
}

16
vendor/github.com/btcsuite/btcd/btcjson/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,16 @@
# This is the list of people who have contributed code to the repository.
#
# Names should be added to this file only after verifying that the individual
# or the individual's organization has agreed to the LICENSE.
#
# Names should be added to this file like so:
# Name <email address>
John C. Vernaleo <jcv@conformal.com>
Dave Collins <davec@conformal.com>
Owain G. Ainsworth <oga@conformal.com>
David Hill <dhill@conformal.com>
Josh Rickmar <jrick@conformal.com>
Andreas Metsälä <andreas.metsala@gmail.com>
Francis Lam <flam@alum.mit.edu>
Geert-Johan Riemer <geertjohan.riemer@gmail.com>

70
vendor/github.com/btcsuite/btcd/btcjson/README.md generated vendored Normal file
View File

@ -0,0 +1,70 @@
btcjson
=======
[![Build Status](https://travis-ci.org/btcsuite/btcd.png?branch=master)](https://travis-ci.org/btcsuite/btcd)
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcd/btcjson)
Package btcjson implements concrete types for marshalling to and from the
bitcoin JSON-RPC API. A comprehensive suite of tests is provided to ensure
proper functionality.
Although this package was primarily written for the btcsuite, it has
intentionally been designed so it can be used as a standalone package for any
projects needing to marshal to and from bitcoin JSON-RPC requests and responses.
Note that although it's possible to use this package directly to implement an
RPC client, it is not recommended since it is only intended as an infrastructure
package. Instead, RPC clients should use the
[btcrpcclient](https://github.com/btcsuite/btcrpcclient) package which provides
a full blown RPC client with many features such as automatic connection
management, websocket support, automatic notification re-registration on
reconnect, and conversion from the raw underlying RPC types (strings, floats,
ints, etc) to higher-level types with many nice and useful properties.
## Installation and Updating
```bash
$ go get -u github.com/btcsuite/btcd/btcjson
```
## Examples
* [Marshal Command](http://godoc.org/github.com/btcsuite/btcd/btcjson#example-MarshalCmd)
Demonstrates how to create and marshal a command into a JSON-RPC request.
* [Unmarshal Command](http://godoc.org/github.com/btcsuite/btcd/btcjson#example-UnmarshalCmd)
Demonstrates how to unmarshal a JSON-RPC request and then unmarshal the
concrete request into a concrete command.
* [Marshal Response](http://godoc.org/github.com/btcsuite/btcd/btcjson#example-MarshalResponse)
Demonstrates how to marshal a JSON-RPC response.
* [Unmarshal Response](http://godoc.org/github.com/btcsuite/btcd/btcjson#example-package--UnmarshalResponse)
Demonstrates how to unmarshal a JSON-RPC response and then unmarshal the
result field in the response to a concrete type.
## GPG Verification Key
All official release tags are signed by Conformal so users can ensure the code
has not been tampered with and is coming from the btcsuite developers. To
verify the signature perform the following:
- Download the public key from the Conformal website at
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
- Import the public key into your GPG keyring:
```bash
gpg --import GIT-GPG-KEY-conformal.txt
```
- Verify the release tag with the following command where `TAG_NAME` is a
placeholder for the specific tag:
```bash
git tag -v TAG_NAME
```
## License
Package btcjson is licensed under the [copyfree](http://copyfree.org) ISC
License.

138
vendor/github.com/btcsuite/btcd/btcjson/btcdextcmds.go generated vendored Normal file
View File

@ -0,0 +1,138 @@
// Copyright (c) 2014-2016 The btcsuite developers
// Copyright (c) 2015-2016 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// NOTE: This file is intended to house the RPC commands that are supported by
// a chain server with btcd extensions.
package btcjson
// NodeSubCmd defines the type used in the addnode JSON-RPC command for the
// sub command field.
type NodeSubCmd string
const (
// NConnect indicates the specified host that should be connected to.
NConnect NodeSubCmd = "connect"
// NRemove indicates the specified peer that should be removed as a
// persistent peer.
NRemove NodeSubCmd = "remove"
// NDisconnect indicates the specified peer should be disonnected.
NDisconnect NodeSubCmd = "disconnect"
)
// NodeCmd defines the dropnode JSON-RPC command.
type NodeCmd struct {
SubCmd NodeSubCmd `jsonrpcusage:"\"connect|remove|disconnect\""`
Target string
ConnectSubCmd *string `jsonrpcusage:"\"perm|temp\""`
}
// NewNodeCmd returns a new instance which can be used to issue a `node`
// JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewNodeCmd(subCmd NodeSubCmd, target string, connectSubCmd *string) *NodeCmd {
return &NodeCmd{
SubCmd: subCmd,
Target: target,
ConnectSubCmd: connectSubCmd,
}
}
// DebugLevelCmd defines the debuglevel JSON-RPC command. This command is not a
// standard Bitcoin command. It is an extension for btcd.
type DebugLevelCmd struct {
LevelSpec string
}
// NewDebugLevelCmd returns a new DebugLevelCmd which can be used to issue a
// debuglevel JSON-RPC command. This command is not a standard Bitcoin command.
// It is an extension for btcd.
func NewDebugLevelCmd(levelSpec string) *DebugLevelCmd {
return &DebugLevelCmd{
LevelSpec: levelSpec,
}
}
// GenerateCmd defines the generate JSON-RPC command.
type GenerateCmd struct {
NumBlocks uint32
}
// NewGenerateCmd returns a new instance which can be used to issue a generate
// JSON-RPC command.
func NewGenerateCmd(numBlocks uint32) *GenerateCmd {
return &GenerateCmd{
NumBlocks: numBlocks,
}
}
// GetBestBlockCmd defines the getbestblock JSON-RPC command.
type GetBestBlockCmd struct{}
// NewGetBestBlockCmd returns a new instance which can be used to issue a
// getbestblock JSON-RPC command.
func NewGetBestBlockCmd() *GetBestBlockCmd {
return &GetBestBlockCmd{}
}
// GetCurrentNetCmd defines the getcurrentnet JSON-RPC command.
type GetCurrentNetCmd struct{}
// NewGetCurrentNetCmd returns a new instance which can be used to issue a
// getcurrentnet JSON-RPC command.
func NewGetCurrentNetCmd() *GetCurrentNetCmd {
return &GetCurrentNetCmd{}
}
// GetHeadersCmd defines the getheaders JSON-RPC command.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrd/dcrjson.
type GetHeadersCmd struct {
BlockLocators []string `json:"blocklocators"`
HashStop string `json:"hashstop"`
}
// NewGetHeadersCmd returns a new instance which can be used to issue a
// getheaders JSON-RPC command.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrd/dcrjson.
func NewGetHeadersCmd(blockLocators []string, hashStop string) *GetHeadersCmd {
return &GetHeadersCmd{
BlockLocators: blockLocators,
HashStop: hashStop,
}
}
// VersionCmd defines the version JSON-RPC command.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrd/dcrjson.
type VersionCmd struct{}
// NewVersionCmd returns a new instance which can be used to issue a JSON-RPC
// version command.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrd/dcrjson.
func NewVersionCmd() *VersionCmd { return new(VersionCmd) }
func init() {
// No special flags for commands in this file.
flags := UsageFlag(0)
MustRegisterCmd("debuglevel", (*DebugLevelCmd)(nil), flags)
MustRegisterCmd("node", (*NodeCmd)(nil), flags)
MustRegisterCmd("generate", (*GenerateCmd)(nil), flags)
MustRegisterCmd("getbestblock", (*GetBestBlockCmd)(nil), flags)
MustRegisterCmd("getcurrentnet", (*GetCurrentNetCmd)(nil), flags)
MustRegisterCmd("getheaders", (*GetHeadersCmd)(nil), flags)
MustRegisterCmd("version", (*VersionCmd)(nil), flags)
}

View File

@ -0,0 +1,20 @@
// Copyright (c) 2016-2017 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
// VersionResult models objects included in the version response. In the actual
// result, these objects are keyed by the program or API name.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrd/dcrjson.
type VersionResult struct {
VersionString string `json:"versionstring"`
Major uint32 `json:"major"`
Minor uint32 `json:"minor"`
Patch uint32 `json:"patch"`
Prerelease string `json:"prerelease"`
BuildMetadata string `json:"buildmetadata"`
}

View File

@ -0,0 +1,106 @@
// Copyright (c) 2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// NOTE: This file is intended to house the RPC commands that are supported by
// a wallet server with btcwallet extensions.
package btcjson
// CreateNewAccountCmd defines the createnewaccount JSON-RPC command.
type CreateNewAccountCmd struct {
Account string
}
// NewCreateNewAccountCmd returns a new instance which can be used to issue a
// createnewaccount JSON-RPC command.
func NewCreateNewAccountCmd(account string) *CreateNewAccountCmd {
return &CreateNewAccountCmd{
Account: account,
}
}
// DumpWalletCmd defines the dumpwallet JSON-RPC command.
type DumpWalletCmd struct {
Filename string
}
// NewDumpWalletCmd returns a new instance which can be used to issue a
// dumpwallet JSON-RPC command.
func NewDumpWalletCmd(filename string) *DumpWalletCmd {
return &DumpWalletCmd{
Filename: filename,
}
}
// ImportAddressCmd defines the importaddress JSON-RPC command.
type ImportAddressCmd struct {
Address string
Account string
Rescan *bool `jsonrpcdefault:"true"`
}
// NewImportAddressCmd returns a new instance which can be used to issue an
// importaddress JSON-RPC command.
func NewImportAddressCmd(address string, account string, rescan *bool) *ImportAddressCmd {
return &ImportAddressCmd{
Address: address,
Account: account,
Rescan: rescan,
}
}
// ImportPubKeyCmd defines the importpubkey JSON-RPC command.
type ImportPubKeyCmd struct {
PubKey string
Rescan *bool `jsonrpcdefault:"true"`
}
// NewImportPubKeyCmd returns a new instance which can be used to issue an
// importpubkey JSON-RPC command.
func NewImportPubKeyCmd(pubKey string, rescan *bool) *ImportPubKeyCmd {
return &ImportPubKeyCmd{
PubKey: pubKey,
Rescan: rescan,
}
}
// ImportWalletCmd defines the importwallet JSON-RPC command.
type ImportWalletCmd struct {
Filename string
}
// NewImportWalletCmd returns a new instance which can be used to issue a
// importwallet JSON-RPC command.
func NewImportWalletCmd(filename string) *ImportWalletCmd {
return &ImportWalletCmd{
Filename: filename,
}
}
// RenameAccountCmd defines the renameaccount JSON-RPC command.
type RenameAccountCmd struct {
OldAccount string
NewAccount string
}
// NewRenameAccountCmd returns a new instance which can be used to issue a
// renameaccount JSON-RPC command.
func NewRenameAccountCmd(oldAccount, newAccount string) *RenameAccountCmd {
return &RenameAccountCmd{
OldAccount: oldAccount,
NewAccount: newAccount,
}
}
func init() {
// The commands in this file are only usable with a wallet server.
flags := UFWalletOnly
MustRegisterCmd("createnewaccount", (*CreateNewAccountCmd)(nil), flags)
MustRegisterCmd("dumpwallet", (*DumpWalletCmd)(nil), flags)
MustRegisterCmd("importaddress", (*ImportAddressCmd)(nil), flags)
MustRegisterCmd("importpubkey", (*ImportPubKeyCmd)(nil), flags)
MustRegisterCmd("importwallet", (*ImportWalletCmd)(nil), flags)
MustRegisterCmd("renameaccount", (*RenameAccountCmd)(nil), flags)
}

828
vendor/github.com/btcsuite/btcd/btcjson/chainsvrcmds.go generated vendored Normal file
View File

@ -0,0 +1,828 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// NOTE: This file is intended to house the RPC commands that are supported by
// a chain server.
package btcjson
import (
"encoding/json"
"fmt"
"github.com/btcsuite/btcd/wire"
)
// AddNodeSubCmd defines the type used in the addnode JSON-RPC command for the
// sub command field.
type AddNodeSubCmd string
const (
// ANAdd indicates the specified host should be added as a persistent
// peer.
ANAdd AddNodeSubCmd = "add"
// ANRemove indicates the specified peer should be removed.
ANRemove AddNodeSubCmd = "remove"
// ANOneTry indicates the specified host should try to connect once,
// but it should not be made persistent.
ANOneTry AddNodeSubCmd = "onetry"
)
// AddNodeCmd defines the addnode JSON-RPC command.
type AddNodeCmd struct {
Addr string
SubCmd AddNodeSubCmd `jsonrpcusage:"\"add|remove|onetry\""`
}
// NewAddNodeCmd returns a new instance which can be used to issue an addnode
// JSON-RPC command.
func NewAddNodeCmd(addr string, subCmd AddNodeSubCmd) *AddNodeCmd {
return &AddNodeCmd{
Addr: addr,
SubCmd: subCmd,
}
}
// TransactionInput represents the inputs to a transaction. Specifically a
// transaction hash and output number pair.
type TransactionInput struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
}
// CreateRawTransactionCmd defines the createrawtransaction JSON-RPC command.
type CreateRawTransactionCmd struct {
Inputs []TransactionInput
Amounts map[string]float64 `jsonrpcusage:"{\"address\":amount,...}"` // In BTC
LockTime *int64
}
// NewCreateRawTransactionCmd returns a new instance which can be used to issue
// a createrawtransaction JSON-RPC command.
//
// Amounts are in BTC.
func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[string]float64,
lockTime *int64) *CreateRawTransactionCmd {
return &CreateRawTransactionCmd{
Inputs: inputs,
Amounts: amounts,
LockTime: lockTime,
}
}
// DecodeRawTransactionCmd defines the decoderawtransaction JSON-RPC command.
type DecodeRawTransactionCmd struct {
HexTx string
}
// NewDecodeRawTransactionCmd returns a new instance which can be used to issue
// a decoderawtransaction JSON-RPC command.
func NewDecodeRawTransactionCmd(hexTx string) *DecodeRawTransactionCmd {
return &DecodeRawTransactionCmd{
HexTx: hexTx,
}
}
// DecodeScriptCmd defines the decodescript JSON-RPC command.
type DecodeScriptCmd struct {
HexScript string
}
// NewDecodeScriptCmd returns a new instance which can be used to issue a
// decodescript JSON-RPC command.
func NewDecodeScriptCmd(hexScript string) *DecodeScriptCmd {
return &DecodeScriptCmd{
HexScript: hexScript,
}
}
// GetAddedNodeInfoCmd defines the getaddednodeinfo JSON-RPC command.
type GetAddedNodeInfoCmd struct {
DNS bool
Node *string
}
// NewGetAddedNodeInfoCmd returns a new instance which can be used to issue a
// getaddednodeinfo JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetAddedNodeInfoCmd(dns bool, node *string) *GetAddedNodeInfoCmd {
return &GetAddedNodeInfoCmd{
DNS: dns,
Node: node,
}
}
// GetBestBlockHashCmd defines the getbestblockhash JSON-RPC command.
type GetBestBlockHashCmd struct{}
// NewGetBestBlockHashCmd returns a new instance which can be used to issue a
// getbestblockhash JSON-RPC command.
func NewGetBestBlockHashCmd() *GetBestBlockHashCmd {
return &GetBestBlockHashCmd{}
}
// GetBlockCmd defines the getblock JSON-RPC command.
type GetBlockCmd struct {
Hash string
Verbose *bool `jsonrpcdefault:"true"`
VerboseTx *bool `jsonrpcdefault:"false"`
}
// NewGetBlockCmd returns a new instance which can be used to issue a getblock
// JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetBlockCmd(hash string, verbose, verboseTx *bool) *GetBlockCmd {
return &GetBlockCmd{
Hash: hash,
Verbose: verbose,
VerboseTx: verboseTx,
}
}
// GetBlockChainInfoCmd defines the getblockchaininfo JSON-RPC command.
type GetBlockChainInfoCmd struct{}
// NewGetBlockChainInfoCmd returns a new instance which can be used to issue a
// getblockchaininfo JSON-RPC command.
func NewGetBlockChainInfoCmd() *GetBlockChainInfoCmd {
return &GetBlockChainInfoCmd{}
}
// GetBlockCountCmd defines the getblockcount JSON-RPC command.
type GetBlockCountCmd struct{}
// NewGetBlockCountCmd returns a new instance which can be used to issue a
// getblockcount JSON-RPC command.
func NewGetBlockCountCmd() *GetBlockCountCmd {
return &GetBlockCountCmd{}
}
// GetBlockHashCmd defines the getblockhash JSON-RPC command.
type GetBlockHashCmd struct {
Index int64
}
// NewGetBlockHashCmd returns a new instance which can be used to issue a
// getblockhash JSON-RPC command.
func NewGetBlockHashCmd(index int64) *GetBlockHashCmd {
return &GetBlockHashCmd{
Index: index,
}
}
// GetBlockHeaderCmd defines the getblockheader JSON-RPC command.
type GetBlockHeaderCmd struct {
Hash string
Verbose *bool `jsonrpcdefault:"true"`
}
// NewGetBlockHeaderCmd returns a new instance which can be used to issue a
// getblockheader JSON-RPC command.
func NewGetBlockHeaderCmd(hash string, verbose *bool) *GetBlockHeaderCmd {
return &GetBlockHeaderCmd{
Hash: hash,
Verbose: verbose,
}
}
// TemplateRequest is a request object as defined in BIP22
// (https://en.bitcoin.it/wiki/BIP_0022), it is optionally provided as an
// pointer argument to GetBlockTemplateCmd.
type TemplateRequest struct {
Mode string `json:"mode,omitempty"`
Capabilities []string `json:"capabilities,omitempty"`
// Optional long polling.
LongPollID string `json:"longpollid,omitempty"`
// Optional template tweaking. SigOpLimit and SizeLimit can be int64
// or bool.
SigOpLimit interface{} `json:"sigoplimit,omitempty"`
SizeLimit interface{} `json:"sizelimit,omitempty"`
MaxVersion uint32 `json:"maxversion,omitempty"`
// Basic pool extension from BIP 0023.
Target string `json:"target,omitempty"`
// Block proposal from BIP 0023. Data is only provided when Mode is
// "proposal".
Data string `json:"data,omitempty"`
WorkID string `json:"workid,omitempty"`
}
// convertTemplateRequestField potentially converts the provided value as
// needed.
func convertTemplateRequestField(fieldName string, iface interface{}) (interface{}, error) {
switch val := iface.(type) {
case nil:
return nil, nil
case bool:
return val, nil
case float64:
if val == float64(int64(val)) {
return int64(val), nil
}
}
str := fmt.Sprintf("the %s field must be unspecified, a boolean, or "+
"a 64-bit integer", fieldName)
return nil, makeError(ErrInvalidType, str)
}
// UnmarshalJSON provides a custom Unmarshal method for TemplateRequest. This
// is necessary because the SigOpLimit and SizeLimit fields can only be specific
// types.
func (t *TemplateRequest) UnmarshalJSON(data []byte) error {
type templateRequest TemplateRequest
request := (*templateRequest)(t)
if err := json.Unmarshal(data, &request); err != nil {
return err
}
// The SigOpLimit field can only be nil, bool, or int64.
val, err := convertTemplateRequestField("sigoplimit", request.SigOpLimit)
if err != nil {
return err
}
request.SigOpLimit = val
// The SizeLimit field can only be nil, bool, or int64.
val, err = convertTemplateRequestField("sizelimit", request.SizeLimit)
if err != nil {
return err
}
request.SizeLimit = val
return nil
}
// GetBlockTemplateCmd defines the getblocktemplate JSON-RPC command.
type GetBlockTemplateCmd struct {
Request *TemplateRequest
}
// NewGetBlockTemplateCmd returns a new instance which can be used to issue a
// getblocktemplate JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetBlockTemplateCmd(request *TemplateRequest) *GetBlockTemplateCmd {
return &GetBlockTemplateCmd{
Request: request,
}
}
// GetCFilterCmd defines the getcfilter JSON-RPC command.
type GetCFilterCmd struct {
Hash string
FilterType wire.FilterType
}
// NewGetCFilterCmd returns a new instance which can be used to issue a
// getcfilter JSON-RPC command.
func NewGetCFilterCmd(hash string, filterType wire.FilterType) *GetCFilterCmd {
return &GetCFilterCmd{
Hash: hash,
FilterType: filterType,
}
}
// GetCFilterHeaderCmd defines the getcfilterheader JSON-RPC command.
type GetCFilterHeaderCmd struct {
Hash string
FilterType wire.FilterType
}
// NewGetCFilterHeaderCmd returns a new instance which can be used to issue a
// getcfilterheader JSON-RPC command.
func NewGetCFilterHeaderCmd(hash string,
filterType wire.FilterType) *GetCFilterHeaderCmd {
return &GetCFilterHeaderCmd{
Hash: hash,
FilterType: filterType,
}
}
// GetChainTipsCmd defines the getchaintips JSON-RPC command.
type GetChainTipsCmd struct{}
// NewGetChainTipsCmd returns a new instance which can be used to issue a
// getchaintips JSON-RPC command.
func NewGetChainTipsCmd() *GetChainTipsCmd {
return &GetChainTipsCmd{}
}
// GetConnectionCountCmd defines the getconnectioncount JSON-RPC command.
type GetConnectionCountCmd struct{}
// NewGetConnectionCountCmd returns a new instance which can be used to issue a
// getconnectioncount JSON-RPC command.
func NewGetConnectionCountCmd() *GetConnectionCountCmd {
return &GetConnectionCountCmd{}
}
// GetDifficultyCmd defines the getdifficulty JSON-RPC command.
type GetDifficultyCmd struct{}
// NewGetDifficultyCmd returns a new instance which can be used to issue a
// getdifficulty JSON-RPC command.
func NewGetDifficultyCmd() *GetDifficultyCmd {
return &GetDifficultyCmd{}
}
// GetGenerateCmd defines the getgenerate JSON-RPC command.
type GetGenerateCmd struct{}
// NewGetGenerateCmd returns a new instance which can be used to issue a
// getgenerate JSON-RPC command.
func NewGetGenerateCmd() *GetGenerateCmd {
return &GetGenerateCmd{}
}
// GetHashesPerSecCmd defines the gethashespersec JSON-RPC command.
type GetHashesPerSecCmd struct{}
// NewGetHashesPerSecCmd returns a new instance which can be used to issue a
// gethashespersec JSON-RPC command.
func NewGetHashesPerSecCmd() *GetHashesPerSecCmd {
return &GetHashesPerSecCmd{}
}
// GetInfoCmd defines the getinfo JSON-RPC command.
type GetInfoCmd struct{}
// NewGetInfoCmd returns a new instance which can be used to issue a
// getinfo JSON-RPC command.
func NewGetInfoCmd() *GetInfoCmd {
return &GetInfoCmd{}
}
// GetMempoolEntryCmd defines the getmempoolentry JSON-RPC command.
type GetMempoolEntryCmd struct {
TxID string
}
// NewGetMempoolEntryCmd returns a new instance which can be used to issue a
// getmempoolentry JSON-RPC command.
func NewGetMempoolEntryCmd(txHash string) *GetMempoolEntryCmd {
return &GetMempoolEntryCmd{
TxID: txHash,
}
}
// GetMempoolInfoCmd defines the getmempoolinfo JSON-RPC command.
type GetMempoolInfoCmd struct{}
// NewGetMempoolInfoCmd returns a new instance which can be used to issue a
// getmempool JSON-RPC command.
func NewGetMempoolInfoCmd() *GetMempoolInfoCmd {
return &GetMempoolInfoCmd{}
}
// GetMiningInfoCmd defines the getmininginfo JSON-RPC command.
type GetMiningInfoCmd struct{}
// NewGetMiningInfoCmd returns a new instance which can be used to issue a
// getmininginfo JSON-RPC command.
func NewGetMiningInfoCmd() *GetMiningInfoCmd {
return &GetMiningInfoCmd{}
}
// GetNetworkInfoCmd defines the getnetworkinfo JSON-RPC command.
type GetNetworkInfoCmd struct{}
// NewGetNetworkInfoCmd returns a new instance which can be used to issue a
// getnetworkinfo JSON-RPC command.
func NewGetNetworkInfoCmd() *GetNetworkInfoCmd {
return &GetNetworkInfoCmd{}
}
// GetNetTotalsCmd defines the getnettotals JSON-RPC command.
type GetNetTotalsCmd struct{}
// NewGetNetTotalsCmd returns a new instance which can be used to issue a
// getnettotals JSON-RPC command.
func NewGetNetTotalsCmd() *GetNetTotalsCmd {
return &GetNetTotalsCmd{}
}
// GetNetworkHashPSCmd defines the getnetworkhashps JSON-RPC command.
type GetNetworkHashPSCmd struct {
Blocks *int `jsonrpcdefault:"120"`
Height *int `jsonrpcdefault:"-1"`
}
// NewGetNetworkHashPSCmd returns a new instance which can be used to issue a
// getnetworkhashps JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetNetworkHashPSCmd(numBlocks, height *int) *GetNetworkHashPSCmd {
return &GetNetworkHashPSCmd{
Blocks: numBlocks,
Height: height,
}
}
// GetPeerInfoCmd defines the getpeerinfo JSON-RPC command.
type GetPeerInfoCmd struct{}
// NewGetPeerInfoCmd returns a new instance which can be used to issue a getpeer
// JSON-RPC command.
func NewGetPeerInfoCmd() *GetPeerInfoCmd {
return &GetPeerInfoCmd{}
}
// GetRawMempoolCmd defines the getmempool JSON-RPC command.
type GetRawMempoolCmd struct {
Verbose *bool `jsonrpcdefault:"false"`
}
// NewGetRawMempoolCmd returns a new instance which can be used to issue a
// getrawmempool JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetRawMempoolCmd(verbose *bool) *GetRawMempoolCmd {
return &GetRawMempoolCmd{
Verbose: verbose,
}
}
// GetRawTransactionCmd defines the getrawtransaction JSON-RPC command.
//
// NOTE: This field is an int versus a bool to remain compatible with Bitcoin
// Core even though it really should be a bool.
type GetRawTransactionCmd struct {
Txid string
Verbose *int `jsonrpcdefault:"0"`
}
// NewGetRawTransactionCmd returns a new instance which can be used to issue a
// getrawtransaction JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetRawTransactionCmd(txHash string, verbose *int) *GetRawTransactionCmd {
return &GetRawTransactionCmd{
Txid: txHash,
Verbose: verbose,
}
}
// GetTxOutCmd defines the gettxout JSON-RPC command.
type GetTxOutCmd struct {
Txid string
Vout uint32
IncludeMempool *bool `jsonrpcdefault:"true"`
}
// NewGetTxOutCmd returns a new instance which can be used to issue a gettxout
// JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetTxOutCmd(txHash string, vout uint32, includeMempool *bool) *GetTxOutCmd {
return &GetTxOutCmd{
Txid: txHash,
Vout: vout,
IncludeMempool: includeMempool,
}
}
// GetTxOutProofCmd defines the gettxoutproof JSON-RPC command.
type GetTxOutProofCmd struct {
TxIDs []string
BlockHash *string
}
// NewGetTxOutProofCmd returns a new instance which can be used to issue a
// gettxoutproof JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetTxOutProofCmd(txIDs []string, blockHash *string) *GetTxOutProofCmd {
return &GetTxOutProofCmd{
TxIDs: txIDs,
BlockHash: blockHash,
}
}
// GetTxOutSetInfoCmd defines the gettxoutsetinfo JSON-RPC command.
type GetTxOutSetInfoCmd struct{}
// NewGetTxOutSetInfoCmd returns a new instance which can be used to issue a
// gettxoutsetinfo JSON-RPC command.
func NewGetTxOutSetInfoCmd() *GetTxOutSetInfoCmd {
return &GetTxOutSetInfoCmd{}
}
// GetWorkCmd defines the getwork JSON-RPC command.
type GetWorkCmd struct {
Data *string
}
// NewGetWorkCmd returns a new instance which can be used to issue a getwork
// JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetWorkCmd(data *string) *GetWorkCmd {
return &GetWorkCmd{
Data: data,
}
}
// HelpCmd defines the help JSON-RPC command.
type HelpCmd struct {
Command *string
}
// NewHelpCmd returns a new instance which can be used to issue a help JSON-RPC
// command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewHelpCmd(command *string) *HelpCmd {
return &HelpCmd{
Command: command,
}
}
// InvalidateBlockCmd defines the invalidateblock JSON-RPC command.
type InvalidateBlockCmd struct {
BlockHash string
}
// NewInvalidateBlockCmd returns a new instance which can be used to issue a
// invalidateblock JSON-RPC command.
func NewInvalidateBlockCmd(blockHash string) *InvalidateBlockCmd {
return &InvalidateBlockCmd{
BlockHash: blockHash,
}
}
// PingCmd defines the ping JSON-RPC command.
type PingCmd struct{}
// NewPingCmd returns a new instance which can be used to issue a ping JSON-RPC
// command.
func NewPingCmd() *PingCmd {
return &PingCmd{}
}
// PreciousBlockCmd defines the preciousblock JSON-RPC command.
type PreciousBlockCmd struct {
BlockHash string
}
// NewPreciousBlockCmd returns a new instance which can be used to issue a
// preciousblock JSON-RPC command.
func NewPreciousBlockCmd(blockHash string) *PreciousBlockCmd {
return &PreciousBlockCmd{
BlockHash: blockHash,
}
}
// ReconsiderBlockCmd defines the reconsiderblock JSON-RPC command.
type ReconsiderBlockCmd struct {
BlockHash string
}
// NewReconsiderBlockCmd returns a new instance which can be used to issue a
// reconsiderblock JSON-RPC command.
func NewReconsiderBlockCmd(blockHash string) *ReconsiderBlockCmd {
return &ReconsiderBlockCmd{
BlockHash: blockHash,
}
}
// SearchRawTransactionsCmd defines the searchrawtransactions JSON-RPC command.
type SearchRawTransactionsCmd struct {
Address string
Verbose *int `jsonrpcdefault:"1"`
Skip *int `jsonrpcdefault:"0"`
Count *int `jsonrpcdefault:"100"`
VinExtra *int `jsonrpcdefault:"0"`
Reverse *bool `jsonrpcdefault:"false"`
FilterAddrs *[]string
}
// NewSearchRawTransactionsCmd returns a new instance which can be used to issue a
// sendrawtransaction JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSearchRawTransactionsCmd(address string, verbose, skip, count *int, vinExtra *int, reverse *bool, filterAddrs *[]string) *SearchRawTransactionsCmd {
return &SearchRawTransactionsCmd{
Address: address,
Verbose: verbose,
Skip: skip,
Count: count,
VinExtra: vinExtra,
Reverse: reverse,
FilterAddrs: filterAddrs,
}
}
// SendRawTransactionCmd defines the sendrawtransaction JSON-RPC command.
type SendRawTransactionCmd struct {
HexTx string
AllowHighFees *bool `jsonrpcdefault:"false"`
}
// NewSendRawTransactionCmd returns a new instance which can be used to issue a
// sendrawtransaction JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSendRawTransactionCmd(hexTx string, allowHighFees *bool) *SendRawTransactionCmd {
return &SendRawTransactionCmd{
HexTx: hexTx,
AllowHighFees: allowHighFees,
}
}
// SetGenerateCmd defines the setgenerate JSON-RPC command.
type SetGenerateCmd struct {
Generate bool
GenProcLimit *int `jsonrpcdefault:"-1"`
}
// NewSetGenerateCmd returns a new instance which can be used to issue a
// setgenerate JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSetGenerateCmd(generate bool, genProcLimit *int) *SetGenerateCmd {
return &SetGenerateCmd{
Generate: generate,
GenProcLimit: genProcLimit,
}
}
// StopCmd defines the stop JSON-RPC command.
type StopCmd struct{}
// NewStopCmd returns a new instance which can be used to issue a stop JSON-RPC
// command.
func NewStopCmd() *StopCmd {
return &StopCmd{}
}
// SubmitBlockOptions represents the optional options struct provided with a
// SubmitBlockCmd command.
type SubmitBlockOptions struct {
// must be provided if server provided a workid with template.
WorkID string `json:"workid,omitempty"`
}
// SubmitBlockCmd defines the submitblock JSON-RPC command.
type SubmitBlockCmd struct {
HexBlock string
Options *SubmitBlockOptions
}
// NewSubmitBlockCmd returns a new instance which can be used to issue a
// submitblock JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSubmitBlockCmd(hexBlock string, options *SubmitBlockOptions) *SubmitBlockCmd {
return &SubmitBlockCmd{
HexBlock: hexBlock,
Options: options,
}
}
// UptimeCmd defines the uptime JSON-RPC command.
type UptimeCmd struct{}
// NewUptimeCmd returns a new instance which can be used to issue an uptime JSON-RPC command.
func NewUptimeCmd() *UptimeCmd {
return &UptimeCmd{}
}
// ValidateAddressCmd defines the validateaddress JSON-RPC command.
type ValidateAddressCmd struct {
Address string
}
// NewValidateAddressCmd returns a new instance which can be used to issue a
// validateaddress JSON-RPC command.
func NewValidateAddressCmd(address string) *ValidateAddressCmd {
return &ValidateAddressCmd{
Address: address,
}
}
// VerifyChainCmd defines the verifychain JSON-RPC command.
type VerifyChainCmd struct {
CheckLevel *int32 `jsonrpcdefault:"3"`
CheckDepth *int32 `jsonrpcdefault:"288"` // 0 = all
}
// NewVerifyChainCmd returns a new instance which can be used to issue a
// verifychain JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewVerifyChainCmd(checkLevel, checkDepth *int32) *VerifyChainCmd {
return &VerifyChainCmd{
CheckLevel: checkLevel,
CheckDepth: checkDepth,
}
}
// VerifyMessageCmd defines the verifymessage JSON-RPC command.
type VerifyMessageCmd struct {
Address string
Signature string
Message string
}
// NewVerifyMessageCmd returns a new instance which can be used to issue a
// verifymessage JSON-RPC command.
func NewVerifyMessageCmd(address, signature, message string) *VerifyMessageCmd {
return &VerifyMessageCmd{
Address: address,
Signature: signature,
Message: message,
}
}
// VerifyTxOutProofCmd defines the verifytxoutproof JSON-RPC command.
type VerifyTxOutProofCmd struct {
Proof string
}
// NewVerifyTxOutProofCmd returns a new instance which can be used to issue a
// verifytxoutproof JSON-RPC command.
func NewVerifyTxOutProofCmd(proof string) *VerifyTxOutProofCmd {
return &VerifyTxOutProofCmd{
Proof: proof,
}
}
func init() {
// No special flags for commands in this file.
flags := UsageFlag(0)
MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags)
MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags)
MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags)
MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags)
MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags)
MustRegisterCmd("getbestblockhash", (*GetBestBlockHashCmd)(nil), flags)
MustRegisterCmd("getblock", (*GetBlockCmd)(nil), flags)
MustRegisterCmd("getblockchaininfo", (*GetBlockChainInfoCmd)(nil), flags)
MustRegisterCmd("getblockcount", (*GetBlockCountCmd)(nil), flags)
MustRegisterCmd("getblockhash", (*GetBlockHashCmd)(nil), flags)
MustRegisterCmd("getblockheader", (*GetBlockHeaderCmd)(nil), flags)
MustRegisterCmd("getblocktemplate", (*GetBlockTemplateCmd)(nil), flags)
MustRegisterCmd("getcfilter", (*GetCFilterCmd)(nil), flags)
MustRegisterCmd("getcfilterheader", (*GetCFilterHeaderCmd)(nil), flags)
MustRegisterCmd("getchaintips", (*GetChainTipsCmd)(nil), flags)
MustRegisterCmd("getconnectioncount", (*GetConnectionCountCmd)(nil), flags)
MustRegisterCmd("getdifficulty", (*GetDifficultyCmd)(nil), flags)
MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags)
MustRegisterCmd("gethashespersec", (*GetHashesPerSecCmd)(nil), flags)
MustRegisterCmd("getinfo", (*GetInfoCmd)(nil), flags)
MustRegisterCmd("getmempoolentry", (*GetMempoolEntryCmd)(nil), flags)
MustRegisterCmd("getmempoolinfo", (*GetMempoolInfoCmd)(nil), flags)
MustRegisterCmd("getmininginfo", (*GetMiningInfoCmd)(nil), flags)
MustRegisterCmd("getnetworkinfo", (*GetNetworkInfoCmd)(nil), flags)
MustRegisterCmd("getnettotals", (*GetNetTotalsCmd)(nil), flags)
MustRegisterCmd("getnetworkhashps", (*GetNetworkHashPSCmd)(nil), flags)
MustRegisterCmd("getpeerinfo", (*GetPeerInfoCmd)(nil), flags)
MustRegisterCmd("getrawmempool", (*GetRawMempoolCmd)(nil), flags)
MustRegisterCmd("getrawtransaction", (*GetRawTransactionCmd)(nil), flags)
MustRegisterCmd("gettxout", (*GetTxOutCmd)(nil), flags)
MustRegisterCmd("gettxoutproof", (*GetTxOutProofCmd)(nil), flags)
MustRegisterCmd("gettxoutsetinfo", (*GetTxOutSetInfoCmd)(nil), flags)
MustRegisterCmd("getwork", (*GetWorkCmd)(nil), flags)
MustRegisterCmd("help", (*HelpCmd)(nil), flags)
MustRegisterCmd("invalidateblock", (*InvalidateBlockCmd)(nil), flags)
MustRegisterCmd("ping", (*PingCmd)(nil), flags)
MustRegisterCmd("preciousblock", (*PreciousBlockCmd)(nil), flags)
MustRegisterCmd("reconsiderblock", (*ReconsiderBlockCmd)(nil), flags)
MustRegisterCmd("searchrawtransactions", (*SearchRawTransactionsCmd)(nil), flags)
MustRegisterCmd("sendrawtransaction", (*SendRawTransactionCmd)(nil), flags)
MustRegisterCmd("setgenerate", (*SetGenerateCmd)(nil), flags)
MustRegisterCmd("stop", (*StopCmd)(nil), flags)
MustRegisterCmd("submitblock", (*SubmitBlockCmd)(nil), flags)
MustRegisterCmd("uptime", (*UptimeCmd)(nil), flags)
MustRegisterCmd("validateaddress", (*ValidateAddressCmd)(nil), flags)
MustRegisterCmd("verifychain", (*VerifyChainCmd)(nil), flags)
MustRegisterCmd("verifymessage", (*VerifyMessageCmd)(nil), flags)
MustRegisterCmd("verifytxoutproof", (*VerifyTxOutProofCmd)(nil), flags)
}

View File

@ -0,0 +1,550 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import "encoding/json"
// GetBlockHeaderVerboseResult models the data from the getblockheader command when
// the verbose flag is set. When the verbose flag is not set, getblockheader
// returns a hex-encoded string.
type GetBlockHeaderVerboseResult struct {
Hash string `json:"hash"`
Confirmations int64 `json:"confirmations"`
Height int32 `json:"height"`
Version int32 `json:"version"`
VersionHex string `json:"versionHex"`
MerkleRoot string `json:"merkleroot"`
Time int64 `json:"time"`
Nonce uint64 `json:"nonce"`
Bits string `json:"bits"`
Difficulty float64 `json:"difficulty"`
PreviousHash string `json:"previousblockhash,omitempty"`
NextHash string `json:"nextblockhash,omitempty"`
}
// GetBlockVerboseResult models the data from the getblock command when the
// verbose flag is set. When the verbose flag is not set, getblock returns a
// hex-encoded string.
type GetBlockVerboseResult struct {
Hash string `json:"hash"`
Confirmations int64 `json:"confirmations"`
StrippedSize int32 `json:"strippedsize"`
Size int32 `json:"size"`
Weight int32 `json:"weight"`
Height int64 `json:"height"`
Version int32 `json:"version"`
VersionHex string `json:"versionHex"`
MerkleRoot string `json:"merkleroot"`
Tx []string `json:"tx,omitempty"`
RawTx []TxRawResult `json:"rawtx,omitempty"`
Time int64 `json:"time"`
Nonce uint32 `json:"nonce"`
Bits string `json:"bits"`
Difficulty float64 `json:"difficulty"`
PreviousHash string `json:"previousblockhash"`
NextHash string `json:"nextblockhash,omitempty"`
}
// CreateMultiSigResult models the data returned from the createmultisig
// command.
type CreateMultiSigResult struct {
Address string `json:"address"`
RedeemScript string `json:"redeemScript"`
}
// DecodeScriptResult models the data returned from the decodescript command.
type DecodeScriptResult struct {
Asm string `json:"asm"`
ReqSigs int32 `json:"reqSigs,omitempty"`
Type string `json:"type"`
Addresses []string `json:"addresses,omitempty"`
P2sh string `json:"p2sh,omitempty"`
}
// GetAddedNodeInfoResultAddr models the data of the addresses portion of the
// getaddednodeinfo command.
type GetAddedNodeInfoResultAddr struct {
Address string `json:"address"`
Connected string `json:"connected"`
}
// GetAddedNodeInfoResult models the data from the getaddednodeinfo command.
type GetAddedNodeInfoResult struct {
AddedNode string `json:"addednode"`
Connected *bool `json:"connected,omitempty"`
Addresses *[]GetAddedNodeInfoResultAddr `json:"addresses,omitempty"`
}
// SoftForkDescription describes the current state of a soft-fork which was
// deployed using a super-majority block signalling.
type SoftForkDescription struct {
ID string `json:"id"`
Version uint32 `json:"version"`
Reject struct {
Status bool `json:"status"`
} `json:"reject"`
}
// Bip9SoftForkDescription describes the current state of a defined BIP0009
// version bits soft-fork.
type Bip9SoftForkDescription struct {
Status string `json:"status"`
Bit uint8 `json:"bit"`
StartTime int64 `json:"startTime"`
Timeout int64 `json:"timeout"`
Since int32 `json:"since"`
}
// GetBlockChainInfoResult models the data returned from the getblockchaininfo
// command.
type GetBlockChainInfoResult struct {
Chain string `json:"chain"`
Blocks int32 `json:"blocks"`
Headers int32 `json:"headers"`
BestBlockHash string `json:"bestblockhash"`
Difficulty float64 `json:"difficulty"`
MedianTime int64 `json:"mediantime"`
VerificationProgress float64 `json:"verificationprogress,omitempty"`
Pruned bool `json:"pruned"`
PruneHeight int32 `json:"pruneheight,omitempty"`
ChainWork string `json:"chainwork,omitempty"`
SoftForks []*SoftForkDescription `json:"softforks"`
Bip9SoftForks map[string]*Bip9SoftForkDescription `json:"bip9_softforks"`
}
// GetBlockTemplateResultTx models the transactions field of the
// getblocktemplate command.
type GetBlockTemplateResultTx struct {
Data string `json:"data"`
Hash string `json:"hash"`
Depends []int64 `json:"depends"`
Fee int64 `json:"fee"`
SigOps int64 `json:"sigops"`
Weight int64 `json:"weight"`
}
// GetBlockTemplateResultAux models the coinbaseaux field of the
// getblocktemplate command.
type GetBlockTemplateResultAux struct {
Flags string `json:"flags"`
}
// GetBlockTemplateResult models the data returned from the getblocktemplate
// command.
type GetBlockTemplateResult struct {
// Base fields from BIP 0022. CoinbaseAux is optional. One of
// CoinbaseTxn or CoinbaseValue must be specified, but not both.
Bits string `json:"bits"`
CurTime int64 `json:"curtime"`
Height int64 `json:"height"`
PreviousHash string `json:"previousblockhash"`
SigOpLimit int64 `json:"sigoplimit,omitempty"`
SizeLimit int64 `json:"sizelimit,omitempty"`
WeightLimit int64 `json:"weightlimit,omitempty"`
Transactions []GetBlockTemplateResultTx `json:"transactions"`
Version int32 `json:"version"`
CoinbaseAux *GetBlockTemplateResultAux `json:"coinbaseaux,omitempty"`
CoinbaseTxn *GetBlockTemplateResultTx `json:"coinbasetxn,omitempty"`
CoinbaseValue *int64 `json:"coinbasevalue,omitempty"`
WorkID string `json:"workid,omitempty"`
// Witness commitment defined in BIP 0141.
DefaultWitnessCommitment string `json:"default_witness_commitment,omitempty"`
// Optional long polling from BIP 0022.
LongPollID string `json:"longpollid,omitempty"`
LongPollURI string `json:"longpolluri,omitempty"`
SubmitOld *bool `json:"submitold,omitempty"`
// Basic pool extension from BIP 0023.
Target string `json:"target,omitempty"`
Expires int64 `json:"expires,omitempty"`
// Mutations from BIP 0023.
MaxTime int64 `json:"maxtime,omitempty"`
MinTime int64 `json:"mintime,omitempty"`
Mutable []string `json:"mutable,omitempty"`
NonceRange string `json:"noncerange,omitempty"`
// Block proposal from BIP 0023.
Capabilities []string `json:"capabilities,omitempty"`
RejectReasion string `json:"reject-reason,omitempty"`
}
// GetMempoolEntryResult models the data returned from the getmempoolentry
// command.
type GetMempoolEntryResult struct {
Size int32 `json:"size"`
Fee float64 `json:"fee"`
ModifiedFee float64 `json:"modifiedfee"`
Time int64 `json:"time"`
Height int64 `json:"height"`
StartingPriority float64 `json:"startingpriority"`
CurrentPriority float64 `json:"currentpriority"`
DescendantCount int64 `json:"descendantcount"`
DescendantSize int64 `json:"descendantsize"`
DescendantFees float64 `json:"descendantfees"`
AncestorCount int64 `json:"ancestorcount"`
AncestorSize int64 `json:"ancestorsize"`
AncestorFees float64 `json:"ancestorfees"`
Depends []string `json:"depends"`
}
// GetMempoolInfoResult models the data returned from the getmempoolinfo
// command.
type GetMempoolInfoResult struct {
Size int64 `json:"size"`
Bytes int64 `json:"bytes"`
}
// NetworksResult models the networks data from the getnetworkinfo command.
type NetworksResult struct {
Name string `json:"name"`
Limited bool `json:"limited"`
Reachable bool `json:"reachable"`
Proxy string `json:"proxy"`
ProxyRandomizeCredentials bool `json:"proxy_randomize_credentials"`
}
// LocalAddressesResult models the localaddresses data from the getnetworkinfo
// command.
type LocalAddressesResult struct {
Address string `json:"address"`
Port uint16 `json:"port"`
Score int32 `json:"score"`
}
// GetNetworkInfoResult models the data returned from the getnetworkinfo
// command.
type GetNetworkInfoResult struct {
Version int32 `json:"version"`
SubVersion string `json:"subversion"`
ProtocolVersion int32 `json:"protocolversion"`
LocalServices string `json:"localservices"`
LocalRelay bool `json:"localrelay"`
TimeOffset int64 `json:"timeoffset"`
Connections int32 `json:"connections"`
NetworkActive bool `json:"networkactive"`
Networks []NetworksResult `json:"networks"`
RelayFee float64 `json:"relayfee"`
IncrementalFee float64 `json:"incrementalfee"`
LocalAddresses []LocalAddressesResult `json:"localaddresses"`
Warnings string `json:"warnings"`
}
// GetPeerInfoResult models the data returned from the getpeerinfo command.
type GetPeerInfoResult struct {
ID int32 `json:"id"`
Addr string `json:"addr"`
AddrLocal string `json:"addrlocal,omitempty"`
Services string `json:"services"`
RelayTxes bool `json:"relaytxes"`
LastSend int64 `json:"lastsend"`
LastRecv int64 `json:"lastrecv"`
BytesSent uint64 `json:"bytessent"`
BytesRecv uint64 `json:"bytesrecv"`
ConnTime int64 `json:"conntime"`
TimeOffset int64 `json:"timeoffset"`
PingTime float64 `json:"pingtime"`
PingWait float64 `json:"pingwait,omitempty"`
Version uint32 `json:"version"`
SubVer string `json:"subver"`
Inbound bool `json:"inbound"`
StartingHeight int32 `json:"startingheight"`
CurrentHeight int32 `json:"currentheight,omitempty"`
BanScore int32 `json:"banscore"`
FeeFilter int64 `json:"feefilter"`
SyncNode bool `json:"syncnode"`
}
// GetRawMempoolVerboseResult models the data returned from the getrawmempool
// command when the verbose flag is set. When the verbose flag is not set,
// getrawmempool returns an array of transaction hashes.
type GetRawMempoolVerboseResult struct {
Size int32 `json:"size"`
Vsize int32 `json:"vsize"`
Fee float64 `json:"fee"`
Time int64 `json:"time"`
Height int64 `json:"height"`
StartingPriority float64 `json:"startingpriority"`
CurrentPriority float64 `json:"currentpriority"`
Depends []string `json:"depends"`
}
// ScriptPubKeyResult models the scriptPubKey data of a tx script. It is
// defined separately since it is used by multiple commands.
type ScriptPubKeyResult struct {
Asm string `json:"asm"`
Hex string `json:"hex,omitempty"`
ReqSigs int32 `json:"reqSigs,omitempty"`
Type string `json:"type"`
Addresses []string `json:"addresses,omitempty"`
}
// GetTxOutResult models the data from the gettxout command.
type GetTxOutResult struct {
BestBlock string `json:"bestblock"`
Confirmations int64 `json:"confirmations"`
Value float64 `json:"value"`
ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"`
Coinbase bool `json:"coinbase"`
}
// GetNetTotalsResult models the data returned from the getnettotals command.
type GetNetTotalsResult struct {
TotalBytesRecv uint64 `json:"totalbytesrecv"`
TotalBytesSent uint64 `json:"totalbytessent"`
TimeMillis int64 `json:"timemillis"`
}
// ScriptSig models a signature script. It is defined separately since it only
// applies to non-coinbase. Therefore the field in the Vin structure needs
// to be a pointer.
type ScriptSig struct {
Asm string `json:"asm"`
Hex string `json:"hex"`
}
// Vin models parts of the tx data. It is defined separately since
// getrawtransaction, decoderawtransaction, and searchrawtransaction use the
// same structure.
type Vin struct {
Coinbase string `json:"coinbase"`
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Sequence uint32 `json:"sequence"`
Witness []string `json:"txinwitness"`
}
// IsCoinBase returns a bool to show if a Vin is a Coinbase one or not.
func (v *Vin) IsCoinBase() bool {
return len(v.Coinbase) > 0
}
// HasWitness returns a bool to show if a Vin has any witness data associated
// with it or not.
func (v *Vin) HasWitness() bool {
return len(v.Witness) > 0
}
// MarshalJSON provides a custom Marshal method for Vin.
func (v *Vin) MarshalJSON() ([]byte, error) {
if v.IsCoinBase() {
coinbaseStruct := struct {
Coinbase string `json:"coinbase"`
Sequence uint32 `json:"sequence"`
Witness []string `json:"witness,omitempty"`
}{
Coinbase: v.Coinbase,
Sequence: v.Sequence,
Witness: v.Witness,
}
return json.Marshal(coinbaseStruct)
}
if v.HasWitness() {
txStruct := struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Witness []string `json:"txinwitness"`
Sequence uint32 `json:"sequence"`
}{
Txid: v.Txid,
Vout: v.Vout,
ScriptSig: v.ScriptSig,
Witness: v.Witness,
Sequence: v.Sequence,
}
return json.Marshal(txStruct)
}
txStruct := struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Sequence uint32 `json:"sequence"`
}{
Txid: v.Txid,
Vout: v.Vout,
ScriptSig: v.ScriptSig,
Sequence: v.Sequence,
}
return json.Marshal(txStruct)
}
// PrevOut represents previous output for an input Vin.
type PrevOut struct {
Addresses []string `json:"addresses,omitempty"`
Value float64 `json:"value"`
}
// VinPrevOut is like Vin except it includes PrevOut. It is used by searchrawtransaction
type VinPrevOut struct {
Coinbase string `json:"coinbase"`
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Witness []string `json:"txinwitness"`
PrevOut *PrevOut `json:"prevOut"`
Sequence uint32 `json:"sequence"`
}
// IsCoinBase returns a bool to show if a Vin is a Coinbase one or not.
func (v *VinPrevOut) IsCoinBase() bool {
return len(v.Coinbase) > 0
}
// HasWitness returns a bool to show if a Vin has any witness data associated
// with it or not.
func (v *VinPrevOut) HasWitness() bool {
return len(v.Witness) > 0
}
// MarshalJSON provides a custom Marshal method for VinPrevOut.
func (v *VinPrevOut) MarshalJSON() ([]byte, error) {
if v.IsCoinBase() {
coinbaseStruct := struct {
Coinbase string `json:"coinbase"`
Sequence uint32 `json:"sequence"`
}{
Coinbase: v.Coinbase,
Sequence: v.Sequence,
}
return json.Marshal(coinbaseStruct)
}
if v.HasWitness() {
txStruct := struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
Witness []string `json:"txinwitness"`
PrevOut *PrevOut `json:"prevOut,omitempty"`
Sequence uint32 `json:"sequence"`
}{
Txid: v.Txid,
Vout: v.Vout,
ScriptSig: v.ScriptSig,
Witness: v.Witness,
PrevOut: v.PrevOut,
Sequence: v.Sequence,
}
return json.Marshal(txStruct)
}
txStruct := struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig *ScriptSig `json:"scriptSig"`
PrevOut *PrevOut `json:"prevOut,omitempty"`
Sequence uint32 `json:"sequence"`
}{
Txid: v.Txid,
Vout: v.Vout,
ScriptSig: v.ScriptSig,
PrevOut: v.PrevOut,
Sequence: v.Sequence,
}
return json.Marshal(txStruct)
}
// Vout models parts of the tx data. It is defined separately since both
// getrawtransaction and decoderawtransaction use the same structure.
type Vout struct {
Value float64 `json:"value"`
N uint32 `json:"n"`
ScriptPubKey ScriptPubKeyResult `json:"scriptPubKey"`
}
// GetMiningInfoResult models the data from the getmininginfo command.
type GetMiningInfoResult struct {
Blocks int64 `json:"blocks"`
CurrentBlockSize uint64 `json:"currentblocksize"`
CurrentBlockWeight uint64 `json:"currentblockweight"`
CurrentBlockTx uint64 `json:"currentblocktx"`
Difficulty float64 `json:"difficulty"`
Errors string `json:"errors"`
Generate bool `json:"generate"`
GenProcLimit int32 `json:"genproclimit"`
HashesPerSec int64 `json:"hashespersec"`
NetworkHashPS int64 `json:"networkhashps"`
PooledTx uint64 `json:"pooledtx"`
TestNet bool `json:"testnet"`
}
// GetWorkResult models the data from the getwork command.
type GetWorkResult struct {
Data string `json:"data"`
Hash1 string `json:"hash1"`
Midstate string `json:"midstate"`
Target string `json:"target"`
}
// InfoChainResult models the data returned by the chain server getinfo command.
type InfoChainResult struct {
Version int32 `json:"version"`
ProtocolVersion int32 `json:"protocolversion"`
Blocks int32 `json:"blocks"`
TimeOffset int64 `json:"timeoffset"`
Connections int32 `json:"connections"`
Proxy string `json:"proxy"`
Difficulty float64 `json:"difficulty"`
TestNet bool `json:"testnet"`
RelayFee float64 `json:"relayfee"`
Errors string `json:"errors"`
}
// TxRawResult models the data from the getrawtransaction command.
type TxRawResult struct {
Hex string `json:"hex"`
Txid string `json:"txid"`
Hash string `json:"hash,omitempty"`
Size int32 `json:"size,omitempty"`
Vsize int32 `json:"vsize,omitempty"`
Version int32 `json:"version"`
LockTime uint32 `json:"locktime"`
Vin []Vin `json:"vin"`
Vout []Vout `json:"vout"`
BlockHash string `json:"blockhash,omitempty"`
Confirmations uint64 `json:"confirmations,omitempty"`
Time int64 `json:"time,omitempty"`
Blocktime int64 `json:"blocktime,omitempty"`
}
// SearchRawTransactionsResult models the data from the searchrawtransaction
// command.
type SearchRawTransactionsResult struct {
Hex string `json:"hex,omitempty"`
Txid string `json:"txid"`
Hash string `json:"hash"`
Size string `json:"size"`
Vsize string `json:"vsize"`
Version int32 `json:"version"`
LockTime uint32 `json:"locktime"`
Vin []VinPrevOut `json:"vin"`
Vout []Vout `json:"vout"`
BlockHash string `json:"blockhash,omitempty"`
Confirmations uint64 `json:"confirmations,omitempty"`
Time int64 `json:"time,omitempty"`
Blocktime int64 `json:"blocktime,omitempty"`
}
// TxRawDecodeResult models the data from the decoderawtransaction command.
type TxRawDecodeResult struct {
Txid string `json:"txid"`
Version int32 `json:"version"`
Locktime uint32 `json:"locktime"`
Vin []Vin `json:"vin"`
Vout []Vout `json:"vout"`
}
// ValidateAddressChainResult models the data returned by the chain server
// validateaddress command.
type ValidateAddressChainResult struct {
IsValid bool `json:"isvalid"`
Address string `json:"address,omitempty"`
}

View File

@ -0,0 +1,241 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// NOTE: This file is intended to house the RPC commands that are supported by
// a chain server, but are only available via websockets.
package btcjson
// AuthenticateCmd defines the authenticate JSON-RPC command.
type AuthenticateCmd struct {
Username string
Passphrase string
}
// NewAuthenticateCmd returns a new instance which can be used to issue an
// authenticate JSON-RPC command.
func NewAuthenticateCmd(username, passphrase string) *AuthenticateCmd {
return &AuthenticateCmd{
Username: username,
Passphrase: passphrase,
}
}
// NotifyBlocksCmd defines the notifyblocks JSON-RPC command.
type NotifyBlocksCmd struct{}
// NewNotifyBlocksCmd returns a new instance which can be used to issue a
// notifyblocks JSON-RPC command.
func NewNotifyBlocksCmd() *NotifyBlocksCmd {
return &NotifyBlocksCmd{}
}
// StopNotifyBlocksCmd defines the stopnotifyblocks JSON-RPC command.
type StopNotifyBlocksCmd struct{}
// NewStopNotifyBlocksCmd returns a new instance which can be used to issue a
// stopnotifyblocks JSON-RPC command.
func NewStopNotifyBlocksCmd() *StopNotifyBlocksCmd {
return &StopNotifyBlocksCmd{}
}
// NotifyNewTransactionsCmd defines the notifynewtransactions JSON-RPC command.
type NotifyNewTransactionsCmd struct {
Verbose *bool `jsonrpcdefault:"false"`
}
// NewNotifyNewTransactionsCmd returns a new instance which can be used to issue
// a notifynewtransactions JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewNotifyNewTransactionsCmd(verbose *bool) *NotifyNewTransactionsCmd {
return &NotifyNewTransactionsCmd{
Verbose: verbose,
}
}
// SessionCmd defines the session JSON-RPC command.
type SessionCmd struct{}
// NewSessionCmd returns a new instance which can be used to issue a session
// JSON-RPC command.
func NewSessionCmd() *SessionCmd {
return &SessionCmd{}
}
// StopNotifyNewTransactionsCmd defines the stopnotifynewtransactions JSON-RPC command.
type StopNotifyNewTransactionsCmd struct{}
// NewStopNotifyNewTransactionsCmd returns a new instance which can be used to issue
// a stopnotifynewtransactions JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewStopNotifyNewTransactionsCmd() *StopNotifyNewTransactionsCmd {
return &StopNotifyNewTransactionsCmd{}
}
// NotifyReceivedCmd defines the notifyreceived JSON-RPC command.
//
// NOTE: Deprecated. Use LoadTxFilterCmd instead.
type NotifyReceivedCmd struct {
Addresses []string
}
// NewNotifyReceivedCmd returns a new instance which can be used to issue a
// notifyreceived JSON-RPC command.
//
// NOTE: Deprecated. Use NewLoadTxFilterCmd instead.
func NewNotifyReceivedCmd(addresses []string) *NotifyReceivedCmd {
return &NotifyReceivedCmd{
Addresses: addresses,
}
}
// OutPoint describes a transaction outpoint that will be marshalled to and
// from JSON.
type OutPoint struct {
Hash string `json:"hash"`
Index uint32 `json:"index"`
}
// LoadTxFilterCmd defines the loadtxfilter request parameters to load or
// reload a transaction filter.
//
// NOTE: This is a btcd extension ported from github.com/decred/dcrd/dcrjson
// and requires a websocket connection.
type LoadTxFilterCmd struct {
Reload bool
Addresses []string
OutPoints []OutPoint
}
// NewLoadTxFilterCmd returns a new instance which can be used to issue a
// loadtxfilter JSON-RPC command.
//
// NOTE: This is a btcd extension ported from github.com/decred/dcrd/dcrjson
// and requires a websocket connection.
func NewLoadTxFilterCmd(reload bool, addresses []string, outPoints []OutPoint) *LoadTxFilterCmd {
return &LoadTxFilterCmd{
Reload: reload,
Addresses: addresses,
OutPoints: outPoints,
}
}
// NotifySpentCmd defines the notifyspent JSON-RPC command.
//
// NOTE: Deprecated. Use LoadTxFilterCmd instead.
type NotifySpentCmd struct {
OutPoints []OutPoint
}
// NewNotifySpentCmd returns a new instance which can be used to issue a
// notifyspent JSON-RPC command.
//
// NOTE: Deprecated. Use NewLoadTxFilterCmd instead.
func NewNotifySpentCmd(outPoints []OutPoint) *NotifySpentCmd {
return &NotifySpentCmd{
OutPoints: outPoints,
}
}
// StopNotifyReceivedCmd defines the stopnotifyreceived JSON-RPC command.
//
// NOTE: Deprecated. Use LoadTxFilterCmd instead.
type StopNotifyReceivedCmd struct {
Addresses []string
}
// NewStopNotifyReceivedCmd returns a new instance which can be used to issue a
// stopnotifyreceived JSON-RPC command.
//
// NOTE: Deprecated. Use NewLoadTxFilterCmd instead.
func NewStopNotifyReceivedCmd(addresses []string) *StopNotifyReceivedCmd {
return &StopNotifyReceivedCmd{
Addresses: addresses,
}
}
// StopNotifySpentCmd defines the stopnotifyspent JSON-RPC command.
//
// NOTE: Deprecated. Use LoadTxFilterCmd instead.
type StopNotifySpentCmd struct {
OutPoints []OutPoint
}
// NewStopNotifySpentCmd returns a new instance which can be used to issue a
// stopnotifyspent JSON-RPC command.
//
// NOTE: Deprecated. Use NewLoadTxFilterCmd instead.
func NewStopNotifySpentCmd(outPoints []OutPoint) *StopNotifySpentCmd {
return &StopNotifySpentCmd{
OutPoints: outPoints,
}
}
// RescanCmd defines the rescan JSON-RPC command.
//
// NOTE: Deprecated. Use RescanBlocksCmd instead.
type RescanCmd struct {
BeginBlock string
Addresses []string
OutPoints []OutPoint
EndBlock *string
}
// NewRescanCmd returns a new instance which can be used to issue a rescan
// JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
//
// NOTE: Deprecated. Use NewRescanBlocksCmd instead.
func NewRescanCmd(beginBlock string, addresses []string, outPoints []OutPoint, endBlock *string) *RescanCmd {
return &RescanCmd{
BeginBlock: beginBlock,
Addresses: addresses,
OutPoints: outPoints,
EndBlock: endBlock,
}
}
// RescanBlocksCmd defines the rescan JSON-RPC command.
//
// NOTE: This is a btcd extension ported from github.com/decred/dcrd/dcrjson
// and requires a websocket connection.
type RescanBlocksCmd struct {
// Block hashes as a string array.
BlockHashes []string
}
// NewRescanBlocksCmd returns a new instance which can be used to issue a rescan
// JSON-RPC command.
//
// NOTE: This is a btcd extension ported from github.com/decred/dcrd/dcrjson
// and requires a websocket connection.
func NewRescanBlocksCmd(blockHashes []string) *RescanBlocksCmd {
return &RescanBlocksCmd{BlockHashes: blockHashes}
}
func init() {
// The commands in this file are only usable by websockets.
flags := UFWebsocketOnly
MustRegisterCmd("authenticate", (*AuthenticateCmd)(nil), flags)
MustRegisterCmd("loadtxfilter", (*LoadTxFilterCmd)(nil), flags)
MustRegisterCmd("notifyblocks", (*NotifyBlocksCmd)(nil), flags)
MustRegisterCmd("notifynewtransactions", (*NotifyNewTransactionsCmd)(nil), flags)
MustRegisterCmd("notifyreceived", (*NotifyReceivedCmd)(nil), flags)
MustRegisterCmd("notifyspent", (*NotifySpentCmd)(nil), flags)
MustRegisterCmd("session", (*SessionCmd)(nil), flags)
MustRegisterCmd("stopnotifyblocks", (*StopNotifyBlocksCmd)(nil), flags)
MustRegisterCmd("stopnotifynewtransactions", (*StopNotifyNewTransactionsCmd)(nil), flags)
MustRegisterCmd("stopnotifyspent", (*StopNotifySpentCmd)(nil), flags)
MustRegisterCmd("stopnotifyreceived", (*StopNotifyReceivedCmd)(nil), flags)
MustRegisterCmd("rescan", (*RescanCmd)(nil), flags)
MustRegisterCmd("rescanblocks", (*RescanBlocksCmd)(nil), flags)
}

View File

@ -0,0 +1,304 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// NOTE: This file is intended to house the RPC websocket notifications that are
// supported by a chain server.
package btcjson
const (
// BlockConnectedNtfnMethod is the legacy, deprecated method used for
// notifications from the chain server that a block has been connected.
//
// NOTE: Deprecated. Use FilteredBlockConnectedNtfnMethod instead.
BlockConnectedNtfnMethod = "blockconnected"
// BlockDisconnectedNtfnMethod is the legacy, deprecated method used for
// notifications from the chain server that a block has been
// disconnected.
//
// NOTE: Deprecated. Use FilteredBlockDisconnectedNtfnMethod instead.
BlockDisconnectedNtfnMethod = "blockdisconnected"
// FilteredBlockConnectedNtfnMethod is the new method used for
// notifications from the chain server that a block has been connected.
FilteredBlockConnectedNtfnMethod = "filteredblockconnected"
// FilteredBlockDisconnectedNtfnMethod is the new method used for
// notifications from the chain server that a block has been
// disconnected.
FilteredBlockDisconnectedNtfnMethod = "filteredblockdisconnected"
// RecvTxNtfnMethod is the legacy, deprecated method used for
// notifications from the chain server that a transaction which pays to
// a registered address has been processed.
//
// NOTE: Deprecated. Use RelevantTxAcceptedNtfnMethod and
// FilteredBlockConnectedNtfnMethod instead.
RecvTxNtfnMethod = "recvtx"
// RedeemingTxNtfnMethod is the legacy, deprecated method used for
// notifications from the chain server that a transaction which spends a
// registered outpoint has been processed.
//
// NOTE: Deprecated. Use RelevantTxAcceptedNtfnMethod and
// FilteredBlockConnectedNtfnMethod instead.
RedeemingTxNtfnMethod = "redeemingtx"
// RescanFinishedNtfnMethod is the legacy, deprecated method used for
// notifications from the chain server that a legacy, deprecated rescan
// operation has finished.
//
// NOTE: Deprecated. Not used with rescanblocks command.
RescanFinishedNtfnMethod = "rescanfinished"
// RescanProgressNtfnMethod is the legacy, deprecated method used for
// notifications from the chain server that a legacy, deprecated rescan
// operation this is underway has made progress.
//
// NOTE: Deprecated. Not used with rescanblocks command.
RescanProgressNtfnMethod = "rescanprogress"
// TxAcceptedNtfnMethod is the method used for notifications from the
// chain server that a transaction has been accepted into the mempool.
TxAcceptedNtfnMethod = "txaccepted"
// TxAcceptedVerboseNtfnMethod is the method used for notifications from
// the chain server that a transaction has been accepted into the
// mempool. This differs from TxAcceptedNtfnMethod in that it provides
// more details in the notification.
TxAcceptedVerboseNtfnMethod = "txacceptedverbose"
// RelevantTxAcceptedNtfnMethod is the new method used for notifications
// from the chain server that inform a client that a transaction that
// matches the loaded filter was accepted by the mempool.
RelevantTxAcceptedNtfnMethod = "relevanttxaccepted"
)
// BlockConnectedNtfn defines the blockconnected JSON-RPC notification.
//
// NOTE: Deprecated. Use FilteredBlockConnectedNtfn instead.
type BlockConnectedNtfn struct {
Hash string
Height int32
Time int64
}
// NewBlockConnectedNtfn returns a new instance which can be used to issue a
// blockconnected JSON-RPC notification.
//
// NOTE: Deprecated. Use NewFilteredBlockConnectedNtfn instead.
func NewBlockConnectedNtfn(hash string, height int32, time int64) *BlockConnectedNtfn {
return &BlockConnectedNtfn{
Hash: hash,
Height: height,
Time: time,
}
}
// BlockDisconnectedNtfn defines the blockdisconnected JSON-RPC notification.
//
// NOTE: Deprecated. Use FilteredBlockDisconnectedNtfn instead.
type BlockDisconnectedNtfn struct {
Hash string
Height int32
Time int64
}
// NewBlockDisconnectedNtfn returns a new instance which can be used to issue a
// blockdisconnected JSON-RPC notification.
//
// NOTE: Deprecated. Use NewFilteredBlockDisconnectedNtfn instead.
func NewBlockDisconnectedNtfn(hash string, height int32, time int64) *BlockDisconnectedNtfn {
return &BlockDisconnectedNtfn{
Hash: hash,
Height: height,
Time: time,
}
}
// FilteredBlockConnectedNtfn defines the filteredblockconnected JSON-RPC
// notification.
type FilteredBlockConnectedNtfn struct {
Height int32
Header string
SubscribedTxs []string
}
// NewFilteredBlockConnectedNtfn returns a new instance which can be used to
// issue a filteredblockconnected JSON-RPC notification.
func NewFilteredBlockConnectedNtfn(height int32, header string, subscribedTxs []string) *FilteredBlockConnectedNtfn {
return &FilteredBlockConnectedNtfn{
Height: height,
Header: header,
SubscribedTxs: subscribedTxs,
}
}
// FilteredBlockDisconnectedNtfn defines the filteredblockdisconnected JSON-RPC
// notification.
type FilteredBlockDisconnectedNtfn struct {
Height int32
Header string
}
// NewFilteredBlockDisconnectedNtfn returns a new instance which can be used to
// issue a filteredblockdisconnected JSON-RPC notification.
func NewFilteredBlockDisconnectedNtfn(height int32, header string) *FilteredBlockDisconnectedNtfn {
return &FilteredBlockDisconnectedNtfn{
Height: height,
Header: header,
}
}
// BlockDetails describes details of a tx in a block.
type BlockDetails struct {
Height int32 `json:"height"`
Hash string `json:"hash"`
Index int `json:"index"`
Time int64 `json:"time"`
}
// RecvTxNtfn defines the recvtx JSON-RPC notification.
//
// NOTE: Deprecated. Use RelevantTxAcceptedNtfn and FilteredBlockConnectedNtfn
// instead.
type RecvTxNtfn struct {
HexTx string
Block *BlockDetails
}
// NewRecvTxNtfn returns a new instance which can be used to issue a recvtx
// JSON-RPC notification.
//
// NOTE: Deprecated. Use NewRelevantTxAcceptedNtfn and
// NewFilteredBlockConnectedNtfn instead.
func NewRecvTxNtfn(hexTx string, block *BlockDetails) *RecvTxNtfn {
return &RecvTxNtfn{
HexTx: hexTx,
Block: block,
}
}
// RedeemingTxNtfn defines the redeemingtx JSON-RPC notification.
//
// NOTE: Deprecated. Use RelevantTxAcceptedNtfn and FilteredBlockConnectedNtfn
// instead.
type RedeemingTxNtfn struct {
HexTx string
Block *BlockDetails
}
// NewRedeemingTxNtfn returns a new instance which can be used to issue a
// redeemingtx JSON-RPC notification.
//
// NOTE: Deprecated. Use NewRelevantTxAcceptedNtfn and
// NewFilteredBlockConnectedNtfn instead.
func NewRedeemingTxNtfn(hexTx string, block *BlockDetails) *RedeemingTxNtfn {
return &RedeemingTxNtfn{
HexTx: hexTx,
Block: block,
}
}
// RescanFinishedNtfn defines the rescanfinished JSON-RPC notification.
//
// NOTE: Deprecated. Not used with rescanblocks command.
type RescanFinishedNtfn struct {
Hash string
Height int32
Time int64
}
// NewRescanFinishedNtfn returns a new instance which can be used to issue a
// rescanfinished JSON-RPC notification.
//
// NOTE: Deprecated. Not used with rescanblocks command.
func NewRescanFinishedNtfn(hash string, height int32, time int64) *RescanFinishedNtfn {
return &RescanFinishedNtfn{
Hash: hash,
Height: height,
Time: time,
}
}
// RescanProgressNtfn defines the rescanprogress JSON-RPC notification.
//
// NOTE: Deprecated. Not used with rescanblocks command.
type RescanProgressNtfn struct {
Hash string
Height int32
Time int64
}
// NewRescanProgressNtfn returns a new instance which can be used to issue a
// rescanprogress JSON-RPC notification.
//
// NOTE: Deprecated. Not used with rescanblocks command.
func NewRescanProgressNtfn(hash string, height int32, time int64) *RescanProgressNtfn {
return &RescanProgressNtfn{
Hash: hash,
Height: height,
Time: time,
}
}
// TxAcceptedNtfn defines the txaccepted JSON-RPC notification.
type TxAcceptedNtfn struct {
TxID string
Amount float64
}
// NewTxAcceptedNtfn returns a new instance which can be used to issue a
// txaccepted JSON-RPC notification.
func NewTxAcceptedNtfn(txHash string, amount float64) *TxAcceptedNtfn {
return &TxAcceptedNtfn{
TxID: txHash,
Amount: amount,
}
}
// TxAcceptedVerboseNtfn defines the txacceptedverbose JSON-RPC notification.
type TxAcceptedVerboseNtfn struct {
RawTx TxRawResult
}
// NewTxAcceptedVerboseNtfn returns a new instance which can be used to issue a
// txacceptedverbose JSON-RPC notification.
func NewTxAcceptedVerboseNtfn(rawTx TxRawResult) *TxAcceptedVerboseNtfn {
return &TxAcceptedVerboseNtfn{
RawTx: rawTx,
}
}
// RelevantTxAcceptedNtfn defines the parameters to the relevanttxaccepted
// JSON-RPC notification.
type RelevantTxAcceptedNtfn struct {
Transaction string `json:"transaction"`
}
// NewRelevantTxAcceptedNtfn returns a new instance which can be used to issue a
// relevantxaccepted JSON-RPC notification.
func NewRelevantTxAcceptedNtfn(txHex string) *RelevantTxAcceptedNtfn {
return &RelevantTxAcceptedNtfn{Transaction: txHex}
}
func init() {
// The commands in this file are only usable by websockets and are
// notifications.
flags := UFWebsocketOnly | UFNotification
MustRegisterCmd(BlockConnectedNtfnMethod, (*BlockConnectedNtfn)(nil), flags)
MustRegisterCmd(BlockDisconnectedNtfnMethod, (*BlockDisconnectedNtfn)(nil), flags)
MustRegisterCmd(FilteredBlockConnectedNtfnMethod, (*FilteredBlockConnectedNtfn)(nil), flags)
MustRegisterCmd(FilteredBlockDisconnectedNtfnMethod, (*FilteredBlockDisconnectedNtfn)(nil), flags)
MustRegisterCmd(RecvTxNtfnMethod, (*RecvTxNtfn)(nil), flags)
MustRegisterCmd(RedeemingTxNtfnMethod, (*RedeemingTxNtfn)(nil), flags)
MustRegisterCmd(RescanFinishedNtfnMethod, (*RescanFinishedNtfn)(nil), flags)
MustRegisterCmd(RescanProgressNtfnMethod, (*RescanProgressNtfn)(nil), flags)
MustRegisterCmd(TxAcceptedNtfnMethod, (*TxAcceptedNtfn)(nil), flags)
MustRegisterCmd(TxAcceptedVerboseNtfnMethod, (*TxAcceptedVerboseNtfn)(nil), flags)
MustRegisterCmd(RelevantTxAcceptedNtfnMethod, (*RelevantTxAcceptedNtfn)(nil), flags)
}

View File

@ -0,0 +1,21 @@
// Copyright (c) 2015-2017 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
// SessionResult models the data from the session command.
type SessionResult struct {
SessionID uint64 `json:"sessionid"`
}
// RescannedBlock contains the hash and all discovered transactions of a single
// rescanned block.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrd/dcrjson.
type RescannedBlock struct {
Hash string `json:"hash"`
Transactions []string `json:"transactions"`
}

249
vendor/github.com/btcsuite/btcd/btcjson/cmdinfo.go generated vendored Normal file
View File

@ -0,0 +1,249 @@
// Copyright (c) 2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import (
"fmt"
"reflect"
"strings"
)
// CmdMethod returns the method for the passed command. The provided command
// type must be a registered type. All commands provided by this package are
// registered by default.
func CmdMethod(cmd interface{}) (string, error) {
// Look up the cmd type and error out if not registered.
rt := reflect.TypeOf(cmd)
registerLock.RLock()
method, ok := concreteTypeToMethod[rt]
registerLock.RUnlock()
if !ok {
str := fmt.Sprintf("%q is not registered", method)
return "", makeError(ErrUnregisteredMethod, str)
}
return method, nil
}
// MethodUsageFlags returns the usage flags for the passed command method. The
// provided method must be associated with a registered type. All commands
// provided by this package are registered by default.
func MethodUsageFlags(method string) (UsageFlag, error) {
// Look up details about the provided method and error out if not
// registered.
registerLock.RLock()
info, ok := methodToInfo[method]
registerLock.RUnlock()
if !ok {
str := fmt.Sprintf("%q is not registered", method)
return 0, makeError(ErrUnregisteredMethod, str)
}
return info.flags, nil
}
// subStructUsage returns a string for use in the one-line usage for the given
// sub struct. Note that this is specifically for fields which consist of
// structs (or an array/slice of structs) as opposed to the top-level command
// struct.
//
// Any fields that include a jsonrpcusage struct tag will use that instead of
// being automatically generated.
func subStructUsage(structType reflect.Type) string {
numFields := structType.NumField()
fieldUsages := make([]string, 0, numFields)
for i := 0; i < structType.NumField(); i++ {
rtf := structType.Field(i)
// When the field has a jsonrpcusage struct tag specified use
// that instead of automatically generating it.
if tag := rtf.Tag.Get("jsonrpcusage"); tag != "" {
fieldUsages = append(fieldUsages, tag)
continue
}
// Create the name/value entry for the field while considering
// the type of the field. Not all possible types are covered
// here and when one of the types not specifically covered is
// encountered, the field name is simply reused for the value.
fieldName := strings.ToLower(rtf.Name)
fieldValue := fieldName
fieldKind := rtf.Type.Kind()
switch {
case isNumeric(fieldKind):
if fieldKind == reflect.Float32 || fieldKind == reflect.Float64 {
fieldValue = "n.nnn"
} else {
fieldValue = "n"
}
case fieldKind == reflect.String:
fieldValue = `"value"`
case fieldKind == reflect.Struct:
fieldValue = subStructUsage(rtf.Type)
case fieldKind == reflect.Array || fieldKind == reflect.Slice:
fieldValue = subArrayUsage(rtf.Type, fieldName)
}
usage := fmt.Sprintf("%q:%s", fieldName, fieldValue)
fieldUsages = append(fieldUsages, usage)
}
return fmt.Sprintf("{%s}", strings.Join(fieldUsages, ","))
}
// subArrayUsage returns a string for use in the one-line usage for the given
// array or slice. It also contains logic to convert plural field names to
// singular so the generated usage string reads better.
func subArrayUsage(arrayType reflect.Type, fieldName string) string {
// Convert plural field names to singular. Only works for English.
singularFieldName := fieldName
if strings.HasSuffix(fieldName, "ies") {
singularFieldName = strings.TrimSuffix(fieldName, "ies")
singularFieldName = singularFieldName + "y"
} else if strings.HasSuffix(fieldName, "es") {
singularFieldName = strings.TrimSuffix(fieldName, "es")
} else if strings.HasSuffix(fieldName, "s") {
singularFieldName = strings.TrimSuffix(fieldName, "s")
}
elemType := arrayType.Elem()
switch elemType.Kind() {
case reflect.String:
return fmt.Sprintf("[%q,...]", singularFieldName)
case reflect.Struct:
return fmt.Sprintf("[%s,...]", subStructUsage(elemType))
}
// Fall back to simply showing the field name in array syntax.
return fmt.Sprintf(`[%s,...]`, singularFieldName)
}
// fieldUsage returns a string for use in the one-line usage for the struct
// field of a command.
//
// Any fields that include a jsonrpcusage struct tag will use that instead of
// being automatically generated.
func fieldUsage(structField reflect.StructField, defaultVal *reflect.Value) string {
// When the field has a jsonrpcusage struct tag specified use that
// instead of automatically generating it.
if tag := structField.Tag.Get("jsonrpcusage"); tag != "" {
return tag
}
// Indirect the pointer if needed.
fieldType := structField.Type
if fieldType.Kind() == reflect.Ptr {
fieldType = fieldType.Elem()
}
// When there is a default value, it must also be a pointer due to the
// rules enforced by RegisterCmd.
if defaultVal != nil {
indirect := defaultVal.Elem()
defaultVal = &indirect
}
// Handle certain types uniquely to provide nicer usage.
fieldName := strings.ToLower(structField.Name)
switch fieldType.Kind() {
case reflect.String:
if defaultVal != nil {
return fmt.Sprintf("%s=%q", fieldName,
defaultVal.Interface())
}
return fmt.Sprintf("%q", fieldName)
case reflect.Array, reflect.Slice:
return subArrayUsage(fieldType, fieldName)
case reflect.Struct:
return subStructUsage(fieldType)
}
// Simply return the field name when none of the above special cases
// apply.
if defaultVal != nil {
return fmt.Sprintf("%s=%v", fieldName, defaultVal.Interface())
}
return fieldName
}
// methodUsageText returns a one-line usage string for the provided command and
// method info. This is the main work horse for the exported MethodUsageText
// function.
func methodUsageText(rtp reflect.Type, defaults map[int]reflect.Value, method string) string {
// Generate the individual usage for each field in the command. Several
// simplifying assumptions are made here because the RegisterCmd
// function has already rigorously enforced the layout.
rt := rtp.Elem()
numFields := rt.NumField()
reqFieldUsages := make([]string, 0, numFields)
optFieldUsages := make([]string, 0, numFields)
for i := 0; i < numFields; i++ {
rtf := rt.Field(i)
var isOptional bool
if kind := rtf.Type.Kind(); kind == reflect.Ptr {
isOptional = true
}
var defaultVal *reflect.Value
if defVal, ok := defaults[i]; ok {
defaultVal = &defVal
}
// Add human-readable usage to the appropriate slice that is
// later used to generate the one-line usage.
usage := fieldUsage(rtf, defaultVal)
if isOptional {
optFieldUsages = append(optFieldUsages, usage)
} else {
reqFieldUsages = append(reqFieldUsages, usage)
}
}
// Generate and return the one-line usage string.
usageStr := method
if len(reqFieldUsages) > 0 {
usageStr += " " + strings.Join(reqFieldUsages, " ")
}
if len(optFieldUsages) > 0 {
usageStr += fmt.Sprintf(" (%s)", strings.Join(optFieldUsages, " "))
}
return usageStr
}
// MethodUsageText returns a one-line usage string for the provided method. The
// provided method must be associated with a registered type. All commands
// provided by this package are registered by default.
func MethodUsageText(method string) (string, error) {
// Look up details about the provided method and error out if not
// registered.
registerLock.RLock()
rtp, ok := methodToConcreteType[method]
info := methodToInfo[method]
registerLock.RUnlock()
if !ok {
str := fmt.Sprintf("%q is not registered", method)
return "", makeError(ErrUnregisteredMethod, str)
}
// When the usage for this method has already been generated, simply
// return it.
if info.usage != "" {
return info.usage, nil
}
// Generate and store the usage string for future calls and return it.
usage := methodUsageText(rtp, info.defaults, method)
registerLock.Lock()
info.usage = usage
methodToInfo[method] = info
registerLock.Unlock()
return usage, nil
}

550
vendor/github.com/btcsuite/btcd/btcjson/cmdparse.go generated vendored Normal file
View File

@ -0,0 +1,550 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"strings"
)
// makeParams creates a slice of interface values for the given struct.
func makeParams(rt reflect.Type, rv reflect.Value) []interface{} {
numFields := rt.NumField()
params := make([]interface{}, 0, numFields)
for i := 0; i < numFields; i++ {
rtf := rt.Field(i)
rvf := rv.Field(i)
if rtf.Type.Kind() == reflect.Ptr {
if rvf.IsNil() {
break
}
rvf.Elem()
}
params = append(params, rvf.Interface())
}
return params
}
// MarshalCmd marshals the passed command to a JSON-RPC request byte slice that
// is suitable for transmission to an RPC server. The provided command type
// must be a registered type. All commands provided by this package are
// registered by default.
func MarshalCmd(id interface{}, cmd interface{}) ([]byte, error) {
// Look up the cmd type and error out if not registered.
rt := reflect.TypeOf(cmd)
registerLock.RLock()
method, ok := concreteTypeToMethod[rt]
registerLock.RUnlock()
if !ok {
str := fmt.Sprintf("%q is not registered", method)
return nil, makeError(ErrUnregisteredMethod, str)
}
// The provided command must not be nil.
rv := reflect.ValueOf(cmd)
if rv.IsNil() {
str := "the specified command is nil"
return nil, makeError(ErrInvalidType, str)
}
// Create a slice of interface values in the order of the struct fields
// while respecting pointer fields as optional params and only adding
// them if they are non-nil.
params := makeParams(rt.Elem(), rv.Elem())
// Generate and marshal the final JSON-RPC request.
rawCmd, err := NewRequest(id, method, params)
if err != nil {
return nil, err
}
return json.Marshal(rawCmd)
}
// checkNumParams ensures the supplied number of params is at least the minimum
// required number for the command and less than the maximum allowed.
func checkNumParams(numParams int, info *methodInfo) error {
if numParams < info.numReqParams || numParams > info.maxParams {
if info.numReqParams == info.maxParams {
str := fmt.Sprintf("wrong number of params (expected "+
"%d, received %d)", info.numReqParams,
numParams)
return makeError(ErrNumParams, str)
}
str := fmt.Sprintf("wrong number of params (expected "+
"between %d and %d, received %d)", info.numReqParams,
info.maxParams, numParams)
return makeError(ErrNumParams, str)
}
return nil
}
// populateDefaults populates default values into any remaining optional struct
// fields that did not have parameters explicitly provided. The caller should
// have previously checked that the number of parameters being passed is at
// least the required number of parameters to avoid unnecessary work in this
// function, but since required fields never have default values, it will work
// properly even without the check.
func populateDefaults(numParams int, info *methodInfo, rv reflect.Value) {
// When there are no more parameters left in the supplied parameters,
// any remaining struct fields must be optional. Thus, populate them
// with their associated default value as needed.
for i := numParams; i < info.maxParams; i++ {
rvf := rv.Field(i)
if defaultVal, ok := info.defaults[i]; ok {
rvf.Set(defaultVal)
}
}
}
// UnmarshalCmd unmarshals a JSON-RPC request into a suitable concrete command
// so long as the method type contained within the marshalled request is
// registered.
func UnmarshalCmd(r *Request) (interface{}, error) {
registerLock.RLock()
rtp, ok := methodToConcreteType[r.Method]
info := methodToInfo[r.Method]
registerLock.RUnlock()
if !ok {
str := fmt.Sprintf("%q is not registered", r.Method)
return nil, makeError(ErrUnregisteredMethod, str)
}
rt := rtp.Elem()
rvp := reflect.New(rt)
rv := rvp.Elem()
// Ensure the number of parameters are correct.
numParams := len(r.Params)
if err := checkNumParams(numParams, &info); err != nil {
return nil, err
}
// Loop through each of the struct fields and unmarshal the associated
// parameter into them.
for i := 0; i < numParams; i++ {
rvf := rv.Field(i)
// Unmarshal the parameter into the struct field.
concreteVal := rvf.Addr().Interface()
if err := json.Unmarshal(r.Params[i], &concreteVal); err != nil {
// The most common error is the wrong type, so
// explicitly detect that error and make it nicer.
fieldName := strings.ToLower(rt.Field(i).Name)
if jerr, ok := err.(*json.UnmarshalTypeError); ok {
str := fmt.Sprintf("parameter #%d '%s' must "+
"be type %v (got %v)", i+1, fieldName,
jerr.Type, jerr.Value)
return nil, makeError(ErrInvalidType, str)
}
// Fallback to showing the underlying error.
str := fmt.Sprintf("parameter #%d '%s' failed to "+
"unmarshal: %v", i+1, fieldName, err)
return nil, makeError(ErrInvalidType, str)
}
}
// When there are less supplied parameters than the total number of
// params, any remaining struct fields must be optional. Thus, populate
// them with their associated default value as needed.
if numParams < info.maxParams {
populateDefaults(numParams, &info, rv)
}
return rvp.Interface(), nil
}
// isNumeric returns whether the passed reflect kind is a signed or unsigned
// integer of any magnitude or a float of any magnitude.
func isNumeric(kind reflect.Kind) bool {
switch kind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
reflect.Uint64, reflect.Float32, reflect.Float64:
return true
}
return false
}
// typesMaybeCompatible returns whether the source type can possibly be
// assigned to the destination type. This is intended as a relatively quick
// check to weed out obviously invalid conversions.
func typesMaybeCompatible(dest reflect.Type, src reflect.Type) bool {
// The same types are obviously compatible.
if dest == src {
return true
}
// When both types are numeric, they are potentially compatible.
srcKind := src.Kind()
destKind := dest.Kind()
if isNumeric(destKind) && isNumeric(srcKind) {
return true
}
if srcKind == reflect.String {
// Strings can potentially be converted to numeric types.
if isNumeric(destKind) {
return true
}
switch destKind {
// Strings can potentially be converted to bools by
// strconv.ParseBool.
case reflect.Bool:
return true
// Strings can be converted to any other type which has as
// underlying type of string.
case reflect.String:
return true
// Strings can potentially be converted to arrays, slice,
// structs, and maps via json.Unmarshal.
case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
return true
}
}
return false
}
// baseType returns the type of the argument after indirecting through all
// pointers along with how many indirections were necessary.
func baseType(arg reflect.Type) (reflect.Type, int) {
var numIndirects int
for arg.Kind() == reflect.Ptr {
arg = arg.Elem()
numIndirects++
}
return arg, numIndirects
}
// assignField is the main workhorse for the NewCmd function which handles
// assigning the provided source value to the destination field. It supports
// direct type assignments, indirection, conversion of numeric types, and
// unmarshaling of strings into arrays, slices, structs, and maps via
// json.Unmarshal.
func assignField(paramNum int, fieldName string, dest reflect.Value, src reflect.Value) error {
// Just error now when the types have no chance of being compatible.
destBaseType, destIndirects := baseType(dest.Type())
srcBaseType, srcIndirects := baseType(src.Type())
if !typesMaybeCompatible(destBaseType, srcBaseType) {
str := fmt.Sprintf("parameter #%d '%s' must be type %v (got "+
"%v)", paramNum, fieldName, destBaseType, srcBaseType)
return makeError(ErrInvalidType, str)
}
// Check if it's possible to simply set the dest to the provided source.
// This is the case when the base types are the same or they are both
// pointers that can be indirected to be the same without needing to
// create pointers for the destination field.
if destBaseType == srcBaseType && srcIndirects >= destIndirects {
for i := 0; i < srcIndirects-destIndirects; i++ {
src = src.Elem()
}
dest.Set(src)
return nil
}
// When the destination has more indirects than the source, the extra
// pointers have to be created. Only create enough pointers to reach
// the same level of indirection as the source so the dest can simply be
// set to the provided source when the types are the same.
destIndirectsRemaining := destIndirects
if destIndirects > srcIndirects {
indirectDiff := destIndirects - srcIndirects
for i := 0; i < indirectDiff; i++ {
dest.Set(reflect.New(dest.Type().Elem()))
dest = dest.Elem()
destIndirectsRemaining--
}
}
if destBaseType == srcBaseType {
dest.Set(src)
return nil
}
// Make any remaining pointers needed to get to the base dest type since
// the above direct assign was not possible and conversions are done
// against the base types.
for i := 0; i < destIndirectsRemaining; i++ {
dest.Set(reflect.New(dest.Type().Elem()))
dest = dest.Elem()
}
// Indirect through to the base source value.
for src.Kind() == reflect.Ptr {
src = src.Elem()
}
// Perform supported type conversions.
switch src.Kind() {
// Source value is a signed integer of various magnitude.
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
reflect.Int64:
switch dest.Kind() {
// Destination is a signed integer of various magnitude.
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
reflect.Int64:
srcInt := src.Int()
if dest.OverflowInt(srcInt) {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetInt(srcInt)
// Destination is an unsigned integer of various magnitude.
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
reflect.Uint64:
srcInt := src.Int()
if srcInt < 0 || dest.OverflowUint(uint64(srcInt)) {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetUint(uint64(srcInt))
default:
str := fmt.Sprintf("parameter #%d '%s' must be type "+
"%v (got %v)", paramNum, fieldName, destBaseType,
srcBaseType)
return makeError(ErrInvalidType, str)
}
// Source value is an unsigned integer of various magnitude.
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
reflect.Uint64:
switch dest.Kind() {
// Destination is a signed integer of various magnitude.
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
reflect.Int64:
srcUint := src.Uint()
if srcUint > uint64(1<<63)-1 {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
if dest.OverflowInt(int64(srcUint)) {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetInt(int64(srcUint))
// Destination is an unsigned integer of various magnitude.
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32,
reflect.Uint64:
srcUint := src.Uint()
if dest.OverflowUint(srcUint) {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetUint(srcUint)
default:
str := fmt.Sprintf("parameter #%d '%s' must be type "+
"%v (got %v)", paramNum, fieldName, destBaseType,
srcBaseType)
return makeError(ErrInvalidType, str)
}
// Source value is a float.
case reflect.Float32, reflect.Float64:
destKind := dest.Kind()
if destKind != reflect.Float32 && destKind != reflect.Float64 {
str := fmt.Sprintf("parameter #%d '%s' must be type "+
"%v (got %v)", paramNum, fieldName, destBaseType,
srcBaseType)
return makeError(ErrInvalidType, str)
}
srcFloat := src.Float()
if dest.OverflowFloat(srcFloat) {
str := fmt.Sprintf("parameter #%d '%s' overflows "+
"destination type %v", paramNum, fieldName,
destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetFloat(srcFloat)
// Source value is a string.
case reflect.String:
switch dest.Kind() {
// String -> bool
case reflect.Bool:
b, err := strconv.ParseBool(src.String())
if err != nil {
str := fmt.Sprintf("parameter #%d '%s' must "+
"parse to a %v", paramNum, fieldName,
destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetBool(b)
// String -> signed integer of varying size.
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,
reflect.Int64:
srcInt, err := strconv.ParseInt(src.String(), 0, 0)
if err != nil {
str := fmt.Sprintf("parameter #%d '%s' must "+
"parse to a %v", paramNum, fieldName,
destBaseType)
return makeError(ErrInvalidType, str)
}
if dest.OverflowInt(srcInt) {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetInt(srcInt)
// String -> unsigned integer of varying size.
case reflect.Uint, reflect.Uint8, reflect.Uint16,
reflect.Uint32, reflect.Uint64:
srcUint, err := strconv.ParseUint(src.String(), 0, 0)
if err != nil {
str := fmt.Sprintf("parameter #%d '%s' must "+
"parse to a %v", paramNum, fieldName,
destBaseType)
return makeError(ErrInvalidType, str)
}
if dest.OverflowUint(srcUint) {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetUint(srcUint)
// String -> float of varying size.
case reflect.Float32, reflect.Float64:
srcFloat, err := strconv.ParseFloat(src.String(), 0)
if err != nil {
str := fmt.Sprintf("parameter #%d '%s' must "+
"parse to a %v", paramNum, fieldName,
destBaseType)
return makeError(ErrInvalidType, str)
}
if dest.OverflowFloat(srcFloat) {
str := fmt.Sprintf("parameter #%d '%s' "+
"overflows destination type %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.SetFloat(srcFloat)
// String -> string (typecast).
case reflect.String:
dest.SetString(src.String())
// String -> arrays, slices, structs, and maps via
// json.Unmarshal.
case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
concreteVal := dest.Addr().Interface()
err := json.Unmarshal([]byte(src.String()), &concreteVal)
if err != nil {
str := fmt.Sprintf("parameter #%d '%s' must "+
"be valid JSON which unsmarshals to a %v",
paramNum, fieldName, destBaseType)
return makeError(ErrInvalidType, str)
}
dest.Set(reflect.ValueOf(concreteVal).Elem())
}
}
return nil
}
// NewCmd provides a generic mechanism to create a new command that can marshal
// to a JSON-RPC request while respecting the requirements of the provided
// method. The method must have been registered with the package already along
// with its type definition. All methods associated with the commands exported
// by this package are already registered by default.
//
// The arguments are most efficient when they are the exact same type as the
// underlying field in the command struct associated with the the method,
// however this function also will perform a variety of conversions to make it
// more flexible. This allows, for example, command line args which are strings
// to be passed unaltered. In particular, the following conversions are
// supported:
//
// - Conversion between any size signed or unsigned integer so long as the
// value does not overflow the destination type
// - Conversion between float32 and float64 so long as the value does not
// overflow the destination type
// - Conversion from string to boolean for everything strconv.ParseBool
// recognizes
// - Conversion from string to any size integer for everything
// strconv.ParseInt and strconv.ParseUint recognizes
// - Conversion from string to any size float for everything
// strconv.ParseFloat recognizes
// - Conversion from string to arrays, slices, structs, and maps by treating
// the string as marshalled JSON and calling json.Unmarshal into the
// destination field
func NewCmd(method string, args ...interface{}) (interface{}, error) {
// Look up details about the provided method. Any methods that aren't
// registered are an error.
registerLock.RLock()
rtp, ok := methodToConcreteType[method]
info := methodToInfo[method]
registerLock.RUnlock()
if !ok {
str := fmt.Sprintf("%q is not registered", method)
return nil, makeError(ErrUnregisteredMethod, str)
}
// Ensure the number of parameters are correct.
numParams := len(args)
if err := checkNumParams(numParams, &info); err != nil {
return nil, err
}
// Create the appropriate command type for the method. Since all types
// are enforced to be a pointer to a struct at registration time, it's
// safe to indirect to the struct now.
rvp := reflect.New(rtp.Elem())
rv := rvp.Elem()
rt := rtp.Elem()
// Loop through each of the struct fields and assign the associated
// parameter into them after checking its type validity.
for i := 0; i < numParams; i++ {
// Attempt to assign each of the arguments to the according
// struct field.
rvf := rv.Field(i)
fieldName := strings.ToLower(rt.Field(i).Name)
err := assignField(i+1, fieldName, rvf, reflect.ValueOf(args[i]))
if err != nil {
return nil, err
}
}
return rvp.Interface(), nil
}

146
vendor/github.com/btcsuite/btcd/btcjson/doc.go generated vendored Normal file
View File

@ -0,0 +1,146 @@
// Copyright (c) 2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
/*
Package btcjson provides primitives for working with the bitcoin JSON-RPC API.
Overview
When communicating via the JSON-RPC protocol, all of the commands need to be
marshalled to and from the the wire in the appropriate format. This package
provides data structures and primitives to ease this process.
In addition, it also provides some additional features such as custom command
registration, command categorization, and reflection-based help generation.
JSON-RPC Protocol Overview
This information is not necessary in order to use this package, but it does
provide some intuition into what the marshalling and unmarshalling that is
discussed below is doing under the hood.
As defined by the JSON-RPC spec, there are effectively two forms of messages on
the wire:
- Request Objects
{"jsonrpc":"1.0","id":"SOMEID","method":"SOMEMETHOD","params":[SOMEPARAMS]}
NOTE: Notifications are the same format except the id field is null.
- Response Objects
{"result":SOMETHING,"error":null,"id":"SOMEID"}
{"result":null,"error":{"code":SOMEINT,"message":SOMESTRING},"id":"SOMEID"}
For requests, the params field can vary in what it contains depending on the
method (a.k.a. command) being sent. Each parameter can be as simple as an int
or a complex structure containing many nested fields. The id field is used to
identify a request and will be included in the associated response.
When working with asynchronous transports, such as websockets, spontaneous
notifications are also possible. As indicated, they are the same as a request
object, except they have the id field set to null. Therefore, servers will
ignore requests with the id field set to null, while clients can choose to
consume or ignore them.
Unfortunately, the original Bitcoin JSON-RPC API (and hence anything compatible
with it) doesn't always follow the spec and will sometimes return an error
string in the result field with a null error for certain commands. However,
for the most part, the error field will be set as described on failure.
Marshalling and Unmarshalling
Based upon the discussion above, it should be easy to see how the types of this
package map into the required parts of the protocol
- Request Objects (type Request)
- Commands (type <Foo>Cmd)
- Notifications (type <Foo>Ntfn)
- Response Objects (type Response)
- Result (type <Foo>Result)
To simplify the marshalling of the requests and responses, the MarshalCmd and
MarshalResponse functions are provided. They return the raw bytes ready to be
sent across the wire.
Unmarshalling a received Request object is a two step process:
1) Unmarshal the raw bytes into a Request struct instance via json.Unmarshal
2) Use UnmarshalCmd on the Result field of the unmarshalled Request to create
a concrete command or notification instance with all struct fields set
accordingly
This approach is used since it provides the caller with access to the additional
fields in the request that are not part of the command such as the ID.
Unmarshalling a received Response object is also a two step process:
1) Unmarhsal the raw bytes into a Response struct instance via json.Unmarshal
2) Depending on the ID, unmarshal the Result field of the unmarshalled
Response to create a concrete type instance
As above, this approach is used since it provides the caller with access to the
fields in the response such as the ID and Error.
Command Creation
This package provides two approaches for creating a new command. This first,
and preferred, method is to use one of the New<Foo>Cmd functions. This allows
static compile-time checking to help ensure the parameters stay in sync with
the struct definitions.
The second approach is the NewCmd function which takes a method (command) name
and variable arguments. The function includes full checking to ensure the
parameters are accurate according to provided method, however these checks are,
obviously, run-time which means any mistakes won't be found until the code is
actually executed. However, it is quite useful for user-supplied commands
that are intentionally dynamic.
Custom Command Registration
The command handling of this package is built around the concept of registered
commands. This is true for the wide variety of commands already provided by the
package, but it also means caller can easily provide custom commands with all
of the same functionality as the built-in commands. Use the RegisterCmd
function for this purpose.
A list of all registered methods can be obtained with the RegisteredCmdMethods
function.
Command Inspection
All registered commands are registered with flags that identify information such
as whether the command applies to a chain server, wallet server, or is a
notification along with the method name to use. These flags can be obtained
with the MethodUsageFlags flags, and the method can be obtained with the
CmdMethod function.
Help Generation
To facilitate providing consistent help to users of the RPC server, this package
exposes the GenerateHelp and function which uses reflection on registered
commands or notifications, as well as the provided expected result types, to
generate the final help text.
In addition, the MethodUsageText function is provided to generate consistent
one-line usage for registered commands and notifications using reflection.
Errors
There are 2 distinct type of errors supported by this package:
- General errors related to marshalling or unmarshalling or improper use of
the package (type Error)
- RPC errors which are intended to be returned across the wire as a part of
the JSON-RPC response (type RPCError)
The first category of errors (type Error) typically indicates a programmer error
and can be avoided by properly using the API. Errors of this type will be
returned from the various functions available in this package. They identify
issues such as unsupported field types, attempts to register malformed commands,
and attempting to create a new command with an improper number of parameters.
The specific reason for the error can be detected by type asserting it to a
*btcjson.Error and accessing the ErrorCode field.
The second category of errors (type RPCError), on the other hand, are useful for
returning errors to RPC clients. Consequently, they are used in the previously
described Response type.
*/
package btcjson

111
vendor/github.com/btcsuite/btcd/btcjson/error.go generated vendored Normal file
View File

@ -0,0 +1,111 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import (
"fmt"
)
// ErrorCode identifies a kind of error. These error codes are NOT used for
// JSON-RPC response errors.
type ErrorCode int
// These constants are used to identify a specific RuleError.
const (
// ErrDuplicateMethod indicates a command with the specified method
// already exists.
ErrDuplicateMethod ErrorCode = iota
// ErrInvalidUsageFlags indicates one or more unrecognized flag bits
// were specified.
ErrInvalidUsageFlags
// ErrInvalidType indicates a type was passed that is not the required
// type.
ErrInvalidType
// ErrEmbeddedType indicates the provided command struct contains an
// embedded type which is not not supported.
ErrEmbeddedType
// ErrUnexportedField indiciates the provided command struct contains an
// unexported field which is not supported.
ErrUnexportedField
// ErrUnsupportedFieldType indicates the type of a field in the provided
// command struct is not one of the supported types.
ErrUnsupportedFieldType
// ErrNonOptionalField indicates a non-optional field was specified
// after an optional field.
ErrNonOptionalField
// ErrNonOptionalDefault indicates a 'jsonrpcdefault' struct tag was
// specified for a non-optional field.
ErrNonOptionalDefault
// ErrMismatchedDefault indicates a 'jsonrpcdefault' struct tag contains
// a value that doesn't match the type of the field.
ErrMismatchedDefault
// ErrUnregisteredMethod indicates a method was specified that has not
// been registered.
ErrUnregisteredMethod
// ErrMissingDescription indicates a description required to generate
// help is missing.
ErrMissingDescription
// ErrNumParams inidcates the number of params supplied do not
// match the requirements of the associated command.
ErrNumParams
// numErrorCodes is the maximum error code number used in tests.
numErrorCodes
)
// Map of ErrorCode values back to their constant names for pretty printing.
var errorCodeStrings = map[ErrorCode]string{
ErrDuplicateMethod: "ErrDuplicateMethod",
ErrInvalidUsageFlags: "ErrInvalidUsageFlags",
ErrInvalidType: "ErrInvalidType",
ErrEmbeddedType: "ErrEmbeddedType",
ErrUnexportedField: "ErrUnexportedField",
ErrUnsupportedFieldType: "ErrUnsupportedFieldType",
ErrNonOptionalField: "ErrNonOptionalField",
ErrNonOptionalDefault: "ErrNonOptionalDefault",
ErrMismatchedDefault: "ErrMismatchedDefault",
ErrUnregisteredMethod: "ErrUnregisteredMethod",
ErrMissingDescription: "ErrMissingDescription",
ErrNumParams: "ErrNumParams",
}
// String returns the ErrorCode as a human-readable name.
func (e ErrorCode) String() string {
if s := errorCodeStrings[e]; s != "" {
return s
}
return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
}
// Error identifies a general error. This differs from an RPCError in that this
// error typically is used more by the consumers of the package as opposed to
// RPCErrors which are intended to be returned to the client across the wire via
// a JSON-RPC Response. The caller can use type assertions to determine the
// specific error and access the ErrorCode field.
type Error struct {
ErrorCode ErrorCode // Describes the kind of error
Description string // Human readable description of the issue
}
// Error satisfies the error interface and prints human-readable errors.
func (e Error) Error() string {
return e.Description
}
// makeError creates an Error given a set of arguments.
func makeError(c ErrorCode, desc string) Error {
return Error{ErrorCode: c, Description: desc}
}

560
vendor/github.com/btcsuite/btcd/btcjson/help.go generated vendored Normal file
View File

@ -0,0 +1,560 @@
// Copyright (c) 2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import (
"bytes"
"fmt"
"reflect"
"strings"
"text/tabwriter"
)
// baseHelpDescs house the various help labels, types, and example values used
// when generating help. The per-command synopsis, field descriptions,
// conditions, and result descriptions are to be provided by the caller.
var baseHelpDescs = map[string]string{
// Misc help labels and output.
"help-arguments": "Arguments",
"help-arguments-none": "None",
"help-result": "Result",
"help-result-nothing": "Nothing",
"help-default": "default",
"help-optional": "optional",
"help-required": "required",
// JSON types.
"json-type-numeric": "numeric",
"json-type-string": "string",
"json-type-bool": "boolean",
"json-type-array": "array of ",
"json-type-object": "object",
"json-type-value": "value",
// JSON examples.
"json-example-string": "value",
"json-example-bool": "true|false",
"json-example-map-data": "data",
"json-example-unknown": "unknown",
}
// descLookupFunc is a function which is used to lookup a description given
// a key.
type descLookupFunc func(string) string
// reflectTypeToJSONType returns a string that represents the JSON type
// associated with the provided Go type.
func reflectTypeToJSONType(xT descLookupFunc, rt reflect.Type) string {
kind := rt.Kind()
if isNumeric(kind) {
return xT("json-type-numeric")
}
switch kind {
case reflect.String:
return xT("json-type-string")
case reflect.Bool:
return xT("json-type-bool")
case reflect.Array, reflect.Slice:
return xT("json-type-array") + reflectTypeToJSONType(xT,
rt.Elem())
case reflect.Struct:
return xT("json-type-object")
case reflect.Map:
return xT("json-type-object")
}
return xT("json-type-value")
}
// resultStructHelp returns a slice of strings containing the result help output
// for a struct. Each line makes use of tabs to separate the relevant pieces so
// a tabwriter can be used later to line everything up. The descriptions are
// pulled from the active help descriptions map based on the lowercase version
// of the provided reflect type and json name (or the lowercase version of the
// field name if no json tag was specified).
func resultStructHelp(xT descLookupFunc, rt reflect.Type, indentLevel int) []string {
indent := strings.Repeat(" ", indentLevel)
typeName := strings.ToLower(rt.Name())
// Generate the help for each of the fields in the result struct.
numField := rt.NumField()
results := make([]string, 0, numField)
for i := 0; i < numField; i++ {
rtf := rt.Field(i)
// The field name to display is the json name when it's
// available, otherwise use the lowercase field name.
var fieldName string
if tag := rtf.Tag.Get("json"); tag != "" {
fieldName = strings.Split(tag, ",")[0]
} else {
fieldName = strings.ToLower(rtf.Name)
}
// Deference pointer if needed.
rtfType := rtf.Type
if rtfType.Kind() == reflect.Ptr {
rtfType = rtf.Type.Elem()
}
// Generate the JSON example for the result type of this struct
// field. When it is a complex type, examine the type and
// adjust the opening bracket and brace combination accordingly.
fieldType := reflectTypeToJSONType(xT, rtfType)
fieldDescKey := typeName + "-" + fieldName
fieldExamples, isComplex := reflectTypeToJSONExample(xT,
rtfType, indentLevel, fieldDescKey)
if isComplex {
var brace string
kind := rtfType.Kind()
if kind == reflect.Array || kind == reflect.Slice {
brace = "[{"
} else {
brace = "{"
}
result := fmt.Sprintf("%s\"%s\": %s\t(%s)\t%s", indent,
fieldName, brace, fieldType, xT(fieldDescKey))
results = append(results, result)
results = append(results, fieldExamples...)
} else {
result := fmt.Sprintf("%s\"%s\": %s,\t(%s)\t%s", indent,
fieldName, fieldExamples[0], fieldType,
xT(fieldDescKey))
results = append(results, result)
}
}
return results
}
// reflectTypeToJSONExample generates example usage in the format used by the
// help output. It handles arrays, slices and structs recursively. The output
// is returned as a slice of lines so the final help can be nicely aligned via
// a tab writer. A bool is also returned which specifies whether or not the
// type results in a complex JSON object since they need to be handled
// differently.
func reflectTypeToJSONExample(xT descLookupFunc, rt reflect.Type, indentLevel int, fieldDescKey string) ([]string, bool) {
// Indirect pointer if needed.
if rt.Kind() == reflect.Ptr {
rt = rt.Elem()
}
kind := rt.Kind()
if isNumeric(kind) {
if kind == reflect.Float32 || kind == reflect.Float64 {
return []string{"n.nnn"}, false
}
return []string{"n"}, false
}
switch kind {
case reflect.String:
return []string{`"` + xT("json-example-string") + `"`}, false
case reflect.Bool:
return []string{xT("json-example-bool")}, false
case reflect.Struct:
indent := strings.Repeat(" ", indentLevel)
results := resultStructHelp(xT, rt, indentLevel+1)
// An opening brace is needed for the first indent level. For
// all others, it will be included as a part of the previous
// field.
if indentLevel == 0 {
newResults := make([]string, len(results)+1)
newResults[0] = "{"
copy(newResults[1:], results)
results = newResults
}
// The closing brace has a comma after it except for the first
// indent level. The final tabs are necessary so the tab writer
// lines things up properly.
closingBrace := indent + "}"
if indentLevel > 0 {
closingBrace += ","
}
results = append(results, closingBrace+"\t\t")
return results, true
case reflect.Array, reflect.Slice:
results, isComplex := reflectTypeToJSONExample(xT, rt.Elem(),
indentLevel, fieldDescKey)
// When the result is complex, it is because this is an array of
// objects.
if isComplex {
// When this is at indent level zero, there is no
// previous field to house the opening array bracket, so
// replace the opening object brace with the array
// syntax. Also, replace the final closing object brace
// with the variadiac array closing syntax.
indent := strings.Repeat(" ", indentLevel)
if indentLevel == 0 {
results[0] = indent + "[{"
results[len(results)-1] = indent + "},...]"
return results, true
}
// At this point, the indent level is greater than 0, so
// the opening array bracket and object brace are
// already a part of the previous field. However, the
// closing entry is a simple object brace, so replace it
// with the variadiac array closing syntax. The final
// tabs are necessary so the tab writer lines things up
// properly.
results[len(results)-1] = indent + "},...],\t\t"
return results, true
}
// It's an array of primitives, so return the formatted text
// accordingly.
return []string{fmt.Sprintf("[%s,...]", results[0])}, false
case reflect.Map:
indent := strings.Repeat(" ", indentLevel)
results := make([]string, 0, 3)
// An opening brace is needed for the first indent level. For
// all others, it will be included as a part of the previous
// field.
if indentLevel == 0 {
results = append(results, indent+"{")
}
// Maps are a bit special in that they need to have the key,
// value, and description of the object entry specifically
// called out.
innerIndent := strings.Repeat(" ", indentLevel+1)
result := fmt.Sprintf("%s%q: %s, (%s) %s", innerIndent,
xT(fieldDescKey+"--key"), xT(fieldDescKey+"--value"),
reflectTypeToJSONType(xT, rt), xT(fieldDescKey+"--desc"))
results = append(results, result)
results = append(results, innerIndent+"...")
results = append(results, indent+"}")
return results, true
}
return []string{xT("json-example-unknown")}, false
}
// resultTypeHelp generates and returns formatted help for the provided result
// type.
func resultTypeHelp(xT descLookupFunc, rt reflect.Type, fieldDescKey string) string {
// Generate the JSON example for the result type.
results, isComplex := reflectTypeToJSONExample(xT, rt, 0, fieldDescKey)
// When this is a primitive type, add the associated JSON type and
// result description into the final string, format it accordingly,
// and return it.
if !isComplex {
return fmt.Sprintf("%s (%s) %s", results[0],
reflectTypeToJSONType(xT, rt), xT(fieldDescKey))
}
// At this point, this is a complex type that already has the JSON types
// and descriptions in the results. Thus, use a tab writer to nicely
// align the help text.
var formatted bytes.Buffer
w := new(tabwriter.Writer)
w.Init(&formatted, 0, 4, 1, ' ', 0)
for i, text := range results {
if i == len(results)-1 {
fmt.Fprintf(w, text)
} else {
fmt.Fprintln(w, text)
}
}
w.Flush()
return formatted.String()
}
// argTypeHelp returns the type of provided command argument as a string in the
// format used by the help output. In particular, it includes the JSON type
// (boolean, numeric, string, array, object) along with optional and the default
// value if applicable.
func argTypeHelp(xT descLookupFunc, structField reflect.StructField, defaultVal *reflect.Value) string {
// Indirect the pointer if needed and track if it's an optional field.
fieldType := structField.Type
var isOptional bool
if fieldType.Kind() == reflect.Ptr {
fieldType = fieldType.Elem()
isOptional = true
}
// When there is a default value, it must also be a pointer due to the
// rules enforced by RegisterCmd.
if defaultVal != nil {
indirect := defaultVal.Elem()
defaultVal = &indirect
}
// Convert the field type to a JSON type.
details := make([]string, 0, 3)
details = append(details, reflectTypeToJSONType(xT, fieldType))
// Add optional and default value to the details if needed.
if isOptional {
details = append(details, xT("help-optional"))
// Add the default value if there is one. This is only checked
// when the field is optional since a non-optional field can't
// have a default value.
if defaultVal != nil {
val := defaultVal.Interface()
if defaultVal.Kind() == reflect.String {
val = fmt.Sprintf(`"%s"`, val)
}
str := fmt.Sprintf("%s=%v", xT("help-default"), val)
details = append(details, str)
}
} else {
details = append(details, xT("help-required"))
}
return strings.Join(details, ", ")
}
// argHelp generates and returns formatted help for the provided command.
func argHelp(xT descLookupFunc, rtp reflect.Type, defaults map[int]reflect.Value, method string) string {
// Return now if the command has no arguments.
rt := rtp.Elem()
numFields := rt.NumField()
if numFields == 0 {
return ""
}
// Generate the help for each argument in the command. Several
// simplifying assumptions are made here because the RegisterCmd
// function has already rigorously enforced the layout.
args := make([]string, 0, numFields)
for i := 0; i < numFields; i++ {
rtf := rt.Field(i)
var defaultVal *reflect.Value
if defVal, ok := defaults[i]; ok {
defaultVal = &defVal
}
fieldName := strings.ToLower(rtf.Name)
helpText := fmt.Sprintf("%d.\t%s\t(%s)\t%s", i+1, fieldName,
argTypeHelp(xT, rtf, defaultVal),
xT(method+"-"+fieldName))
args = append(args, helpText)
// For types which require a JSON object, or an array of JSON
// objects, generate the full syntax for the argument.
fieldType := rtf.Type
if fieldType.Kind() == reflect.Ptr {
fieldType = fieldType.Elem()
}
kind := fieldType.Kind()
switch kind {
case reflect.Struct:
fieldDescKey := fmt.Sprintf("%s-%s", method, fieldName)
resultText := resultTypeHelp(xT, fieldType, fieldDescKey)
args = append(args, resultText)
case reflect.Map:
fieldDescKey := fmt.Sprintf("%s-%s", method, fieldName)
resultText := resultTypeHelp(xT, fieldType, fieldDescKey)
args = append(args, resultText)
case reflect.Array, reflect.Slice:
fieldDescKey := fmt.Sprintf("%s-%s", method, fieldName)
if rtf.Type.Elem().Kind() == reflect.Struct {
resultText := resultTypeHelp(xT, fieldType,
fieldDescKey)
args = append(args, resultText)
}
}
}
// Add argument names, types, and descriptions if there are any. Use a
// tab writer to nicely align the help text.
var formatted bytes.Buffer
w := new(tabwriter.Writer)
w.Init(&formatted, 0, 4, 1, ' ', 0)
for _, text := range args {
fmt.Fprintln(w, text)
}
w.Flush()
return formatted.String()
}
// methodHelp generates and returns the help output for the provided command
// and method info. This is the main work horse for the exported MethodHelp
// function.
func methodHelp(xT descLookupFunc, rtp reflect.Type, defaults map[int]reflect.Value, method string, resultTypes []interface{}) string {
// Start off with the method usage and help synopsis.
help := fmt.Sprintf("%s\n\n%s\n", methodUsageText(rtp, defaults, method),
xT(method+"--synopsis"))
// Generate the help for each argument in the command.
if argText := argHelp(xT, rtp, defaults, method); argText != "" {
help += fmt.Sprintf("\n%s:\n%s", xT("help-arguments"),
argText)
} else {
help += fmt.Sprintf("\n%s:\n%s\n", xT("help-arguments"),
xT("help-arguments-none"))
}
// Generate the help text for each result type.
resultTexts := make([]string, 0, len(resultTypes))
for i := range resultTypes {
rtp := reflect.TypeOf(resultTypes[i])
fieldDescKey := fmt.Sprintf("%s--result%d", method, i)
if resultTypes[i] == nil {
resultText := xT("help-result-nothing")
resultTexts = append(resultTexts, resultText)
continue
}
resultText := resultTypeHelp(xT, rtp.Elem(), fieldDescKey)
resultTexts = append(resultTexts, resultText)
}
// Add result types and descriptions. When there is more than one
// result type, also add the condition which triggers it.
if len(resultTexts) > 1 {
for i, resultText := range resultTexts {
condKey := fmt.Sprintf("%s--condition%d", method, i)
help += fmt.Sprintf("\n%s (%s):\n%s\n",
xT("help-result"), xT(condKey), resultText)
}
} else if len(resultTexts) > 0 {
help += fmt.Sprintf("\n%s:\n%s\n", xT("help-result"),
resultTexts[0])
} else {
help += fmt.Sprintf("\n%s:\n%s\n", xT("help-result"),
xT("help-result-nothing"))
}
return help
}
// isValidResultType returns whether the passed reflect kind is one of the
// acceptable types for results.
func isValidResultType(kind reflect.Kind) bool {
if isNumeric(kind) {
return true
}
switch kind {
case reflect.String, reflect.Struct, reflect.Array, reflect.Slice,
reflect.Bool, reflect.Map:
return true
}
return false
}
// GenerateHelp generates and returns help output for the provided method and
// result types given a map to provide the appropriate keys for the method
// synopsis, field descriptions, conditions, and result descriptions. The
// method must be associated with a registered type. All commands provided by
// this package are registered by default.
//
// The resultTypes must be pointer-to-types which represent the specific types
// of values the command returns. For example, if the command only returns a
// boolean value, there should only be a single entry of (*bool)(nil). Note
// that each type must be a single pointer to the type. Therefore, it is
// recommended to simply pass a nil pointer cast to the appropriate type as
// previously shown.
//
// The provided descriptions map must contain all of the keys or an error will
// be returned which includes the missing key, or the final missing key when
// there is more than one key missing. The generated help in the case of such
// an error will use the key in place of the description.
//
// The following outlines the required keys:
// "<method>--synopsis" Synopsis for the command
// "<method>-<lowerfieldname>" Description for each command argument
// "<typename>-<lowerfieldname>" Description for each object field
// "<method>--condition<#>" Description for each result condition
// "<method>--result<#>" Description for each primitive result num
//
// Notice that the "special" keys synopsis, condition<#>, and result<#> are
// preceded by a double dash to ensure they don't conflict with field names.
//
// The condition keys are only required when there is more than on result type,
// and the result key for a given result type is only required if it's not an
// object.
//
// For example, consider the 'help' command itself. There are two possible
// returns depending on the provided parameters. So, the help would be
// generated by calling the function as follows:
// GenerateHelp("help", descs, (*string)(nil), (*string)(nil)).
//
// The following keys would then be required in the provided descriptions map:
//
// "help--synopsis": "Returns a list of all commands or help for ...."
// "help-command": "The command to retrieve help for",
// "help--condition0": "no command provided"
// "help--condition1": "command specified"
// "help--result0": "List of commands"
// "help--result1": "Help for specified command"
func GenerateHelp(method string, descs map[string]string, resultTypes ...interface{}) (string, error) {
// Look up details about the provided method and error out if not
// registered.
registerLock.RLock()
rtp, ok := methodToConcreteType[method]
info := methodToInfo[method]
registerLock.RUnlock()
if !ok {
str := fmt.Sprintf("%q is not registered", method)
return "", makeError(ErrUnregisteredMethod, str)
}
// Validate each result type is a pointer to a supported type (or nil).
for i, resultType := range resultTypes {
if resultType == nil {
continue
}
rtp := reflect.TypeOf(resultType)
if rtp.Kind() != reflect.Ptr {
str := fmt.Sprintf("result #%d (%v) is not a pointer",
i, rtp.Kind())
return "", makeError(ErrInvalidType, str)
}
elemKind := rtp.Elem().Kind()
if !isValidResultType(elemKind) {
str := fmt.Sprintf("result #%d (%v) is not an allowed "+
"type", i, elemKind)
return "", makeError(ErrInvalidType, str)
}
}
// Create a closure for the description lookup function which falls back
// to the base help descriptions map for unrecognized keys and tracks
// and missing keys.
var missingKey string
xT := func(key string) string {
if desc, ok := descs[key]; ok {
return desc
}
if desc, ok := baseHelpDescs[key]; ok {
return desc
}
missingKey = key
return key
}
// Generate and return the help for the method.
help := methodHelp(xT, rtp, info.defaults, method, resultTypes)
if missingKey != "" {
return help, makeError(ErrMissingDescription, missingKey)
}
return help, nil
}

77
vendor/github.com/btcsuite/btcd/btcjson/helpers.go generated vendored Normal file
View File

@ -0,0 +1,77 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
// Bool is a helper routine that allocates a new bool value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Bool(v bool) *bool {
p := new(bool)
*p = v
return p
}
// Int is a helper routine that allocates a new int value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Int(v int) *int {
p := new(int)
*p = v
return p
}
// Uint is a helper routine that allocates a new uint value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Uint(v uint) *uint {
p := new(uint)
*p = v
return p
}
// Int32 is a helper routine that allocates a new int32 value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Int32(v int32) *int32 {
p := new(int32)
*p = v
return p
}
// Uint32 is a helper routine that allocates a new uint32 value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Uint32(v uint32) *uint32 {
p := new(uint32)
*p = v
return p
}
// Int64 is a helper routine that allocates a new int64 value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Int64(v int64) *int64 {
p := new(int64)
*p = v
return p
}
// Uint64 is a helper routine that allocates a new uint64 value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Uint64(v uint64) *uint64 {
p := new(uint64)
*p = v
return p
}
// Float64 is a helper routine that allocates a new float64 value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func Float64(v float64) *float64 {
p := new(float64)
*p = v
return p
}
// String is a helper routine that allocates a new string value to store v and
// returns a pointer to it. This is useful when assigning optional parameters.
func String(v string) *string {
p := new(string)
*p = v
return p
}

150
vendor/github.com/btcsuite/btcd/btcjson/jsonrpc.go generated vendored Normal file
View File

@ -0,0 +1,150 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import (
"encoding/json"
"fmt"
)
// RPCErrorCode represents an error code to be used as a part of an RPCError
// which is in turn used in a JSON-RPC Response object.
//
// A specific type is used to help ensure the wrong errors aren't used.
type RPCErrorCode int
// RPCError represents an error that is used as a part of a JSON-RPC Response
// object.
type RPCError struct {
Code RPCErrorCode `json:"code,omitempty"`
Message string `json:"message,omitempty"`
}
// Guarantee RPCError satisifies the builtin error interface.
var _, _ error = RPCError{}, (*RPCError)(nil)
// Error returns a string describing the RPC error. This satisifies the
// builtin error interface.
func (e RPCError) Error() string {
return fmt.Sprintf("%d: %s", e.Code, e.Message)
}
// NewRPCError constructs and returns a new JSON-RPC error that is suitable
// for use in a JSON-RPC Response object.
func NewRPCError(code RPCErrorCode, message string) *RPCError {
return &RPCError{
Code: code,
Message: message,
}
}
// IsValidIDType checks that the ID field (which can go in any of the JSON-RPC
// requests, responses, or notifications) is valid. JSON-RPC 1.0 allows any
// valid JSON type. JSON-RPC 2.0 (which bitcoind follows for some parts) only
// allows string, number, or null, so this function restricts the allowed types
// to that list. This function is only provided in case the caller is manually
// marshalling for some reason. The functions which accept an ID in this
// package already call this function to ensure the provided id is valid.
func IsValidIDType(id interface{}) bool {
switch id.(type) {
case int, int8, int16, int32, int64,
uint, uint8, uint16, uint32, uint64,
float32, float64,
string,
nil:
return true
default:
return false
}
}
// Request is a type for raw JSON-RPC 1.0 requests. The Method field identifies
// the specific command type which in turns leads to different parameters.
// Callers typically will not use this directly since this package provides a
// statically typed command infrastructure which handles creation of these
// requests, however this struct it being exported in case the caller wants to
// construct raw requests for some reason.
type Request struct {
Jsonrpc string `json:"jsonrpc"`
Method string `json:"method"`
Params []json.RawMessage `json:"params"`
ID interface{} `json:"id"`
}
// NewRequest returns a new JSON-RPC 1.0 request object given the provided id,
// method, and parameters. The parameters are marshalled into a json.RawMessage
// for the Params field of the returned request object. This function is only
// provided in case the caller wants to construct raw requests for some reason.
//
// Typically callers will instead want to create a registered concrete command
// type with the NewCmd or New<Foo>Cmd functions and call the MarshalCmd
// function with that command to generate the marshalled JSON-RPC request.
func NewRequest(id interface{}, method string, params []interface{}) (*Request, error) {
if !IsValidIDType(id) {
str := fmt.Sprintf("the id of type '%T' is invalid", id)
return nil, makeError(ErrInvalidType, str)
}
rawParams := make([]json.RawMessage, 0, len(params))
for _, param := range params {
marshalledParam, err := json.Marshal(param)
if err != nil {
return nil, err
}
rawMessage := json.RawMessage(marshalledParam)
rawParams = append(rawParams, rawMessage)
}
return &Request{
Jsonrpc: "1.0",
ID: id,
Method: method,
Params: rawParams,
}, nil
}
// Response is the general form of a JSON-RPC response. The type of the Result
// field varies from one command to the next, so it is implemented as an
// interface. The ID field has to be a pointer for Go to put a null in it when
// empty.
type Response struct {
Result json.RawMessage `json:"result"`
Error *RPCError `json:"error"`
ID *interface{} `json:"id"`
}
// NewResponse returns a new JSON-RPC response object given the provided id,
// marshalled result, and RPC error. This function is only provided in case the
// caller wants to construct raw responses for some reason.
//
// Typically callers will instead want to create the fully marshalled JSON-RPC
// response to send over the wire with the MarshalResponse function.
func NewResponse(id interface{}, marshalledResult []byte, rpcErr *RPCError) (*Response, error) {
if !IsValidIDType(id) {
str := fmt.Sprintf("the id of type '%T' is invalid", id)
return nil, makeError(ErrInvalidType, str)
}
pid := &id
return &Response{
Result: marshalledResult,
Error: rpcErr,
ID: pid,
}, nil
}
// MarshalResponse marshals the passed id, result, and RPCError to a JSON-RPC
// response byte slice that is suitable for transmission to a JSON-RPC client.
func MarshalResponse(id interface{}, result interface{}, rpcErr *RPCError) ([]byte, error) {
marshalledResult, err := json.Marshal(result)
if err != nil {
return nil, err
}
response, err := NewResponse(id, marshalledResult, rpcErr)
if err != nil {
return nil, err
}
return json.Marshal(&response)
}

85
vendor/github.com/btcsuite/btcd/btcjson/jsonrpcerr.go generated vendored Normal file
View File

@ -0,0 +1,85 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
// Standard JSON-RPC 2.0 errors.
var (
ErrRPCInvalidRequest = &RPCError{
Code: -32600,
Message: "Invalid request",
}
ErrRPCMethodNotFound = &RPCError{
Code: -32601,
Message: "Method not found",
}
ErrRPCInvalidParams = &RPCError{
Code: -32602,
Message: "Invalid parameters",
}
ErrRPCInternal = &RPCError{
Code: -32603,
Message: "Internal error",
}
ErrRPCParse = &RPCError{
Code: -32700,
Message: "Parse error",
}
)
// General application defined JSON errors.
const (
ErrRPCMisc RPCErrorCode = -1
ErrRPCForbiddenBySafeMode RPCErrorCode = -2
ErrRPCType RPCErrorCode = -3
ErrRPCInvalidAddressOrKey RPCErrorCode = -5
ErrRPCOutOfMemory RPCErrorCode = -7
ErrRPCInvalidParameter RPCErrorCode = -8
ErrRPCDatabase RPCErrorCode = -20
ErrRPCDeserialization RPCErrorCode = -22
ErrRPCVerify RPCErrorCode = -25
)
// Peer-to-peer client errors.
const (
ErrRPCClientNotConnected RPCErrorCode = -9
ErrRPCClientInInitialDownload RPCErrorCode = -10
ErrRPCClientNodeNotAdded RPCErrorCode = -24
)
// Wallet JSON errors
const (
ErrRPCWallet RPCErrorCode = -4
ErrRPCWalletInsufficientFunds RPCErrorCode = -6
ErrRPCWalletInvalidAccountName RPCErrorCode = -11
ErrRPCWalletKeypoolRanOut RPCErrorCode = -12
ErrRPCWalletUnlockNeeded RPCErrorCode = -13
ErrRPCWalletPassphraseIncorrect RPCErrorCode = -14
ErrRPCWalletWrongEncState RPCErrorCode = -15
ErrRPCWalletEncryptionFailed RPCErrorCode = -16
ErrRPCWalletAlreadyUnlocked RPCErrorCode = -17
)
// Specific Errors related to commands. These are the ones a user of the RPC
// server are most likely to see. Generally, the codes should match one of the
// more general errors above.
const (
ErrRPCBlockNotFound RPCErrorCode = -5
ErrRPCBlockCount RPCErrorCode = -5
ErrRPCBestBlockHash RPCErrorCode = -5
ErrRPCDifficulty RPCErrorCode = -5
ErrRPCOutOfRange RPCErrorCode = -1
ErrRPCNoTxInfo RPCErrorCode = -5
ErrRPCNoCFIndex RPCErrorCode = -5
ErrRPCNoNewestBlockInfo RPCErrorCode = -5
ErrRPCInvalidTxVout RPCErrorCode = -5
ErrRPCRawTxString RPCErrorCode = -32602
ErrRPCDecodeHexString RPCErrorCode = -22
)
// Errors that are specific to btcd.
const (
ErrRPCNoWallet RPCErrorCode = -1
ErrRPCUnimplemented RPCErrorCode = -1
)

292
vendor/github.com/btcsuite/btcd/btcjson/register.go generated vendored Normal file
View File

@ -0,0 +1,292 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
import (
"encoding/json"
"fmt"
"reflect"
"sort"
"strconv"
"strings"
"sync"
)
// UsageFlag define flags that specify additional properties about the
// circumstances under which a command can be used.
type UsageFlag uint32
const (
// UFWalletOnly indicates that the command can only be used with an RPC
// server that supports wallet commands.
UFWalletOnly UsageFlag = 1 << iota
// UFWebsocketOnly indicates that the command can only be used when
// communicating with an RPC server over websockets. This typically
// applies to notifications and notification registration functions
// since neiher makes since when using a single-shot HTTP-POST request.
UFWebsocketOnly
// UFNotification indicates that the command is actually a notification.
// This means when it is marshalled, the ID must be nil.
UFNotification
// highestUsageFlagBit is the maximum usage flag bit and is used in the
// stringer and tests to ensure all of the above constants have been
// tested.
highestUsageFlagBit
)
// Map of UsageFlag values back to their constant names for pretty printing.
var usageFlagStrings = map[UsageFlag]string{
UFWalletOnly: "UFWalletOnly",
UFWebsocketOnly: "UFWebsocketOnly",
UFNotification: "UFNotification",
}
// String returns the UsageFlag in human-readable form.
func (fl UsageFlag) String() string {
// No flags are set.
if fl == 0 {
return "0x0"
}
// Add individual bit flags.
s := ""
for flag := UFWalletOnly; flag < highestUsageFlagBit; flag <<= 1 {
if fl&flag == flag {
s += usageFlagStrings[flag] + "|"
fl -= flag
}
}
// Add remaining value as raw hex.
s = strings.TrimRight(s, "|")
if fl != 0 {
s += "|0x" + strconv.FormatUint(uint64(fl), 16)
}
s = strings.TrimLeft(s, "|")
return s
}
// methodInfo keeps track of information about each registered method such as
// the parameter information.
type methodInfo struct {
maxParams int
numReqParams int
numOptParams int
defaults map[int]reflect.Value
flags UsageFlag
usage string
}
var (
// These fields are used to map the registered types to method names.
registerLock sync.RWMutex
methodToConcreteType = make(map[string]reflect.Type)
methodToInfo = make(map[string]methodInfo)
concreteTypeToMethod = make(map[reflect.Type]string)
)
// baseKindString returns the base kind for a given reflect.Type after
// indirecting through all pointers.
func baseKindString(rt reflect.Type) string {
numIndirects := 0
for rt.Kind() == reflect.Ptr {
numIndirects++
rt = rt.Elem()
}
return fmt.Sprintf("%s%s", strings.Repeat("*", numIndirects), rt.Kind())
}
// isAcceptableKind returns whether or not the passed field type is a supported
// type. It is called after the first pointer indirection, so further pointers
// are not supported.
func isAcceptableKind(kind reflect.Kind) bool {
switch kind {
case reflect.Chan:
fallthrough
case reflect.Complex64:
fallthrough
case reflect.Complex128:
fallthrough
case reflect.Func:
fallthrough
case reflect.Ptr:
fallthrough
case reflect.Interface:
return false
}
return true
}
// RegisterCmd registers a new command that will automatically marshal to and
// from JSON-RPC with full type checking and positional parameter support. It
// also accepts usage flags which identify the circumstances under which the
// command can be used.
//
// This package automatically registers all of the exported commands by default
// using this function, however it is also exported so callers can easily
// register custom types.
//
// The type format is very strict since it needs to be able to automatically
// marshal to and from JSON-RPC 1.0. The following enumerates the requirements:
//
// - The provided command must be a single pointer to a struct
// - All fields must be exported
// - The order of the positional parameters in the marshalled JSON will be in
// the same order as declared in the struct definition
// - Struct embedding is not supported
// - Struct fields may NOT be channels, functions, complex, or interface
// - A field in the provided struct with a pointer is treated as optional
// - Multiple indirections (i.e **int) are not supported
// - Once the first optional field (pointer) is encountered, the remaining
// fields must also be optional fields (pointers) as required by positional
// params
// - A field that has a 'jsonrpcdefault' struct tag must be an optional field
// (pointer)
//
// NOTE: This function only needs to be able to examine the structure of the
// passed struct, so it does not need to be an actual instance. Therefore, it
// is recommended to simply pass a nil pointer cast to the appropriate type.
// For example, (*FooCmd)(nil).
func RegisterCmd(method string, cmd interface{}, flags UsageFlag) error {
registerLock.Lock()
defer registerLock.Unlock()
if _, ok := methodToConcreteType[method]; ok {
str := fmt.Sprintf("method %q is already registered", method)
return makeError(ErrDuplicateMethod, str)
}
// Ensure that no unrecognized flag bits were specified.
if ^(highestUsageFlagBit-1)&flags != 0 {
str := fmt.Sprintf("invalid usage flags specified for method "+
"%s: %v", method, flags)
return makeError(ErrInvalidUsageFlags, str)
}
rtp := reflect.TypeOf(cmd)
if rtp.Kind() != reflect.Ptr {
str := fmt.Sprintf("type must be *struct not '%s (%s)'", rtp,
rtp.Kind())
return makeError(ErrInvalidType, str)
}
rt := rtp.Elem()
if rt.Kind() != reflect.Struct {
str := fmt.Sprintf("type must be *struct not '%s (*%s)'",
rtp, rt.Kind())
return makeError(ErrInvalidType, str)
}
// Enumerate the struct fields to validate them and gather parameter
// information.
numFields := rt.NumField()
numOptFields := 0
defaults := make(map[int]reflect.Value)
for i := 0; i < numFields; i++ {
rtf := rt.Field(i)
if rtf.Anonymous {
str := fmt.Sprintf("embedded fields are not supported "+
"(field name: %q)", rtf.Name)
return makeError(ErrEmbeddedType, str)
}
if rtf.PkgPath != "" {
str := fmt.Sprintf("unexported fields are not supported "+
"(field name: %q)", rtf.Name)
return makeError(ErrUnexportedField, str)
}
// Disallow types that can't be JSON encoded. Also, determine
// if the field is optional based on it being a pointer.
var isOptional bool
switch kind := rtf.Type.Kind(); kind {
case reflect.Ptr:
isOptional = true
kind = rtf.Type.Elem().Kind()
fallthrough
default:
if !isAcceptableKind(kind) {
str := fmt.Sprintf("unsupported field type "+
"'%s (%s)' (field name %q)", rtf.Type,
baseKindString(rtf.Type), rtf.Name)
return makeError(ErrUnsupportedFieldType, str)
}
}
// Count the optional fields and ensure all fields after the
// first optional field are also optional.
if isOptional {
numOptFields++
} else {
if numOptFields > 0 {
str := fmt.Sprintf("all fields after the first "+
"optional field must also be optional "+
"(field name %q)", rtf.Name)
return makeError(ErrNonOptionalField, str)
}
}
// Ensure the default value can be unsmarshalled into the type
// and that defaults are only specified for optional fields.
if tag := rtf.Tag.Get("jsonrpcdefault"); tag != "" {
if !isOptional {
str := fmt.Sprintf("required fields must not "+
"have a default specified (field name "+
"%q)", rtf.Name)
return makeError(ErrNonOptionalDefault, str)
}
rvf := reflect.New(rtf.Type.Elem())
err := json.Unmarshal([]byte(tag), rvf.Interface())
if err != nil {
str := fmt.Sprintf("default value of %q is "+
"the wrong type (field name %q)", tag,
rtf.Name)
return makeError(ErrMismatchedDefault, str)
}
defaults[i] = rvf
}
}
// Update the registration maps.
methodToConcreteType[method] = rtp
methodToInfo[method] = methodInfo{
maxParams: numFields,
numReqParams: numFields - numOptFields,
numOptParams: numOptFields,
defaults: defaults,
flags: flags,
}
concreteTypeToMethod[rtp] = method
return nil
}
// MustRegisterCmd performs the same function as RegisterCmd except it panics
// if there is an error. This should only be called from package init
// functions.
func MustRegisterCmd(method string, cmd interface{}, flags UsageFlag) {
if err := RegisterCmd(method, cmd, flags); err != nil {
panic(fmt.Sprintf("failed to register type %q: %v\n", method,
err))
}
}
// RegisteredCmdMethods returns a sorted list of methods for all registered
// commands.
func RegisteredCmdMethods() []string {
registerLock.Lock()
defer registerLock.Unlock()
methods := make([]string, 0, len(methodToInfo))
for k := range methodToInfo {
methods = append(methods, k)
}
sort.Sort(sort.StringSlice(methods))
return methods
}

View File

@ -0,0 +1,699 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// NOTE: This file is intended to house the RPC commands that are supported by
// a wallet server.
package btcjson
// AddMultisigAddressCmd defines the addmutisigaddress JSON-RPC command.
type AddMultisigAddressCmd struct {
NRequired int
Keys []string
Account *string
}
// NewAddMultisigAddressCmd returns a new instance which can be used to issue a
// addmultisigaddress JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewAddMultisigAddressCmd(nRequired int, keys []string, account *string) *AddMultisigAddressCmd {
return &AddMultisigAddressCmd{
NRequired: nRequired,
Keys: keys,
Account: account,
}
}
// AddWitnessAddressCmd defines the addwitnessaddress JSON-RPC command.
type AddWitnessAddressCmd struct {
Address string
}
// NewAddWitnessAddressCmd returns a new instance which can be used to issue a
// addwitnessaddress JSON-RPC command.
func NewAddWitnessAddressCmd(address string) *AddWitnessAddressCmd {
return &AddWitnessAddressCmd{
Address: address,
}
}
// CreateMultisigCmd defines the createmultisig JSON-RPC command.
type CreateMultisigCmd struct {
NRequired int
Keys []string
}
// NewCreateMultisigCmd returns a new instance which can be used to issue a
// createmultisig JSON-RPC command.
func NewCreateMultisigCmd(nRequired int, keys []string) *CreateMultisigCmd {
return &CreateMultisigCmd{
NRequired: nRequired,
Keys: keys,
}
}
// DumpPrivKeyCmd defines the dumpprivkey JSON-RPC command.
type DumpPrivKeyCmd struct {
Address string
}
// NewDumpPrivKeyCmd returns a new instance which can be used to issue a
// dumpprivkey JSON-RPC command.
func NewDumpPrivKeyCmd(address string) *DumpPrivKeyCmd {
return &DumpPrivKeyCmd{
Address: address,
}
}
// EncryptWalletCmd defines the encryptwallet JSON-RPC command.
type EncryptWalletCmd struct {
Passphrase string
}
// NewEncryptWalletCmd returns a new instance which can be used to issue a
// encryptwallet JSON-RPC command.
func NewEncryptWalletCmd(passphrase string) *EncryptWalletCmd {
return &EncryptWalletCmd{
Passphrase: passphrase,
}
}
// EstimateFeeCmd defines the estimatefee JSON-RPC command.
type EstimateFeeCmd struct {
NumBlocks int64
}
// NewEstimateFeeCmd returns a new instance which can be used to issue a
// estimatefee JSON-RPC command.
func NewEstimateFeeCmd(numBlocks int64) *EstimateFeeCmd {
return &EstimateFeeCmd{
NumBlocks: numBlocks,
}
}
// EstimatePriorityCmd defines the estimatepriority JSON-RPC command.
type EstimatePriorityCmd struct {
NumBlocks int64
}
// NewEstimatePriorityCmd returns a new instance which can be used to issue a
// estimatepriority JSON-RPC command.
func NewEstimatePriorityCmd(numBlocks int64) *EstimatePriorityCmd {
return &EstimatePriorityCmd{
NumBlocks: numBlocks,
}
}
// GetAccountCmd defines the getaccount JSON-RPC command.
type GetAccountCmd struct {
Address string
}
// NewGetAccountCmd returns a new instance which can be used to issue a
// getaccount JSON-RPC command.
func NewGetAccountCmd(address string) *GetAccountCmd {
return &GetAccountCmd{
Address: address,
}
}
// GetAccountAddressCmd defines the getaccountaddress JSON-RPC command.
type GetAccountAddressCmd struct {
Account string
}
// NewGetAccountAddressCmd returns a new instance which can be used to issue a
// getaccountaddress JSON-RPC command.
func NewGetAccountAddressCmd(account string) *GetAccountAddressCmd {
return &GetAccountAddressCmd{
Account: account,
}
}
// GetAddressesByAccountCmd defines the getaddressesbyaccount JSON-RPC command.
type GetAddressesByAccountCmd struct {
Account string
}
// NewGetAddressesByAccountCmd returns a new instance which can be used to issue
// a getaddressesbyaccount JSON-RPC command.
func NewGetAddressesByAccountCmd(account string) *GetAddressesByAccountCmd {
return &GetAddressesByAccountCmd{
Account: account,
}
}
// GetBalanceCmd defines the getbalance JSON-RPC command.
type GetBalanceCmd struct {
Account *string
MinConf *int `jsonrpcdefault:"1"`
}
// NewGetBalanceCmd returns a new instance which can be used to issue a
// getbalance JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetBalanceCmd(account *string, minConf *int) *GetBalanceCmd {
return &GetBalanceCmd{
Account: account,
MinConf: minConf,
}
}
// GetNewAddressCmd defines the getnewaddress JSON-RPC command.
type GetNewAddressCmd struct {
Account *string
}
// NewGetNewAddressCmd returns a new instance which can be used to issue a
// getnewaddress JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetNewAddressCmd(account *string) *GetNewAddressCmd {
return &GetNewAddressCmd{
Account: account,
}
}
// GetRawChangeAddressCmd defines the getrawchangeaddress JSON-RPC command.
type GetRawChangeAddressCmd struct {
Account *string
}
// NewGetRawChangeAddressCmd returns a new instance which can be used to issue a
// getrawchangeaddress JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetRawChangeAddressCmd(account *string) *GetRawChangeAddressCmd {
return &GetRawChangeAddressCmd{
Account: account,
}
}
// GetReceivedByAccountCmd defines the getreceivedbyaccount JSON-RPC command.
type GetReceivedByAccountCmd struct {
Account string
MinConf *int `jsonrpcdefault:"1"`
}
// NewGetReceivedByAccountCmd returns a new instance which can be used to issue
// a getreceivedbyaccount JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetReceivedByAccountCmd(account string, minConf *int) *GetReceivedByAccountCmd {
return &GetReceivedByAccountCmd{
Account: account,
MinConf: minConf,
}
}
// GetReceivedByAddressCmd defines the getreceivedbyaddress JSON-RPC command.
type GetReceivedByAddressCmd struct {
Address string
MinConf *int `jsonrpcdefault:"1"`
}
// NewGetReceivedByAddressCmd returns a new instance which can be used to issue
// a getreceivedbyaddress JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetReceivedByAddressCmd(address string, minConf *int) *GetReceivedByAddressCmd {
return &GetReceivedByAddressCmd{
Address: address,
MinConf: minConf,
}
}
// GetTransactionCmd defines the gettransaction JSON-RPC command.
type GetTransactionCmd struct {
Txid string
IncludeWatchOnly *bool `jsonrpcdefault:"false"`
}
// NewGetTransactionCmd returns a new instance which can be used to issue a
// gettransaction JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetTransactionCmd(txHash string, includeWatchOnly *bool) *GetTransactionCmd {
return &GetTransactionCmd{
Txid: txHash,
IncludeWatchOnly: includeWatchOnly,
}
}
// GetWalletInfoCmd defines the getwalletinfo JSON-RPC command.
type GetWalletInfoCmd struct{}
// NewGetWalletInfoCmd returns a new instance which can be used to issue a
// getwalletinfo JSON-RPC command.
func NewGetWalletInfoCmd() *GetWalletInfoCmd {
return &GetWalletInfoCmd{}
}
// ImportPrivKeyCmd defines the importprivkey JSON-RPC command.
type ImportPrivKeyCmd struct {
PrivKey string
Label *string
Rescan *bool `jsonrpcdefault:"true"`
}
// NewImportPrivKeyCmd returns a new instance which can be used to issue a
// importprivkey JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewImportPrivKeyCmd(privKey string, label *string, rescan *bool) *ImportPrivKeyCmd {
return &ImportPrivKeyCmd{
PrivKey: privKey,
Label: label,
Rescan: rescan,
}
}
// KeyPoolRefillCmd defines the keypoolrefill JSON-RPC command.
type KeyPoolRefillCmd struct {
NewSize *uint `jsonrpcdefault:"100"`
}
// NewKeyPoolRefillCmd returns a new instance which can be used to issue a
// keypoolrefill JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewKeyPoolRefillCmd(newSize *uint) *KeyPoolRefillCmd {
return &KeyPoolRefillCmd{
NewSize: newSize,
}
}
// ListAccountsCmd defines the listaccounts JSON-RPC command.
type ListAccountsCmd struct {
MinConf *int `jsonrpcdefault:"1"`
}
// NewListAccountsCmd returns a new instance which can be used to issue a
// listaccounts JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListAccountsCmd(minConf *int) *ListAccountsCmd {
return &ListAccountsCmd{
MinConf: minConf,
}
}
// ListAddressGroupingsCmd defines the listaddressgroupings JSON-RPC command.
type ListAddressGroupingsCmd struct{}
// NewListAddressGroupingsCmd returns a new instance which can be used to issue
// a listaddressgroupoings JSON-RPC command.
func NewListAddressGroupingsCmd() *ListAddressGroupingsCmd {
return &ListAddressGroupingsCmd{}
}
// ListLockUnspentCmd defines the listlockunspent JSON-RPC command.
type ListLockUnspentCmd struct{}
// NewListLockUnspentCmd returns a new instance which can be used to issue a
// listlockunspent JSON-RPC command.
func NewListLockUnspentCmd() *ListLockUnspentCmd {
return &ListLockUnspentCmd{}
}
// ListReceivedByAccountCmd defines the listreceivedbyaccount JSON-RPC command.
type ListReceivedByAccountCmd struct {
MinConf *int `jsonrpcdefault:"1"`
IncludeEmpty *bool `jsonrpcdefault:"false"`
IncludeWatchOnly *bool `jsonrpcdefault:"false"`
}
// NewListReceivedByAccountCmd returns a new instance which can be used to issue
// a listreceivedbyaccount JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListReceivedByAccountCmd(minConf *int, includeEmpty, includeWatchOnly *bool) *ListReceivedByAccountCmd {
return &ListReceivedByAccountCmd{
MinConf: minConf,
IncludeEmpty: includeEmpty,
IncludeWatchOnly: includeWatchOnly,
}
}
// ListReceivedByAddressCmd defines the listreceivedbyaddress JSON-RPC command.
type ListReceivedByAddressCmd struct {
MinConf *int `jsonrpcdefault:"1"`
IncludeEmpty *bool `jsonrpcdefault:"false"`
IncludeWatchOnly *bool `jsonrpcdefault:"false"`
}
// NewListReceivedByAddressCmd returns a new instance which can be used to issue
// a listreceivedbyaddress JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListReceivedByAddressCmd(minConf *int, includeEmpty, includeWatchOnly *bool) *ListReceivedByAddressCmd {
return &ListReceivedByAddressCmd{
MinConf: minConf,
IncludeEmpty: includeEmpty,
IncludeWatchOnly: includeWatchOnly,
}
}
// ListSinceBlockCmd defines the listsinceblock JSON-RPC command.
type ListSinceBlockCmd struct {
BlockHash *string
TargetConfirmations *int `jsonrpcdefault:"1"`
IncludeWatchOnly *bool `jsonrpcdefault:"false"`
}
// NewListSinceBlockCmd returns a new instance which can be used to issue a
// listsinceblock JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListSinceBlockCmd(blockHash *string, targetConfirms *int, includeWatchOnly *bool) *ListSinceBlockCmd {
return &ListSinceBlockCmd{
BlockHash: blockHash,
TargetConfirmations: targetConfirms,
IncludeWatchOnly: includeWatchOnly,
}
}
// ListTransactionsCmd defines the listtransactions JSON-RPC command.
type ListTransactionsCmd struct {
Account *string
Count *int `jsonrpcdefault:"10"`
From *int `jsonrpcdefault:"0"`
IncludeWatchOnly *bool `jsonrpcdefault:"false"`
}
// NewListTransactionsCmd returns a new instance which can be used to issue a
// listtransactions JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListTransactionsCmd(account *string, count, from *int, includeWatchOnly *bool) *ListTransactionsCmd {
return &ListTransactionsCmd{
Account: account,
Count: count,
From: from,
IncludeWatchOnly: includeWatchOnly,
}
}
// ListUnspentCmd defines the listunspent JSON-RPC command.
type ListUnspentCmd struct {
MinConf *int `jsonrpcdefault:"1"`
MaxConf *int `jsonrpcdefault:"9999999"`
Addresses *[]string
}
// NewListUnspentCmd returns a new instance which can be used to issue a
// listunspent JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListUnspentCmd(minConf, maxConf *int, addresses *[]string) *ListUnspentCmd {
return &ListUnspentCmd{
MinConf: minConf,
MaxConf: maxConf,
Addresses: addresses,
}
}
// LockUnspentCmd defines the lockunspent JSON-RPC command.
type LockUnspentCmd struct {
Unlock bool
Transactions []TransactionInput
}
// NewLockUnspentCmd returns a new instance which can be used to issue a
// lockunspent JSON-RPC command.
func NewLockUnspentCmd(unlock bool, transactions []TransactionInput) *LockUnspentCmd {
return &LockUnspentCmd{
Unlock: unlock,
Transactions: transactions,
}
}
// MoveCmd defines the move JSON-RPC command.
type MoveCmd struct {
FromAccount string
ToAccount string
Amount float64 // In BTC
MinConf *int `jsonrpcdefault:"1"`
Comment *string
}
// NewMoveCmd returns a new instance which can be used to issue a move JSON-RPC
// command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewMoveCmd(fromAccount, toAccount string, amount float64, minConf *int, comment *string) *MoveCmd {
return &MoveCmd{
FromAccount: fromAccount,
ToAccount: toAccount,
Amount: amount,
MinConf: minConf,
Comment: comment,
}
}
// SendFromCmd defines the sendfrom JSON-RPC command.
type SendFromCmd struct {
FromAccount string
ToAddress string
Amount float64 // In BTC
MinConf *int `jsonrpcdefault:"1"`
Comment *string
CommentTo *string
}
// NewSendFromCmd returns a new instance which can be used to issue a sendfrom
// JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSendFromCmd(fromAccount, toAddress string, amount float64, minConf *int, comment, commentTo *string) *SendFromCmd {
return &SendFromCmd{
FromAccount: fromAccount,
ToAddress: toAddress,
Amount: amount,
MinConf: minConf,
Comment: comment,
CommentTo: commentTo,
}
}
// SendManyCmd defines the sendmany JSON-RPC command.
type SendManyCmd struct {
FromAccount string
Amounts map[string]float64 `jsonrpcusage:"{\"address\":amount,...}"` // In BTC
MinConf *int `jsonrpcdefault:"1"`
Comment *string
}
// NewSendManyCmd returns a new instance which can be used to issue a sendmany
// JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSendManyCmd(fromAccount string, amounts map[string]float64, minConf *int, comment *string) *SendManyCmd {
return &SendManyCmd{
FromAccount: fromAccount,
Amounts: amounts,
MinConf: minConf,
Comment: comment,
}
}
// SendToAddressCmd defines the sendtoaddress JSON-RPC command.
type SendToAddressCmd struct {
Address string
Amount float64
Comment *string
CommentTo *string
}
// NewSendToAddressCmd returns a new instance which can be used to issue a
// sendtoaddress JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSendToAddressCmd(address string, amount float64, comment, commentTo *string) *SendToAddressCmd {
return &SendToAddressCmd{
Address: address,
Amount: amount,
Comment: comment,
CommentTo: commentTo,
}
}
// SetAccountCmd defines the setaccount JSON-RPC command.
type SetAccountCmd struct {
Address string
Account string
}
// NewSetAccountCmd returns a new instance which can be used to issue a
// setaccount JSON-RPC command.
func NewSetAccountCmd(address, account string) *SetAccountCmd {
return &SetAccountCmd{
Address: address,
Account: account,
}
}
// SetTxFeeCmd defines the settxfee JSON-RPC command.
type SetTxFeeCmd struct {
Amount float64 // In BTC
}
// NewSetTxFeeCmd returns a new instance which can be used to issue a settxfee
// JSON-RPC command.
func NewSetTxFeeCmd(amount float64) *SetTxFeeCmd {
return &SetTxFeeCmd{
Amount: amount,
}
}
// SignMessageCmd defines the signmessage JSON-RPC command.
type SignMessageCmd struct {
Address string
Message string
}
// NewSignMessageCmd returns a new instance which can be used to issue a
// signmessage JSON-RPC command.
func NewSignMessageCmd(address, message string) *SignMessageCmd {
return &SignMessageCmd{
Address: address,
Message: message,
}
}
// RawTxInput models the data needed for raw transaction input that is used in
// the SignRawTransactionCmd struct.
type RawTxInput struct {
Txid string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptPubKey string `json:"scriptPubKey"`
RedeemScript string `json:"redeemScript"`
}
// SignRawTransactionCmd defines the signrawtransaction JSON-RPC command.
type SignRawTransactionCmd struct {
RawTx string
Inputs *[]RawTxInput
PrivKeys *[]string
Flags *string `jsonrpcdefault:"\"ALL\""`
}
// NewSignRawTransactionCmd returns a new instance which can be used to issue a
// signrawtransaction JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewSignRawTransactionCmd(hexEncodedTx string, inputs *[]RawTxInput, privKeys *[]string, flags *string) *SignRawTransactionCmd {
return &SignRawTransactionCmd{
RawTx: hexEncodedTx,
Inputs: inputs,
PrivKeys: privKeys,
Flags: flags,
}
}
// WalletLockCmd defines the walletlock JSON-RPC command.
type WalletLockCmd struct{}
// NewWalletLockCmd returns a new instance which can be used to issue a
// walletlock JSON-RPC command.
func NewWalletLockCmd() *WalletLockCmd {
return &WalletLockCmd{}
}
// WalletPassphraseCmd defines the walletpassphrase JSON-RPC command.
type WalletPassphraseCmd struct {
Passphrase string
Timeout int64
}
// NewWalletPassphraseCmd returns a new instance which can be used to issue a
// walletpassphrase JSON-RPC command.
func NewWalletPassphraseCmd(passphrase string, timeout int64) *WalletPassphraseCmd {
return &WalletPassphraseCmd{
Passphrase: passphrase,
Timeout: timeout,
}
}
// WalletPassphraseChangeCmd defines the walletpassphrase JSON-RPC command.
type WalletPassphraseChangeCmd struct {
OldPassphrase string
NewPassphrase string
}
// NewWalletPassphraseChangeCmd returns a new instance which can be used to
// issue a walletpassphrasechange JSON-RPC command.
func NewWalletPassphraseChangeCmd(oldPassphrase, newPassphrase string) *WalletPassphraseChangeCmd {
return &WalletPassphraseChangeCmd{
OldPassphrase: oldPassphrase,
NewPassphrase: newPassphrase,
}
}
func init() {
// The commands in this file are only usable with a wallet server.
flags := UFWalletOnly
MustRegisterCmd("addmultisigaddress", (*AddMultisigAddressCmd)(nil), flags)
MustRegisterCmd("addwitnessaddress", (*AddWitnessAddressCmd)(nil), flags)
MustRegisterCmd("createmultisig", (*CreateMultisigCmd)(nil), flags)
MustRegisterCmd("dumpprivkey", (*DumpPrivKeyCmd)(nil), flags)
MustRegisterCmd("encryptwallet", (*EncryptWalletCmd)(nil), flags)
MustRegisterCmd("estimatefee", (*EstimateFeeCmd)(nil), flags)
MustRegisterCmd("estimatepriority", (*EstimatePriorityCmd)(nil), flags)
MustRegisterCmd("getaccount", (*GetAccountCmd)(nil), flags)
MustRegisterCmd("getaccountaddress", (*GetAccountAddressCmd)(nil), flags)
MustRegisterCmd("getaddressesbyaccount", (*GetAddressesByAccountCmd)(nil), flags)
MustRegisterCmd("getbalance", (*GetBalanceCmd)(nil), flags)
MustRegisterCmd("getnewaddress", (*GetNewAddressCmd)(nil), flags)
MustRegisterCmd("getrawchangeaddress", (*GetRawChangeAddressCmd)(nil), flags)
MustRegisterCmd("getreceivedbyaccount", (*GetReceivedByAccountCmd)(nil), flags)
MustRegisterCmd("getreceivedbyaddress", (*GetReceivedByAddressCmd)(nil), flags)
MustRegisterCmd("gettransaction", (*GetTransactionCmd)(nil), flags)
MustRegisterCmd("getwalletinfo", (*GetWalletInfoCmd)(nil), flags)
MustRegisterCmd("importprivkey", (*ImportPrivKeyCmd)(nil), flags)
MustRegisterCmd("keypoolrefill", (*KeyPoolRefillCmd)(nil), flags)
MustRegisterCmd("listaccounts", (*ListAccountsCmd)(nil), flags)
MustRegisterCmd("listaddressgroupings", (*ListAddressGroupingsCmd)(nil), flags)
MustRegisterCmd("listlockunspent", (*ListLockUnspentCmd)(nil), flags)
MustRegisterCmd("listreceivedbyaccount", (*ListReceivedByAccountCmd)(nil), flags)
MustRegisterCmd("listreceivedbyaddress", (*ListReceivedByAddressCmd)(nil), flags)
MustRegisterCmd("listsinceblock", (*ListSinceBlockCmd)(nil), flags)
MustRegisterCmd("listtransactions", (*ListTransactionsCmd)(nil), flags)
MustRegisterCmd("listunspent", (*ListUnspentCmd)(nil), flags)
MustRegisterCmd("lockunspent", (*LockUnspentCmd)(nil), flags)
MustRegisterCmd("move", (*MoveCmd)(nil), flags)
MustRegisterCmd("sendfrom", (*SendFromCmd)(nil), flags)
MustRegisterCmd("sendmany", (*SendManyCmd)(nil), flags)
MustRegisterCmd("sendtoaddress", (*SendToAddressCmd)(nil), flags)
MustRegisterCmd("setaccount", (*SetAccountCmd)(nil), flags)
MustRegisterCmd("settxfee", (*SetTxFeeCmd)(nil), flags)
MustRegisterCmd("signmessage", (*SignMessageCmd)(nil), flags)
MustRegisterCmd("signrawtransaction", (*SignRawTransactionCmd)(nil), flags)
MustRegisterCmd("walletlock", (*WalletLockCmd)(nil), flags)
MustRegisterCmd("walletpassphrase", (*WalletPassphraseCmd)(nil), flags)
MustRegisterCmd("walletpassphrasechange", (*WalletPassphraseChangeCmd)(nil), flags)
}

View File

@ -0,0 +1,161 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
// GetTransactionDetailsResult models the details data from the gettransaction command.
//
// This models the "short" version of the ListTransactionsResult type, which
// excludes fields common to the transaction. These common fields are instead
// part of the GetTransactionResult.
type GetTransactionDetailsResult struct {
Account string `json:"account"`
Address string `json:"address,omitempty"`
Amount float64 `json:"amount"`
Category string `json:"category"`
InvolvesWatchOnly bool `json:"involveswatchonly,omitempty"`
Fee *float64 `json:"fee,omitempty"`
Vout uint32 `json:"vout"`
}
// GetTransactionResult models the data from the gettransaction command.
type GetTransactionResult struct {
Amount float64 `json:"amount"`
Fee float64 `json:"fee,omitempty"`
Confirmations int64 `json:"confirmations"`
BlockHash string `json:"blockhash"`
BlockIndex int64 `json:"blockindex"`
BlockTime int64 `json:"blocktime"`
TxID string `json:"txid"`
WalletConflicts []string `json:"walletconflicts"`
Time int64 `json:"time"`
TimeReceived int64 `json:"timereceived"`
Details []GetTransactionDetailsResult `json:"details"`
Hex string `json:"hex"`
}
// InfoWalletResult models the data returned by the wallet server getinfo
// command.
type InfoWalletResult struct {
Version int32 `json:"version"`
ProtocolVersion int32 `json:"protocolversion"`
WalletVersion int32 `json:"walletversion"`
Balance float64 `json:"balance"`
Blocks int32 `json:"blocks"`
TimeOffset int64 `json:"timeoffset"`
Connections int32 `json:"connections"`
Proxy string `json:"proxy"`
Difficulty float64 `json:"difficulty"`
TestNet bool `json:"testnet"`
KeypoolOldest int64 `json:"keypoololdest"`
KeypoolSize int32 `json:"keypoolsize"`
UnlockedUntil int64 `json:"unlocked_until"`
PaytxFee float64 `json:"paytxfee"`
RelayFee float64 `json:"relayfee"`
Errors string `json:"errors"`
}
// ListTransactionsResult models the data from the listtransactions command.
type ListTransactionsResult struct {
Abandoned bool `json:"abandoned"`
Account string `json:"account"`
Address string `json:"address,omitempty"`
Amount float64 `json:"amount"`
BIP125Replaceable string `json:"bip125-replaceable,omitempty"`
BlockHash string `json:"blockhash,omitempty"`
BlockIndex *int64 `json:"blockindex,omitempty"`
BlockTime int64 `json:"blocktime,omitempty"`
Category string `json:"category"`
Confirmations int64 `json:"confirmations"`
Fee *float64 `json:"fee,omitempty"`
Generated bool `json:"generated,omitempty"`
InvolvesWatchOnly bool `json:"involveswatchonly,omitempty"`
Time int64 `json:"time"`
TimeReceived int64 `json:"timereceived"`
Trusted bool `json:"trusted"`
TxID string `json:"txid"`
Vout uint32 `json:"vout"`
WalletConflicts []string `json:"walletconflicts"`
Comment string `json:"comment,omitempty"`
OtherAccount string `json:"otheraccount,omitempty"`
}
// ListReceivedByAccountResult models the data from the listreceivedbyaccount
// command.
type ListReceivedByAccountResult struct {
Account string `json:"account"`
Amount float64 `json:"amount"`
Confirmations uint64 `json:"confirmations"`
}
// ListReceivedByAddressResult models the data from the listreceivedbyaddress
// command.
type ListReceivedByAddressResult struct {
Account string `json:"account"`
Address string `json:"address"`
Amount float64 `json:"amount"`
Confirmations uint64 `json:"confirmations"`
TxIDs []string `json:"txids,omitempty"`
InvolvesWatchonly bool `json:"involvesWatchonly,omitempty"`
}
// ListSinceBlockResult models the data from the listsinceblock command.
type ListSinceBlockResult struct {
Transactions []ListTransactionsResult `json:"transactions"`
LastBlock string `json:"lastblock"`
}
// ListUnspentResult models a successful response from the listunspent request.
type ListUnspentResult struct {
TxID string `json:"txid"`
Vout uint32 `json:"vout"`
Address string `json:"address"`
Account string `json:"account"`
ScriptPubKey string `json:"scriptPubKey"`
RedeemScript string `json:"redeemScript,omitempty"`
Amount float64 `json:"amount"`
Confirmations int64 `json:"confirmations"`
Spendable bool `json:"spendable"`
}
// SignRawTransactionError models the data that contains script verification
// errors from the signrawtransaction request.
type SignRawTransactionError struct {
TxID string `json:"txid"`
Vout uint32 `json:"vout"`
ScriptSig string `json:"scriptSig"`
Sequence uint32 `json:"sequence"`
Error string `json:"error"`
}
// SignRawTransactionResult models the data from the signrawtransaction
// command.
type SignRawTransactionResult struct {
Hex string `json:"hex"`
Complete bool `json:"complete"`
Errors []SignRawTransactionError `json:"errors,omitempty"`
}
// ValidateAddressWalletResult models the data returned by the wallet server
// validateaddress command.
type ValidateAddressWalletResult struct {
IsValid bool `json:"isvalid"`
Address string `json:"address,omitempty"`
IsMine bool `json:"ismine,omitempty"`
IsWatchOnly bool `json:"iswatchonly,omitempty"`
IsScript bool `json:"isscript,omitempty"`
PubKey string `json:"pubkey,omitempty"`
IsCompressed bool `json:"iscompressed,omitempty"`
Account string `json:"account,omitempty"`
Addresses []string `json:"addresses,omitempty"`
Hex string `json:"hex,omitempty"`
Script string `json:"script,omitempty"`
SigsRequired int32 `json:"sigsrequired,omitempty"`
}
// GetBestBlockResult models the data from the getbestblock command.
type GetBestBlockResult struct {
Hash string `json:"hash"`
Height int32 `json:"height"`
}

View File

@ -0,0 +1,128 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcjson
// NOTE: This file is intended to house the RPC commands that are supported by
// a wallet server, but are only available via websockets.
// CreateEncryptedWalletCmd defines the createencryptedwallet JSON-RPC command.
type CreateEncryptedWalletCmd struct {
Passphrase string
}
// NewCreateEncryptedWalletCmd returns a new instance which can be used to issue
// a createencryptedwallet JSON-RPC command.
func NewCreateEncryptedWalletCmd(passphrase string) *CreateEncryptedWalletCmd {
return &CreateEncryptedWalletCmd{
Passphrase: passphrase,
}
}
// ExportWatchingWalletCmd defines the exportwatchingwallet JSON-RPC command.
type ExportWatchingWalletCmd struct {
Account *string
Download *bool `jsonrpcdefault:"false"`
}
// NewExportWatchingWalletCmd returns a new instance which can be used to issue
// a exportwatchingwallet JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewExportWatchingWalletCmd(account *string, download *bool) *ExportWatchingWalletCmd {
return &ExportWatchingWalletCmd{
Account: account,
Download: download,
}
}
// GetUnconfirmedBalanceCmd defines the getunconfirmedbalance JSON-RPC command.
type GetUnconfirmedBalanceCmd struct {
Account *string
}
// NewGetUnconfirmedBalanceCmd returns a new instance which can be used to issue
// a getunconfirmedbalance JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewGetUnconfirmedBalanceCmd(account *string) *GetUnconfirmedBalanceCmd {
return &GetUnconfirmedBalanceCmd{
Account: account,
}
}
// ListAddressTransactionsCmd defines the listaddresstransactions JSON-RPC
// command.
type ListAddressTransactionsCmd struct {
Addresses []string
Account *string
}
// NewListAddressTransactionsCmd returns a new instance which can be used to
// issue a listaddresstransactions JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListAddressTransactionsCmd(addresses []string, account *string) *ListAddressTransactionsCmd {
return &ListAddressTransactionsCmd{
Addresses: addresses,
Account: account,
}
}
// ListAllTransactionsCmd defines the listalltransactions JSON-RPC command.
type ListAllTransactionsCmd struct {
Account *string
}
// NewListAllTransactionsCmd returns a new instance which can be used to issue a
// listalltransactions JSON-RPC command.
//
// The parameters which are pointers indicate they are optional. Passing nil
// for optional parameters will use the default value.
func NewListAllTransactionsCmd(account *string) *ListAllTransactionsCmd {
return &ListAllTransactionsCmd{
Account: account,
}
}
// RecoverAddressesCmd defines the recoveraddresses JSON-RPC command.
type RecoverAddressesCmd struct {
Account string
N int
}
// NewRecoverAddressesCmd returns a new instance which can be used to issue a
// recoveraddresses JSON-RPC command.
func NewRecoverAddressesCmd(account string, n int) *RecoverAddressesCmd {
return &RecoverAddressesCmd{
Account: account,
N: n,
}
}
// WalletIsLockedCmd defines the walletislocked JSON-RPC command.
type WalletIsLockedCmd struct{}
// NewWalletIsLockedCmd returns a new instance which can be used to issue a
// walletislocked JSON-RPC command.
func NewWalletIsLockedCmd() *WalletIsLockedCmd {
return &WalletIsLockedCmd{}
}
func init() {
// The commands in this file are only usable with a wallet server via
// websockets.
flags := UFWalletOnly | UFWebsocketOnly
MustRegisterCmd("createencryptedwallet", (*CreateEncryptedWalletCmd)(nil), flags)
MustRegisterCmd("exportwatchingwallet", (*ExportWatchingWalletCmd)(nil), flags)
MustRegisterCmd("getunconfirmedbalance", (*GetUnconfirmedBalanceCmd)(nil), flags)
MustRegisterCmd("listaddresstransactions", (*ListAddressTransactionsCmd)(nil), flags)
MustRegisterCmd("listalltransactions", (*ListAllTransactionsCmd)(nil), flags)
MustRegisterCmd("recoveraddresses", (*RecoverAddressesCmd)(nil), flags)
MustRegisterCmd("walletislocked", (*WalletIsLockedCmd)(nil), flags)
}

View File

@ -0,0 +1,95 @@
// Copyright (c) 2014 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
// NOTE: This file is intended to house the RPC websocket notifications that are
// supported by a wallet server.
package btcjson
const (
// AccountBalanceNtfnMethod is the method used for account balance
// notifications.
AccountBalanceNtfnMethod = "accountbalance"
// BtcdConnectedNtfnMethod is the method used for notifications when
// a wallet server is connected to a chain server.
BtcdConnectedNtfnMethod = "btcdconnected"
// WalletLockStateNtfnMethod is the method used to notify the lock state
// of a wallet has changed.
WalletLockStateNtfnMethod = "walletlockstate"
// NewTxNtfnMethod is the method used to notify that a wallet server has
// added a new transaction to the transaction store.
NewTxNtfnMethod = "newtx"
)
// AccountBalanceNtfn defines the accountbalance JSON-RPC notification.
type AccountBalanceNtfn struct {
Account string
Balance float64 // In BTC
Confirmed bool // Whether Balance is confirmed or unconfirmed.
}
// NewAccountBalanceNtfn returns a new instance which can be used to issue an
// accountbalance JSON-RPC notification.
func NewAccountBalanceNtfn(account string, balance float64, confirmed bool) *AccountBalanceNtfn {
return &AccountBalanceNtfn{
Account: account,
Balance: balance,
Confirmed: confirmed,
}
}
// BtcdConnectedNtfn defines the btcdconnected JSON-RPC notification.
type BtcdConnectedNtfn struct {
Connected bool
}
// NewBtcdConnectedNtfn returns a new instance which can be used to issue a
// btcdconnected JSON-RPC notification.
func NewBtcdConnectedNtfn(connected bool) *BtcdConnectedNtfn {
return &BtcdConnectedNtfn{
Connected: connected,
}
}
// WalletLockStateNtfn defines the walletlockstate JSON-RPC notification.
type WalletLockStateNtfn struct {
Locked bool
}
// NewWalletLockStateNtfn returns a new instance which can be used to issue a
// walletlockstate JSON-RPC notification.
func NewWalletLockStateNtfn(locked bool) *WalletLockStateNtfn {
return &WalletLockStateNtfn{
Locked: locked,
}
}
// NewTxNtfn defines the newtx JSON-RPC notification.
type NewTxNtfn struct {
Account string
Details ListTransactionsResult
}
// NewNewTxNtfn returns a new instance which can be used to issue a newtx
// JSON-RPC notification.
func NewNewTxNtfn(account string, details ListTransactionsResult) *NewTxNtfn {
return &NewTxNtfn{
Account: account,
Details: details,
}
}
func init() {
// The commands in this file are only usable with a wallet server via
// websockets and are notifications.
flags := UFWalletOnly | UFWebsocketOnly | UFNotification
MustRegisterCmd(AccountBalanceNtfnMethod, (*AccountBalanceNtfn)(nil), flags)
MustRegisterCmd(BtcdConnectedNtfnMethod, (*BtcdConnectedNtfn)(nil), flags)
MustRegisterCmd(WalletLockStateNtfnMethod, (*WalletLockStateNtfn)(nil), flags)
MustRegisterCmd(NewTxNtfnMethod, (*NewTxNtfn)(nil), flags)
}

85
vendor/github.com/btcsuite/btcd/chaincfg/README.md generated vendored Normal file
View File

@ -0,0 +1,85 @@
chaincfg
========
[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/btcd)
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcd/chaincfg)
Package chaincfg defines chain configuration parameters for the three standard
Bitcoin networks and provides the ability for callers to define their own custom
Bitcoin networks.
Although this package was primarily written for btcd, it has intentionally been
designed so it can be used as a standalone package for any projects needing to
use parameters for the standard Bitcoin networks or for projects needing to
define their own network.
## Sample Use
```Go
package main
import (
"flag"
"fmt"
"log"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcd/chaincfg"
)
var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network")
// By default (without -testnet), use mainnet.
var chainParams = &chaincfg.MainNetParams
func main() {
flag.Parse()
// Modify active network parameters if operating on testnet.
if *testnet {
chainParams = &chaincfg.TestNet3Params
}
// later...
// Create and print new payment address, specific to the active network.
pubKeyHash := make([]byte, 20)
addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, chainParams)
if err != nil {
log.Fatal(err)
}
fmt.Println(addr)
}
```
## Installation and Updating
```bash
$ go get -u github.com/btcsuite/btcd/chaincfg
```
## GPG Verification Key
All official release tags are signed by Conformal so users can ensure the code
has not been tampered with and is coming from the btcsuite developers. To
verify the signature perform the following:
- Download the public key from the Conformal website at
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
- Import the public key into your GPG keyring:
```bash
gpg --import GIT-GPG-KEY-conformal.txt
```
- Verify the release tag with the following command where `TAG_NAME` is a
placeholder for the specific tag:
```bash
git tag -v TAG_NAME
```
## License
Package chaincfg is licensed under the [copyfree](http://copyfree.org) ISC
License.

View File

@ -0,0 +1,41 @@
chainhash
=========
[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/btcd)
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcd/chaincfg/chainhash)
=======
chainhash provides a generic hash type and associated functions that allows the
specific hash algorithm to be abstracted.
## Installation and Updating
```bash
$ go get -u github.com/btcsuite/btcd/chaincfg/chainhash
```
## GPG Verification Key
All official release tags are signed by Conformal so users can ensure the code
has not been tampered with and is coming from the btcsuite developers. To
verify the signature perform the following:
- Download the public key from the Conformal website at
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
- Import the public key into your GPG keyring:
```bash
gpg --import GIT-GPG-KEY-conformal.txt
```
- Verify the release tag with the following command where `TAG_NAME` is a
placeholder for the specific tag:
```bash
git tag -v TAG_NAME
```
## License
Package chainhash is licensed under the [copyfree](http://copyfree.org) ISC
License.

View File

@ -0,0 +1,5 @@
// Package chainhash provides abstracted hash functionality.
//
// This package provides a generic hash type and associated functions that
// allows the specific hash algorithm to be abstracted.
package chainhash

View File

@ -0,0 +1,128 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Copyright (c) 2015 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package chainhash
import (
"encoding/hex"
"fmt"
)
// HashSize of array used to store hashes. See Hash.
const HashSize = 32
// MaxHashStringSize is the maximum length of a Hash hash string.
const MaxHashStringSize = HashSize * 2
// ErrHashStrSize describes an error that indicates the caller specified a hash
// string that has too many characters.
var ErrHashStrSize = fmt.Errorf("max hash string length is %v bytes", MaxHashStringSize)
// Hash is used in several of the bitcoin messages and common structures. It
// typically represents the double sha256 of data.
type Hash [HashSize]byte
// String returns the Hash as the hexadecimal string of the byte-reversed
// hash.
func (hash Hash) String() string {
for i := 0; i < HashSize/2; i++ {
hash[i], hash[HashSize-1-i] = hash[HashSize-1-i], hash[i]
}
return hex.EncodeToString(hash[:])
}
// CloneBytes returns a copy of the bytes which represent the hash as a byte
// slice.
//
// NOTE: It is generally cheaper to just slice the hash directly thereby reusing
// the same bytes rather than calling this method.
func (hash *Hash) CloneBytes() []byte {
newHash := make([]byte, HashSize)
copy(newHash, hash[:])
return newHash
}
// SetBytes sets the bytes which represent the hash. An error is returned if
// the number of bytes passed in is not HashSize.
func (hash *Hash) SetBytes(newHash []byte) error {
nhlen := len(newHash)
if nhlen != HashSize {
return fmt.Errorf("invalid hash length of %v, want %v", nhlen,
HashSize)
}
copy(hash[:], newHash)
return nil
}
// IsEqual returns true if target is the same as hash.
func (hash *Hash) IsEqual(target *Hash) bool {
if hash == nil && target == nil {
return true
}
if hash == nil || target == nil {
return false
}
return *hash == *target
}
// NewHash returns a new Hash from a byte slice. An error is returned if
// the number of bytes passed in is not HashSize.
func NewHash(newHash []byte) (*Hash, error) {
var sh Hash
err := sh.SetBytes(newHash)
if err != nil {
return nil, err
}
return &sh, err
}
// NewHashFromStr creates a Hash from a hash string. The string should be
// the hexadecimal string of a byte-reversed hash, but any missing characters
// result in zero padding at the end of the Hash.
func NewHashFromStr(hash string) (*Hash, error) {
ret := new(Hash)
err := Decode(ret, hash)
if err != nil {
return nil, err
}
return ret, nil
}
// Decode decodes the byte-reversed hexadecimal string encoding of a Hash to a
// destination.
func Decode(dst *Hash, src string) error {
// Return error if hash string is too long.
if len(src) > MaxHashStringSize {
return ErrHashStrSize
}
// Hex decoder expects the hash to be a multiple of two. When not, pad
// with a leading zero.
var srcBytes []byte
if len(src)%2 == 0 {
srcBytes = []byte(src)
} else {
srcBytes = make([]byte, 1+len(src))
srcBytes[0] = '0'
copy(srcBytes[1:], src)
}
// Hex decode the source bytes to a temporary destination.
var reversedHash Hash
_, err := hex.Decode(reversedHash[HashSize-hex.DecodedLen(len(srcBytes)):], srcBytes)
if err != nil {
return err
}
// Reverse copy from the temporary hash to destination. Because the
// temporary was zeroed, the written result will be correctly padded.
for i, b := range reversedHash[:HashSize/2] {
dst[i], dst[HashSize-1-i] = reversedHash[HashSize-1-i], b
}
return nil
}

View File

@ -0,0 +1,33 @@
// Copyright (c) 2015 The Decred developers
// Copyright (c) 2016-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package chainhash
import "crypto/sha256"
// HashB calculates hash(b) and returns the resulting bytes.
func HashB(b []byte) []byte {
hash := sha256.Sum256(b)
return hash[:]
}
// HashH calculates hash(b) and returns the resulting bytes as a Hash.
func HashH(b []byte) Hash {
return Hash(sha256.Sum256(b))
}
// DoubleHashB calculates hash(hash(b)) and returns the resulting bytes.
func DoubleHashB(b []byte) []byte {
first := sha256.Sum256(b)
second := sha256.Sum256(first[:])
return second[:]
}
// DoubleHashH calculates hash(hash(b)) and returns the resulting bytes as a
// Hash.
func DoubleHashH(b []byte) Hash {
first := sha256.Sum256(b)
return Hash(sha256.Sum256(first[:]))
}

61
vendor/github.com/btcsuite/btcd/chaincfg/doc.go generated vendored Normal file
View File

@ -0,0 +1,61 @@
// Package chaincfg defines chain configuration parameters.
//
// In addition to the main Bitcoin network, which is intended for the transfer
// of monetary value, there also exists two currently active standard networks:
// regression test and testnet (version 3). These networks are incompatible
// with each other (each sharing a different genesis block) and software should
// handle errors where input intended for one network is used on an application
// instance running on a different network.
//
// For library packages, chaincfg provides the ability to lookup chain
// parameters and encoding magics when passed a *Params. Older APIs not updated
// to the new convention of passing a *Params may lookup the parameters for a
// wire.BitcoinNet using ParamsForNet, but be aware that this usage is
// deprecated and will be removed from chaincfg in the future.
//
// For main packages, a (typically global) var may be assigned the address of
// one of the standard Param vars for use as the application's "active" network.
// When a network parameter is needed, it may then be looked up through this
// variable (either directly, or hidden in a library call).
//
// package main
//
// import (
// "flag"
// "fmt"
// "log"
//
// "github.com/btcsuite/btcutil"
// "github.com/btcsuite/btcd/chaincfg"
// )
//
// var testnet = flag.Bool("testnet", false, "operate on the testnet Bitcoin network")
//
// // By default (without -testnet), use mainnet.
// var chainParams = &chaincfg.MainNetParams
//
// func main() {
// flag.Parse()
//
// // Modify active network parameters if operating on testnet.
// if *testnet {
// chainParams = &chaincfg.TestNet3Params
// }
//
// // later...
//
// // Create and print new payment address, specific to the active network.
// pubKeyHash := make([]byte, 20)
// addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash, chainParams)
// if err != nil {
// log.Fatal(err)
// }
// fmt.Println(addr)
// }
//
// If an application does not use one of the three standard Bitcoin networks,
// a new Params struct may be created which defines the parameters for the
// non-standard network. As a general rule of thumb, all network parameters
// should be unique to the network, but parameter collisions can still occur
// (unfortunately, this is the case with regtest and testnet3 sharing magics).
package chaincfg

172
vendor/github.com/btcsuite/btcd/chaincfg/genesis.go generated vendored Normal file
View File

@ -0,0 +1,172 @@
// Copyright (c) 2014-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package chaincfg
import (
"time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
)
// genesisCoinbaseTx is the coinbase transaction for the genesis blocks for
// the main network, regression test network, and test network (version 3).
var genesisCoinbaseTx = wire.MsgTx{
Version: 1,
TxIn: []*wire.TxIn{
{
PreviousOutPoint: wire.OutPoint{
Hash: chainhash.Hash{},
Index: 0xffffffff,
},
SignatureScript: []byte{
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */
0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */
0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */
0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */
0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */
0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */
0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/
0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */
0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/
0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */
},
Sequence: 0xffffffff,
},
},
TxOut: []*wire.TxOut{
{
Value: 0x12a05f200,
PkScript: []byte{
0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */
0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */
0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */
0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */
0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */
0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */
0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */
0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */
0x1d, 0x5f, 0xac, /* |._.| */
},
},
},
LockTime: 0,
}
// genesisHash is the hash of the first block in the block chain for the main
// network (genesis block).
var genesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
})
// genesisMerkleRoot is the hash of the first transaction in the genesis block
// for the main network.
var genesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a,
})
// genesisBlock defines the genesis block of the block chain which serves as the
// public transaction ledger for the main network.
var genesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
MerkleRoot: genesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 18:15:05 +0000 UTC
Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000]
Nonce: 0x7c2bac1d, // 2083236893
},
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
}
// regTestGenesisHash is the hash of the first block in the block chain for the
// regression test network (genesis block).
var regTestGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0x06, 0x22, 0x6e, 0x46, 0x11, 0x1a, 0x0b, 0x59,
0xca, 0xaf, 0x12, 0x60, 0x43, 0xeb, 0x5b, 0xbf,
0x28, 0xc3, 0x4f, 0x3a, 0x5e, 0x33, 0x2a, 0x1f,
0xc7, 0xb2, 0xb7, 0x3c, 0xf1, 0x88, 0x91, 0x0f,
})
// regTestGenesisMerkleRoot is the hash of the first transaction in the genesis
// block for the regression test network. It is the same as the merkle root for
// the main network.
var regTestGenesisMerkleRoot = genesisMerkleRoot
// regTestGenesisBlock defines the genesis block of the block chain which serves
// as the public transaction ledger for the regression test network.
var regTestGenesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
MerkleRoot: regTestGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC
Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000]
Nonce: 2,
},
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
}
// testNet3GenesisHash is the hash of the first block in the block chain for the
// test network (version 3).
var testNet3GenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71,
0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce, 0xc3, 0xae,
0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad,
0x01, 0xea, 0x33, 0x09, 0x00, 0x00, 0x00, 0x00,
})
// testNet3GenesisMerkleRoot is the hash of the first transaction in the genesis
// block for the test network (version 3). It is the same as the merkle root
// for the main network.
var testNet3GenesisMerkleRoot = genesisMerkleRoot
// testNet3GenesisBlock defines the genesis block of the block chain which
// serves as the public transaction ledger for the test network (version 3).
var testNet3GenesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
MerkleRoot: testNet3GenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Timestamp: time.Unix(1296688602, 0), // 2011-02-02 23:16:42 +0000 UTC
Bits: 0x1d00ffff, // 486604799 [00000000ffff0000000000000000000000000000000000000000000000000000]
Nonce: 0x18aea41a, // 414098458
},
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
}
// simNetGenesisHash is the hash of the first block in the block chain for the
// simulation test network.
var simNetGenesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0xf6, 0x7a, 0xd7, 0x69, 0x5d, 0x9b, 0x66, 0x2a,
0x72, 0xff, 0x3d, 0x8e, 0xdb, 0xbb, 0x2d, 0xe0,
0xbf, 0xa6, 0x7b, 0x13, 0x97, 0x4b, 0xb9, 0x91,
0x0d, 0x11, 0x6d, 0x5c, 0xbd, 0x86, 0x3e, 0x68,
})
// simNetGenesisMerkleRoot is the hash of the first transaction in the genesis
// block for the simulation test network. It is the same as the merkle root for
// the main network.
var simNetGenesisMerkleRoot = genesisMerkleRoot
// simNetGenesisBlock defines the genesis block of the block chain which serves
// as the public transaction ledger for the simulation test network.
var simNetGenesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
MerkleRoot: simNetGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b
Timestamp: time.Unix(1401292357, 0), // 2014-05-28 15:52:37 +0000 UTC
Bits: 0x207fffff, // 545259519 [7fffff0000000000000000000000000000000000000000000000000000000000]
Nonce: 2,
},
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
}

702
vendor/github.com/btcsuite/btcd/chaincfg/params.go generated vendored Normal file
View File

@ -0,0 +1,702 @@
// Copyright (c) 2014-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package chaincfg
import (
"errors"
"math"
"math/big"
"strings"
"time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
)
// These variables are the chain proof-of-work limit parameters for each default
// network.
var (
// bigOne is 1 represented as a big.Int. It is defined here to avoid
// the overhead of creating it multiple times.
bigOne = big.NewInt(1)
// mainPowLimit is the highest proof of work value a Bitcoin block can
// have for the main network. It is the value 2^224 - 1.
mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne)
// regressionPowLimit is the highest proof of work value a Bitcoin block
// can have for the regression test network. It is the value 2^255 - 1.
regressionPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne)
// testNet3PowLimit is the highest proof of work value a Bitcoin block
// can have for the test network (version 3). It is the value
// 2^224 - 1.
testNet3PowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne)
// simNetPowLimit is the highest proof of work value a Bitcoin block
// can have for the simulation test network. It is the value 2^255 - 1.
simNetPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 255), bigOne)
)
// Checkpoint identifies a known good point in the block chain. Using
// checkpoints allows a few optimizations for old blocks during initial download
// and also prevents forks from old blocks.
//
// Each checkpoint is selected based upon several factors. See the
// documentation for blockchain.IsCheckpointCandidate for details on the
// selection criteria.
type Checkpoint struct {
Height int32
Hash *chainhash.Hash
}
// DNSSeed identifies a DNS seed.
type DNSSeed struct {
// Host defines the hostname of the seed.
Host string
// HasFiltering defines whether the seed supports filtering
// by service flags (wire.ServiceFlag).
HasFiltering bool
}
// ConsensusDeployment defines details related to a specific consensus rule
// change that is voted in. This is part of BIP0009.
type ConsensusDeployment struct {
// BitNumber defines the specific bit number within the block version
// this particular soft-fork deployment refers to.
BitNumber uint8
// StartTime is the median block time after which voting on the
// deployment starts.
StartTime uint64
// ExpireTime is the median block time after which the attempted
// deployment expires.
ExpireTime uint64
}
// Constants that define the deployment offset in the deployments field of the
// parameters for each deployment. This is useful to be able to get the details
// of a specific deployment by name.
const (
// DeploymentTestDummy defines the rule change deployment ID for testing
// purposes.
DeploymentTestDummy = iota
// DeploymentCSV defines the rule change deployment ID for the CSV
// soft-fork package. The CSV package includes the deployment of BIPS
// 68, 112, and 113.
DeploymentCSV
// DeploymentSegwit defines the rule change deployment ID for the
// Segregated Witness (segwit) soft-fork package. The segwit package
// includes the deployment of BIPS 141, 142, 144, 145, 147 and 173.
DeploymentSegwit
// NOTE: DefinedDeployments must always come last since it is used to
// determine how many defined deployments there currently are.
// DefinedDeployments is the number of currently defined deployments.
DefinedDeployments
)
// Params defines a Bitcoin network by its parameters. These parameters may be
// used by Bitcoin applications to differentiate networks as well as addresses
// and keys for one network from those intended for use on another network.
type Params struct {
// Name defines a human-readable identifier for the network.
Name string
// Net defines the magic bytes used to identify the network.
Net wire.BitcoinNet
// DefaultPort defines the default peer-to-peer port for the network.
DefaultPort string
// DNSSeeds defines a list of DNS seeds for the network that are used
// as one method to discover peers.
DNSSeeds []DNSSeed
// GenesisBlock defines the first block of the chain.
GenesisBlock *wire.MsgBlock
// GenesisHash is the starting block hash.
GenesisHash *chainhash.Hash
// PowLimit defines the highest allowed proof of work value for a block
// as a uint256.
PowLimit *big.Int
// PowLimitBits defines the highest allowed proof of work value for a
// block in compact form.
PowLimitBits uint32
// These fields define the block heights at which the specified softfork
// BIP became active.
BIP0034Height int32
BIP0065Height int32
BIP0066Height int32
// CoinbaseMaturity is the number of blocks required before newly mined
// coins (coinbase transactions) can be spent.
CoinbaseMaturity uint16
// SubsidyReductionInterval is the interval of blocks before the subsidy
// is reduced.
SubsidyReductionInterval int32
// TargetTimespan is the desired amount of time that should elapse
// before the block difficulty requirement is examined to determine how
// it should be changed in order to maintain the desired block
// generation rate.
TargetTimespan time.Duration
// TargetTimePerBlock is the desired amount of time to generate each
// block.
TargetTimePerBlock time.Duration
// RetargetAdjustmentFactor is the adjustment factor used to limit
// the minimum and maximum amount of adjustment that can occur between
// difficulty retargets.
RetargetAdjustmentFactor int64
// ReduceMinDifficulty defines whether the network should reduce the
// minimum required difficulty after a long enough period of time has
// passed without finding a block. This is really only useful for test
// networks and should not be set on a main network.
ReduceMinDifficulty bool
// MinDiffReductionTime is the amount of time after which the minimum
// required difficulty should be reduced when a block hasn't been found.
//
// NOTE: This only applies if ReduceMinDifficulty is true.
MinDiffReductionTime time.Duration
// GenerateSupported specifies whether or not CPU mining is allowed.
GenerateSupported bool
// Checkpoints ordered from oldest to newest.
Checkpoints []Checkpoint
// These fields are related to voting on consensus rule changes as
// defined by BIP0009.
//
// RuleChangeActivationThreshold is the number of blocks in a threshold
// state retarget window for which a positive vote for a rule change
// must be cast in order to lock in a rule change. It should typically
// be 95% for the main network and 75% for test networks.
//
// MinerConfirmationWindow is the number of blocks in each threshold
// state retarget window.
//
// Deployments define the specific consensus rule changes to be voted
// on.
RuleChangeActivationThreshold uint32
MinerConfirmationWindow uint32
Deployments [DefinedDeployments]ConsensusDeployment
// Mempool parameters
RelayNonStdTxs bool
// Human-readable part for Bech32 encoded segwit addresses, as defined
// in BIP 173.
Bech32HRPSegwit string
// Address encoding magics
PubKeyHashAddrID byte // First byte of a P2PKH address
ScriptHashAddrID byte // First byte of a P2SH address
PrivateKeyID byte // First byte of a WIF private key
WitnessPubKeyHashAddrID byte // First byte of a P2WPKH address
WitnessScriptHashAddrID byte // First byte of a P2WSH address
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID [4]byte
HDPublicKeyID [4]byte
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType uint32
}
// MainNetParams defines the network parameters for the main Bitcoin network.
var MainNetParams = Params{
Name: "mainnet",
Net: wire.MainNet,
DefaultPort: "8333",
DNSSeeds: []DNSSeed{
{"seed.bitcoin.sipa.be", true},
{"dnsseed.bluematt.me", true},
{"dnsseed.bitcoin.dashjr.org", false},
{"seed.bitcoinstats.com", true},
{"seed.bitnodes.io", false},
{"seed.bitcoin.jonasschnelli.ch", true},
},
// Chain parameters
GenesisBlock: &genesisBlock,
GenesisHash: &genesisHash,
PowLimit: mainPowLimit,
PowLimitBits: 0x1d00ffff,
BIP0034Height: 227931, // 000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8
BIP0065Height: 388381, // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
BIP0066Height: 363725, // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
CoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimespan: time.Hour * 24 * 14, // 14 days
TargetTimePerBlock: time.Minute * 10, // 10 minutes
RetargetAdjustmentFactor: 4, // 25% less, 400% more
ReduceMinDifficulty: false,
MinDiffReductionTime: 0,
GenerateSupported: false,
// Checkpoints ordered from oldest to newest.
Checkpoints: []Checkpoint{
{11111, newHashFromStr("0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")},
{33333, newHashFromStr("000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")},
{74000, newHashFromStr("0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")},
{105000, newHashFromStr("00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")},
{134444, newHashFromStr("00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")},
{168000, newHashFromStr("000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")},
{193000, newHashFromStr("000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")},
{210000, newHashFromStr("000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")},
{216116, newHashFromStr("00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")},
{225430, newHashFromStr("00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")},
{250000, newHashFromStr("000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")},
{267300, newHashFromStr("000000000000000a83fbd660e918f218bf37edd92b748ad940483c7c116179ac")},
{279000, newHashFromStr("0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")},
{300255, newHashFromStr("0000000000000000162804527c6e9b9f0563a280525f9d08c12041def0a0f3b2")},
{319400, newHashFromStr("000000000000000021c6052e9becade189495d1c539aa37c58917305fd15f13b")},
{343185, newHashFromStr("0000000000000000072b8bf361d01a6ba7d445dd024203fafc78768ed4368554")},
{352940, newHashFromStr("000000000000000010755df42dba556bb72be6a32f3ce0b6941ce4430152c9ff")},
{382320, newHashFromStr("00000000000000000a8dc6ed5b133d0eb2fd6af56203e4159789b092defd8ab2")},
},
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
// target proof of work timespan / target proof of work spacing
RuleChangeActivationThreshold: 1916, // 95% of MinerConfirmationWindow
MinerConfirmationWindow: 2016, //
Deployments: [DefinedDeployments]ConsensusDeployment{
DeploymentTestDummy: {
BitNumber: 28,
StartTime: 1199145601, // January 1, 2008 UTC
ExpireTime: 1230767999, // December 31, 2008 UTC
},
DeploymentCSV: {
BitNumber: 0,
StartTime: 1462060800, // May 1st, 2016
ExpireTime: 1493596800, // May 1st, 2017
},
DeploymentSegwit: {
BitNumber: 1,
StartTime: 1479168000, // November 15, 2016 UTC
ExpireTime: 1510704000, // November 15, 2017 UTC.
},
},
// Mempool parameters
RelayNonStdTxs: false,
// Human-readable part for Bech32 encoded segwit addresses, as defined in
// BIP 173.
Bech32HRPSegwit: "bc", // always bc for main net
// Address encoding magics
PubKeyHashAddrID: 0x00, // starts with 1
ScriptHashAddrID: 0x05, // starts with 3
PrivateKeyID: 0x80, // starts with 5 (uncompressed) or K (compressed)
WitnessPubKeyHashAddrID: 0x06, // starts with p2
WitnessScriptHashAddrID: 0x0A, // starts with 7Xh
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, // starts with xprv
HDPublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // starts with xpub
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 0,
}
// RegressionNetParams defines the network parameters for the regression test
// Bitcoin network. Not to be confused with the test Bitcoin network (version
// 3), this network is sometimes simply called "testnet".
var RegressionNetParams = Params{
Name: "regtest",
Net: wire.TestNet,
DefaultPort: "18444",
DNSSeeds: []DNSSeed{},
// Chain parameters
GenesisBlock: &regTestGenesisBlock,
GenesisHash: &regTestGenesisHash,
PowLimit: regressionPowLimit,
PowLimitBits: 0x207fffff,
CoinbaseMaturity: 100,
BIP0034Height: 100000000, // Not active - Permit ver 1 blocks
BIP0065Height: 1351, // Used by regression tests
BIP0066Height: 1251, // Used by regression tests
SubsidyReductionInterval: 150,
TargetTimespan: time.Hour * 24 * 14, // 14 days
TargetTimePerBlock: time.Minute * 10, // 10 minutes
RetargetAdjustmentFactor: 4, // 25% less, 400% more
ReduceMinDifficulty: true,
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
GenerateSupported: true,
// Checkpoints ordered from oldest to newest.
Checkpoints: nil,
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
// target proof of work timespan / target proof of work spacing
RuleChangeActivationThreshold: 108, // 75% of MinerConfirmationWindow
MinerConfirmationWindow: 144,
Deployments: [DefinedDeployments]ConsensusDeployment{
DeploymentTestDummy: {
BitNumber: 28,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires
},
DeploymentCSV: {
BitNumber: 0,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires
},
DeploymentSegwit: {
BitNumber: 1,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires.
},
},
// Mempool parameters
RelayNonStdTxs: true,
// Human-readable part for Bech32 encoded segwit addresses, as defined in
// BIP 173.
Bech32HRPSegwit: "bcrt", // always bcrt for reg test net
// Address encoding magics
PubKeyHashAddrID: 0x6f, // starts with m or n
ScriptHashAddrID: 0xc4, // starts with 2
PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed)
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
HDPublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 1,
}
// TestNet3Params defines the network parameters for the test Bitcoin network
// (version 3). Not to be confused with the regression test network, this
// network is sometimes simply called "testnet".
var TestNet3Params = Params{
Name: "testnet3",
Net: wire.TestNet3,
DefaultPort: "18333",
DNSSeeds: []DNSSeed{
{"testnet-seed.bitcoin.jonasschnelli.ch", true},
{"testnet-seed.bitcoin.schildbach.de", false},
{"seed.tbtc.petertodd.org", true},
{"testnet-seed.bluematt.me", false},
},
// Chain parameters
GenesisBlock: &testNet3GenesisBlock,
GenesisHash: &testNet3GenesisHash,
PowLimit: testNet3PowLimit,
PowLimitBits: 0x1d00ffff,
BIP0034Height: 21111, // 0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8
BIP0065Height: 581885, // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
BIP0066Height: 330776, // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
CoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimespan: time.Hour * 24 * 14, // 14 days
TargetTimePerBlock: time.Minute * 10, // 10 minutes
RetargetAdjustmentFactor: 4, // 25% less, 400% more
ReduceMinDifficulty: true,
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
GenerateSupported: false,
// Checkpoints ordered from oldest to newest.
Checkpoints: []Checkpoint{
{546, newHashFromStr("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")},
{100000, newHashFromStr("00000000009e2958c15ff9290d571bf9459e93b19765c6801ddeccadbb160a1e")},
{200000, newHashFromStr("0000000000287bffd321963ef05feab753ebe274e1d78b2fd4e2bfe9ad3aa6f2")},
{300001, newHashFromStr("0000000000004829474748f3d1bc8fcf893c88be255e6d7f571c548aff57abf4")},
{400002, newHashFromStr("0000000005e2c73b8ecb82ae2dbc2e8274614ebad7172b53528aba7501f5a089")},
{500011, newHashFromStr("00000000000929f63977fbac92ff570a9bd9e7715401ee96f2848f7b07750b02")},
{600002, newHashFromStr("000000000001f471389afd6ee94dcace5ccc44adc18e8bff402443f034b07240")},
{700000, newHashFromStr("000000000000406178b12a4dea3b27e13b3c4fe4510994fd667d7c1e6a3f4dc1")},
{800010, newHashFromStr("000000000017ed35296433190b6829db01e657d80631d43f5983fa403bfdb4c1")},
{900000, newHashFromStr("0000000000356f8d8924556e765b7a94aaebc6b5c8685dcfa2b1ee8b41acd89b")},
{1000007, newHashFromStr("00000000001ccb893d8a1f25b70ad173ce955e5f50124261bbbc50379a612ddf")},
},
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
// target proof of work timespan / target proof of work spacing
RuleChangeActivationThreshold: 1512, // 75% of MinerConfirmationWindow
MinerConfirmationWindow: 2016,
Deployments: [DefinedDeployments]ConsensusDeployment{
DeploymentTestDummy: {
BitNumber: 28,
StartTime: 1199145601, // January 1, 2008 UTC
ExpireTime: 1230767999, // December 31, 2008 UTC
},
DeploymentCSV: {
BitNumber: 0,
StartTime: 1456790400, // March 1st, 2016
ExpireTime: 1493596800, // May 1st, 2017
},
DeploymentSegwit: {
BitNumber: 1,
StartTime: 1462060800, // May 1, 2016 UTC
ExpireTime: 1493596800, // May 1, 2017 UTC.
},
},
// Mempool parameters
RelayNonStdTxs: true,
// Human-readable part for Bech32 encoded segwit addresses, as defined in
// BIP 173.
Bech32HRPSegwit: "tb", // always tb for test net
// Address encoding magics
PubKeyHashAddrID: 0x6f, // starts with m or n
ScriptHashAddrID: 0xc4, // starts with 2
WitnessPubKeyHashAddrID: 0x03, // starts with QW
WitnessScriptHashAddrID: 0x28, // starts with T7n
PrivateKeyID: 0xef, // starts with 9 (uncompressed) or c (compressed)
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with tprv
HDPublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with tpub
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 1,
}
// SimNetParams defines the network parameters for the simulation test Bitcoin
// network. This network is similar to the normal test network except it is
// intended for private use within a group of individuals doing simulation
// testing. The functionality is intended to differ in that the only nodes
// which are specifically specified are used to create the network rather than
// following normal discovery rules. This is important as otherwise it would
// just turn into another public testnet.
var SimNetParams = Params{
Name: "simnet",
Net: wire.SimNet,
DefaultPort: "18555",
DNSSeeds: []DNSSeed{}, // NOTE: There must NOT be any seeds.
// Chain parameters
GenesisBlock: &simNetGenesisBlock,
GenesisHash: &simNetGenesisHash,
PowLimit: simNetPowLimit,
PowLimitBits: 0x207fffff,
BIP0034Height: 0, // Always active on simnet
BIP0065Height: 0, // Always active on simnet
BIP0066Height: 0, // Always active on simnet
CoinbaseMaturity: 100,
SubsidyReductionInterval: 210000,
TargetTimespan: time.Hour * 24 * 14, // 14 days
TargetTimePerBlock: time.Minute * 10, // 10 minutes
RetargetAdjustmentFactor: 4, // 25% less, 400% more
ReduceMinDifficulty: true,
MinDiffReductionTime: time.Minute * 20, // TargetTimePerBlock * 2
GenerateSupported: true,
// Checkpoints ordered from oldest to newest.
Checkpoints: nil,
// Consensus rule change deployments.
//
// The miner confirmation window is defined as:
// target proof of work timespan / target proof of work spacing
RuleChangeActivationThreshold: 75, // 75% of MinerConfirmationWindow
MinerConfirmationWindow: 100,
Deployments: [DefinedDeployments]ConsensusDeployment{
DeploymentTestDummy: {
BitNumber: 28,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires
},
DeploymentCSV: {
BitNumber: 0,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires
},
DeploymentSegwit: {
BitNumber: 1,
StartTime: 0, // Always available for vote
ExpireTime: math.MaxInt64, // Never expires.
},
},
// Mempool parameters
RelayNonStdTxs: true,
// Human-readable part for Bech32 encoded segwit addresses, as defined in
// BIP 173.
Bech32HRPSegwit: "sb", // always sb for sim net
// Address encoding magics
PubKeyHashAddrID: 0x3f, // starts with S
ScriptHashAddrID: 0x7b, // starts with s
PrivateKeyID: 0x64, // starts with 4 (uncompressed) or F (compressed)
WitnessPubKeyHashAddrID: 0x19, // starts with Gg
WitnessScriptHashAddrID: 0x28, // starts with ?
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x20, 0xb9, 0x00}, // starts with sprv
HDPublicKeyID: [4]byte{0x04, 0x20, 0xbd, 0x3a}, // starts with spub
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 115, // ASCII for s
}
var (
// ErrDuplicateNet describes an error where the parameters for a Bitcoin
// network could not be set due to the network already being a standard
// network or previously-registered into this package.
ErrDuplicateNet = errors.New("duplicate Bitcoin network")
// ErrUnknownHDKeyID describes an error where the provided id which
// is intended to identify the network for a hierarchical deterministic
// private extended key is not registered.
ErrUnknownHDKeyID = errors.New("unknown hd private extended key bytes")
)
var (
registeredNets = make(map[wire.BitcoinNet]struct{})
pubKeyHashAddrIDs = make(map[byte]struct{})
scriptHashAddrIDs = make(map[byte]struct{})
bech32SegwitPrefixes = make(map[string]struct{})
hdPrivToPubKeyIDs = make(map[[4]byte][]byte)
)
// String returns the hostname of the DNS seed in human-readable form.
func (d DNSSeed) String() string {
return d.Host
}
// Register registers the network parameters for a Bitcoin network. This may
// error with ErrDuplicateNet if the network is already registered (either
// due to a previous Register call, or the network being one of the default
// networks).
//
// Network parameters should be registered into this package by a main package
// as early as possible. Then, library packages may lookup networks or network
// parameters based on inputs and work regardless of the network being standard
// or not.
func Register(params *Params) error {
if _, ok := registeredNets[params.Net]; ok {
return ErrDuplicateNet
}
registeredNets[params.Net] = struct{}{}
pubKeyHashAddrIDs[params.PubKeyHashAddrID] = struct{}{}
scriptHashAddrIDs[params.ScriptHashAddrID] = struct{}{}
hdPrivToPubKeyIDs[params.HDPrivateKeyID] = params.HDPublicKeyID[:]
// A valid Bech32 encoded segwit address always has as prefix the
// human-readable part for the given net followed by '1'.
bech32SegwitPrefixes[params.Bech32HRPSegwit+"1"] = struct{}{}
return nil
}
// mustRegister performs the same function as Register except it panics if there
// is an error. This should only be called from package init functions.
func mustRegister(params *Params) {
if err := Register(params); err != nil {
panic("failed to register network: " + err.Error())
}
}
// IsPubKeyHashAddrID returns whether the id is an identifier known to prefix a
// pay-to-pubkey-hash address on any default or registered network. This is
// used when decoding an address string into a specific address type. It is up
// to the caller to check both this and IsScriptHashAddrID and decide whether an
// address is a pubkey hash address, script hash address, neither, or
// undeterminable (if both return true).
func IsPubKeyHashAddrID(id byte) bool {
_, ok := pubKeyHashAddrIDs[id]
return ok
}
// IsScriptHashAddrID returns whether the id is an identifier known to prefix a
// pay-to-script-hash address on any default or registered network. This is
// used when decoding an address string into a specific address type. It is up
// to the caller to check both this and IsPubKeyHashAddrID and decide whether an
// address is a pubkey hash address, script hash address, neither, or
// undeterminable (if both return true).
func IsScriptHashAddrID(id byte) bool {
_, ok := scriptHashAddrIDs[id]
return ok
}
// IsBech32SegwitPrefix returns whether the prefix is a known prefix for segwit
// addresses on any default or registered network. This is used when decoding
// an address string into a specific address type.
func IsBech32SegwitPrefix(prefix string) bool {
prefix = strings.ToLower(prefix)
_, ok := bech32SegwitPrefixes[prefix]
return ok
}
// HDPrivateKeyToPublicKeyID accepts a private hierarchical deterministic
// extended key id and returns the associated public key id. When the provided
// id is not registered, the ErrUnknownHDKeyID error will be returned.
func HDPrivateKeyToPublicKeyID(id []byte) ([]byte, error) {
if len(id) != 4 {
return nil, ErrUnknownHDKeyID
}
var key [4]byte
copy(key[:], id)
pubBytes, ok := hdPrivToPubKeyIDs[key]
if !ok {
return nil, ErrUnknownHDKeyID
}
return pubBytes, nil
}
// newHashFromStr converts the passed big-endian hex string into a
// chainhash.Hash. It only differs from the one available in chainhash in that
// it panics on an error since it will only (and must only) be called with
// hard-coded, and therefore known good, hashes.
func newHashFromStr(hexStr string) *chainhash.Hash {
hash, err := chainhash.NewHashFromStr(hexStr)
if err != nil {
// Ordinarily I don't like panics in library code since it
// can take applications down without them having a chance to
// recover which is extremely annoying, however an exception is
// being made in this case because the only way this can panic
// is if there is an error in the hard-coded hashes. Thus it
// will only ever potentially panic on init and therefore is
// 100% predictable.
panic(err)
}
return hash
}
func init() {
// Register all default networks when the package is initialized.
mustRegister(&MainNetParams)
mustRegister(&TestNet3Params)
mustRegister(&RegressionNetParams)
mustRegister(&SimNetParams)
}

13
vendor/github.com/btcsuite/btcd/rpcclient/CONTRIBUTORS generated vendored Normal file
View File

@ -0,0 +1,13 @@
# This is the list of people who have contributed code to the repository.
#
# Names should be added to this file only after verifying that the individual
# or the individual's organization has agreed to the LICENSE.
#
# Names should be added to this file like so:
# Name <email address>
Dave Collins <davec@conformal.com>
Geert-Johan Riemer <geertjohan.riemer@gmail.com>
Josh Rickmar <jrick@conformal.com>
Michalis Kargakis <michaliskargakis@gmail.com>
Ruben de Vries <ruben@rubensayshi.com

56
vendor/github.com/btcsuite/btcd/rpcclient/README.md generated vendored Normal file
View File

@ -0,0 +1,56 @@
rpcclient
=========
[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/btcd)
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcd/rpcclient)
rpcclient implements a Websocket-enabled Bitcoin JSON-RPC client package written
in [Go](http://golang.org/). It provides a robust and easy to use client for
interfacing with a Bitcoin RPC server that uses a btcd/bitcoin core compatible
Bitcoin JSON-RPC API.
## Status
This package is currently under active development. It is already stable and
the infrastructure is complete. However, there are still several RPCs left to
implement and the API is not stable yet.
## Documentation
* [API Reference](http://godoc.org/github.com/btcsuite/btcd/rpcclient)
* [btcd Websockets Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/btcdwebsockets)
Connects to a btcd RPC server using TLS-secured websockets, registers for
block connected and block disconnected notifications, and gets the current
block count
* [btcwallet Websockets Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/btcwalletwebsockets)
Connects to a btcwallet RPC server using TLS-secured websockets, registers for
notifications about changes to account balances, and gets a list of unspent
transaction outputs (utxos) the wallet can sign
* [Bitcoin Core HTTP POST Example](https://github.com/btcsuite/btcd/tree/master/rpcclient/examples/bitcoincorehttp)
Connects to a bitcoin core RPC server using HTTP POST mode with TLS disabled
and gets the current block count
## Major Features
* Supports Websockets (btcd/btcwallet) and HTTP POST mode (bitcoin core)
* Provides callback and registration functions for btcd/btcwallet notifications
* Supports btcd extensions
* Translates to and from higher-level and easier to use Go types
* Offers a synchronous (blocking) and asynchronous API
* When running in Websockets mode (the default):
* Automatic reconnect handling (can be disabled)
* Outstanding commands are automatically reissued
* Registered notifications are automatically reregistered
* Back-off support on reconnect attempts
## Installation
```bash
$ go get -u github.com/btcsuite/btcd/rpcclient
```
## License
Package rpcclient is licensed under the [copyfree](http://copyfree.org) ISC
License.

929
vendor/github.com/btcsuite/btcd/rpcclient/chain.go generated vendored Normal file
View File

@ -0,0 +1,929 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcclient
import (
"bytes"
"encoding/hex"
"encoding/json"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
)
// FutureGetBestBlockHashResult is a future promise to deliver the result of a
// GetBestBlockAsync RPC invocation (or an applicable error).
type FutureGetBestBlockHashResult chan *response
// Receive waits for the response promised by the future and returns the hash of
// the best block in the longest block chain.
func (r FutureGetBestBlockHashResult) Receive() (*chainhash.Hash, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var txHashStr string
err = json.Unmarshal(res, &txHashStr)
if err != nil {
return nil, err
}
return chainhash.NewHashFromStr(txHashStr)
}
// GetBestBlockHashAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetBestBlockHash for the blocking version and more details.
func (c *Client) GetBestBlockHashAsync() FutureGetBestBlockHashResult {
cmd := btcjson.NewGetBestBlockHashCmd()
return c.sendCmd(cmd)
}
// GetBestBlockHash returns the hash of the best block in the longest block
// chain.
func (c *Client) GetBestBlockHash() (*chainhash.Hash, error) {
return c.GetBestBlockHashAsync().Receive()
}
// FutureGetBlockResult is a future promise to deliver the result of a
// GetBlockAsync RPC invocation (or an applicable error).
type FutureGetBlockResult chan *response
// Receive waits for the response promised by the future and returns the raw
// block requested from the server given its hash.
func (r FutureGetBlockResult) Receive() (*wire.MsgBlock, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var blockHex string
err = json.Unmarshal(res, &blockHex)
if err != nil {
return nil, err
}
// Decode the serialized block hex to raw bytes.
serializedBlock, err := hex.DecodeString(blockHex)
if err != nil {
return nil, err
}
// Deserialize the block and return it.
var msgBlock wire.MsgBlock
err = msgBlock.Deserialize(bytes.NewReader(serializedBlock))
if err != nil {
return nil, err
}
return &msgBlock, nil
}
// GetBlockAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetBlock for the blocking version and more details.
func (c *Client) GetBlockAsync(blockHash *chainhash.Hash) FutureGetBlockResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(false), nil)
return c.sendCmd(cmd)
}
// GetBlock returns a raw block from the server given its hash.
//
// See GetBlockVerbose to retrieve a data structure with information about the
// block instead.
func (c *Client) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
return c.GetBlockAsync(blockHash).Receive()
}
// FutureGetBlockVerboseResult is a future promise to deliver the result of a
// GetBlockVerboseAsync RPC invocation (or an applicable error).
type FutureGetBlockVerboseResult chan *response
// Receive waits for the response promised by the future and returns the data
// structure from the server with information about the requested block.
func (r FutureGetBlockVerboseResult) Receive() (*btcjson.GetBlockVerboseResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal the raw result into a BlockResult.
var blockResult btcjson.GetBlockVerboseResult
err = json.Unmarshal(res, &blockResult)
if err != nil {
return nil, err
}
return &blockResult, nil
}
// GetBlockVerboseAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetBlockVerbose for the blocking version and more details.
func (c *Client) GetBlockVerboseAsync(blockHash *chainhash.Hash) FutureGetBlockVerboseResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), nil)
return c.sendCmd(cmd)
}
// GetBlockVerbose returns a data structure from the server with information
// about a block given its hash.
//
// See GetBlockVerboseTx to retrieve transaction data structures as well.
// See GetBlock to retrieve a raw block instead.
func (c *Client) GetBlockVerbose(blockHash *chainhash.Hash) (*btcjson.GetBlockVerboseResult, error) {
return c.GetBlockVerboseAsync(blockHash).Receive()
}
// GetBlockVerboseTxAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetBlockVerboseTx or the blocking version and more details.
func (c *Client) GetBlockVerboseTxAsync(blockHash *chainhash.Hash) FutureGetBlockVerboseResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), btcjson.Bool(true))
return c.sendCmd(cmd)
}
// GetBlockVerboseTx returns a data structure from the server with information
// about a block and its transactions given its hash.
//
// See GetBlockVerbose if only transaction hashes are preferred.
// See GetBlock to retrieve a raw block instead.
func (c *Client) GetBlockVerboseTx(blockHash *chainhash.Hash) (*btcjson.GetBlockVerboseResult, error) {
return c.GetBlockVerboseTxAsync(blockHash).Receive()
}
// FutureGetBlockCountResult is a future promise to deliver the result of a
// GetBlockCountAsync RPC invocation (or an applicable error).
type FutureGetBlockCountResult chan *response
// Receive waits for the response promised by the future and returns the number
// of blocks in the longest block chain.
func (r FutureGetBlockCountResult) Receive() (int64, error) {
res, err := receiveFuture(r)
if err != nil {
return 0, err
}
// Unmarshal the result as an int64.
var count int64
err = json.Unmarshal(res, &count)
if err != nil {
return 0, err
}
return count, nil
}
// GetBlockCountAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetBlockCount for the blocking version and more details.
func (c *Client) GetBlockCountAsync() FutureGetBlockCountResult {
cmd := btcjson.NewGetBlockCountCmd()
return c.sendCmd(cmd)
}
// GetBlockCount returns the number of blocks in the longest block chain.
func (c *Client) GetBlockCount() (int64, error) {
return c.GetBlockCountAsync().Receive()
}
// FutureGetDifficultyResult is a future promise to deliver the result of a
// GetDifficultyAsync RPC invocation (or an applicable error).
type FutureGetDifficultyResult chan *response
// Receive waits for the response promised by the future and returns the
// proof-of-work difficulty as a multiple of the minimum difficulty.
func (r FutureGetDifficultyResult) Receive() (float64, error) {
res, err := receiveFuture(r)
if err != nil {
return 0, err
}
// Unmarshal the result as a float64.
var difficulty float64
err = json.Unmarshal(res, &difficulty)
if err != nil {
return 0, err
}
return difficulty, nil
}
// GetDifficultyAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetDifficulty for the blocking version and more details.
func (c *Client) GetDifficultyAsync() FutureGetDifficultyResult {
cmd := btcjson.NewGetDifficultyCmd()
return c.sendCmd(cmd)
}
// GetDifficulty returns the proof-of-work difficulty as a multiple of the
// minimum difficulty.
func (c *Client) GetDifficulty() (float64, error) {
return c.GetDifficultyAsync().Receive()
}
// FutureGetBlockChainInfoResult is a promise to deliver the result of a
// GetBlockChainInfoAsync RPC invocation (or an applicable error).
type FutureGetBlockChainInfoResult chan *response
// Receive waits for the response promised by the future and returns chain info
// result provided by the server.
func (r FutureGetBlockChainInfoResult) Receive() (*btcjson.GetBlockChainInfoResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
var chainInfo btcjson.GetBlockChainInfoResult
if err := json.Unmarshal(res, &chainInfo); err != nil {
return nil, err
}
return &chainInfo, nil
}
// GetBlockChainInfoAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function
// on the returned instance.
//
// See GetBlockChainInfo for the blocking version and more details.
func (c *Client) GetBlockChainInfoAsync() FutureGetBlockChainInfoResult {
cmd := btcjson.NewGetBlockChainInfoCmd()
return c.sendCmd(cmd)
}
// GetBlockChainInfo returns information related to the processing state of
// various chain-specific details such as the current difficulty from the tip
// of the main chain.
func (c *Client) GetBlockChainInfo() (*btcjson.GetBlockChainInfoResult, error) {
return c.GetBlockChainInfoAsync().Receive()
}
// FutureGetBlockHashResult is a future promise to deliver the result of a
// GetBlockHashAsync RPC invocation (or an applicable error).
type FutureGetBlockHashResult chan *response
// Receive waits for the response promised by the future and returns the hash of
// the block in the best block chain at the given height.
func (r FutureGetBlockHashResult) Receive() (*chainhash.Hash, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal the result as a string-encoded sha.
var txHashStr string
err = json.Unmarshal(res, &txHashStr)
if err != nil {
return nil, err
}
return chainhash.NewHashFromStr(txHashStr)
}
// GetBlockHashAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetBlockHash for the blocking version and more details.
func (c *Client) GetBlockHashAsync(blockHeight int64) FutureGetBlockHashResult {
cmd := btcjson.NewGetBlockHashCmd(blockHeight)
return c.sendCmd(cmd)
}
// GetBlockHash returns the hash of the block in the best block chain at the
// given height.
func (c *Client) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
return c.GetBlockHashAsync(blockHeight).Receive()
}
// FutureGetBlockHeaderResult is a future promise to deliver the result of a
// GetBlockHeaderAsync RPC invocation (or an applicable error).
type FutureGetBlockHeaderResult chan *response
// Receive waits for the response promised by the future and returns the
// blockheader requested from the server given its hash.
func (r FutureGetBlockHeaderResult) Receive() (*wire.BlockHeader, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var bhHex string
err = json.Unmarshal(res, &bhHex)
if err != nil {
return nil, err
}
serializedBH, err := hex.DecodeString(bhHex)
if err != nil {
return nil, err
}
// Deserialize the blockheader and return it.
var bh wire.BlockHeader
err = bh.Deserialize(bytes.NewReader(serializedBH))
if err != nil {
return nil, err
}
return &bh, err
}
// GetBlockHeaderAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetBlockHeader for the blocking version and more details.
func (c *Client) GetBlockHeaderAsync(blockHash *chainhash.Hash) FutureGetBlockHeaderResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewGetBlockHeaderCmd(hash, btcjson.Bool(false))
return c.sendCmd(cmd)
}
// GetBlockHeader returns the blockheader from the server given its hash.
//
// See GetBlockHeaderVerbose to retrieve a data structure with information about the
// block instead.
func (c *Client) GetBlockHeader(blockHash *chainhash.Hash) (*wire.BlockHeader, error) {
return c.GetBlockHeaderAsync(blockHash).Receive()
}
// FutureGetBlockHeaderVerboseResult is a future promise to deliver the result of a
// GetBlockAsync RPC invocation (or an applicable error).
type FutureGetBlockHeaderVerboseResult chan *response
// Receive waits for the response promised by the future and returns the
// data structure of the blockheader requested from the server given its hash.
func (r FutureGetBlockHeaderVerboseResult) Receive() (*btcjson.GetBlockHeaderVerboseResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var bh btcjson.GetBlockHeaderVerboseResult
err = json.Unmarshal(res, &bh)
if err != nil {
return nil, err
}
return &bh, nil
}
// GetBlockHeaderVerboseAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetBlockHeader for the blocking version and more details.
func (c *Client) GetBlockHeaderVerboseAsync(blockHash *chainhash.Hash) FutureGetBlockHeaderVerboseResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewGetBlockHeaderCmd(hash, btcjson.Bool(true))
return c.sendCmd(cmd)
}
// GetBlockHeaderVerbose returns a data structure with information about the
// blockheader from the server given its hash.
//
// See GetBlockHeader to retrieve a blockheader instead.
func (c *Client) GetBlockHeaderVerbose(blockHash *chainhash.Hash) (*btcjson.GetBlockHeaderVerboseResult, error) {
return c.GetBlockHeaderVerboseAsync(blockHash).Receive()
}
// FutureGetMempoolEntryResult is a future promise to deliver the result of a
// GetMempoolEntryAsync RPC invocation (or an applicable error).
type FutureGetMempoolEntryResult chan *response
// Receive waits for the response promised by the future and returns a data
// structure with information about the transaction in the memory pool given
// its hash.
func (r FutureGetMempoolEntryResult) Receive() (*btcjson.GetMempoolEntryResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal the result as an array of strings.
var mempoolEntryResult btcjson.GetMempoolEntryResult
err = json.Unmarshal(res, &mempoolEntryResult)
if err != nil {
return nil, err
}
return &mempoolEntryResult, nil
}
// GetMempoolEntryAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetMempoolEntry for the blocking version and more details.
func (c *Client) GetMempoolEntryAsync(txHash string) FutureGetMempoolEntryResult {
cmd := btcjson.NewGetMempoolEntryCmd(txHash)
return c.sendCmd(cmd)
}
// GetMempoolEntry returns a data structure with information about the
// transaction in the memory pool given its hash.
func (c *Client) GetMempoolEntry(txHash string) (*btcjson.GetMempoolEntryResult, error) {
return c.GetMempoolEntryAsync(txHash).Receive()
}
// FutureGetRawMempoolResult is a future promise to deliver the result of a
// GetRawMempoolAsync RPC invocation (or an applicable error).
type FutureGetRawMempoolResult chan *response
// Receive waits for the response promised by the future and returns the hashes
// of all transactions in the memory pool.
func (r FutureGetRawMempoolResult) Receive() ([]*chainhash.Hash, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal the result as an array of strings.
var txHashStrs []string
err = json.Unmarshal(res, &txHashStrs)
if err != nil {
return nil, err
}
// Create a slice of ShaHash arrays from the string slice.
txHashes := make([]*chainhash.Hash, 0, len(txHashStrs))
for _, hashStr := range txHashStrs {
txHash, err := chainhash.NewHashFromStr(hashStr)
if err != nil {
return nil, err
}
txHashes = append(txHashes, txHash)
}
return txHashes, nil
}
// GetRawMempoolAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetRawMempool for the blocking version and more details.
func (c *Client) GetRawMempoolAsync() FutureGetRawMempoolResult {
cmd := btcjson.NewGetRawMempoolCmd(btcjson.Bool(false))
return c.sendCmd(cmd)
}
// GetRawMempool returns the hashes of all transactions in the memory pool.
//
// See GetRawMempoolVerbose to retrieve data structures with information about
// the transactions instead.
func (c *Client) GetRawMempool() ([]*chainhash.Hash, error) {
return c.GetRawMempoolAsync().Receive()
}
// FutureGetRawMempoolVerboseResult is a future promise to deliver the result of
// a GetRawMempoolVerboseAsync RPC invocation (or an applicable error).
type FutureGetRawMempoolVerboseResult chan *response
// Receive waits for the response promised by the future and returns a map of
// transaction hashes to an associated data structure with information about the
// transaction for all transactions in the memory pool.
func (r FutureGetRawMempoolVerboseResult) Receive() (map[string]btcjson.GetRawMempoolVerboseResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal the result as a map of strings (tx shas) to their detailed
// results.
var mempoolItems map[string]btcjson.GetRawMempoolVerboseResult
err = json.Unmarshal(res, &mempoolItems)
if err != nil {
return nil, err
}
return mempoolItems, nil
}
// GetRawMempoolVerboseAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See GetRawMempoolVerbose for the blocking version and more details.
func (c *Client) GetRawMempoolVerboseAsync() FutureGetRawMempoolVerboseResult {
cmd := btcjson.NewGetRawMempoolCmd(btcjson.Bool(true))
return c.sendCmd(cmd)
}
// GetRawMempoolVerbose returns a map of transaction hashes to an associated
// data structure with information about the transaction for all transactions in
// the memory pool.
//
// See GetRawMempool to retrieve only the transaction hashes instead.
func (c *Client) GetRawMempoolVerbose() (map[string]btcjson.GetRawMempoolVerboseResult, error) {
return c.GetRawMempoolVerboseAsync().Receive()
}
// FutureEstimateFeeResult is a future promise to deliver the result of a
// EstimateFeeAsync RPC invocation (or an applicable error).
type FutureEstimateFeeResult chan *response
// Receive waits for the response promised by the future and returns the info
// provided by the server.
func (r FutureEstimateFeeResult) Receive() (float64, error) {
res, err := receiveFuture(r)
if err != nil {
return -1, err
}
// Unmarshal result as a getinfo result object.
var fee float64
err = json.Unmarshal(res, &fee)
if err != nil {
return -1, err
}
return fee, nil
}
// EstimateFeeAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See EstimateFee for the blocking version and more details.
func (c *Client) EstimateFeeAsync(numBlocks int64) FutureEstimateFeeResult {
cmd := btcjson.NewEstimateFeeCmd(numBlocks)
return c.sendCmd(cmd)
}
// EstimateFee provides an estimated fee in bitcoins per kilobyte.
func (c *Client) EstimateFee(numBlocks int64) (float64, error) {
return c.EstimateFeeAsync(numBlocks).Receive()
}
// FutureVerifyChainResult is a future promise to deliver the result of a
// VerifyChainAsync, VerifyChainLevelAsyncRPC, or VerifyChainBlocksAsync
// invocation (or an applicable error).
type FutureVerifyChainResult chan *response
// Receive waits for the response promised by the future and returns whether
// or not the chain verified based on the check level and number of blocks
// to verify specified in the original call.
func (r FutureVerifyChainResult) Receive() (bool, error) {
res, err := receiveFuture(r)
if err != nil {
return false, err
}
// Unmarshal the result as a boolean.
var verified bool
err = json.Unmarshal(res, &verified)
if err != nil {
return false, err
}
return verified, nil
}
// VerifyChainAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See VerifyChain for the blocking version and more details.
func (c *Client) VerifyChainAsync() FutureVerifyChainResult {
cmd := btcjson.NewVerifyChainCmd(nil, nil)
return c.sendCmd(cmd)
}
// VerifyChain requests the server to verify the block chain database using
// the default check level and number of blocks to verify.
//
// See VerifyChainLevel and VerifyChainBlocks to override the defaults.
func (c *Client) VerifyChain() (bool, error) {
return c.VerifyChainAsync().Receive()
}
// VerifyChainLevelAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See VerifyChainLevel for the blocking version and more details.
func (c *Client) VerifyChainLevelAsync(checkLevel int32) FutureVerifyChainResult {
cmd := btcjson.NewVerifyChainCmd(&checkLevel, nil)
return c.sendCmd(cmd)
}
// VerifyChainLevel requests the server to verify the block chain database using
// the passed check level and default number of blocks to verify.
//
// The check level controls how thorough the verification is with higher numbers
// increasing the amount of checks done as consequently how long the
// verification takes.
//
// See VerifyChain to use the default check level and VerifyChainBlocks to
// override the number of blocks to verify.
func (c *Client) VerifyChainLevel(checkLevel int32) (bool, error) {
return c.VerifyChainLevelAsync(checkLevel).Receive()
}
// VerifyChainBlocksAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See VerifyChainBlocks for the blocking version and more details.
func (c *Client) VerifyChainBlocksAsync(checkLevel, numBlocks int32) FutureVerifyChainResult {
cmd := btcjson.NewVerifyChainCmd(&checkLevel, &numBlocks)
return c.sendCmd(cmd)
}
// VerifyChainBlocks requests the server to verify the block chain database
// using the passed check level and number of blocks to verify.
//
// The check level controls how thorough the verification is with higher numbers
// increasing the amount of checks done as consequently how long the
// verification takes.
//
// The number of blocks refers to the number of blocks from the end of the
// current longest chain.
//
// See VerifyChain and VerifyChainLevel to use defaults.
func (c *Client) VerifyChainBlocks(checkLevel, numBlocks int32) (bool, error) {
return c.VerifyChainBlocksAsync(checkLevel, numBlocks).Receive()
}
// FutureGetTxOutResult is a future promise to deliver the result of a
// GetTxOutAsync RPC invocation (or an applicable error).
type FutureGetTxOutResult chan *response
// Receive waits for the response promised by the future and returns a
// transaction given its hash.
func (r FutureGetTxOutResult) Receive() (*btcjson.GetTxOutResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// take care of the special case where the output has been spent already
// it should return the string "null"
if string(res) == "null" {
return nil, nil
}
// Unmarshal result as an gettxout result object.
var txOutInfo *btcjson.GetTxOutResult
err = json.Unmarshal(res, &txOutInfo)
if err != nil {
return nil, err
}
return txOutInfo, nil
}
// GetTxOutAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetTxOut for the blocking version and more details.
func (c *Client) GetTxOutAsync(txHash *chainhash.Hash, index uint32, mempool bool) FutureGetTxOutResult {
hash := ""
if txHash != nil {
hash = txHash.String()
}
cmd := btcjson.NewGetTxOutCmd(hash, index, &mempool)
return c.sendCmd(cmd)
}
// GetTxOut returns the transaction output info if it's unspent and
// nil, otherwise.
func (c *Client) GetTxOut(txHash *chainhash.Hash, index uint32, mempool bool) (*btcjson.GetTxOutResult, error) {
return c.GetTxOutAsync(txHash, index, mempool).Receive()
}
// FutureRescanBlocksResult is a future promise to deliver the result of a
// RescanBlocksAsync RPC invocation (or an applicable error).
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
type FutureRescanBlocksResult chan *response
// Receive waits for the response promised by the future and returns the
// discovered rescanblocks data.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (r FutureRescanBlocksResult) Receive() ([]btcjson.RescannedBlock, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
var rescanBlocksResult []btcjson.RescannedBlock
err = json.Unmarshal(res, &rescanBlocksResult)
if err != nil {
return nil, err
}
return rescanBlocksResult, nil
}
// RescanBlocksAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See RescanBlocks for the blocking version and more details.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (c *Client) RescanBlocksAsync(blockHashes []chainhash.Hash) FutureRescanBlocksResult {
strBlockHashes := make([]string, len(blockHashes))
for i := range blockHashes {
strBlockHashes[i] = blockHashes[i].String()
}
cmd := btcjson.NewRescanBlocksCmd(strBlockHashes)
return c.sendCmd(cmd)
}
// RescanBlocks rescans the blocks identified by blockHashes, in order, using
// the client's loaded transaction filter. The blocks do not need to be on the
// main chain, but they do need to be adjacent to each other.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (c *Client) RescanBlocks(blockHashes []chainhash.Hash) ([]btcjson.RescannedBlock, error) {
return c.RescanBlocksAsync(blockHashes).Receive()
}
// FutureInvalidateBlockResult is a future promise to deliver the result of a
// InvalidateBlockAsync RPC invocation (or an applicable error).
type FutureInvalidateBlockResult chan *response
// Receive waits for the response promised by the future and returns the raw
// block requested from the server given its hash.
func (r FutureInvalidateBlockResult) Receive() error {
_, err := receiveFuture(r)
return err
}
// InvalidateBlockAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See InvalidateBlock for the blocking version and more details.
func (c *Client) InvalidateBlockAsync(blockHash *chainhash.Hash) FutureInvalidateBlockResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewInvalidateBlockCmd(hash)
return c.sendCmd(cmd)
}
// InvalidateBlock invalidates a specific block.
func (c *Client) InvalidateBlock(blockHash *chainhash.Hash) error {
return c.InvalidateBlockAsync(blockHash).Receive()
}
// FutureGetCFilterResult is a future promise to deliver the result of a
// GetCFilterAsync RPC invocation (or an applicable error).
type FutureGetCFilterResult chan *response
// Receive waits for the response promised by the future and returns the raw
// filter requested from the server given its block hash.
func (r FutureGetCFilterResult) Receive() (*wire.MsgCFilter, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var filterHex string
err = json.Unmarshal(res, &filterHex)
if err != nil {
return nil, err
}
// Decode the serialized cf hex to raw bytes.
serializedFilter, err := hex.DecodeString(filterHex)
if err != nil {
return nil, err
}
// Assign the filter bytes to the correct field of the wire message.
// We aren't going to set the block hash or extended flag, since we
// don't actually get that back in the RPC response.
var msgCFilter wire.MsgCFilter
msgCFilter.Data = serializedFilter
return &msgCFilter, nil
}
// GetCFilterAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetCFilter for the blocking version and more details.
func (c *Client) GetCFilterAsync(blockHash *chainhash.Hash,
filterType wire.FilterType) FutureGetCFilterResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewGetCFilterCmd(hash, filterType)
return c.sendCmd(cmd)
}
// GetCFilter returns a raw filter from the server given its block hash.
func (c *Client) GetCFilter(blockHash *chainhash.Hash,
filterType wire.FilterType) (*wire.MsgCFilter, error) {
return c.GetCFilterAsync(blockHash, filterType).Receive()
}
// FutureGetCFilterHeaderResult is a future promise to deliver the result of a
// GetCFilterHeaderAsync RPC invocation (or an applicable error).
type FutureGetCFilterHeaderResult chan *response
// Receive waits for the response promised by the future and returns the raw
// filter header requested from the server given its block hash.
func (r FutureGetCFilterHeaderResult) Receive() (*wire.MsgCFHeaders, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var headerHex string
err = json.Unmarshal(res, &headerHex)
if err != nil {
return nil, err
}
// Assign the decoded header into a hash
headerHash, err := chainhash.NewHashFromStr(headerHex)
if err != nil {
return nil, err
}
// Assign the hash to a headers message and return it.
msgCFHeaders := wire.MsgCFHeaders{PrevFilterHeader: *headerHash}
return &msgCFHeaders, nil
}
// GetCFilterHeaderAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function
// on the returned instance.
//
// See GetCFilterHeader for the blocking version and more details.
func (c *Client) GetCFilterHeaderAsync(blockHash *chainhash.Hash,
filterType wire.FilterType) FutureGetCFilterHeaderResult {
hash := ""
if blockHash != nil {
hash = blockHash.String()
}
cmd := btcjson.NewGetCFilterHeaderCmd(hash, filterType)
return c.sendCmd(cmd)
}
// GetCFilterHeader returns a raw filter header from the server given its block
// hash.
func (c *Client) GetCFilterHeader(blockHash *chainhash.Hash,
filterType wire.FilterType) (*wire.MsgCFHeaders, error) {
return c.GetCFilterHeaderAsync(blockHash, filterType).Receive()
}

178
vendor/github.com/btcsuite/btcd/rpcclient/doc.go generated vendored Normal file
View File

@ -0,0 +1,178 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
/*
Package rpcclient implements a websocket-enabled Bitcoin JSON-RPC client.
Overview
This client provides a robust and easy to use client for interfacing with a
Bitcoin RPC server that uses a btcd/bitcoin core compatible Bitcoin JSON-RPC
API. This client has been tested with btcd (https://github.com/btcsuite/btcd),
btcwallet (https://github.com/btcsuite/btcwallet), and
bitcoin core (https://github.com/bitcoin).
In addition to the compatible standard HTTP POST JSON-RPC API, btcd and
btcwallet provide a websocket interface that is more efficient than the standard
HTTP POST method of accessing RPC. The section below discusses the differences
between HTTP POST and websockets.
By default, this client assumes the RPC server supports websockets and has
TLS enabled. In practice, this currently means it assumes you are talking to
btcd or btcwallet by default. However, configuration options are provided to
fall back to HTTP POST and disable TLS to support talking with inferior bitcoin
core style RPC servers.
Websockets vs HTTP POST
In HTTP POST-based JSON-RPC, every request creates a new HTTP connection,
issues the call, waits for the response, and closes the connection. This adds
quite a bit of overhead to every call and lacks flexibility for features such as
notifications.
In contrast, the websocket-based JSON-RPC interface provided by btcd and
btcwallet only uses a single connection that remains open and allows
asynchronous bi-directional communication.
The websocket interface supports all of the same commands as HTTP POST, but they
can be invoked without having to go through a connect/disconnect cycle for every
call. In addition, the websocket interface provides other nice features such as
the ability to register for asynchronous notifications of various events.
Synchronous vs Asynchronous API
The client provides both a synchronous (blocking) and asynchronous API.
The synchronous (blocking) API is typically sufficient for most use cases. It
works by issuing the RPC and blocking until the response is received. This
allows straightforward code where you have the response as soon as the function
returns.
The asynchronous API works on the concept of futures. When you invoke the async
version of a command, it will quickly return an instance of a type that promises
to provide the result of the RPC at some future time. In the background, the
RPC call is issued and the result is stored in the returned instance. Invoking
the Receive method on the returned instance will either return the result
immediately if it has already arrived, or block until it has. This is useful
since it provides the caller with greater control over concurrency.
Notifications
The first important part of notifications is to realize that they will only
work when connected via websockets. This should intuitively make sense
because HTTP POST mode does not keep a connection open!
All notifications provided by btcd require registration to opt-in. For example,
if you want to be notified when funds are received by a set of addresses, you
register the addresses via the NotifyReceived (or NotifyReceivedAsync) function.
Notification Handlers
Notifications are exposed by the client through the use of callback handlers
which are setup via a NotificationHandlers instance that is specified by the
caller when creating the client.
It is important that these notification handlers complete quickly since they
are intentionally in the main read loop and will block further reads until
they complete. This provides the caller with the flexibility to decide what to
do when notifications are coming in faster than they are being handled.
In particular this means issuing a blocking RPC call from a callback handler
will cause a deadlock as more server responses won't be read until the callback
returns, but the callback would be waiting for a response. Thus, any
additional RPCs must be issued an a completely decoupled manner.
Automatic Reconnection
By default, when running in websockets mode, this client will automatically
keep trying to reconnect to the RPC server should the connection be lost. There
is a back-off in between each connection attempt until it reaches one try per
minute. Once a connection is re-established, all previously registered
notifications are automatically re-registered and any in-flight commands are
re-issued. This means from the caller's perspective, the request simply takes
longer to complete.
The caller may invoke the Shutdown method on the client to force the client
to cease reconnect attempts and return ErrClientShutdown for all outstanding
commands.
The automatic reconnection can be disabled by setting the DisableAutoReconnect
flag to true in the connection config when creating the client.
Minor RPC Server Differences and Chain/Wallet Separation
Some of the commands are extensions specific to a particular RPC server. For
example, the DebugLevel call is an extension only provided by btcd (and
btcwallet passthrough). Therefore if you call one of these commands against
an RPC server that doesn't provide them, you will get an unimplemented error
from the server. An effort has been made to call out which commmands are
extensions in their documentation.
Also, it is important to realize that btcd intentionally separates the wallet
functionality into a separate process named btcwallet. This means if you are
connected to the btcd RPC server directly, only the RPCs which are related to
chain services will be available. Depending on your application, you might only
need chain-related RPCs. In contrast, btcwallet provides pass through treatment
for chain-related RPCs, so it supports them in addition to wallet-related RPCs.
Errors
There are 3 categories of errors that will be returned throughout this package:
- Errors related to the client connection such as authentication, endpoint,
disconnect, and shutdown
- Errors that occur before communicating with the remote RPC server such as
command creation and marshaling errors or issues talking to the remote
server
- Errors returned from the remote RPC server like unimplemented commands,
nonexistent requested blocks and transactions, malformed data, and incorrect
networks
The first category of errors are typically one of ErrInvalidAuth,
ErrInvalidEndpoint, ErrClientDisconnect, or ErrClientShutdown.
NOTE: The ErrClientDisconnect will not be returned unless the
DisableAutoReconnect flag is set since the client automatically handles
reconnect by default as previously described.
The second category of errors typically indicates a programmer error and as such
the type can vary, but usually will be best handled by simply showing/logging
it.
The third category of errors, that is errors returned by the server, can be
detected by type asserting the error in a *btcjson.RPCError. For example, to
detect if a command is unimplemented by the remote RPC server:
amount, err := client.GetBalance("")
if err != nil {
if jerr, ok := err.(*btcjson.RPCError); ok {
switch jerr.Code {
case btcjson.ErrRPCUnimplemented:
// Handle not implemented error
// Handle other specific errors you care about
}
}
// Log or otherwise handle the error knowing it was not one returned
// from the remote RPC server.
}
Example Usage
The following full-blown client examples are in the examples directory:
- bitcoincorehttp
Connects to a bitcoin core RPC server using HTTP POST mode with TLS disabled
and gets the current block count
- btcdwebsockets
Connects to a btcd RPC server using TLS-secured websockets, registers for
block connected and block disconnected notifications, and gets the current
block count
- btcwalletwebsockets
Connects to a btcwallet RPC server using TLS-secured websockets, registers
for notifications about changes to account balances, and gets a list of
unspent transaction outputs (utxos) the wallet can sign
*/
package rpcclient

473
vendor/github.com/btcsuite/btcd/rpcclient/extensions.go generated vendored Normal file
View File

@ -0,0 +1,473 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Copyright (c) 2015-2017 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcclient
import (
"bytes"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
)
// FutureDebugLevelResult is a future promise to deliver the result of a
// DebugLevelAsync RPC invocation (or an applicable error).
type FutureDebugLevelResult chan *response
// Receive waits for the response promised by the future and returns the result
// of setting the debug logging level to the passed level specification or the
// list of of the available subsystems for the special keyword 'show'.
func (r FutureDebugLevelResult) Receive() (string, error) {
res, err := receiveFuture(r)
if err != nil {
return "", err
}
// Unmashal the result as a string.
var result string
err = json.Unmarshal(res, &result)
if err != nil {
return "", err
}
return result, nil
}
// DebugLevelAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See DebugLevel for the blocking version and more details.
//
// NOTE: This is a btcd extension.
func (c *Client) DebugLevelAsync(levelSpec string) FutureDebugLevelResult {
cmd := btcjson.NewDebugLevelCmd(levelSpec)
return c.sendCmd(cmd)
}
// DebugLevel dynamically sets the debug logging level to the passed level
// specification.
//
// The levelspec can be either a debug level or of the form:
// <subsystem>=<level>,<subsystem2>=<level2>,...
//
// Additionally, the special keyword 'show' can be used to get a list of the
// available subsystems.
//
// NOTE: This is a btcd extension.
func (c *Client) DebugLevel(levelSpec string) (string, error) {
return c.DebugLevelAsync(levelSpec).Receive()
}
// FutureCreateEncryptedWalletResult is a future promise to deliver the error
// result of a CreateEncryptedWalletAsync RPC invocation.
type FutureCreateEncryptedWalletResult chan *response
// Receive waits for and returns the error response promised by the future.
func (r FutureCreateEncryptedWalletResult) Receive() error {
_, err := receiveFuture(r)
return err
}
// CreateEncryptedWalletAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See CreateEncryptedWallet for the blocking version and more details.
//
// NOTE: This is a btcwallet extension.
func (c *Client) CreateEncryptedWalletAsync(passphrase string) FutureCreateEncryptedWalletResult {
cmd := btcjson.NewCreateEncryptedWalletCmd(passphrase)
return c.sendCmd(cmd)
}
// CreateEncryptedWallet requests the creation of an encrypted wallet. Wallets
// managed by btcwallet are only written to disk with encrypted private keys,
// and generating wallets on the fly is impossible as it requires user input for
// the encryption passphrase. This RPC specifies the passphrase and instructs
// the wallet creation. This may error if a wallet is already opened, or the
// new wallet cannot be written to disk.
//
// NOTE: This is a btcwallet extension.
func (c *Client) CreateEncryptedWallet(passphrase string) error {
return c.CreateEncryptedWalletAsync(passphrase).Receive()
}
// FutureListAddressTransactionsResult is a future promise to deliver the result
// of a ListAddressTransactionsAsync RPC invocation (or an applicable error).
type FutureListAddressTransactionsResult chan *response
// Receive waits for the response promised by the future and returns information
// about all transactions associated with the provided addresses.
func (r FutureListAddressTransactionsResult) Receive() ([]btcjson.ListTransactionsResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal the result as an array of listtransactions objects.
var transactions []btcjson.ListTransactionsResult
err = json.Unmarshal(res, &transactions)
if err != nil {
return nil, err
}
return transactions, nil
}
// ListAddressTransactionsAsync returns an instance of a type that can be used
// to get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See ListAddressTransactions for the blocking version and more details.
//
// NOTE: This is a btcd extension.
func (c *Client) ListAddressTransactionsAsync(addresses []btcutil.Address, account string) FutureListAddressTransactionsResult {
// Convert addresses to strings.
addrs := make([]string, 0, len(addresses))
for _, addr := range addresses {
addrs = append(addrs, addr.EncodeAddress())
}
cmd := btcjson.NewListAddressTransactionsCmd(addrs, &account)
return c.sendCmd(cmd)
}
// ListAddressTransactions returns information about all transactions associated
// with the provided addresses.
//
// NOTE: This is a btcwallet extension.
func (c *Client) ListAddressTransactions(addresses []btcutil.Address, account string) ([]btcjson.ListTransactionsResult, error) {
return c.ListAddressTransactionsAsync(addresses, account).Receive()
}
// FutureGetBestBlockResult is a future promise to deliver the result of a
// GetBestBlockAsync RPC invocation (or an applicable error).
type FutureGetBestBlockResult chan *response
// Receive waits for the response promised by the future and returns the hash
// and height of the block in the longest (best) chain.
func (r FutureGetBestBlockResult) Receive() (*chainhash.Hash, int32, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, 0, err
}
// Unmarshal result as a getbestblock result object.
var bestBlock btcjson.GetBestBlockResult
err = json.Unmarshal(res, &bestBlock)
if err != nil {
return nil, 0, err
}
// Convert to hash from string.
hash, err := chainhash.NewHashFromStr(bestBlock.Hash)
if err != nil {
return nil, 0, err
}
return hash, bestBlock.Height, nil
}
// GetBestBlockAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetBestBlock for the blocking version and more details.
//
// NOTE: This is a btcd extension.
func (c *Client) GetBestBlockAsync() FutureGetBestBlockResult {
cmd := btcjson.NewGetBestBlockCmd()
return c.sendCmd(cmd)
}
// GetBestBlock returns the hash and height of the block in the longest (best)
// chain.
//
// NOTE: This is a btcd extension.
func (c *Client) GetBestBlock() (*chainhash.Hash, int32, error) {
return c.GetBestBlockAsync().Receive()
}
// FutureGetCurrentNetResult is a future promise to deliver the result of a
// GetCurrentNetAsync RPC invocation (or an applicable error).
type FutureGetCurrentNetResult chan *response
// Receive waits for the response promised by the future and returns the network
// the server is running on.
func (r FutureGetCurrentNetResult) Receive() (wire.BitcoinNet, error) {
res, err := receiveFuture(r)
if err != nil {
return 0, err
}
// Unmarshal result as an int64.
var net int64
err = json.Unmarshal(res, &net)
if err != nil {
return 0, err
}
return wire.BitcoinNet(net), nil
}
// GetCurrentNetAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetCurrentNet for the blocking version and more details.
//
// NOTE: This is a btcd extension.
func (c *Client) GetCurrentNetAsync() FutureGetCurrentNetResult {
cmd := btcjson.NewGetCurrentNetCmd()
return c.sendCmd(cmd)
}
// GetCurrentNet returns the network the server is running on.
//
// NOTE: This is a btcd extension.
func (c *Client) GetCurrentNet() (wire.BitcoinNet, error) {
return c.GetCurrentNetAsync().Receive()
}
// FutureGetHeadersResult is a future promise to deliver the result of a
// getheaders RPC invocation (or an applicable error).
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
type FutureGetHeadersResult chan *response
// Receive waits for the response promised by the future and returns the
// getheaders result.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (r FutureGetHeadersResult) Receive() ([]wire.BlockHeader, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a slice of strings.
var result []string
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
// Deserialize the []string into []wire.BlockHeader.
headers := make([]wire.BlockHeader, len(result))
for i, headerHex := range result {
serialized, err := hex.DecodeString(headerHex)
if err != nil {
return nil, err
}
err = headers[i].Deserialize(bytes.NewReader(serialized))
if err != nil {
return nil, err
}
}
return headers, nil
}
// GetHeadersAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the returned instance.
//
// See GetHeaders for the blocking version and more details.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (c *Client) GetHeadersAsync(blockLocators []chainhash.Hash, hashStop *chainhash.Hash) FutureGetHeadersResult {
locators := make([]string, len(blockLocators))
for i := range blockLocators {
locators[i] = blockLocators[i].String()
}
hash := ""
if hashStop != nil {
hash = hashStop.String()
}
cmd := btcjson.NewGetHeadersCmd(locators, hash)
return c.sendCmd(cmd)
}
// GetHeaders mimics the wire protocol getheaders and headers messages by
// returning all headers on the main chain after the first known block in the
// locators, up until a block hash matches hashStop.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (c *Client) GetHeaders(blockLocators []chainhash.Hash, hashStop *chainhash.Hash) ([]wire.BlockHeader, error) {
return c.GetHeadersAsync(blockLocators, hashStop).Receive()
}
// FutureExportWatchingWalletResult is a future promise to deliver the result of
// an ExportWatchingWalletAsync RPC invocation (or an applicable error).
type FutureExportWatchingWalletResult chan *response
// Receive waits for the response promised by the future and returns the
// exported wallet.
func (r FutureExportWatchingWalletResult) Receive() ([]byte, []byte, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, nil, err
}
// Unmarshal result as a JSON object.
var obj map[string]interface{}
err = json.Unmarshal(res, &obj)
if err != nil {
return nil, nil, err
}
// Check for the wallet and tx string fields in the object.
base64Wallet, ok := obj["wallet"].(string)
if !ok {
return nil, nil, fmt.Errorf("unexpected response type for "+
"exportwatchingwallet 'wallet' field: %T\n",
obj["wallet"])
}
base64TxStore, ok := obj["tx"].(string)
if !ok {
return nil, nil, fmt.Errorf("unexpected response type for "+
"exportwatchingwallet 'tx' field: %T\n",
obj["tx"])
}
walletBytes, err := base64.StdEncoding.DecodeString(base64Wallet)
if err != nil {
return nil, nil, err
}
txStoreBytes, err := base64.StdEncoding.DecodeString(base64TxStore)
if err != nil {
return nil, nil, err
}
return walletBytes, txStoreBytes, nil
}
// ExportWatchingWalletAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See ExportWatchingWallet for the blocking version and more details.
//
// NOTE: This is a btcwallet extension.
func (c *Client) ExportWatchingWalletAsync(account string) FutureExportWatchingWalletResult {
cmd := btcjson.NewExportWatchingWalletCmd(&account, btcjson.Bool(true))
return c.sendCmd(cmd)
}
// ExportWatchingWallet returns the raw bytes for a watching-only version of
// wallet.bin and tx.bin, respectively, for the specified account that can be
// used by btcwallet to enable a wallet which does not have the private keys
// necessary to spend funds.
//
// NOTE: This is a btcwallet extension.
func (c *Client) ExportWatchingWallet(account string) ([]byte, []byte, error) {
return c.ExportWatchingWalletAsync(account).Receive()
}
// FutureSessionResult is a future promise to deliver the result of a
// SessionAsync RPC invocation (or an applicable error).
type FutureSessionResult chan *response
// Receive waits for the response promised by the future and returns the
// session result.
func (r FutureSessionResult) Receive() (*btcjson.SessionResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a session result object.
var session btcjson.SessionResult
err = json.Unmarshal(res, &session)
if err != nil {
return nil, err
}
return &session, nil
}
// SessionAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See Session for the blocking version and more details.
//
// NOTE: This is a btcsuite extension.
func (c *Client) SessionAsync() FutureSessionResult {
// Not supported in HTTP POST mode.
if c.config.HTTPPostMode {
return newFutureError(ErrWebsocketsRequired)
}
cmd := btcjson.NewSessionCmd()
return c.sendCmd(cmd)
}
// Session returns details regarding a websocket client's current connection.
//
// This RPC requires the client to be running in websocket mode.
//
// NOTE: This is a btcsuite extension.
func (c *Client) Session() (*btcjson.SessionResult, error) {
return c.SessionAsync().Receive()
}
// FutureVersionResult is a future promise to deliver the result of a version
// RPC invocation (or an applicable error).
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
type FutureVersionResult chan *response
// Receive waits for the response promised by the future and returns the version
// result.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (r FutureVersionResult) Receive() (map[string]btcjson.VersionResult,
error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a version result object.
var vr map[string]btcjson.VersionResult
err = json.Unmarshal(res, &vr)
if err != nil {
return nil, err
}
return vr, nil
}
// VersionAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See Version for the blocking version and more details.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (c *Client) VersionAsync() FutureVersionResult {
cmd := btcjson.NewVersionCmd()
return c.sendCmd(cmd)
}
// Version returns information about the server's JSON-RPC API versions.
//
// NOTE: This is a btcsuite extension ported from
// github.com/decred/dcrrpcclient.
func (c *Client) Version() (map[string]btcjson.VersionResult, error) {
return c.VersionAsync().Receive()
}

File diff suppressed because it is too large Load Diff

47
vendor/github.com/btcsuite/btcd/rpcclient/log.go generated vendored Normal file
View File

@ -0,0 +1,47 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcclient
import (
"github.com/btcsuite/btclog"
)
// log is a logger that is initialized with no output filters. This
// means the package will not perform any logging by default until the caller
// requests it.
var log btclog.Logger
// The default amount of logging is none.
func init() {
DisableLog()
}
// DisableLog disables all library log output. Logging output is disabled
// by default until UseLogger is called.
func DisableLog() {
log = btclog.Disabled
}
// UseLogger uses a specified Logger to output package logging info.
func UseLogger(logger btclog.Logger) {
log = logger
}
// LogClosure is a closure that can be printed with %v to be used to
// generate expensive-to-create data for a detailed log level and avoid doing
// the work if the data isn't printed.
type logClosure func() string
// String invokes the log closure and returns the results string.
func (c logClosure) String() string {
return c()
}
// newLogClosure returns a new closure over the passed function which allows
// it to be used as a parameter in a logging function that is only invoked when
// the logging level is such that the message will actually be logged.
func newLogClosure(c func() string) logClosure {
return logClosure(c)
}

417
vendor/github.com/btcsuite/btcd/rpcclient/mining.go generated vendored Normal file
View File

@ -0,0 +1,417 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcclient
import (
"encoding/hex"
"encoding/json"
"errors"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil"
)
// FutureGenerateResult is a future promise to deliver the result of a
// GenerateAsync RPC invocation (or an applicable error).
type FutureGenerateResult chan *response
// Receive waits for the response promised by the future and returns a list of
// block hashes generated by the call.
func (r FutureGenerateResult) Receive() ([]*chainhash.Hash, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a list of strings.
var result []string
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
// Convert each block hash to a chainhash.Hash and store a pointer to
// each.
convertedResult := make([]*chainhash.Hash, len(result))
for i, hashString := range result {
convertedResult[i], err = chainhash.NewHashFromStr(hashString)
if err != nil {
return nil, err
}
}
return convertedResult, nil
}
// GenerateAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See Generate for the blocking version and more details.
func (c *Client) GenerateAsync(numBlocks uint32) FutureGenerateResult {
cmd := btcjson.NewGenerateCmd(numBlocks)
return c.sendCmd(cmd)
}
// Generate generates numBlocks blocks and returns their hashes.
func (c *Client) Generate(numBlocks uint32) ([]*chainhash.Hash, error) {
return c.GenerateAsync(numBlocks).Receive()
}
// FutureGetGenerateResult is a future promise to deliver the result of a
// GetGenerateAsync RPC invocation (or an applicable error).
type FutureGetGenerateResult chan *response
// Receive waits for the response promised by the future and returns true if the
// server is set to mine, otherwise false.
func (r FutureGetGenerateResult) Receive() (bool, error) {
res, err := receiveFuture(r)
if err != nil {
return false, err
}
// Unmarshal result as a boolean.
var result bool
err = json.Unmarshal(res, &result)
if err != nil {
return false, err
}
return result, nil
}
// GetGenerateAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetGenerate for the blocking version and more details.
func (c *Client) GetGenerateAsync() FutureGetGenerateResult {
cmd := btcjson.NewGetGenerateCmd()
return c.sendCmd(cmd)
}
// GetGenerate returns true if the server is set to mine, otherwise false.
func (c *Client) GetGenerate() (bool, error) {
return c.GetGenerateAsync().Receive()
}
// FutureSetGenerateResult is a future promise to deliver the result of a
// SetGenerateAsync RPC invocation (or an applicable error).
type FutureSetGenerateResult chan *response
// Receive waits for the response promised by the future and returns an error if
// any occurred when setting the server to generate coins (mine) or not.
func (r FutureSetGenerateResult) Receive() error {
_, err := receiveFuture(r)
return err
}
// SetGenerateAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See SetGenerate for the blocking version and more details.
func (c *Client) SetGenerateAsync(enable bool, numCPUs int) FutureSetGenerateResult {
cmd := btcjson.NewSetGenerateCmd(enable, &numCPUs)
return c.sendCmd(cmd)
}
// SetGenerate sets the server to generate coins (mine) or not.
func (c *Client) SetGenerate(enable bool, numCPUs int) error {
return c.SetGenerateAsync(enable, numCPUs).Receive()
}
// FutureGetHashesPerSecResult is a future promise to deliver the result of a
// GetHashesPerSecAsync RPC invocation (or an applicable error).
type FutureGetHashesPerSecResult chan *response
// Receive waits for the response promised by the future and returns a recent
// hashes per second performance measurement while generating coins (mining).
// Zero is returned if the server is not mining.
func (r FutureGetHashesPerSecResult) Receive() (int64, error) {
res, err := receiveFuture(r)
if err != nil {
return -1, err
}
// Unmarshal result as an int64.
var result int64
err = json.Unmarshal(res, &result)
if err != nil {
return 0, err
}
return result, nil
}
// GetHashesPerSecAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetHashesPerSec for the blocking version and more details.
func (c *Client) GetHashesPerSecAsync() FutureGetHashesPerSecResult {
cmd := btcjson.NewGetHashesPerSecCmd()
return c.sendCmd(cmd)
}
// GetHashesPerSec returns a recent hashes per second performance measurement
// while generating coins (mining). Zero is returned if the server is not
// mining.
func (c *Client) GetHashesPerSec() (int64, error) {
return c.GetHashesPerSecAsync().Receive()
}
// FutureGetMiningInfoResult is a future promise to deliver the result of a
// GetMiningInfoAsync RPC invocation (or an applicable error).
type FutureGetMiningInfoResult chan *response
// Receive waits for the response promised by the future and returns the mining
// information.
func (r FutureGetMiningInfoResult) Receive() (*btcjson.GetMiningInfoResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a getmininginfo result object.
var infoResult btcjson.GetMiningInfoResult
err = json.Unmarshal(res, &infoResult)
if err != nil {
return nil, err
}
return &infoResult, nil
}
// GetMiningInfoAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetMiningInfo for the blocking version and more details.
func (c *Client) GetMiningInfoAsync() FutureGetMiningInfoResult {
cmd := btcjson.NewGetMiningInfoCmd()
return c.sendCmd(cmd)
}
// GetMiningInfo returns mining information.
func (c *Client) GetMiningInfo() (*btcjson.GetMiningInfoResult, error) {
return c.GetMiningInfoAsync().Receive()
}
// FutureGetNetworkHashPS is a future promise to deliver the result of a
// GetNetworkHashPSAsync RPC invocation (or an applicable error).
type FutureGetNetworkHashPS chan *response
// Receive waits for the response promised by the future and returns the
// estimated network hashes per second for the block heights provided by the
// parameters.
func (r FutureGetNetworkHashPS) Receive() (int64, error) {
res, err := receiveFuture(r)
if err != nil {
return -1, err
}
// Unmarshal result as an int64.
var result int64
err = json.Unmarshal(res, &result)
if err != nil {
return 0, err
}
return result, nil
}
// GetNetworkHashPSAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetNetworkHashPS for the blocking version and more details.
func (c *Client) GetNetworkHashPSAsync() FutureGetNetworkHashPS {
cmd := btcjson.NewGetNetworkHashPSCmd(nil, nil)
return c.sendCmd(cmd)
}
// GetNetworkHashPS returns the estimated network hashes per second using the
// default number of blocks and the most recent block height.
//
// See GetNetworkHashPS2 to override the number of blocks to use and
// GetNetworkHashPS3 to override the height at which to calculate the estimate.
func (c *Client) GetNetworkHashPS() (int64, error) {
return c.GetNetworkHashPSAsync().Receive()
}
// GetNetworkHashPS2Async returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetNetworkHashPS2 for the blocking version and more details.
func (c *Client) GetNetworkHashPS2Async(blocks int) FutureGetNetworkHashPS {
cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, nil)
return c.sendCmd(cmd)
}
// GetNetworkHashPS2 returns the estimated network hashes per second for the
// specified previous number of blocks working backwards from the most recent
// block height. The blocks parameter can also be -1 in which case the number
// of blocks since the last difficulty change will be used.
//
// See GetNetworkHashPS to use defaults and GetNetworkHashPS3 to override the
// height at which to calculate the estimate.
func (c *Client) GetNetworkHashPS2(blocks int) (int64, error) {
return c.GetNetworkHashPS2Async(blocks).Receive()
}
// GetNetworkHashPS3Async returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetNetworkHashPS3 for the blocking version and more details.
func (c *Client) GetNetworkHashPS3Async(blocks, height int) FutureGetNetworkHashPS {
cmd := btcjson.NewGetNetworkHashPSCmd(&blocks, &height)
return c.sendCmd(cmd)
}
// GetNetworkHashPS3 returns the estimated network hashes per second for the
// specified previous number of blocks working backwards from the specified
// block height. The blocks parameter can also be -1 in which case the number
// of blocks since the last difficulty change will be used.
//
// See GetNetworkHashPS and GetNetworkHashPS2 to use defaults.
func (c *Client) GetNetworkHashPS3(blocks, height int) (int64, error) {
return c.GetNetworkHashPS3Async(blocks, height).Receive()
}
// FutureGetWork is a future promise to deliver the result of a
// GetWorkAsync RPC invocation (or an applicable error).
type FutureGetWork chan *response
// Receive waits for the response promised by the future and returns the hash
// data to work on.
func (r FutureGetWork) Receive() (*btcjson.GetWorkResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a getwork result object.
var result btcjson.GetWorkResult
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
return &result, nil
}
// GetWorkAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetWork for the blocking version and more details.
func (c *Client) GetWorkAsync() FutureGetWork {
cmd := btcjson.NewGetWorkCmd(nil)
return c.sendCmd(cmd)
}
// GetWork returns hash data to work on.
//
// See GetWorkSubmit to submit the found solution.
func (c *Client) GetWork() (*btcjson.GetWorkResult, error) {
return c.GetWorkAsync().Receive()
}
// FutureGetWorkSubmit is a future promise to deliver the result of a
// GetWorkSubmitAsync RPC invocation (or an applicable error).
type FutureGetWorkSubmit chan *response
// Receive waits for the response promised by the future and returns whether
// or not the submitted block header was accepted.
func (r FutureGetWorkSubmit) Receive() (bool, error) {
res, err := receiveFuture(r)
if err != nil {
return false, err
}
// Unmarshal result as a boolean.
var accepted bool
err = json.Unmarshal(res, &accepted)
if err != nil {
return false, err
}
return accepted, nil
}
// GetWorkSubmitAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetWorkSubmit for the blocking version and more details.
func (c *Client) GetWorkSubmitAsync(data string) FutureGetWorkSubmit {
cmd := btcjson.NewGetWorkCmd(&data)
return c.sendCmd(cmd)
}
// GetWorkSubmit submits a block header which is a solution to previously
// requested data and returns whether or not the solution was accepted.
//
// See GetWork to request data to work on.
func (c *Client) GetWorkSubmit(data string) (bool, error) {
return c.GetWorkSubmitAsync(data).Receive()
}
// FutureSubmitBlockResult is a future promise to deliver the result of a
// SubmitBlockAsync RPC invocation (or an applicable error).
type FutureSubmitBlockResult chan *response
// Receive waits for the response promised by the future and returns an error if
// any occurred when submitting the block.
func (r FutureSubmitBlockResult) Receive() error {
res, err := receiveFuture(r)
if err != nil {
return err
}
if string(res) != "null" {
var result string
err = json.Unmarshal(res, &result)
if err != nil {
return err
}
return errors.New(result)
}
return nil
}
// SubmitBlockAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See SubmitBlock for the blocking version and more details.
func (c *Client) SubmitBlockAsync(block *btcutil.Block, options *btcjson.SubmitBlockOptions) FutureSubmitBlockResult {
blockHex := ""
if block != nil {
blockBytes, err := block.Bytes()
if err != nil {
return newFutureError(err)
}
blockHex = hex.EncodeToString(blockBytes)
}
cmd := btcjson.NewSubmitBlockCmd(blockHex, options)
return c.sendCmd(cmd)
}
// SubmitBlock attempts to submit a new block into the bitcoin network.
func (c *Client) SubmitBlock(block *btcutil.Block, options *btcjson.SubmitBlockOptions) error {
return c.SubmitBlockAsync(block, options).Receive()
}
// TODO(davec): Implement GetBlockTemplate

319
vendor/github.com/btcsuite/btcd/rpcclient/net.go generated vendored Normal file
View File

@ -0,0 +1,319 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcclient
import (
"encoding/json"
"github.com/btcsuite/btcd/btcjson"
)
// AddNodeCommand enumerates the available commands that the AddNode function
// accepts.
type AddNodeCommand string
// Constants used to indicate the command for the AddNode function.
const (
// ANAdd indicates the specified host should be added as a persistent
// peer.
ANAdd AddNodeCommand = "add"
// ANRemove indicates the specified peer should be removed.
ANRemove AddNodeCommand = "remove"
// ANOneTry indicates the specified host should try to connect once,
// but it should not be made persistent.
ANOneTry AddNodeCommand = "onetry"
)
// String returns the AddNodeCommand in human-readable form.
func (cmd AddNodeCommand) String() string {
return string(cmd)
}
// FutureAddNodeResult is a future promise to deliver the result of an
// AddNodeAsync RPC invocation (or an applicable error).
type FutureAddNodeResult chan *response
// Receive waits for the response promised by the future and returns an error if
// any occurred when performing the specified command.
func (r FutureAddNodeResult) Receive() error {
_, err := receiveFuture(r)
return err
}
// AddNodeAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See AddNode for the blocking version and more details.
func (c *Client) AddNodeAsync(host string, command AddNodeCommand) FutureAddNodeResult {
cmd := btcjson.NewAddNodeCmd(host, btcjson.AddNodeSubCmd(command))
return c.sendCmd(cmd)
}
// AddNode attempts to perform the passed command on the passed persistent peer.
// For example, it can be used to add or a remove a persistent peer, or to do
// a one time connection to a peer.
//
// It may not be used to remove non-persistent peers.
func (c *Client) AddNode(host string, command AddNodeCommand) error {
return c.AddNodeAsync(host, command).Receive()
}
// FutureNodeResult is a future promise to deliver the result of a NodeAsync
// RPC invocation (or an applicable error).
type FutureNodeResult chan *response
// Receive waits for the response promised by the future and returns an error if
// any occurred when performing the specified command.
func (r FutureNodeResult) Receive() error {
_, err := receiveFuture(r)
return err
}
// NodeAsync returns an instance of a type that can be used to get the result
// of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See Node for the blocking version and more details.
func (c *Client) NodeAsync(command btcjson.NodeSubCmd, host string,
connectSubCmd *string) FutureNodeResult {
cmd := btcjson.NewNodeCmd(command, host, connectSubCmd)
return c.sendCmd(cmd)
}
// Node attempts to perform the passed node command on the host.
// For example, it can be used to add or a remove a persistent peer, or to do
// connect or diconnect a non-persistent one.
//
// The connectSubCmd should be set either "perm" or "temp", depending on
// whether we are targetting a persistent or non-persistent peer. Passing nil
// will cause the default value to be used, which currently is "temp".
func (c *Client) Node(command btcjson.NodeSubCmd, host string,
connectSubCmd *string) error {
return c.NodeAsync(command, host, connectSubCmd).Receive()
}
// FutureGetAddedNodeInfoResult is a future promise to deliver the result of a
// GetAddedNodeInfoAsync RPC invocation (or an applicable error).
type FutureGetAddedNodeInfoResult chan *response
// Receive waits for the response promised by the future and returns information
// about manually added (persistent) peers.
func (r FutureGetAddedNodeInfoResult) Receive() ([]btcjson.GetAddedNodeInfoResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal as an array of getaddednodeinfo result objects.
var nodeInfo []btcjson.GetAddedNodeInfoResult
err = json.Unmarshal(res, &nodeInfo)
if err != nil {
return nil, err
}
return nodeInfo, nil
}
// GetAddedNodeInfoAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetAddedNodeInfo for the blocking version and more details.
func (c *Client) GetAddedNodeInfoAsync(peer string) FutureGetAddedNodeInfoResult {
cmd := btcjson.NewGetAddedNodeInfoCmd(true, &peer)
return c.sendCmd(cmd)
}
// GetAddedNodeInfo returns information about manually added (persistent) peers.
//
// See GetAddedNodeInfoNoDNS to retrieve only a list of the added (persistent)
// peers.
func (c *Client) GetAddedNodeInfo(peer string) ([]btcjson.GetAddedNodeInfoResult, error) {
return c.GetAddedNodeInfoAsync(peer).Receive()
}
// FutureGetAddedNodeInfoNoDNSResult is a future promise to deliver the result
// of a GetAddedNodeInfoNoDNSAsync RPC invocation (or an applicable error).
type FutureGetAddedNodeInfoNoDNSResult chan *response
// Receive waits for the response promised by the future and returns a list of
// manually added (persistent) peers.
func (r FutureGetAddedNodeInfoNoDNSResult) Receive() ([]string, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as an array of strings.
var nodes []string
err = json.Unmarshal(res, &nodes)
if err != nil {
return nil, err
}
return nodes, nil
}
// GetAddedNodeInfoNoDNSAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See GetAddedNodeInfoNoDNS for the blocking version and more details.
func (c *Client) GetAddedNodeInfoNoDNSAsync(peer string) FutureGetAddedNodeInfoNoDNSResult {
cmd := btcjson.NewGetAddedNodeInfoCmd(false, &peer)
return c.sendCmd(cmd)
}
// GetAddedNodeInfoNoDNS returns a list of manually added (persistent) peers.
// This works by setting the dns flag to false in the underlying RPC.
//
// See GetAddedNodeInfo to obtain more information about each added (persistent)
// peer.
func (c *Client) GetAddedNodeInfoNoDNS(peer string) ([]string, error) {
return c.GetAddedNodeInfoNoDNSAsync(peer).Receive()
}
// FutureGetConnectionCountResult is a future promise to deliver the result
// of a GetConnectionCountAsync RPC invocation (or an applicable error).
type FutureGetConnectionCountResult chan *response
// Receive waits for the response promised by the future and returns the number
// of active connections to other peers.
func (r FutureGetConnectionCountResult) Receive() (int64, error) {
res, err := receiveFuture(r)
if err != nil {
return 0, err
}
// Unmarshal result as an int64.
var count int64
err = json.Unmarshal(res, &count)
if err != nil {
return 0, err
}
return count, nil
}
// GetConnectionCountAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetConnectionCount for the blocking version and more details.
func (c *Client) GetConnectionCountAsync() FutureGetConnectionCountResult {
cmd := btcjson.NewGetConnectionCountCmd()
return c.sendCmd(cmd)
}
// GetConnectionCount returns the number of active connections to other peers.
func (c *Client) GetConnectionCount() (int64, error) {
return c.GetConnectionCountAsync().Receive()
}
// FuturePingResult is a future promise to deliver the result of a PingAsync RPC
// invocation (or an applicable error).
type FuturePingResult chan *response
// Receive waits for the response promised by the future and returns the result
// of queueing a ping to be sent to each connected peer.
func (r FuturePingResult) Receive() error {
_, err := receiveFuture(r)
return err
}
// PingAsync returns an instance of a type that can be used to get the result of
// the RPC at some future time by invoking the Receive function on the returned
// instance.
//
// See Ping for the blocking version and more details.
func (c *Client) PingAsync() FuturePingResult {
cmd := btcjson.NewPingCmd()
return c.sendCmd(cmd)
}
// Ping queues a ping to be sent to each connected peer.
//
// Use the GetPeerInfo function and examine the PingTime and PingWait fields to
// access the ping times.
func (c *Client) Ping() error {
return c.PingAsync().Receive()
}
// FutureGetPeerInfoResult is a future promise to deliver the result of a
// GetPeerInfoAsync RPC invocation (or an applicable error).
type FutureGetPeerInfoResult chan *response
// Receive waits for the response promised by the future and returns data about
// each connected network peer.
func (r FutureGetPeerInfoResult) Receive() ([]btcjson.GetPeerInfoResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as an array of getpeerinfo result objects.
var peerInfo []btcjson.GetPeerInfoResult
err = json.Unmarshal(res, &peerInfo)
if err != nil {
return nil, err
}
return peerInfo, nil
}
// GetPeerInfoAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetPeerInfo for the blocking version and more details.
func (c *Client) GetPeerInfoAsync() FutureGetPeerInfoResult {
cmd := btcjson.NewGetPeerInfoCmd()
return c.sendCmd(cmd)
}
// GetPeerInfo returns data about each connected network peer.
func (c *Client) GetPeerInfo() ([]btcjson.GetPeerInfoResult, error) {
return c.GetPeerInfoAsync().Receive()
}
// FutureGetNetTotalsResult is a future promise to deliver the result of a
// GetNetTotalsAsync RPC invocation (or an applicable error).
type FutureGetNetTotalsResult chan *response
// Receive waits for the response promised by the future and returns network
// traffic statistics.
func (r FutureGetNetTotalsResult) Receive() (*btcjson.GetNetTotalsResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a getnettotals result object.
var totals btcjson.GetNetTotalsResult
err = json.Unmarshal(res, &totals)
if err != nil {
return nil, err
}
return &totals, nil
}
// GetNetTotalsAsync returns an instance of a type that can be used to get the
// result of the RPC at some future time by invoking the Receive function on the
// returned instance.
//
// See GetNetTotals for the blocking version and more details.
func (c *Client) GetNetTotalsAsync() FutureGetNetTotalsResult {
cmd := btcjson.NewGetNetTotalsCmd()
return c.sendCmd(cmd)
}
// GetNetTotals returns network traffic statistics.
func (c *Client) GetNetTotals() (*btcjson.GetNetTotalsResult, error) {
return c.GetNetTotalsAsync().Receive()
}

1357
vendor/github.com/btcsuite/btcd/rpcclient/notify.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcclient
import (
"encoding/json"
"errors"
"github.com/btcsuite/btcd/btcjson"
)
// FutureRawResult is a future promise to deliver the result of a RawRequest RPC
// invocation (or an applicable error).
type FutureRawResult chan *response
// Receive waits for the response promised by the future and returns the raw
// response, or an error if the request was unsuccessful.
func (r FutureRawResult) Receive() (json.RawMessage, error) {
return receiveFuture(r)
}
// RawRequestAsync returns an instance of a type that can be used to get the
// result of a custom RPC request at some future time by invoking the Receive
// function on the returned instance.
//
// See RawRequest for the blocking version and more details.
func (c *Client) RawRequestAsync(method string, params []json.RawMessage) FutureRawResult {
// Method may not be empty.
if method == "" {
return newFutureError(errors.New("no method"))
}
// Marshal parameters as "[]" instead of "null" when no parameters
// are passed.
if params == nil {
params = []json.RawMessage{}
}
// Create a raw JSON-RPC request using the provided method and params
// and marshal it. This is done rather than using the sendCmd function
// since that relies on marshalling registered btcjson commands rather
// than custom commands.
id := c.NextID()
rawRequest := &btcjson.Request{
Jsonrpc: "1.0",
ID: id,
Method: method,
Params: params,
}
marshalledJSON, err := json.Marshal(rawRequest)
if err != nil {
return newFutureError(err)
}
// Generate the request and send it along with a channel to respond on.
responseChan := make(chan *response, 1)
jReq := &jsonRequest{
id: id,
method: method,
cmd: nil,
marshalledJSON: marshalledJSON,
responseChan: responseChan,
}
c.sendRequest(jReq)
return responseChan
}
// RawRequest allows the caller to send a raw or custom request to the server.
// This method may be used to send and receive requests and responses for
// requests that are not handled by this client package, or to proxy partially
// unmarshaled requests to another JSON-RPC server if a request cannot be
// handled directly.
func (c *Client) RawRequest(method string, params []json.RawMessage) (json.RawMessage, error) {
return c.RawRequestAsync(method, params).Receive()
}

View File

@ -0,0 +1,664 @@
// Copyright (c) 2014-2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package rpcclient
import (
"bytes"
"encoding/hex"
"encoding/json"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil"
)
// SigHashType enumerates the available signature hashing types that the
// SignRawTransaction function accepts.
type SigHashType string
// Constants used to indicate the signature hash type for SignRawTransaction.
const (
// SigHashAll indicates ALL of the outputs should be signed.
SigHashAll SigHashType = "ALL"
// SigHashNone indicates NONE of the outputs should be signed. This
// can be thought of as specifying the signer does not care where the
// bitcoins go.
SigHashNone SigHashType = "NONE"
// SigHashSingle indicates that a SINGLE output should be signed. This
// can be thought of specifying the signer only cares about where ONE of
// the outputs goes, but not any of the others.
SigHashSingle SigHashType = "SINGLE"
// SigHashAllAnyoneCanPay indicates that signer does not care where the
// other inputs to the transaction come from, so it allows other people
// to add inputs. In addition, it uses the SigHashAll signing method
// for outputs.
SigHashAllAnyoneCanPay SigHashType = "ALL|ANYONECANPAY"
// SigHashNoneAnyoneCanPay indicates that signer does not care where the
// other inputs to the transaction come from, so it allows other people
// to add inputs. In addition, it uses the SigHashNone signing method
// for outputs.
SigHashNoneAnyoneCanPay SigHashType = "NONE|ANYONECANPAY"
// SigHashSingleAnyoneCanPay indicates that signer does not care where
// the other inputs to the transaction come from, so it allows other
// people to add inputs. In addition, it uses the SigHashSingle signing
// method for outputs.
SigHashSingleAnyoneCanPay SigHashType = "SINGLE|ANYONECANPAY"
)
// String returns the SighHashType in human-readable form.
func (s SigHashType) String() string {
return string(s)
}
// FutureGetRawTransactionResult is a future promise to deliver the result of a
// GetRawTransactionAsync RPC invocation (or an applicable error).
type FutureGetRawTransactionResult chan *response
// Receive waits for the response promised by the future and returns a
// transaction given its hash.
func (r FutureGetRawTransactionResult) Receive() (*btcutil.Tx, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var txHex string
err = json.Unmarshal(res, &txHex)
if err != nil {
return nil, err
}
// Decode the serialized transaction hex to raw bytes.
serializedTx, err := hex.DecodeString(txHex)
if err != nil {
return nil, err
}
// Deserialize the transaction and return it.
var msgTx wire.MsgTx
if err := msgTx.Deserialize(bytes.NewReader(serializedTx)); err != nil {
return nil, err
}
return btcutil.NewTx(&msgTx), nil
}
// GetRawTransactionAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See GetRawTransaction for the blocking version and more details.
func (c *Client) GetRawTransactionAsync(txHash *chainhash.Hash) FutureGetRawTransactionResult {
hash := ""
if txHash != nil {
hash = txHash.String()
}
cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(0))
return c.sendCmd(cmd)
}
// GetRawTransaction returns a transaction given its hash.
//
// See GetRawTransactionVerbose to obtain additional information about the
// transaction.
func (c *Client) GetRawTransaction(txHash *chainhash.Hash) (*btcutil.Tx, error) {
return c.GetRawTransactionAsync(txHash).Receive()
}
// FutureGetRawTransactionVerboseResult is a future promise to deliver the
// result of a GetRawTransactionVerboseAsync RPC invocation (or an applicable
// error).
type FutureGetRawTransactionVerboseResult chan *response
// Receive waits for the response promised by the future and returns information
// about a transaction given its hash.
func (r FutureGetRawTransactionVerboseResult) Receive() (*btcjson.TxRawResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a gettrawtransaction result object.
var rawTxResult btcjson.TxRawResult
err = json.Unmarshal(res, &rawTxResult)
if err != nil {
return nil, err
}
return &rawTxResult, nil
}
// GetRawTransactionVerboseAsync returns an instance of a type that can be used
// to get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See GetRawTransactionVerbose for the blocking version and more details.
func (c *Client) GetRawTransactionVerboseAsync(txHash *chainhash.Hash) FutureGetRawTransactionVerboseResult {
hash := ""
if txHash != nil {
hash = txHash.String()
}
cmd := btcjson.NewGetRawTransactionCmd(hash, btcjson.Int(1))
return c.sendCmd(cmd)
}
// GetRawTransactionVerbose returns information about a transaction given
// its hash.
//
// See GetRawTransaction to obtain only the transaction already deserialized.
func (c *Client) GetRawTransactionVerbose(txHash *chainhash.Hash) (*btcjson.TxRawResult, error) {
return c.GetRawTransactionVerboseAsync(txHash).Receive()
}
// FutureDecodeRawTransactionResult is a future promise to deliver the result
// of a DecodeRawTransactionAsync RPC invocation (or an applicable error).
type FutureDecodeRawTransactionResult chan *response
// Receive waits for the response promised by the future and returns information
// about a transaction given its serialized bytes.
func (r FutureDecodeRawTransactionResult) Receive() (*btcjson.TxRawResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a decoderawtransaction result object.
var rawTxResult btcjson.TxRawResult
err = json.Unmarshal(res, &rawTxResult)
if err != nil {
return nil, err
}
return &rawTxResult, nil
}
// DecodeRawTransactionAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See DecodeRawTransaction for the blocking version and more details.
func (c *Client) DecodeRawTransactionAsync(serializedTx []byte) FutureDecodeRawTransactionResult {
txHex := hex.EncodeToString(serializedTx)
cmd := btcjson.NewDecodeRawTransactionCmd(txHex)
return c.sendCmd(cmd)
}
// DecodeRawTransaction returns information about a transaction given its
// serialized bytes.
func (c *Client) DecodeRawTransaction(serializedTx []byte) (*btcjson.TxRawResult, error) {
return c.DecodeRawTransactionAsync(serializedTx).Receive()
}
// FutureCreateRawTransactionResult is a future promise to deliver the result
// of a CreateRawTransactionAsync RPC invocation (or an applicable error).
type FutureCreateRawTransactionResult chan *response
// Receive waits for the response promised by the future and returns a new
// transaction spending the provided inputs and sending to the provided
// addresses.
func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var txHex string
err = json.Unmarshal(res, &txHex)
if err != nil {
return nil, err
}
// Decode the serialized transaction hex to raw bytes.
serializedTx, err := hex.DecodeString(txHex)
if err != nil {
return nil, err
}
// Deserialize the transaction and return it.
var msgTx wire.MsgTx
if err := msgTx.Deserialize(bytes.NewReader(serializedTx)); err != nil {
return nil, err
}
return &msgTx, nil
}
// CreateRawTransactionAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See CreateRawTransaction for the blocking version and more details.
func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput,
amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) FutureCreateRawTransactionResult {
convertedAmts := make(map[string]float64, len(amounts))
for addr, amount := range amounts {
convertedAmts[addr.String()] = amount.ToBTC()
}
cmd := btcjson.NewCreateRawTransactionCmd(inputs, convertedAmts, lockTime)
return c.sendCmd(cmd)
}
// CreateRawTransaction returns a new transaction spending the provided inputs
// and sending to the provided addresses.
func (c *Client) CreateRawTransaction(inputs []btcjson.TransactionInput,
amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) (*wire.MsgTx, error) {
return c.CreateRawTransactionAsync(inputs, amounts, lockTime).Receive()
}
// FutureSendRawTransactionResult is a future promise to deliver the result
// of a SendRawTransactionAsync RPC invocation (or an applicable error).
type FutureSendRawTransactionResult chan *response
// Receive waits for the response promised by the future and returns the result
// of submitting the encoded transaction to the server which then relays it to
// the network.
func (r FutureSendRawTransactionResult) Receive() (*chainhash.Hash, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a string.
var txHashStr string
err = json.Unmarshal(res, &txHashStr)
if err != nil {
return nil, err
}
return chainhash.NewHashFromStr(txHashStr)
}
// SendRawTransactionAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See SendRawTransaction for the blocking version and more details.
func (c *Client) SendRawTransactionAsync(tx *wire.MsgTx, allowHighFees bool) FutureSendRawTransactionResult {
txHex := ""
if tx != nil {
// Serialize the transaction and convert to hex string.
buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
if err := tx.Serialize(buf); err != nil {
return newFutureError(err)
}
txHex = hex.EncodeToString(buf.Bytes())
}
cmd := btcjson.NewSendRawTransactionCmd(txHex, &allowHighFees)
return c.sendCmd(cmd)
}
// SendRawTransaction submits the encoded transaction to the server which will
// then relay it to the network.
func (c *Client) SendRawTransaction(tx *wire.MsgTx, allowHighFees bool) (*chainhash.Hash, error) {
return c.SendRawTransactionAsync(tx, allowHighFees).Receive()
}
// FutureSignRawTransactionResult is a future promise to deliver the result
// of one of the SignRawTransactionAsync family of RPC invocations (or an
// applicable error).
type FutureSignRawTransactionResult chan *response
// Receive waits for the response promised by the future and returns the
// signed transaction as well as whether or not all inputs are now signed.
func (r FutureSignRawTransactionResult) Receive() (*wire.MsgTx, bool, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, false, err
}
// Unmarshal as a signrawtransaction result.
var signRawTxResult btcjson.SignRawTransactionResult
err = json.Unmarshal(res, &signRawTxResult)
if err != nil {
return nil, false, err
}
// Decode the serialized transaction hex to raw bytes.
serializedTx, err := hex.DecodeString(signRawTxResult.Hex)
if err != nil {
return nil, false, err
}
// Deserialize the transaction and return it.
var msgTx wire.MsgTx
if err := msgTx.Deserialize(bytes.NewReader(serializedTx)); err != nil {
return nil, false, err
}
return &msgTx, signRawTxResult.Complete, nil
}
// SignRawTransactionAsync returns an instance of a type that can be used to get
// the result of the RPC at some future time by invoking the Receive function on
// the returned instance.
//
// See SignRawTransaction for the blocking version and more details.
func (c *Client) SignRawTransactionAsync(tx *wire.MsgTx) FutureSignRawTransactionResult {
txHex := ""
if tx != nil {
// Serialize the transaction and convert to hex string.
buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
if err := tx.Serialize(buf); err != nil {
return newFutureError(err)
}
txHex = hex.EncodeToString(buf.Bytes())
}
cmd := btcjson.NewSignRawTransactionCmd(txHex, nil, nil, nil)
return c.sendCmd(cmd)
}
// SignRawTransaction signs inputs for the passed transaction and returns the
// signed transaction as well as whether or not all inputs are now signed.
//
// This function assumes the RPC server already knows the input transactions and
// private keys for the passed transaction which needs to be signed and uses the
// default signature hash type. Use one of the SignRawTransaction# variants to
// specify that information if needed.
func (c *Client) SignRawTransaction(tx *wire.MsgTx) (*wire.MsgTx, bool, error) {
return c.SignRawTransactionAsync(tx).Receive()
}
// SignRawTransaction2Async returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See SignRawTransaction2 for the blocking version and more details.
func (c *Client) SignRawTransaction2Async(tx *wire.MsgTx, inputs []btcjson.RawTxInput) FutureSignRawTransactionResult {
txHex := ""
if tx != nil {
// Serialize the transaction and convert to hex string.
buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
if err := tx.Serialize(buf); err != nil {
return newFutureError(err)
}
txHex = hex.EncodeToString(buf.Bytes())
}
cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, nil, nil)
return c.sendCmd(cmd)
}
// SignRawTransaction2 signs inputs for the passed transaction given the list
// of information about the input transactions needed to perform the signing
// process.
//
// This only input transactions that need to be specified are ones the
// RPC server does not already know. Already known input transactions will be
// merged with the specified transactions.
//
// See SignRawTransaction if the RPC server already knows the input
// transactions.
func (c *Client) SignRawTransaction2(tx *wire.MsgTx, inputs []btcjson.RawTxInput) (*wire.MsgTx, bool, error) {
return c.SignRawTransaction2Async(tx, inputs).Receive()
}
// SignRawTransaction3Async returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See SignRawTransaction3 for the blocking version and more details.
func (c *Client) SignRawTransaction3Async(tx *wire.MsgTx,
inputs []btcjson.RawTxInput,
privKeysWIF []string) FutureSignRawTransactionResult {
txHex := ""
if tx != nil {
// Serialize the transaction and convert to hex string.
buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
if err := tx.Serialize(buf); err != nil {
return newFutureError(err)
}
txHex = hex.EncodeToString(buf.Bytes())
}
cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, &privKeysWIF,
nil)
return c.sendCmd(cmd)
}
// SignRawTransaction3 signs inputs for the passed transaction given the list
// of information about extra input transactions and a list of private keys
// needed to perform the signing process. The private keys must be in wallet
// import format (WIF).
//
// This only input transactions that need to be specified are ones the
// RPC server does not already know. Already known input transactions will be
// merged with the specified transactions. This means the list of transaction
// inputs can be nil if the RPC server already knows them all.
//
// NOTE: Unlike the merging functionality of the input transactions, ONLY the
// specified private keys will be used, so even if the server already knows some
// of the private keys, they will NOT be used.
//
// See SignRawTransaction if the RPC server already knows the input
// transactions and private keys or SignRawTransaction2 if it already knows the
// private keys.
func (c *Client) SignRawTransaction3(tx *wire.MsgTx,
inputs []btcjson.RawTxInput,
privKeysWIF []string) (*wire.MsgTx, bool, error) {
return c.SignRawTransaction3Async(tx, inputs, privKeysWIF).Receive()
}
// SignRawTransaction4Async returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See SignRawTransaction4 for the blocking version and more details.
func (c *Client) SignRawTransaction4Async(tx *wire.MsgTx,
inputs []btcjson.RawTxInput, privKeysWIF []string,
hashType SigHashType) FutureSignRawTransactionResult {
txHex := ""
if tx != nil {
// Serialize the transaction and convert to hex string.
buf := bytes.NewBuffer(make([]byte, 0, tx.SerializeSize()))
if err := tx.Serialize(buf); err != nil {
return newFutureError(err)
}
txHex = hex.EncodeToString(buf.Bytes())
}
cmd := btcjson.NewSignRawTransactionCmd(txHex, &inputs, &privKeysWIF,
btcjson.String(string(hashType)))
return c.sendCmd(cmd)
}
// SignRawTransaction4 signs inputs for the passed transaction using the
// the specified signature hash type given the list of information about extra
// input transactions and a potential list of private keys needed to perform
// the signing process. The private keys, if specified, must be in wallet
// import format (WIF).
//
// The only input transactions that need to be specified are ones the RPC server
// does not already know. This means the list of transaction inputs can be nil
// if the RPC server already knows them all.
//
// NOTE: Unlike the merging functionality of the input transactions, ONLY the
// specified private keys will be used, so even if the server already knows some
// of the private keys, they will NOT be used. The list of private keys can be
// nil in which case any private keys the RPC server knows will be used.
//
// This function should only used if a non-default signature hash type is
// desired. Otherwise, see SignRawTransaction if the RPC server already knows
// the input transactions and private keys, SignRawTransaction2 if it already
// knows the private keys, or SignRawTransaction3 if it does not know both.
func (c *Client) SignRawTransaction4(tx *wire.MsgTx,
inputs []btcjson.RawTxInput, privKeysWIF []string,
hashType SigHashType) (*wire.MsgTx, bool, error) {
return c.SignRawTransaction4Async(tx, inputs, privKeysWIF,
hashType).Receive()
}
// FutureSearchRawTransactionsResult is a future promise to deliver the result
// of the SearchRawTransactionsAsync RPC invocation (or an applicable error).
type FutureSearchRawTransactionsResult chan *response
// Receive waits for the response promised by the future and returns the
// found raw transactions.
func (r FutureSearchRawTransactionsResult) Receive() ([]*wire.MsgTx, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal as an array of strings.
var searchRawTxnsResult []string
err = json.Unmarshal(res, &searchRawTxnsResult)
if err != nil {
return nil, err
}
// Decode and deserialize each transaction.
msgTxns := make([]*wire.MsgTx, 0, len(searchRawTxnsResult))
for _, hexTx := range searchRawTxnsResult {
// Decode the serialized transaction hex to raw bytes.
serializedTx, err := hex.DecodeString(hexTx)
if err != nil {
return nil, err
}
// Deserialize the transaction and add it to the result slice.
var msgTx wire.MsgTx
err = msgTx.Deserialize(bytes.NewReader(serializedTx))
if err != nil {
return nil, err
}
msgTxns = append(msgTxns, &msgTx)
}
return msgTxns, nil
}
// SearchRawTransactionsAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See SearchRawTransactions for the blocking version and more details.
func (c *Client) SearchRawTransactionsAsync(address btcutil.Address, skip, count int, reverse bool, filterAddrs []string) FutureSearchRawTransactionsResult {
addr := address.EncodeAddress()
verbose := btcjson.Int(0)
cmd := btcjson.NewSearchRawTransactionsCmd(addr, verbose, &skip, &count,
nil, &reverse, &filterAddrs)
return c.sendCmd(cmd)
}
// SearchRawTransactions returns transactions that involve the passed address.
//
// NOTE: Chain servers do not typically provide this capability unless it has
// specifically been enabled.
//
// See SearchRawTransactionsVerbose to retrieve a list of data structures with
// information about the transactions instead of the transactions themselves.
func (c *Client) SearchRawTransactions(address btcutil.Address, skip, count int, reverse bool, filterAddrs []string) ([]*wire.MsgTx, error) {
return c.SearchRawTransactionsAsync(address, skip, count, reverse, filterAddrs).Receive()
}
// FutureSearchRawTransactionsVerboseResult is a future promise to deliver the
// result of the SearchRawTransactionsVerboseAsync RPC invocation (or an
// applicable error).
type FutureSearchRawTransactionsVerboseResult chan *response
// Receive waits for the response promised by the future and returns the
// found raw transactions.
func (r FutureSearchRawTransactionsVerboseResult) Receive() ([]*btcjson.SearchRawTransactionsResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal as an array of raw transaction results.
var result []*btcjson.SearchRawTransactionsResult
err = json.Unmarshal(res, &result)
if err != nil {
return nil, err
}
return result, nil
}
// SearchRawTransactionsVerboseAsync returns an instance of a type that can be
// used to get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See SearchRawTransactionsVerbose for the blocking version and more details.
func (c *Client) SearchRawTransactionsVerboseAsync(address btcutil.Address, skip,
count int, includePrevOut, reverse bool, filterAddrs *[]string) FutureSearchRawTransactionsVerboseResult {
addr := address.EncodeAddress()
verbose := btcjson.Int(1)
var prevOut *int
if includePrevOut {
prevOut = btcjson.Int(1)
}
cmd := btcjson.NewSearchRawTransactionsCmd(addr, verbose, &skip, &count,
prevOut, &reverse, filterAddrs)
return c.sendCmd(cmd)
}
// SearchRawTransactionsVerbose returns a list of data structures that describe
// transactions which involve the passed address.
//
// NOTE: Chain servers do not typically provide this capability unless it has
// specifically been enabled.
//
// See SearchRawTransactions to retrieve a list of raw transactions instead.
func (c *Client) SearchRawTransactionsVerbose(address btcutil.Address, skip,
count int, includePrevOut, reverse bool, filterAddrs []string) ([]*btcjson.SearchRawTransactionsResult, error) {
return c.SearchRawTransactionsVerboseAsync(address, skip, count,
includePrevOut, reverse, &filterAddrs).Receive()
}
// FutureDecodeScriptResult is a future promise to deliver the result
// of a DecodeScriptAsync RPC invocation (or an applicable error).
type FutureDecodeScriptResult chan *response
// Receive waits for the response promised by the future and returns information
// about a script given its serialized bytes.
func (r FutureDecodeScriptResult) Receive() (*btcjson.DecodeScriptResult, error) {
res, err := receiveFuture(r)
if err != nil {
return nil, err
}
// Unmarshal result as a decodescript result object.
var decodeScriptResult btcjson.DecodeScriptResult
err = json.Unmarshal(res, &decodeScriptResult)
if err != nil {
return nil, err
}
return &decodeScriptResult, nil
}
// DecodeScriptAsync returns an instance of a type that can be used to
// get the result of the RPC at some future time by invoking the Receive
// function on the returned instance.
//
// See DecodeScript for the blocking version and more details.
func (c *Client) DecodeScriptAsync(serializedScript []byte) FutureDecodeScriptResult {
scriptHex := hex.EncodeToString(serializedScript)
cmd := btcjson.NewDecodeScriptCmd(scriptHex)
return c.sendCmd(cmd)
}
// DecodeScript returns information about a script given its serialized bytes.
func (c *Client) DecodeScript(serializedScript []byte) (*btcjson.DecodeScriptResult, error) {
return c.DecodeScriptAsync(serializedScript).Receive()
}

2279
vendor/github.com/btcsuite/btcd/rpcclient/wallet.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

113
vendor/github.com/btcsuite/btcd/wire/README.md generated vendored Normal file
View File

@ -0,0 +1,113 @@
wire
====
[![Build Status](http://img.shields.io/travis/btcsuite/btcd.svg)](https://travis-ci.org/btcsuite/btcd)
[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcd/wire)
=======
Package wire implements the bitcoin wire protocol. A comprehensive suite of
tests with 100% test coverage is provided to ensure proper functionality.
There is an associated blog post about the release of this package
[here](https://blog.conformal.com/btcwire-the-bitcoin-wire-protocol-package-from-btcd/).
This package has intentionally been designed so it can be used as a standalone
package for any projects needing to interface with bitcoin peers at the wire
protocol level.
## Installation and Updating
```bash
$ go get -u github.com/btcsuite/btcd/wire
```
## Bitcoin Message Overview
The bitcoin protocol consists of exchanging messages between peers. Each message
is preceded by a header which identifies information about it such as which
bitcoin network it is a part of, its type, how big it is, and a checksum to
verify validity. All encoding and decoding of message headers is handled by this
package.
To accomplish this, there is a generic interface for bitcoin messages named
`Message` which allows messages of any type to be read, written, or passed
around through channels, functions, etc. In addition, concrete implementations
of most of the currently supported bitcoin messages are provided. For these
supported messages, all of the details of marshalling and unmarshalling to and
from the wire using bitcoin encoding are handled so the caller doesn't have to
concern themselves with the specifics.
## Reading Messages Example
In order to unmarshal bitcoin messages from the wire, use the `ReadMessage`
function. It accepts any `io.Reader`, but typically this will be a `net.Conn`
to a remote node running a bitcoin peer. Example syntax is:
```Go
// Use the most recent protocol version supported by the package and the
// main bitcoin network.
pver := wire.ProtocolVersion
btcnet := wire.MainNet
// Reads and validates the next bitcoin message from conn using the
// protocol version pver and the bitcoin network btcnet. The returns
// are a wire.Message, a []byte which contains the unmarshalled
// raw payload, and a possible error.
msg, rawPayload, err := wire.ReadMessage(conn, pver, btcnet)
if err != nil {
// Log and handle the error
}
```
See the package documentation for details on determining the message type.
## Writing Messages Example
In order to marshal bitcoin messages to the wire, use the `WriteMessage`
function. It accepts any `io.Writer`, but typically this will be a `net.Conn`
to a remote node running a bitcoin peer. Example syntax to request addresses
from a remote peer is:
```Go
// Use the most recent protocol version supported by the package and the
// main bitcoin network.
pver := wire.ProtocolVersion
btcnet := wire.MainNet
// Create a new getaddr bitcoin message.
msg := wire.NewMsgGetAddr()
// Writes a bitcoin message msg to conn using the protocol version
// pver, and the bitcoin network btcnet. The return is a possible
// error.
err := wire.WriteMessage(conn, msg, pver, btcnet)
if err != nil {
// Log and handle the error
}
```
## GPG Verification Key
All official release tags are signed by Conformal so users can ensure the code
has not been tampered with and is coming from the btcsuite developers. To
verify the signature perform the following:
- Download the public key from the Conformal website at
https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt
- Import the public key into your GPG keyring:
```bash
gpg --import GIT-GPG-KEY-conformal.txt
```
- Verify the release tag with the following command where `TAG_NAME` is a
placeholder for the specific tag:
```bash
git tag -v TAG_NAME
```
## License
Package wire is licensed under the [copyfree](http://copyfree.org) ISC
License.

128
vendor/github.com/btcsuite/btcd/wire/blockheader.go generated vendored Normal file
View File

@ -0,0 +1,128 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"bytes"
"io"
"time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// MaxBlockHeaderPayload is the maximum number of bytes a block header can be.
// Version 4 bytes + Timestamp 4 bytes + Bits 4 bytes + Nonce 4 bytes +
// PrevBlock and MerkleRoot hashes.
const MaxBlockHeaderPayload = 16 + (chainhash.HashSize * 2)
// BlockHeader defines information about a block and is used in the bitcoin
// block (MsgBlock) and headers (MsgHeaders) messages.
type BlockHeader struct {
// Version of the block. This is not the same as the protocol version.
Version int32
// Hash of the previous block header in the block chain.
PrevBlock chainhash.Hash
// Merkle tree reference to hash of all transactions for the block.
MerkleRoot chainhash.Hash
// Time the block was created. This is, unfortunately, encoded as a
// uint32 on the wire and therefore is limited to 2106.
Timestamp time.Time
// Difficulty target for the block.
Bits uint32
// Nonce used to generate the block.
Nonce uint32
}
// blockHeaderLen is a constant that represents the number of bytes for a block
// header.
const blockHeaderLen = 80
// BlockHash computes the block identifier hash for the given block header.
func (h *BlockHeader) BlockHash() chainhash.Hash {
// Encode the header and double sha256 everything prior to the number of
// transactions. Ignore the error returns since there is no way the
// encode could fail except being out of memory which would cause a
// run-time panic.
buf := bytes.NewBuffer(make([]byte, 0, MaxBlockHeaderPayload))
_ = writeBlockHeader(buf, 0, h)
return chainhash.DoubleHashH(buf.Bytes())
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding block headers stored to disk, such as in a
// database, as opposed to decoding block headers from the wire.
func (h *BlockHeader) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
return readBlockHeader(r, pver, h)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding block headers to be stored to disk, such as in a
// database, as opposed to encoding block headers for the wire.
func (h *BlockHeader) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
return writeBlockHeader(w, pver, h)
}
// Deserialize decodes a block header from r into the receiver using a format
// that is suitable for long-term storage such as a database while respecting
// the Version field.
func (h *BlockHeader) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the wire encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of readBlockHeader.
return readBlockHeader(r, 0, h)
}
// Serialize encodes a block header from r into the receiver using a format
// that is suitable for long-term storage such as a database while respecting
// the Version field.
func (h *BlockHeader) Serialize(w io.Writer) error {
// At the current time, there is no difference between the wire encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of writeBlockHeader.
return writeBlockHeader(w, 0, h)
}
// NewBlockHeader returns a new BlockHeader using the provided version, previous
// block hash, merkle root hash, difficulty bits, and nonce used to generate the
// block with defaults for the remaining fields.
func NewBlockHeader(version int32, prevHash, merkleRootHash *chainhash.Hash,
bits uint32, nonce uint32) *BlockHeader {
// Limit the timestamp to one second precision since the protocol
// doesn't support better.
return &BlockHeader{
Version: version,
PrevBlock: *prevHash,
MerkleRoot: *merkleRootHash,
Timestamp: time.Unix(time.Now().Unix(), 0),
Bits: bits,
Nonce: nonce,
}
}
// readBlockHeader reads a bitcoin block header from r. See Deserialize for
// decoding block headers stored to disk, such as in a database, as opposed to
// decoding from the wire.
func readBlockHeader(r io.Reader, pver uint32, bh *BlockHeader) error {
return readElements(r, &bh.Version, &bh.PrevBlock, &bh.MerkleRoot,
(*uint32Time)(&bh.Timestamp), &bh.Bits, &bh.Nonce)
}
// writeBlockHeader writes a bitcoin block header to w. See Serialize for
// encoding block headers to be stored to disk, such as in a database, as
// opposed to encoding for the wire.
func writeBlockHeader(w io.Writer, pver uint32, bh *BlockHeader) error {
sec := uint32(bh.Timestamp.Unix())
return writeElements(w, bh.Version, &bh.PrevBlock, &bh.MerkleRoot,
sec, bh.Bits, bh.Nonce)
}

689
vendor/github.com/btcsuite/btcd/wire/common.go generated vendored Normal file
View File

@ -0,0 +1,689 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"crypto/rand"
"encoding/binary"
"fmt"
"io"
"math"
"time"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
const (
// MaxVarIntPayload is the maximum payload size for a variable length integer.
MaxVarIntPayload = 9
// binaryFreeListMaxItems is the number of buffers to keep in the free
// list to use for binary serialization and deserialization.
binaryFreeListMaxItems = 1024
)
var (
// littleEndian is a convenience variable since binary.LittleEndian is
// quite long.
littleEndian = binary.LittleEndian
// bigEndian is a convenience variable since binary.BigEndian is quite
// long.
bigEndian = binary.BigEndian
)
// binaryFreeList defines a concurrent safe free list of byte slices (up to the
// maximum number defined by the binaryFreeListMaxItems constant) that have a
// cap of 8 (thus it supports up to a uint64). It is used to provide temporary
// buffers for serializing and deserializing primitive numbers to and from their
// binary encoding in order to greatly reduce the number of allocations
// required.
//
// For convenience, functions are provided for each of the primitive unsigned
// integers that automatically obtain a buffer from the free list, perform the
// necessary binary conversion, read from or write to the given io.Reader or
// io.Writer, and return the buffer to the free list.
type binaryFreeList chan []byte
// Borrow returns a byte slice from the free list with a length of 8. A new
// buffer is allocated if there are not any available on the free list.
func (l binaryFreeList) Borrow() []byte {
var buf []byte
select {
case buf = <-l:
default:
buf = make([]byte, 8)
}
return buf[:8]
}
// Return puts the provided byte slice back on the free list. The buffer MUST
// have been obtained via the Borrow function and therefore have a cap of 8.
func (l binaryFreeList) Return(buf []byte) {
select {
case l <- buf:
default:
// Let it go to the garbage collector.
}
}
// Uint8 reads a single byte from the provided reader using a buffer from the
// free list and returns it as a uint8.
func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) {
buf := l.Borrow()[:1]
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := buf[0]
l.Return(buf)
return rv, nil
}
// Uint16 reads two bytes from the provided reader using a buffer from the
// free list, converts it to a number using the provided byte order, and returns
// the resulting uint16.
func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, error) {
buf := l.Borrow()[:2]
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := byteOrder.Uint16(buf)
l.Return(buf)
return rv, nil
}
// Uint32 reads four bytes from the provided reader using a buffer from the
// free list, converts it to a number using the provided byte order, and returns
// the resulting uint32.
func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, error) {
buf := l.Borrow()[:4]
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := byteOrder.Uint32(buf)
l.Return(buf)
return rv, nil
}
// Uint64 reads eight bytes from the provided reader using a buffer from the
// free list, converts it to a number using the provided byte order, and returns
// the resulting uint64.
func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder) (uint64, error) {
buf := l.Borrow()[:8]
if _, err := io.ReadFull(r, buf); err != nil {
l.Return(buf)
return 0, err
}
rv := byteOrder.Uint64(buf)
l.Return(buf)
return rv, nil
}
// PutUint8 copies the provided uint8 into a buffer from the free list and
// writes the resulting byte to the given writer.
func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error {
buf := l.Borrow()[:1]
buf[0] = val
_, err := w.Write(buf)
l.Return(buf)
return err
}
// PutUint16 serializes the provided uint16 using the given byte order into a
// buffer from the free list and writes the resulting two bytes to the given
// writer.
func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val uint16) error {
buf := l.Borrow()[:2]
byteOrder.PutUint16(buf, val)
_, err := w.Write(buf)
l.Return(buf)
return err
}
// PutUint32 serializes the provided uint32 using the given byte order into a
// buffer from the free list and writes the resulting four bytes to the given
// writer.
func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val uint32) error {
buf := l.Borrow()[:4]
byteOrder.PutUint32(buf, val)
_, err := w.Write(buf)
l.Return(buf)
return err
}
// PutUint64 serializes the provided uint64 using the given byte order into a
// buffer from the free list and writes the resulting eight bytes to the given
// writer.
func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOrder, val uint64) error {
buf := l.Borrow()[:8]
byteOrder.PutUint64(buf, val)
_, err := w.Write(buf)
l.Return(buf)
return err
}
// binarySerializer provides a free list of buffers to use for serializing and
// deserializing primitive integer values to and from io.Readers and io.Writers.
var binarySerializer binaryFreeList = make(chan []byte, binaryFreeListMaxItems)
// errNonCanonicalVarInt is the common format string used for non-canonically
// encoded variable length integer errors.
var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " +
"encode a value greater than %x"
// uint32Time represents a unix timestamp encoded with a uint32. It is used as
// a way to signal the readElement function how to decode a timestamp into a Go
// time.Time since it is otherwise ambiguous.
type uint32Time time.Time
// int64Time represents a unix timestamp encoded with an int64. It is used as
// a way to signal the readElement function how to decode a timestamp into a Go
// time.Time since it is otherwise ambiguous.
type int64Time time.Time
// readElement reads the next sequence of bytes from r using little endian
// depending on the concrete type of element pointed to.
func readElement(r io.Reader, element interface{}) error {
// Attempt to read the element based on the concrete type via fast
// type assertions first.
switch e := element.(type) {
case *int32:
rv, err := binarySerializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = int32(rv)
return nil
case *uint32:
rv, err := binarySerializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = rv
return nil
case *int64:
rv, err := binarySerializer.Uint64(r, littleEndian)
if err != nil {
return err
}
*e = int64(rv)
return nil
case *uint64:
rv, err := binarySerializer.Uint64(r, littleEndian)
if err != nil {
return err
}
*e = rv
return nil
case *bool:
rv, err := binarySerializer.Uint8(r)
if err != nil {
return err
}
if rv == 0x00 {
*e = false
} else {
*e = true
}
return nil
// Unix timestamp encoded as a uint32.
case *uint32Time:
rv, err := binarySerializer.Uint32(r, binary.LittleEndian)
if err != nil {
return err
}
*e = uint32Time(time.Unix(int64(rv), 0))
return nil
// Unix timestamp encoded as an int64.
case *int64Time:
rv, err := binarySerializer.Uint64(r, binary.LittleEndian)
if err != nil {
return err
}
*e = int64Time(time.Unix(int64(rv), 0))
return nil
// Message header checksum.
case *[4]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
// Message header command.
case *[CommandSize]uint8:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
// IP address.
case *[16]byte:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
case *chainhash.Hash:
_, err := io.ReadFull(r, e[:])
if err != nil {
return err
}
return nil
case *ServiceFlag:
rv, err := binarySerializer.Uint64(r, littleEndian)
if err != nil {
return err
}
*e = ServiceFlag(rv)
return nil
case *InvType:
rv, err := binarySerializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = InvType(rv)
return nil
case *BitcoinNet:
rv, err := binarySerializer.Uint32(r, littleEndian)
if err != nil {
return err
}
*e = BitcoinNet(rv)
return nil
case *BloomUpdateType:
rv, err := binarySerializer.Uint8(r)
if err != nil {
return err
}
*e = BloomUpdateType(rv)
return nil
case *RejectCode:
rv, err := binarySerializer.Uint8(r)
if err != nil {
return err
}
*e = RejectCode(rv)
return nil
}
// Fall back to the slower binary.Read if a fast path was not available
// above.
return binary.Read(r, littleEndian, element)
}
// readElements reads multiple items from r. It is equivalent to multiple
// calls to readElement.
func readElements(r io.Reader, elements ...interface{}) error {
for _, element := range elements {
err := readElement(r, element)
if err != nil {
return err
}
}
return nil
}
// writeElement writes the little endian representation of element to w.
func writeElement(w io.Writer, element interface{}) error {
// Attempt to write the element based on the concrete type via fast
// type assertions first.
switch e := element.(type) {
case int32:
err := binarySerializer.PutUint32(w, littleEndian, uint32(e))
if err != nil {
return err
}
return nil
case uint32:
err := binarySerializer.PutUint32(w, littleEndian, e)
if err != nil {
return err
}
return nil
case int64:
err := binarySerializer.PutUint64(w, littleEndian, uint64(e))
if err != nil {
return err
}
return nil
case uint64:
err := binarySerializer.PutUint64(w, littleEndian, e)
if err != nil {
return err
}
return nil
case bool:
var err error
if e {
err = binarySerializer.PutUint8(w, 0x01)
} else {
err = binarySerializer.PutUint8(w, 0x00)
}
if err != nil {
return err
}
return nil
// Message header checksum.
case [4]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
// Message header command.
case [CommandSize]uint8:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
// IP address.
case [16]byte:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
case *chainhash.Hash:
_, err := w.Write(e[:])
if err != nil {
return err
}
return nil
case ServiceFlag:
err := binarySerializer.PutUint64(w, littleEndian, uint64(e))
if err != nil {
return err
}
return nil
case InvType:
err := binarySerializer.PutUint32(w, littleEndian, uint32(e))
if err != nil {
return err
}
return nil
case BitcoinNet:
err := binarySerializer.PutUint32(w, littleEndian, uint32(e))
if err != nil {
return err
}
return nil
case BloomUpdateType:
err := binarySerializer.PutUint8(w, uint8(e))
if err != nil {
return err
}
return nil
case RejectCode:
err := binarySerializer.PutUint8(w, uint8(e))
if err != nil {
return err
}
return nil
}
// Fall back to the slower binary.Write if a fast path was not available
// above.
return binary.Write(w, littleEndian, element)
}
// writeElements writes multiple items to w. It is equivalent to multiple
// calls to writeElement.
func writeElements(w io.Writer, elements ...interface{}) error {
for _, element := range elements {
err := writeElement(w, element)
if err != nil {
return err
}
}
return nil
}
// ReadVarInt reads a variable length integer from r and returns it as a uint64.
func ReadVarInt(r io.Reader, pver uint32) (uint64, error) {
discriminant, err := binarySerializer.Uint8(r)
if err != nil {
return 0, err
}
var rv uint64
switch discriminant {
case 0xff:
sv, err := binarySerializer.Uint64(r, littleEndian)
if err != nil {
return 0, err
}
rv = sv
// The encoding is not canonical if the value could have been
// encoded using fewer bytes.
min := uint64(0x100000000)
if rv < min {
return 0, messageError("ReadVarInt", fmt.Sprintf(
errNonCanonicalVarInt, rv, discriminant, min))
}
case 0xfe:
sv, err := binarySerializer.Uint32(r, littleEndian)
if err != nil {
return 0, err
}
rv = uint64(sv)
// The encoding is not canonical if the value could have been
// encoded using fewer bytes.
min := uint64(0x10000)
if rv < min {
return 0, messageError("ReadVarInt", fmt.Sprintf(
errNonCanonicalVarInt, rv, discriminant, min))
}
case 0xfd:
sv, err := binarySerializer.Uint16(r, littleEndian)
if err != nil {
return 0, err
}
rv = uint64(sv)
// The encoding is not canonical if the value could have been
// encoded using fewer bytes.
min := uint64(0xfd)
if rv < min {
return 0, messageError("ReadVarInt", fmt.Sprintf(
errNonCanonicalVarInt, rv, discriminant, min))
}
default:
rv = uint64(discriminant)
}
return rv, nil
}
// WriteVarInt serializes val to w using a variable number of bytes depending
// on its value.
func WriteVarInt(w io.Writer, pver uint32, val uint64) error {
if val < 0xfd {
return binarySerializer.PutUint8(w, uint8(val))
}
if val <= math.MaxUint16 {
err := binarySerializer.PutUint8(w, 0xfd)
if err != nil {
return err
}
return binarySerializer.PutUint16(w, littleEndian, uint16(val))
}
if val <= math.MaxUint32 {
err := binarySerializer.PutUint8(w, 0xfe)
if err != nil {
return err
}
return binarySerializer.PutUint32(w, littleEndian, uint32(val))
}
err := binarySerializer.PutUint8(w, 0xff)
if err != nil {
return err
}
return binarySerializer.PutUint64(w, littleEndian, val)
}
// VarIntSerializeSize returns the number of bytes it would take to serialize
// val as a variable length integer.
func VarIntSerializeSize(val uint64) int {
// The value is small enough to be represented by itself, so it's
// just 1 byte.
if val < 0xfd {
return 1
}
// Discriminant 1 byte plus 2 bytes for the uint16.
if val <= math.MaxUint16 {
return 3
}
// Discriminant 1 byte plus 4 bytes for the uint32.
if val <= math.MaxUint32 {
return 5
}
// Discriminant 1 byte plus 8 bytes for the uint64.
return 9
}
// ReadVarString reads a variable length string from r and returns it as a Go
// string. A variable length string is encoded as a variable length integer
// containing the length of the string followed by the bytes that represent the
// string itself. An error is returned if the length is greater than the
// maximum block payload size since it helps protect against memory exhaustion
// attacks and forced panics through malformed messages.
func ReadVarString(r io.Reader, pver uint32) (string, error) {
count, err := ReadVarInt(r, pver)
if err != nil {
return "", err
}
// Prevent variable length strings that are larger than the maximum
// message size. It would be possible to cause memory exhaustion and
// panics without a sane upper bound on this count.
if count > MaxMessagePayload {
str := fmt.Sprintf("variable length string is too long "+
"[count %d, max %d]", count, MaxMessagePayload)
return "", messageError("ReadVarString", str)
}
buf := make([]byte, count)
_, err = io.ReadFull(r, buf)
if err != nil {
return "", err
}
return string(buf), nil
}
// WriteVarString serializes str to w as a variable length integer containing
// the length of the string followed by the bytes that represent the string
// itself.
func WriteVarString(w io.Writer, pver uint32, str string) error {
err := WriteVarInt(w, pver, uint64(len(str)))
if err != nil {
return err
}
_, err = w.Write([]byte(str))
return err
}
// ReadVarBytes reads a variable length byte array. A byte array is encoded
// as a varInt containing the length of the array followed by the bytes
// themselves. An error is returned if the length is greater than the
// passed maxAllowed parameter which helps protect against memory exhaustion
// attacks and forced panics through malformed messages. The fieldName
// parameter is only used for the error message so it provides more context in
// the error.
func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32,
fieldName string) ([]byte, error) {
count, err := ReadVarInt(r, pver)
if err != nil {
return nil, err
}
// Prevent byte array larger than the max message size. It would
// be possible to cause memory exhaustion and panics without a sane
// upper bound on this count.
if count > uint64(maxAllowed) {
str := fmt.Sprintf("%s is larger than the max allowed size "+
"[count %d, max %d]", fieldName, count, maxAllowed)
return nil, messageError("ReadVarBytes", str)
}
b := make([]byte, count)
_, err = io.ReadFull(r, b)
if err != nil {
return nil, err
}
return b, nil
}
// WriteVarBytes serializes a variable length byte array to w as a varInt
// containing the number of bytes, followed by the bytes themselves.
func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error {
slen := uint64(len(bytes))
err := WriteVarInt(w, pver, slen)
if err != nil {
return err
}
_, err = w.Write(bytes)
return err
}
// randomUint64 returns a cryptographically random uint64 value. This
// unexported version takes a reader primarily to ensure the error paths
// can be properly tested by passing a fake reader in the tests.
func randomUint64(r io.Reader) (uint64, error) {
rv, err := binarySerializer.Uint64(r, bigEndian)
if err != nil {
return 0, err
}
return rv, nil
}
// RandomUint64 returns a cryptographically random uint64 value.
func RandomUint64() (uint64, error) {
return randomUint64(rand.Reader)
}

162
vendor/github.com/btcsuite/btcd/wire/doc.go generated vendored Normal file
View File

@ -0,0 +1,162 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
/*
Package wire implements the bitcoin wire protocol.
For the complete details of the bitcoin protocol, see the official wiki entry
at https://en.bitcoin.it/wiki/Protocol_specification. The following only serves
as a quick overview to provide information on how to use the package.
At a high level, this package provides support for marshalling and unmarshalling
supported bitcoin messages to and from the wire. This package does not deal
with the specifics of message handling such as what to do when a message is
received. This provides the caller with a high level of flexibility.
Bitcoin Message Overview
The bitcoin protocol consists of exchanging messages between peers. Each
message is preceded by a header which identifies information about it such as
which bitcoin network it is a part of, its type, how big it is, and a checksum
to verify validity. All encoding and decoding of message headers is handled by
this package.
To accomplish this, there is a generic interface for bitcoin messages named
Message which allows messages of any type to be read, written, or passed around
through channels, functions, etc. In addition, concrete implementations of most
of the currently supported bitcoin messages are provided. For these supported
messages, all of the details of marshalling and unmarshalling to and from the
wire using bitcoin encoding are handled so the caller doesn't have to concern
themselves with the specifics.
Message Interaction
The following provides a quick summary of how the bitcoin messages are intended
to interact with one another. As stated above, these interactions are not
directly handled by this package. For more in-depth details about the
appropriate interactions, see the official bitcoin protocol wiki entry at
https://en.bitcoin.it/wiki/Protocol_specification.
The initial handshake consists of two peers sending each other a version message
(MsgVersion) followed by responding with a verack message (MsgVerAck). Both
peers use the information in the version message (MsgVersion) to negotiate
things such as protocol version and supported services with each other. Once
the initial handshake is complete, the following chart indicates message
interactions in no particular order.
Peer A Sends Peer B Responds
----------------------------------------------------------------------------
getaddr message (MsgGetAddr) addr message (MsgAddr)
getblocks message (MsgGetBlocks) inv message (MsgInv)
inv message (MsgInv) getdata message (MsgGetData)
getdata message (MsgGetData) block message (MsgBlock) -or-
tx message (MsgTx) -or-
notfound message (MsgNotFound)
getheaders message (MsgGetHeaders) headers message (MsgHeaders)
ping message (MsgPing) pong message (MsgHeaders)* -or-
(none -- Ability to send message is enough)
NOTES:
* The pong message was not added until later protocol versions as defined
in BIP0031. The BIP0031Version constant can be used to detect a recent
enough protocol version for this purpose (version > BIP0031Version).
Common Parameters
There are several common parameters that arise when using this package to read
and write bitcoin messages. The following sections provide a quick overview of
these parameters so the next sections can build on them.
Protocol Version
The protocol version should be negotiated with the remote peer at a higher
level than this package via the version (MsgVersion) message exchange, however,
this package provides the wire.ProtocolVersion constant which indicates the
latest protocol version this package supports and is typically the value to use
for all outbound connections before a potentially lower protocol version is
negotiated.
Bitcoin Network
The bitcoin network is a magic number which is used to identify the start of a
message and which bitcoin network the message applies to. This package provides
the following constants:
wire.MainNet
wire.TestNet (Regression test network)
wire.TestNet3 (Test network version 3)
wire.SimNet (Simulation test network)
Determining Message Type
As discussed in the bitcoin message overview section, this package reads
and writes bitcoin messages using a generic interface named Message. In
order to determine the actual concrete type of the message, use a type
switch or type assertion. An example of a type switch follows:
// Assumes msg is already a valid concrete message such as one created
// via NewMsgVersion or read via ReadMessage.
switch msg := msg.(type) {
case *wire.MsgVersion:
// The message is a pointer to a MsgVersion struct.
fmt.Printf("Protocol version: %v", msg.ProtocolVersion)
case *wire.MsgBlock:
// The message is a pointer to a MsgBlock struct.
fmt.Printf("Number of tx in block: %v", msg.Header.TxnCount)
}
Reading Messages
In order to unmarshall bitcoin messages from the wire, use the ReadMessage
function. It accepts any io.Reader, but typically this will be a net.Conn to
a remote node running a bitcoin peer. Example syntax is:
// Reads and validates the next bitcoin message from conn using the
// protocol version pver and the bitcoin network btcnet. The returns
// are a wire.Message, a []byte which contains the unmarshalled
// raw payload, and a possible error.
msg, rawPayload, err := wire.ReadMessage(conn, pver, btcnet)
if err != nil {
// Log and handle the error
}
Writing Messages
In order to marshall bitcoin messages to the wire, use the WriteMessage
function. It accepts any io.Writer, but typically this will be a net.Conn to
a remote node running a bitcoin peer. Example syntax to request addresses
from a remote peer is:
// Create a new getaddr bitcoin message.
msg := wire.NewMsgGetAddr()
// Writes a bitcoin message msg to conn using the protocol version
// pver, and the bitcoin network btcnet. The return is a possible
// error.
err := wire.WriteMessage(conn, msg, pver, btcnet)
if err != nil {
// Log and handle the error
}
Errors
Errors returned by this package are either the raw errors provided by underlying
calls to read/write from streams such as io.EOF, io.ErrUnexpectedEOF, and
io.ErrShortWrite, or of type wire.MessageError. This allows the caller to
differentiate between general IO errors and malformed messages through type
assertions.
Bitcoin Improvement Proposals
This package includes spec changes outlined by the following BIPs:
BIP0014 (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki)
BIP0031 (https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki)
BIP0035 (https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki)
BIP0037 (https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki)
BIP0111 (https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki)
BIP0130 (https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki)
BIP0133 (https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki)
*/
package wire

34
vendor/github.com/btcsuite/btcd/wire/error.go generated vendored Normal file
View File

@ -0,0 +1,34 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
)
// MessageError describes an issue with a message.
// An example of some potential issues are messages from the wrong bitcoin
// network, invalid commands, mismatched checksums, and exceeding max payloads.
//
// This provides a mechanism for the caller to type assert the error to
// differentiate between general io errors such as io.EOF and issues that
// resulted from malformed messages.
type MessageError struct {
Func string // Function name
Description string // Human readable description of the issue
}
// Error satisfies the error interface and prints human-readable errors.
func (e *MessageError) Error() string {
if e.Func != "" {
return fmt.Sprintf("%v: %v", e.Func, e.Description)
}
return e.Description
}
// messageError creates an error for the given function and description.
func messageError(f string, desc string) *MessageError {
return &MessageError{Func: f, Description: desc}
}

86
vendor/github.com/btcsuite/btcd/wire/invvect.go generated vendored Normal file
View File

@ -0,0 +1,86 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
const (
// MaxInvPerMsg is the maximum number of inventory vectors that can be in a
// single bitcoin inv message.
MaxInvPerMsg = 50000
// Maximum payload size for an inventory vector.
maxInvVectPayload = 4 + chainhash.HashSize
// InvWitnessFlag denotes that the inventory vector type is requesting,
// or sending a version which includes witness data.
InvWitnessFlag = 1 << 30
)
// InvType represents the allowed types of inventory vectors. See InvVect.
type InvType uint32
// These constants define the various supported inventory vector types.
const (
InvTypeError InvType = 0
InvTypeTx InvType = 1
InvTypeBlock InvType = 2
InvTypeFilteredBlock InvType = 3
InvTypeWitnessBlock InvType = InvTypeBlock | InvWitnessFlag
InvTypeWitnessTx InvType = InvTypeTx | InvWitnessFlag
InvTypeFilteredWitnessBlock InvType = InvTypeFilteredBlock | InvWitnessFlag
)
// Map of service flags back to their constant names for pretty printing.
var ivStrings = map[InvType]string{
InvTypeError: "ERROR",
InvTypeTx: "MSG_TX",
InvTypeBlock: "MSG_BLOCK",
InvTypeFilteredBlock: "MSG_FILTERED_BLOCK",
InvTypeWitnessBlock: "MSG_WITNESS_BLOCK",
InvTypeWitnessTx: "MSG_WITNESS_TX",
InvTypeFilteredWitnessBlock: "MSG_FILTERED_WITNESS_BLOCK",
}
// String returns the InvType in human-readable form.
func (invtype InvType) String() string {
if s, ok := ivStrings[invtype]; ok {
return s
}
return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype))
}
// InvVect defines a bitcoin inventory vector which is used to describe data,
// as specified by the Type field, that a peer wants, has, or does not have to
// another peer.
type InvVect struct {
Type InvType // Type of data
Hash chainhash.Hash // Hash of the data
}
// NewInvVect returns a new InvVect using the provided type and hash.
func NewInvVect(typ InvType, hash *chainhash.Hash) *InvVect {
return &InvVect{
Type: typ,
Hash: *hash,
}
}
// readInvVect reads an encoded InvVect from r depending on the protocol
// version.
func readInvVect(r io.Reader, pver uint32, iv *InvVect) error {
return readElements(r, &iv.Type, &iv.Hash)
}
// writeInvVect serializes an InvVect to w depending on the protocol version.
func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error {
return writeElements(w, iv.Type, &iv.Hash)
}

436
vendor/github.com/btcsuite/btcd/wire/message.go generated vendored Normal file
View File

@ -0,0 +1,436 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"bytes"
"fmt"
"io"
"unicode/utf8"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// MessageHeaderSize is the number of bytes in a bitcoin message header.
// Bitcoin network (magic) 4 bytes + command 12 bytes + payload length 4 bytes +
// checksum 4 bytes.
const MessageHeaderSize = 24
// CommandSize is the fixed size of all commands in the common bitcoin message
// header. Shorter commands must be zero padded.
const CommandSize = 12
// MaxMessagePayload is the maximum bytes a message can be regardless of other
// individual limits imposed by messages themselves.
const MaxMessagePayload = (1024 * 1024 * 32) // 32MB
// Commands used in bitcoin message headers which describe the type of message.
const (
CmdVersion = "version"
CmdVerAck = "verack"
CmdGetAddr = "getaddr"
CmdAddr = "addr"
CmdGetBlocks = "getblocks"
CmdInv = "inv"
CmdGetData = "getdata"
CmdNotFound = "notfound"
CmdBlock = "block"
CmdTx = "tx"
CmdGetHeaders = "getheaders"
CmdHeaders = "headers"
CmdPing = "ping"
CmdPong = "pong"
CmdAlert = "alert"
CmdMemPool = "mempool"
CmdFilterAdd = "filteradd"
CmdFilterClear = "filterclear"
CmdFilterLoad = "filterload"
CmdMerkleBlock = "merkleblock"
CmdReject = "reject"
CmdSendHeaders = "sendheaders"
CmdFeeFilter = "feefilter"
CmdGetCFilters = "getcfilters"
CmdGetCFHeaders = "getcfheaders"
CmdGetCFCheckpt = "getcfcheckpt"
CmdCFilter = "cfilter"
CmdCFHeaders = "cfheaders"
CmdCFCheckpt = "cfcheckpt"
)
// MessageEncoding represents the wire message encoding format to be used.
type MessageEncoding uint32
const (
// BaseEncoding encodes all messages in the default format specified
// for the Bitcoin wire protocol.
BaseEncoding MessageEncoding = 1 << iota
// WitnessEncoding encodes all messages other than transaction messages
// using the default Bitcoin wire protocol specification. For transaction
// messages, the new encoding format detailed in BIP0144 will be used.
WitnessEncoding
)
// LatestEncoding is the most recently specified encoding for the Bitcoin wire
// protocol.
var LatestEncoding = WitnessEncoding
// Message is an interface that describes a bitcoin message. A type that
// implements Message has complete control over the representation of its data
// and may therefore contain additional or fewer fields than those which
// are used directly in the protocol encoded message.
type Message interface {
BtcDecode(io.Reader, uint32, MessageEncoding) error
BtcEncode(io.Writer, uint32, MessageEncoding) error
Command() string
MaxPayloadLength(uint32) uint32
}
// makeEmptyMessage creates a message of the appropriate concrete type based
// on the command.
func makeEmptyMessage(command string) (Message, error) {
var msg Message
switch command {
case CmdVersion:
msg = &MsgVersion{}
case CmdVerAck:
msg = &MsgVerAck{}
case CmdGetAddr:
msg = &MsgGetAddr{}
case CmdAddr:
msg = &MsgAddr{}
case CmdGetBlocks:
msg = &MsgGetBlocks{}
case CmdBlock:
msg = &MsgBlock{}
case CmdInv:
msg = &MsgInv{}
case CmdGetData:
msg = &MsgGetData{}
case CmdNotFound:
msg = &MsgNotFound{}
case CmdTx:
msg = &MsgTx{}
case CmdPing:
msg = &MsgPing{}
case CmdPong:
msg = &MsgPong{}
case CmdGetHeaders:
msg = &MsgGetHeaders{}
case CmdHeaders:
msg = &MsgHeaders{}
case CmdAlert:
msg = &MsgAlert{}
case CmdMemPool:
msg = &MsgMemPool{}
case CmdFilterAdd:
msg = &MsgFilterAdd{}
case CmdFilterClear:
msg = &MsgFilterClear{}
case CmdFilterLoad:
msg = &MsgFilterLoad{}
case CmdMerkleBlock:
msg = &MsgMerkleBlock{}
case CmdReject:
msg = &MsgReject{}
case CmdSendHeaders:
msg = &MsgSendHeaders{}
case CmdFeeFilter:
msg = &MsgFeeFilter{}
case CmdGetCFilters:
msg = &MsgGetCFilters{}
case CmdGetCFHeaders:
msg = &MsgGetCFHeaders{}
case CmdGetCFCheckpt:
msg = &MsgGetCFCheckpt{}
case CmdCFilter:
msg = &MsgCFilter{}
case CmdCFHeaders:
msg = &MsgCFHeaders{}
case CmdCFCheckpt:
msg = &MsgCFCheckpt{}
default:
return nil, fmt.Errorf("unhandled command [%s]", command)
}
return msg, nil
}
// messageHeader defines the header structure for all bitcoin protocol messages.
type messageHeader struct {
magic BitcoinNet // 4 bytes
command string // 12 bytes
length uint32 // 4 bytes
checksum [4]byte // 4 bytes
}
// readMessageHeader reads a bitcoin message header from r.
func readMessageHeader(r io.Reader) (int, *messageHeader, error) {
// Since readElements doesn't return the amount of bytes read, attempt
// to read the entire header into a buffer first in case there is a
// short read so the proper amount of read bytes are known. This works
// since the header is a fixed size.
var headerBytes [MessageHeaderSize]byte
n, err := io.ReadFull(r, headerBytes[:])
if err != nil {
return n, nil, err
}
hr := bytes.NewReader(headerBytes[:])
// Create and populate a messageHeader struct from the raw header bytes.
hdr := messageHeader{}
var command [CommandSize]byte
readElements(hr, &hdr.magic, &command, &hdr.length, &hdr.checksum)
// Strip trailing zeros from command string.
hdr.command = string(bytes.TrimRight(command[:], string(0)))
return n, &hdr, nil
}
// discardInput reads n bytes from reader r in chunks and discards the read
// bytes. This is used to skip payloads when various errors occur and helps
// prevent rogue nodes from causing massive memory allocation through forging
// header length.
func discardInput(r io.Reader, n uint32) {
maxSize := uint32(10 * 1024) // 10k at a time
numReads := n / maxSize
bytesRemaining := n % maxSize
if n > 0 {
buf := make([]byte, maxSize)
for i := uint32(0); i < numReads; i++ {
io.ReadFull(r, buf)
}
}
if bytesRemaining > 0 {
buf := make([]byte, bytesRemaining)
io.ReadFull(r, buf)
}
}
// WriteMessageN writes a bitcoin Message to w including the necessary header
// information and returns the number of bytes written. This function is the
// same as WriteMessage except it also returns the number of bytes written.
func WriteMessageN(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) (int, error) {
return WriteMessageWithEncodingN(w, msg, pver, btcnet, BaseEncoding)
}
// WriteMessage writes a bitcoin Message to w including the necessary header
// information. This function is the same as WriteMessageN except it doesn't
// doesn't return the number of bytes written. This function is mainly provided
// for backwards compatibility with the original API, but it's also useful for
// callers that don't care about byte counts.
func WriteMessage(w io.Writer, msg Message, pver uint32, btcnet BitcoinNet) error {
_, err := WriteMessageN(w, msg, pver, btcnet)
return err
}
// WriteMessageWithEncodingN writes a bitcoin Message to w including the
// necessary header information and returns the number of bytes written.
// This function is the same as WriteMessageN except it also allows the caller
// to specify the message encoding format to be used when serializing wire
// messages.
func WriteMessageWithEncodingN(w io.Writer, msg Message, pver uint32,
btcnet BitcoinNet, encoding MessageEncoding) (int, error) {
totalBytes := 0
// Enforce max command size.
var command [CommandSize]byte
cmd := msg.Command()
if len(cmd) > CommandSize {
str := fmt.Sprintf("command [%s] is too long [max %v]",
cmd, CommandSize)
return totalBytes, messageError("WriteMessage", str)
}
copy(command[:], []byte(cmd))
// Encode the message payload.
var bw bytes.Buffer
err := msg.BtcEncode(&bw, pver, encoding)
if err != nil {
return totalBytes, err
}
payload := bw.Bytes()
lenp := len(payload)
// Enforce maximum overall message payload.
if lenp > MaxMessagePayload {
str := fmt.Sprintf("message payload is too large - encoded "+
"%d bytes, but maximum message payload is %d bytes",
lenp, MaxMessagePayload)
return totalBytes, messageError("WriteMessage", str)
}
// Enforce maximum message payload based on the message type.
mpl := msg.MaxPayloadLength(pver)
if uint32(lenp) > mpl {
str := fmt.Sprintf("message payload is too large - encoded "+
"%d bytes, but maximum message payload size for "+
"messages of type [%s] is %d.", lenp, cmd, mpl)
return totalBytes, messageError("WriteMessage", str)
}
// Create header for the message.
hdr := messageHeader{}
hdr.magic = btcnet
hdr.command = cmd
hdr.length = uint32(lenp)
copy(hdr.checksum[:], chainhash.DoubleHashB(payload)[0:4])
// Encode the header for the message. This is done to a buffer
// rather than directly to the writer since writeElements doesn't
// return the number of bytes written.
hw := bytes.NewBuffer(make([]byte, 0, MessageHeaderSize))
writeElements(hw, hdr.magic, command, hdr.length, hdr.checksum)
// Write header.
n, err := w.Write(hw.Bytes())
totalBytes += n
if err != nil {
return totalBytes, err
}
// Write payload.
n, err = w.Write(payload)
totalBytes += n
return totalBytes, err
}
// ReadMessageWithEncodingN reads, validates, and parses the next bitcoin Message
// from r for the provided protocol version and bitcoin network. It returns the
// number of bytes read in addition to the parsed Message and raw bytes which
// comprise the message. This function is the same as ReadMessageN except it
// allows the caller to specify which message encoding is to to consult when
// decoding wire messages.
func ReadMessageWithEncodingN(r io.Reader, pver uint32, btcnet BitcoinNet,
enc MessageEncoding) (int, Message, []byte, error) {
totalBytes := 0
n, hdr, err := readMessageHeader(r)
totalBytes += n
if err != nil {
return totalBytes, nil, nil, err
}
// Enforce maximum message payload.
if hdr.length > MaxMessagePayload {
str := fmt.Sprintf("message payload is too large - header "+
"indicates %d bytes, but max message payload is %d "+
"bytes.", hdr.length, MaxMessagePayload)
return totalBytes, nil, nil, messageError("ReadMessage", str)
}
// Check for messages from the wrong bitcoin network.
if hdr.magic != btcnet {
discardInput(r, hdr.length)
str := fmt.Sprintf("message from other network [%v]", hdr.magic)
return totalBytes, nil, nil, messageError("ReadMessage", str)
}
// Check for malformed commands.
command := hdr.command
if !utf8.ValidString(command) {
discardInput(r, hdr.length)
str := fmt.Sprintf("invalid command %v", []byte(command))
return totalBytes, nil, nil, messageError("ReadMessage", str)
}
// Create struct of appropriate message type based on the command.
msg, err := makeEmptyMessage(command)
if err != nil {
discardInput(r, hdr.length)
return totalBytes, nil, nil, messageError("ReadMessage",
err.Error())
}
// Check for maximum length based on the message type as a malicious client
// could otherwise create a well-formed header and set the length to max
// numbers in order to exhaust the machine's memory.
mpl := msg.MaxPayloadLength(pver)
if hdr.length > mpl {
discardInput(r, hdr.length)
str := fmt.Sprintf("payload exceeds max length - header "+
"indicates %v bytes, but max payload size for "+
"messages of type [%v] is %v.", hdr.length, command, mpl)
return totalBytes, nil, nil, messageError("ReadMessage", str)
}
// Read payload.
payload := make([]byte, hdr.length)
n, err = io.ReadFull(r, payload)
totalBytes += n
if err != nil {
return totalBytes, nil, nil, err
}
// Test checksum.
checksum := chainhash.DoubleHashB(payload)[0:4]
if !bytes.Equal(checksum[:], hdr.checksum[:]) {
str := fmt.Sprintf("payload checksum failed - header "+
"indicates %v, but actual checksum is %v.",
hdr.checksum, checksum)
return totalBytes, nil, nil, messageError("ReadMessage", str)
}
// Unmarshal message. NOTE: This must be a *bytes.Buffer since the
// MsgVersion BtcDecode function requires it.
pr := bytes.NewBuffer(payload)
err = msg.BtcDecode(pr, pver, enc)
if err != nil {
return totalBytes, nil, nil, err
}
return totalBytes, msg, payload, nil
}
// ReadMessageN reads, validates, and parses the next bitcoin Message from r for
// the provided protocol version and bitcoin network. It returns the number of
// bytes read in addition to the parsed Message and raw bytes which comprise the
// message. This function is the same as ReadMessage except it also returns the
// number of bytes read.
func ReadMessageN(r io.Reader, pver uint32, btcnet BitcoinNet) (int, Message, []byte, error) {
return ReadMessageWithEncodingN(r, pver, btcnet, BaseEncoding)
}
// ReadMessage reads, validates, and parses the next bitcoin Message from r for
// the provided protocol version and bitcoin network. It returns the parsed
// Message and raw bytes which comprise the message. This function only differs
// from ReadMessageN in that it doesn't return the number of bytes read. This
// function is mainly provided for backwards compatibility with the original
// API, but it's also useful for callers that don't care about byte counts.
func ReadMessage(r io.Reader, pver uint32, btcnet BitcoinNet) (Message, []byte, error) {
_, msg, buf, err := ReadMessageN(r, pver, btcnet)
return msg, buf, err
}

143
vendor/github.com/btcsuite/btcd/wire/msgaddr.go generated vendored Normal file
View File

@ -0,0 +1,143 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MaxAddrPerMsg is the maximum number of addresses that can be in a single
// bitcoin addr message (MsgAddr).
const MaxAddrPerMsg = 1000
// MsgAddr implements the Message interface and represents a bitcoin
// addr message. It is used to provide a list of known active peers on the
// network. An active peer is considered one that has transmitted a message
// within the last 3 hours. Nodes which have not transmitted in that time
// frame should be forgotten. Each message is limited to a maximum number of
// addresses, which is currently 1000. As a result, multiple messages must
// be used to relay the full list.
//
// Use the AddAddress function to build up the list of known addresses when
// sending an addr message to another peer.
type MsgAddr struct {
AddrList []*NetAddress
}
// AddAddress adds a known active peer to the message.
func (msg *MsgAddr) AddAddress(na *NetAddress) error {
if len(msg.AddrList)+1 > MaxAddrPerMsg {
str := fmt.Sprintf("too many addresses in message [max %v]",
MaxAddrPerMsg)
return messageError("MsgAddr.AddAddress", str)
}
msg.AddrList = append(msg.AddrList, na)
return nil
}
// AddAddresses adds multiple known active peers to the message.
func (msg *MsgAddr) AddAddresses(netAddrs ...*NetAddress) error {
for _, na := range netAddrs {
err := msg.AddAddress(na)
if err != nil {
return err
}
}
return nil
}
// ClearAddresses removes all addresses from the message.
func (msg *MsgAddr) ClearAddresses() {
msg.AddrList = []*NetAddress{}
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Limit to max addresses per message.
if count > MaxAddrPerMsg {
str := fmt.Sprintf("too many addresses for message "+
"[count %v, max %v]", count, MaxAddrPerMsg)
return messageError("MsgAddr.BtcDecode", str)
}
addrList := make([]NetAddress, count)
msg.AddrList = make([]*NetAddress, 0, count)
for i := uint64(0); i < count; i++ {
na := &addrList[i]
err := readNetAddress(r, pver, na, true)
if err != nil {
return err
}
msg.AddAddress(na)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// Protocol versions before MultipleAddressVersion only allowed 1 address
// per message.
count := len(msg.AddrList)
if pver < MultipleAddressVersion && count > 1 {
str := fmt.Sprintf("too many addresses for message of "+
"protocol version %v [count %v, max 1]", pver, count)
return messageError("MsgAddr.BtcEncode", str)
}
if count > MaxAddrPerMsg {
str := fmt.Sprintf("too many addresses for message "+
"[count %v, max %v]", count, MaxAddrPerMsg)
return messageError("MsgAddr.BtcEncode", str)
}
err := WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, na := range msg.AddrList {
err = writeNetAddress(w, pver, na, true)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgAddr) Command() string {
return CmdAddr
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgAddr) MaxPayloadLength(pver uint32) uint32 {
if pver < MultipleAddressVersion {
// Num addresses (varInt) + a single net addresses.
return MaxVarIntPayload + maxNetAddressPayload(pver)
}
// Num addresses (varInt) + max allowed addresses.
return MaxVarIntPayload + (MaxAddrPerMsg * maxNetAddressPayload(pver))
}
// NewMsgAddr returns a new bitcoin addr message that conforms to the
// Message interface. See MsgAddr for details.
func NewMsgAddr() *MsgAddr {
return &MsgAddr{
AddrList: make([]*NetAddress, 0, MaxAddrPerMsg),
}
}

407
vendor/github.com/btcsuite/btcd/wire/msgalert.go generated vendored Normal file
View File

@ -0,0 +1,407 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"bytes"
"fmt"
"io"
)
// MsgAlert contains a payload and a signature:
//
// ===============================================
// | Field | Data Type | Size |
// ===============================================
// | payload | []uchar | ? |
// -----------------------------------------------
// | signature | []uchar | ? |
// -----------------------------------------------
//
// Here payload is an Alert serialized into a byte array to ensure that
// versions using incompatible alert formats can still relay
// alerts among one another.
//
// An Alert is the payload deserialized as follows:
//
// ===============================================
// | Field | Data Type | Size |
// ===============================================
// | Version | int32 | 4 |
// -----------------------------------------------
// | RelayUntil | int64 | 8 |
// -----------------------------------------------
// | Expiration | int64 | 8 |
// -----------------------------------------------
// | ID | int32 | 4 |
// -----------------------------------------------
// | Cancel | int32 | 4 |
// -----------------------------------------------
// | SetCancel | set<int32> | ? |
// -----------------------------------------------
// | MinVer | int32 | 4 |
// -----------------------------------------------
// | MaxVer | int32 | 4 |
// -----------------------------------------------
// | SetSubVer | set<string> | ? |
// -----------------------------------------------
// | Priority | int32 | 4 |
// -----------------------------------------------
// | Comment | string | ? |
// -----------------------------------------------
// | StatusBar | string | ? |
// -----------------------------------------------
// | Reserved | string | ? |
// -----------------------------------------------
// | Total (Fixed) | 45 |
// -----------------------------------------------
//
// NOTE:
// * string is a VarString i.e VarInt length followed by the string itself
// * set<string> is a VarInt followed by as many number of strings
// * set<int32> is a VarInt followed by as many number of ints
// * fixedAlertSize = 40 + 5*min(VarInt) = 40 + 5*1 = 45
//
// Now we can define bounds on Alert size, SetCancel and SetSubVer
// Fixed size of the alert payload
const fixedAlertSize = 45
// maxSignatureSize is the max size of an ECDSA signature.
// NOTE: Since this size is fixed and < 255, the size of VarInt required = 1.
const maxSignatureSize = 72
// maxAlertSize is the maximum size an alert.
//
// MessagePayload = VarInt(Alert) + Alert + VarInt(Signature) + Signature
// MaxMessagePayload = maxAlertSize + max(VarInt) + maxSignatureSize + 1
const maxAlertSize = MaxMessagePayload - maxSignatureSize - MaxVarIntPayload - 1
// maxCountSetCancel is the maximum number of cancel IDs that could possibly
// fit into a maximum size alert.
//
// maxAlertSize = fixedAlertSize + max(SetCancel) + max(SetSubVer) + 3*(string)
// for caculating maximum number of cancel IDs, set all other var sizes to 0
// maxAlertSize = fixedAlertSize + (MaxVarIntPayload-1) + x*sizeOf(int32)
// x = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / 4
const maxCountSetCancel = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / 4
// maxCountSetSubVer is the maximum number of subversions that could possibly
// fit into a maximum size alert.
//
// maxAlertSize = fixedAlertSize + max(SetCancel) + max(SetSubVer) + 3*(string)
// for caculating maximum number of subversions, set all other var sizes to 0
// maxAlertSize = fixedAlertSize + (MaxVarIntPayload-1) + x*sizeOf(string)
// x = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / sizeOf(string)
// subversion would typically be something like "/Satoshi:0.7.2/" (15 bytes)
// so assuming < 255 bytes, sizeOf(string) = sizeOf(uint8) + 255 = 256
const maxCountSetSubVer = (maxAlertSize - fixedAlertSize - MaxVarIntPayload + 1) / 256
// Alert contains the data deserialized from the MsgAlert payload.
type Alert struct {
// Alert format version
Version int32
// Timestamp beyond which nodes should stop relaying this alert
RelayUntil int64
// Timestamp beyond which this alert is no longer in effect and
// should be ignored
Expiration int64
// A unique ID number for this alert
ID int32
// All alerts with an ID less than or equal to this number should
// cancelled, deleted and not accepted in the future
Cancel int32
// All alert IDs contained in this set should be cancelled as above
SetCancel []int32
// This alert only applies to versions greater than or equal to this
// version. Other versions should still relay it.
MinVer int32
// This alert only applies to versions less than or equal to this version.
// Other versions should still relay it.
MaxVer int32
// If this set contains any elements, then only nodes that have their
// subVer contained in this set are affected by the alert. Other versions
// should still relay it.
SetSubVer []string
// Relative priority compared to other alerts
Priority int32
// A comment on the alert that is not displayed
Comment string
// The alert message that is displayed to the user
StatusBar string
// Reserved
Reserved string
}
// Serialize encodes the alert to w using the alert protocol encoding format.
func (alert *Alert) Serialize(w io.Writer, pver uint32) error {
err := writeElements(w, alert.Version, alert.RelayUntil,
alert.Expiration, alert.ID, alert.Cancel)
if err != nil {
return err
}
count := len(alert.SetCancel)
if count > maxCountSetCancel {
str := fmt.Sprintf("too many cancel alert IDs for alert "+
"[count %v, max %v]", count, maxCountSetCancel)
return messageError("Alert.Serialize", str)
}
err = WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for i := 0; i < count; i++ {
err = writeElement(w, alert.SetCancel[i])
if err != nil {
return err
}
}
err = writeElements(w, alert.MinVer, alert.MaxVer)
if err != nil {
return err
}
count = len(alert.SetSubVer)
if count > maxCountSetSubVer {
str := fmt.Sprintf("too many sub versions for alert "+
"[count %v, max %v]", count, maxCountSetSubVer)
return messageError("Alert.Serialize", str)
}
err = WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for i := 0; i < count; i++ {
err = WriteVarString(w, pver, alert.SetSubVer[i])
if err != nil {
return err
}
}
err = writeElement(w, alert.Priority)
if err != nil {
return err
}
err = WriteVarString(w, pver, alert.Comment)
if err != nil {
return err
}
err = WriteVarString(w, pver, alert.StatusBar)
if err != nil {
return err
}
return WriteVarString(w, pver, alert.Reserved)
}
// Deserialize decodes from r into the receiver using the alert protocol
// encoding format.
func (alert *Alert) Deserialize(r io.Reader, pver uint32) error {
err := readElements(r, &alert.Version, &alert.RelayUntil,
&alert.Expiration, &alert.ID, &alert.Cancel)
if err != nil {
return err
}
// SetCancel: first read a VarInt that contains
// count - the number of Cancel IDs, then
// iterate count times and read them
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
if count > maxCountSetCancel {
str := fmt.Sprintf("too many cancel alert IDs for alert "+
"[count %v, max %v]", count, maxCountSetCancel)
return messageError("Alert.Deserialize", str)
}
alert.SetCancel = make([]int32, count)
for i := 0; i < int(count); i++ {
err := readElement(r, &alert.SetCancel[i])
if err != nil {
return err
}
}
err = readElements(r, &alert.MinVer, &alert.MaxVer)
if err != nil {
return err
}
// SetSubVer: similar to SetCancel
// but read count number of sub-version strings
count, err = ReadVarInt(r, pver)
if err != nil {
return err
}
if count > maxCountSetSubVer {
str := fmt.Sprintf("too many sub versions for alert "+
"[count %v, max %v]", count, maxCountSetSubVer)
return messageError("Alert.Deserialize", str)
}
alert.SetSubVer = make([]string, count)
for i := 0; i < int(count); i++ {
alert.SetSubVer[i], err = ReadVarString(r, pver)
if err != nil {
return err
}
}
err = readElement(r, &alert.Priority)
if err != nil {
return err
}
alert.Comment, err = ReadVarString(r, pver)
if err != nil {
return err
}
alert.StatusBar, err = ReadVarString(r, pver)
if err != nil {
return err
}
alert.Reserved, err = ReadVarString(r, pver)
return err
}
// NewAlert returns an new Alert with values provided.
func NewAlert(version int32, relayUntil int64, expiration int64,
id int32, cancel int32, setCancel []int32, minVer int32,
maxVer int32, setSubVer []string, priority int32, comment string,
statusBar string) *Alert {
return &Alert{
Version: version,
RelayUntil: relayUntil,
Expiration: expiration,
ID: id,
Cancel: cancel,
SetCancel: setCancel,
MinVer: minVer,
MaxVer: maxVer,
SetSubVer: setSubVer,
Priority: priority,
Comment: comment,
StatusBar: statusBar,
Reserved: "",
}
}
// NewAlertFromPayload returns an Alert with values deserialized from the
// serialized payload.
func NewAlertFromPayload(serializedPayload []byte, pver uint32) (*Alert, error) {
var alert Alert
r := bytes.NewReader(serializedPayload)
err := alert.Deserialize(r, pver)
if err != nil {
return nil, err
}
return &alert, nil
}
// MsgAlert implements the Message interface and defines a bitcoin alert
// message.
//
// This is a signed message that provides notifications that the client should
// display if the signature matches the key. bitcoind/bitcoin-qt only checks
// against a signature from the core developers.
type MsgAlert struct {
// SerializedPayload is the alert payload serialized as a string so that the
// version can change but the Alert can still be passed on by older
// clients.
SerializedPayload []byte
// Signature is the ECDSA signature of the message.
Signature []byte
// Deserialized Payload
Payload *Alert
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgAlert) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
var err error
msg.SerializedPayload, err = ReadVarBytes(r, pver, MaxMessagePayload,
"alert serialized payload")
if err != nil {
return err
}
msg.Payload, err = NewAlertFromPayload(msg.SerializedPayload, pver)
if err != nil {
msg.Payload = nil
}
msg.Signature, err = ReadVarBytes(r, pver, MaxMessagePayload,
"alert signature")
return err
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgAlert) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
var err error
var serializedpayload []byte
if msg.Payload != nil {
// try to Serialize Payload if possible
r := new(bytes.Buffer)
err = msg.Payload.Serialize(r, pver)
if err != nil {
// Serialize failed - ignore & fallback
// to SerializedPayload
serializedpayload = msg.SerializedPayload
} else {
serializedpayload = r.Bytes()
}
} else {
serializedpayload = msg.SerializedPayload
}
slen := uint64(len(serializedpayload))
if slen == 0 {
return messageError("MsgAlert.BtcEncode", "empty serialized payload")
}
err = WriteVarBytes(w, pver, serializedpayload)
if err != nil {
return err
}
return WriteVarBytes(w, pver, msg.Signature)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgAlert) Command() string {
return CmdAlert
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgAlert) MaxPayloadLength(pver uint32) uint32 {
// Since this can vary depending on the message, make it the max
// size allowed.
return MaxMessagePayload
}
// NewMsgAlert returns a new bitcoin alert message that conforms to the Message
// interface. See MsgAlert for details.
func NewMsgAlert(serializedPayload []byte, signature []byte) *MsgAlert {
return &MsgAlert{
SerializedPayload: serializedPayload,
Signature: signature,
Payload: nil,
}
}

290
vendor/github.com/btcsuite/btcd/wire/msgblock.go generated vendored Normal file
View File

@ -0,0 +1,290 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"bytes"
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// defaultTransactionAlloc is the default size used for the backing array
// for transactions. The transaction array will dynamically grow as needed, but
// this figure is intended to provide enough space for the number of
// transactions in the vast majority of blocks without needing to grow the
// backing array multiple times.
const defaultTransactionAlloc = 2048
// MaxBlocksPerMsg is the maximum number of blocks allowed per message.
const MaxBlocksPerMsg = 500
// MaxBlockPayload is the maximum bytes a block message can be in bytes.
// After Segregated Witness, the max block payload has been raised to 4MB.
const MaxBlockPayload = 4000000
// maxTxPerBlock is the maximum number of transactions that could
// possibly fit into a block.
const maxTxPerBlock = (MaxBlockPayload / minTxPayload) + 1
// TxLoc holds locator data for the offset and length of where a transaction is
// located within a MsgBlock data buffer.
type TxLoc struct {
TxStart int
TxLen int
}
// MsgBlock implements the Message interface and represents a bitcoin
// block message. It is used to deliver block and transaction information in
// response to a getdata message (MsgGetData) for a given block hash.
type MsgBlock struct {
Header BlockHeader
Transactions []*MsgTx
}
// AddTransaction adds a transaction to the message.
func (msg *MsgBlock) AddTransaction(tx *MsgTx) error {
msg.Transactions = append(msg.Transactions, tx)
return nil
}
// ClearTransactions removes all transactions from the message.
func (msg *MsgBlock) ClearTransactions() {
msg.Transactions = make([]*MsgTx, 0, defaultTransactionAlloc)
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
// See Deserialize for decoding blocks stored to disk, such as in a database, as
// opposed to decoding blocks from the wire.
func (msg *MsgBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
err := readBlockHeader(r, pver, &msg.Header)
if err != nil {
return err
}
txCount, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Prevent more transactions than could possibly fit into a block.
// It would be possible to cause memory exhaustion and panics without
// a sane upper bound on this count.
if txCount > maxTxPerBlock {
str := fmt.Sprintf("too many transactions to fit into a block "+
"[count %d, max %d]", txCount, maxTxPerBlock)
return messageError("MsgBlock.BtcDecode", str)
}
msg.Transactions = make([]*MsgTx, 0, txCount)
for i := uint64(0); i < txCount; i++ {
tx := MsgTx{}
err := tx.BtcDecode(r, pver, enc)
if err != nil {
return err
}
msg.Transactions = append(msg.Transactions, &tx)
}
return nil
}
// Deserialize decodes a block from r into the receiver using a format that is
// suitable for long-term storage such as a database while respecting the
// Version field in the block. This function differs from BtcDecode in that
// BtcDecode decodes from the bitcoin wire protocol as it was sent across the
// network. The wire encoding can technically differ depending on the protocol
// version and doesn't even really need to match the format of a stored block at
// all. As of the time this comment was written, the encoded block is the same
// in both instances, but there is a distinct difference and separating the two
// allows the API to be flexible enough to deal with changes.
func (msg *MsgBlock) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the wire encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of BtcDecode.
//
// Passing an encoding type of WitnessEncoding to BtcEncode for the
// MessageEncoding parameter indicates that the transactions within the
// block are expected to be serialized according to the new
// serialization structure defined in BIP0141.
return msg.BtcDecode(r, 0, WitnessEncoding)
}
// DeserializeNoWitness decodes a block from r into the receiver similar to
// Deserialize, however DeserializeWitness strips all (if any) witness data
// from the transactions within the block before encoding them.
func (msg *MsgBlock) DeserializeNoWitness(r io.Reader) error {
return msg.BtcDecode(r, 0, BaseEncoding)
}
// DeserializeTxLoc decodes r in the same manner Deserialize does, but it takes
// a byte buffer instead of a generic reader and returns a slice containing the
// start and length of each transaction within the raw data that is being
// deserialized.
func (msg *MsgBlock) DeserializeTxLoc(r *bytes.Buffer) ([]TxLoc, error) {
fullLen := r.Len()
// At the current time, there is no difference between the wire encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of existing wire protocol functions.
err := readBlockHeader(r, 0, &msg.Header)
if err != nil {
return nil, err
}
txCount, err := ReadVarInt(r, 0)
if err != nil {
return nil, err
}
// Prevent more transactions than could possibly fit into a block.
// It would be possible to cause memory exhaustion and panics without
// a sane upper bound on this count.
if txCount > maxTxPerBlock {
str := fmt.Sprintf("too many transactions to fit into a block "+
"[count %d, max %d]", txCount, maxTxPerBlock)
return nil, messageError("MsgBlock.DeserializeTxLoc", str)
}
// Deserialize each transaction while keeping track of its location
// within the byte stream.
msg.Transactions = make([]*MsgTx, 0, txCount)
txLocs := make([]TxLoc, txCount)
for i := uint64(0); i < txCount; i++ {
txLocs[i].TxStart = fullLen - r.Len()
tx := MsgTx{}
err := tx.Deserialize(r)
if err != nil {
return nil, err
}
msg.Transactions = append(msg.Transactions, &tx)
txLocs[i].TxLen = (fullLen - r.Len()) - txLocs[i].TxStart
}
return txLocs, nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
// See Serialize for encoding blocks to be stored to disk, such as in a
// database, as opposed to encoding blocks for the wire.
func (msg *MsgBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
err := writeBlockHeader(w, pver, &msg.Header)
if err != nil {
return err
}
err = WriteVarInt(w, pver, uint64(len(msg.Transactions)))
if err != nil {
return err
}
for _, tx := range msg.Transactions {
err = tx.BtcEncode(w, pver, enc)
if err != nil {
return err
}
}
return nil
}
// Serialize encodes the block to w using a format that suitable for long-term
// storage such as a database while respecting the Version field in the block.
// This function differs from BtcEncode in that BtcEncode encodes the block to
// the bitcoin wire protocol in order to be sent across the network. The wire
// encoding can technically differ depending on the protocol version and doesn't
// even really need to match the format of a stored block at all. As of the
// time this comment was written, the encoded block is the same in both
// instances, but there is a distinct difference and separating the two allows
// the API to be flexible enough to deal with changes.
func (msg *MsgBlock) Serialize(w io.Writer) error {
// At the current time, there is no difference between the wire encoding
// at protocol version 0 and the stable long-term storage format. As
// a result, make use of BtcEncode.
//
// Passing WitnessEncoding as the encoding type here indicates that
// each of the transactions should be serialized using the witness
// serialization structure defined in BIP0141.
return msg.BtcEncode(w, 0, WitnessEncoding)
}
// SerializeNoWitness encodes a block to w using an identical format to
// Serialize, with all (if any) witness data stripped from all transactions.
// This method is provided in additon to the regular Serialize, in order to
// allow one to selectively encode transaction witness data to non-upgraded
// peers which are unaware of the new encoding.
func (msg *MsgBlock) SerializeNoWitness(w io.Writer) error {
return msg.BtcEncode(w, 0, BaseEncoding)
}
// SerializeSize returns the number of bytes it would take to serialize the
// block, factoring in any witness data within transaction.
func (msg *MsgBlock) SerializeSize() int {
// Block header bytes + Serialized varint size for the number of
// transactions.
n := blockHeaderLen + VarIntSerializeSize(uint64(len(msg.Transactions)))
for _, tx := range msg.Transactions {
n += tx.SerializeSize()
}
return n
}
// SerializeSizeStripped returns the number of bytes it would take to serialize
// the block, excluding any witness data (if any).
func (msg *MsgBlock) SerializeSizeStripped() int {
// Block header bytes + Serialized varint size for the number of
// transactions.
n := blockHeaderLen + VarIntSerializeSize(uint64(len(msg.Transactions)))
for _, tx := range msg.Transactions {
n += tx.SerializeSizeStripped()
}
return n
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgBlock) Command() string {
return CmdBlock
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgBlock) MaxPayloadLength(pver uint32) uint32 {
// Block header at 80 bytes + transaction count + max transactions
// which can vary up to the MaxBlockPayload (including the block header
// and transaction count).
return MaxBlockPayload
}
// BlockHash computes the block identifier hash for this block.
func (msg *MsgBlock) BlockHash() chainhash.Hash {
return msg.Header.BlockHash()
}
// TxHashes returns a slice of hashes of all of transactions in this block.
func (msg *MsgBlock) TxHashes() ([]chainhash.Hash, error) {
hashList := make([]chainhash.Hash, 0, len(msg.Transactions))
for _, tx := range msg.Transactions {
hashList = append(hashList, tx.TxHash())
}
return hashList, nil
}
// NewMsgBlock returns a new bitcoin block message that conforms to the
// Message interface. See MsgBlock for details.
func NewMsgBlock(blockHeader *BlockHeader) *MsgBlock {
return &MsgBlock{
Header: *blockHeader,
Transactions: make([]*MsgTx, 0, defaultTransactionAlloc),
}
}

164
vendor/github.com/btcsuite/btcd/wire/msgcfcheckpt.go generated vendored Normal file
View File

@ -0,0 +1,164 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"errors"
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
const (
// CFCheckptInterval is the gap (in number of blocks) between each
// filter header checkpoint.
CFCheckptInterval = 1000
// maxCFHeadersLen is the max number of filter headers we will attempt
// to decode.
maxCFHeadersLen = 100000
)
// ErrInsaneCFHeaderCount signals that we were asked to decode an
// unreasonable number of cfilter headers.
var ErrInsaneCFHeaderCount = errors.New(
"refusing to decode unreasonable number of filter headers")
// MsgCFCheckpt implements the Message interface and represents a bitcoin
// cfcheckpt message. It is used to deliver committed filter header information
// in response to a getcfcheckpt message (MsgGetCFCheckpt). See MsgGetCFCheckpt
// for details on requesting the headers.
type MsgCFCheckpt struct {
FilterType FilterType
StopHash chainhash.Hash
FilterHeaders []*chainhash.Hash
}
// AddCFHeader adds a new committed filter header to the message.
func (msg *MsgCFCheckpt) AddCFHeader(header *chainhash.Hash) error {
if len(msg.FilterHeaders) == cap(msg.FilterHeaders) {
str := fmt.Sprintf("FilterHeaders has insufficient capacity for "+
"additional header: len = %d", len(msg.FilterHeaders))
return messageError("MsgCFCheckpt.AddCFHeader", str)
}
msg.FilterHeaders = append(msg.FilterHeaders, header)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
// Read filter type
err := readElement(r, &msg.FilterType)
if err != nil {
return err
}
// Read stop hash
err = readElement(r, &msg.StopHash)
if err != nil {
return err
}
// Read number of filter headers
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Refuse to decode an insane number of cfheaders.
if count > maxCFHeadersLen {
return ErrInsaneCFHeaderCount
}
// Create a contiguous slice of hashes to deserialize into in order to
// reduce the number of allocations.
msg.FilterHeaders = make([]*chainhash.Hash, count)
for i := uint64(0); i < count; i++ {
var cfh chainhash.Hash
err := readElement(r, &cfh)
if err != nil {
return err
}
msg.FilterHeaders[i] = &cfh
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgCFCheckpt) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
// Write filter type
err := writeElement(w, msg.FilterType)
if err != nil {
return err
}
// Write stop hash
err = writeElement(w, msg.StopHash)
if err != nil {
return err
}
// Write length of FilterHeaders slice
count := len(msg.FilterHeaders)
err = WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, cfh := range msg.FilterHeaders {
err := writeElement(w, cfh)
if err != nil {
return err
}
}
return nil
}
// Deserialize decodes a filter header from r into the receiver using a format
// that is suitable for long-term storage such as a database. This function
// differs from BtcDecode in that BtcDecode decodes from the bitcoin wire
// protocol as it was sent across the network. The wire encoding can
// technically differ depending on the protocol version and doesn't even really
// need to match the format of a stored filter header at all. As of the time
// this comment was written, the encoded filter header is the same in both
// instances, but there is a distinct difference and separating the two allows
// the API to be flexible enough to deal with changes.
func (msg *MsgCFCheckpt) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the wire encoding
// and the stable long-term storage format. As a result, make use of
// BtcDecode.
return msg.BtcDecode(r, 0, BaseEncoding)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgCFCheckpt) Command() string {
return CmdCFCheckpt
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgCFCheckpt) MaxPayloadLength(pver uint32) uint32 {
// Message size depends on the blockchain height, so return general limit
// for all messages.
return MaxMessagePayload
}
// NewMsgCFCheckpt returns a new bitcoin cfheaders message that conforms to
// the Message interface. See MsgCFCheckpt for details.
func NewMsgCFCheckpt(filterType FilterType, stopHash *chainhash.Hash,
headersCount int) *MsgCFCheckpt {
return &MsgCFCheckpt{
FilterType: filterType,
StopHash: *stopHash,
FilterHeaders: make([]*chainhash.Hash, 0, headersCount),
}
}

180
vendor/github.com/btcsuite/btcd/wire/msgcfheaders.go generated vendored Normal file
View File

@ -0,0 +1,180 @@
// Copyright (c) 2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
const (
// MaxCFHeaderPayload is the maximum byte size of a committed
// filter header.
MaxCFHeaderPayload = chainhash.HashSize
// MaxCFHeadersPerMsg is the maximum number of committed filter headers
// that can be in a single bitcoin cfheaders message.
MaxCFHeadersPerMsg = 2000
)
// MsgCFHeaders implements the Message interface and represents a bitcoin
// cfheaders message. It is used to deliver committed filter header information
// in response to a getcfheaders message (MsgGetCFHeaders). The maximum number
// of committed filter headers per message is currently 2000. See
// MsgGetCFHeaders for details on requesting the headers.
type MsgCFHeaders struct {
FilterType FilterType
StopHash chainhash.Hash
PrevFilterHeader chainhash.Hash
FilterHashes []*chainhash.Hash
}
// AddCFHash adds a new filter hash to the message.
func (msg *MsgCFHeaders) AddCFHash(hash *chainhash.Hash) error {
if len(msg.FilterHashes)+1 > MaxCFHeadersPerMsg {
str := fmt.Sprintf("too many block headers in message [max %v]",
MaxBlockHeadersPerMsg)
return messageError("MsgCFHeaders.AddCFHash", str)
}
msg.FilterHashes = append(msg.FilterHashes, hash)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
// Read filter type
err := readElement(r, &msg.FilterType)
if err != nil {
return err
}
// Read stop hash
err = readElement(r, &msg.StopHash)
if err != nil {
return err
}
// Read prev filter header
err = readElement(r, &msg.PrevFilterHeader)
if err != nil {
return err
}
// Read number of filter headers
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Limit to max committed filter headers per message.
if count > MaxCFHeadersPerMsg {
str := fmt.Sprintf("too many committed filter headers for "+
"message [count %v, max %v]", count,
MaxBlockHeadersPerMsg)
return messageError("MsgCFHeaders.BtcDecode", str)
}
// Create a contiguous slice of hashes to deserialize into in order to
// reduce the number of allocations.
msg.FilterHashes = make([]*chainhash.Hash, 0, count)
for i := uint64(0); i < count; i++ {
var cfh chainhash.Hash
err := readElement(r, &cfh)
if err != nil {
return err
}
msg.AddCFHash(&cfh)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
// Write filter type
err := writeElement(w, msg.FilterType)
if err != nil {
return err
}
// Write stop hash
err = writeElement(w, msg.StopHash)
if err != nil {
return err
}
// Write prev filter header
err = writeElement(w, msg.PrevFilterHeader)
if err != nil {
return err
}
// Limit to max committed headers per message.
count := len(msg.FilterHashes)
if count > MaxCFHeadersPerMsg {
str := fmt.Sprintf("too many committed filter headers for "+
"message [count %v, max %v]", count,
MaxBlockHeadersPerMsg)
return messageError("MsgCFHeaders.BtcEncode", str)
}
err = WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, cfh := range msg.FilterHashes {
err := writeElement(w, cfh)
if err != nil {
return err
}
}
return nil
}
// Deserialize decodes a filter header from r into the receiver using a format
// that is suitable for long-term storage such as a database. This function
// differs from BtcDecode in that BtcDecode decodes from the bitcoin wire
// protocol as it was sent across the network. The wire encoding can
// technically differ depending on the protocol version and doesn't even really
// need to match the format of a stored filter header at all. As of the time
// this comment was written, the encoded filter header is the same in both
// instances, but there is a distinct difference and separating the two allows
// the API to be flexible enough to deal with changes.
func (msg *MsgCFHeaders) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the wire encoding
// and the stable long-term storage format. As a result, make use of
// BtcDecode.
return msg.BtcDecode(r, 0, BaseEncoding)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgCFHeaders) Command() string {
return CmdCFHeaders
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgCFHeaders) MaxPayloadLength(pver uint32) uint32 {
// Hash size + filter type + num headers (varInt) +
// (header size * max headers).
return 1 + chainhash.HashSize + chainhash.HashSize + MaxVarIntPayload +
(MaxCFHeaderPayload * MaxCFHeadersPerMsg)
}
// NewMsgCFHeaders returns a new bitcoin cfheaders message that conforms to
// the Message interface. See MsgCFHeaders for details.
func NewMsgCFHeaders() *MsgCFHeaders {
return &MsgCFHeaders{
FilterHashes: make([]*chainhash.Hash, 0, MaxCFHeadersPerMsg),
}
}

119
vendor/github.com/btcsuite/btcd/wire/msgcfilter.go generated vendored Normal file
View File

@ -0,0 +1,119 @@
// Copyright (c) 2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// FilterType is used to represent a filter type.
type FilterType uint8
const (
// GCSFilterRegular is the regular filter type.
GCSFilterRegular FilterType = iota
)
const (
// MaxCFilterDataSize is the maximum byte size of a committed filter.
// The maximum size is currently defined as 256KiB.
MaxCFilterDataSize = 256 * 1024
)
// MsgCFilter implements the Message interface and represents a bitcoin cfilter
// message. It is used to deliver a committed filter in response to a
// getcfilters (MsgGetCFilters) message.
type MsgCFilter struct {
FilterType FilterType
BlockHash chainhash.Hash
Data []byte
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
// Read filter type
err := readElement(r, &msg.FilterType)
if err != nil {
return err
}
// Read the hash of the filter's block
err = readElement(r, &msg.BlockHash)
if err != nil {
return err
}
// Read filter data
msg.Data, err = ReadVarBytes(r, pver, MaxCFilterDataSize,
"cfilter data")
return err
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
size := len(msg.Data)
if size > MaxCFilterDataSize {
str := fmt.Sprintf("cfilter size too large for message "+
"[size %v, max %v]", size, MaxCFilterDataSize)
return messageError("MsgCFilter.BtcEncode", str)
}
err := writeElement(w, msg.FilterType)
if err != nil {
return err
}
err = writeElement(w, msg.BlockHash)
if err != nil {
return err
}
return WriteVarBytes(w, pver, msg.Data)
}
// Deserialize decodes a filter from r into the receiver using a format that is
// suitable for long-term storage such as a database. This function differs
// from BtcDecode in that BtcDecode decodes from the bitcoin wire protocol as
// it was sent across the network. The wire encoding can technically differ
// depending on the protocol version and doesn't even really need to match the
// format of a stored filter at all. As of the time this comment was written,
// the encoded filter is the same in both instances, but there is a distinct
// difference and separating the two allows the API to be flexible enough to
// deal with changes.
func (msg *MsgCFilter) Deserialize(r io.Reader) error {
// At the current time, there is no difference between the wire encoding
// and the stable long-term storage format. As a result, make use of
// BtcDecode.
return msg.BtcDecode(r, 0, BaseEncoding)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgCFilter) Command() string {
return CmdCFilter
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgCFilter) MaxPayloadLength(pver uint32) uint32 {
return uint32(VarIntSerializeSize(MaxCFilterDataSize)) +
MaxCFilterDataSize + chainhash.HashSize + 1
}
// NewMsgCFilter returns a new bitcoin cfilter message that conforms to the
// Message interface. See MsgCFilter for details.
func NewMsgCFilter(filterType FilterType, blockHash *chainhash.Hash,
data []byte) *MsgCFilter {
return &MsgCFilter{
FilterType: filterType,
BlockHash: *blockHash,
Data: data,
}
}

64
vendor/github.com/btcsuite/btcd/wire/msgfeefilter.go generated vendored Normal file
View File

@ -0,0 +1,64 @@
// Copyright (c) 2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MsgFeeFilter implements the Message interface and represents a bitcoin
// feefilter message. It is used to request the receiving peer does not
// announce any transactions below the specified minimum fee rate.
//
// This message was not added until protocol versions starting with
// FeeFilterVersion.
type MsgFeeFilter struct {
MinFee int64
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgFeeFilter) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < FeeFilterVersion {
str := fmt.Sprintf("feefilter message invalid for protocol "+
"version %d", pver)
return messageError("MsgFeeFilter.BtcDecode", str)
}
return readElement(r, &msg.MinFee)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgFeeFilter) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < FeeFilterVersion {
str := fmt.Sprintf("feefilter message invalid for protocol "+
"version %d", pver)
return messageError("MsgFeeFilter.BtcEncode", str)
}
return writeElement(w, msg.MinFee)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgFeeFilter) Command() string {
return CmdFeeFilter
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgFeeFilter) MaxPayloadLength(pver uint32) uint32 {
return 8
}
// NewMsgFeeFilter returns a new bitcoin feefilter message that conforms to
// the Message interface. See MsgFeeFilter for details.
func NewMsgFeeFilter(minfee int64) *MsgFeeFilter {
return &MsgFeeFilter{
MinFee: minfee,
}
}

81
vendor/github.com/btcsuite/btcd/wire/msgfilteradd.go generated vendored Normal file
View File

@ -0,0 +1,81 @@
// Copyright (c) 2014-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
const (
// MaxFilterAddDataSize is the maximum byte size of a data
// element to add to the Bloom filter. It is equal to the
// maximum element size of a script.
MaxFilterAddDataSize = 520
)
// MsgFilterAdd implements the Message interface and represents a bitcoin
// filteradd message. It is used to add a data element to an existing Bloom
// filter.
//
// This message was not added until protocol version BIP0037Version.
type MsgFilterAdd struct {
Data []byte
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgFilterAdd) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("filteradd message invalid for protocol "+
"version %d", pver)
return messageError("MsgFilterAdd.BtcDecode", str)
}
var err error
msg.Data, err = ReadVarBytes(r, pver, MaxFilterAddDataSize,
"filteradd data")
return err
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgFilterAdd) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("filteradd message invalid for protocol "+
"version %d", pver)
return messageError("MsgFilterAdd.BtcEncode", str)
}
size := len(msg.Data)
if size > MaxFilterAddDataSize {
str := fmt.Sprintf("filteradd size too large for message "+
"[size %v, max %v]", size, MaxFilterAddDataSize)
return messageError("MsgFilterAdd.BtcEncode", str)
}
return WriteVarBytes(w, pver, msg.Data)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgFilterAdd) Command() string {
return CmdFilterAdd
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgFilterAdd) MaxPayloadLength(pver uint32) uint32 {
return uint32(VarIntSerializeSize(MaxFilterAddDataSize)) +
MaxFilterAddDataSize
}
// NewMsgFilterAdd returns a new bitcoin filteradd message that conforms to the
// Message interface. See MsgFilterAdd for details.
func NewMsgFilterAdd(data []byte) *MsgFilterAdd {
return &MsgFilterAdd{
Data: data,
}
}

59
vendor/github.com/btcsuite/btcd/wire/msgfilterclear.go generated vendored Normal file
View File

@ -0,0 +1,59 @@
// Copyright (c) 2014-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MsgFilterClear implements the Message interface and represents a bitcoin
// filterclear message which is used to reset a Bloom filter.
//
// This message was not added until protocol version BIP0037Version and has
// no payload.
type MsgFilterClear struct{}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgFilterClear) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("filterclear message invalid for protocol "+
"version %d", pver)
return messageError("MsgFilterClear.BtcDecode", str)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgFilterClear) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("filterclear message invalid for protocol "+
"version %d", pver)
return messageError("MsgFilterClear.BtcEncode", str)
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgFilterClear) Command() string {
return CmdFilterClear
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgFilterClear) MaxPayloadLength(pver uint32) uint32 {
return 0
}
// NewMsgFilterClear returns a new bitcoin filterclear message that conforms to the Message
// interface. See MsgFilterClear for details.
func NewMsgFilterClear() *MsgFilterClear {
return &MsgFilterClear{}
}

136
vendor/github.com/btcsuite/btcd/wire/msgfilterload.go generated vendored Normal file
View File

@ -0,0 +1,136 @@
// Copyright (c) 2014-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// BloomUpdateType specifies how the filter is updated when a match is found
type BloomUpdateType uint8
const (
// BloomUpdateNone indicates the filter is not adjusted when a match is
// found.
BloomUpdateNone BloomUpdateType = 0
// BloomUpdateAll indicates if the filter matches any data element in a
// public key script, the outpoint is serialized and inserted into the
// filter.
BloomUpdateAll BloomUpdateType = 1
// BloomUpdateP2PubkeyOnly indicates if the filter matches a data
// element in a public key script and the script is of the standard
// pay-to-pubkey or multisig, the outpoint is serialized and inserted
// into the filter.
BloomUpdateP2PubkeyOnly BloomUpdateType = 2
)
const (
// MaxFilterLoadHashFuncs is the maximum number of hash functions to
// load into the Bloom filter.
MaxFilterLoadHashFuncs = 50
// MaxFilterLoadFilterSize is the maximum size in bytes a filter may be.
MaxFilterLoadFilterSize = 36000
)
// MsgFilterLoad implements the Message interface and represents a bitcoin
// filterload message which is used to reset a Bloom filter.
//
// This message was not added until protocol version BIP0037Version.
type MsgFilterLoad struct {
Filter []byte
HashFuncs uint32
Tweak uint32
Flags BloomUpdateType
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgFilterLoad) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("filterload message invalid for protocol "+
"version %d", pver)
return messageError("MsgFilterLoad.BtcDecode", str)
}
var err error
msg.Filter, err = ReadVarBytes(r, pver, MaxFilterLoadFilterSize,
"filterload filter size")
if err != nil {
return err
}
err = readElements(r, &msg.HashFuncs, &msg.Tweak, &msg.Flags)
if err != nil {
return err
}
if msg.HashFuncs > MaxFilterLoadHashFuncs {
str := fmt.Sprintf("too many filter hash functions for message "+
"[count %v, max %v]", msg.HashFuncs, MaxFilterLoadHashFuncs)
return messageError("MsgFilterLoad.BtcDecode", str)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgFilterLoad) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("filterload message invalid for protocol "+
"version %d", pver)
return messageError("MsgFilterLoad.BtcEncode", str)
}
size := len(msg.Filter)
if size > MaxFilterLoadFilterSize {
str := fmt.Sprintf("filterload filter size too large for message "+
"[size %v, max %v]", size, MaxFilterLoadFilterSize)
return messageError("MsgFilterLoad.BtcEncode", str)
}
if msg.HashFuncs > MaxFilterLoadHashFuncs {
str := fmt.Sprintf("too many filter hash functions for message "+
"[count %v, max %v]", msg.HashFuncs, MaxFilterLoadHashFuncs)
return messageError("MsgFilterLoad.BtcEncode", str)
}
err := WriteVarBytes(w, pver, msg.Filter)
if err != nil {
return err
}
return writeElements(w, msg.HashFuncs, msg.Tweak, msg.Flags)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgFilterLoad) Command() string {
return CmdFilterLoad
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgFilterLoad) MaxPayloadLength(pver uint32) uint32 {
// Num filter bytes (varInt) + filter + 4 bytes hash funcs +
// 4 bytes tweak + 1 byte flags.
return uint32(VarIntSerializeSize(MaxFilterLoadFilterSize)) +
MaxFilterLoadFilterSize + 9
}
// NewMsgFilterLoad returns a new bitcoin filterload message that conforms to
// the Message interface. See MsgFilterLoad for details.
func NewMsgFilterLoad(filter []byte, hashFuncs uint32, tweak uint32, flags BloomUpdateType) *MsgFilterLoad {
return &MsgFilterLoad{
Filter: filter,
HashFuncs: hashFuncs,
Tweak: tweak,
Flags: flags,
}
}

47
vendor/github.com/btcsuite/btcd/wire/msggetaddr.go generated vendored Normal file
View File

@ -0,0 +1,47 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"io"
)
// MsgGetAddr implements the Message interface and represents a bitcoin
// getaddr message. It is used to request a list of known active peers on the
// network from a peer to help identify potential nodes. The list is returned
// via one or more addr messages (MsgAddr).
//
// This message has no payload.
type MsgGetAddr struct{}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetAddr) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetAddr) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetAddr) Command() string {
return CmdGetAddr
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetAddr) MaxPayloadLength(pver uint32) uint32 {
return 0
}
// NewMsgGetAddr returns a new bitcoin getaddr message that conforms to the
// Message interface. See MsgGetAddr for details.
func NewMsgGetAddr() *MsgGetAddr {
return &MsgGetAddr{}
}

139
vendor/github.com/btcsuite/btcd/wire/msggetblocks.go generated vendored Normal file
View File

@ -0,0 +1,139 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// MaxBlockLocatorsPerMsg is the maximum number of block locator hashes allowed
// per message.
const MaxBlockLocatorsPerMsg = 500
// MsgGetBlocks implements the Message interface and represents a bitcoin
// getblocks message. It is used to request a list of blocks starting after the
// last known hash in the slice of block locator hashes. The list is returned
// via an inv message (MsgInv) and is limited by a specific hash to stop at or
// the maximum number of blocks per message, which is currently 500.
//
// Set the HashStop field to the hash at which to stop and use
// AddBlockLocatorHash to build up the list of block locator hashes.
//
// The algorithm for building the block locator hashes should be to add the
// hashes in reverse order until you reach the genesis block. In order to keep
// the list of locator hashes to a reasonable number of entries, first add the
// most recent 10 block hashes, then double the step each loop iteration to
// exponentially decrease the number of hashes the further away from head and
// closer to the genesis block you get.
type MsgGetBlocks struct {
ProtocolVersion uint32
BlockLocatorHashes []*chainhash.Hash
HashStop chainhash.Hash
}
// AddBlockLocatorHash adds a new block locator hash to the message.
func (msg *MsgGetBlocks) AddBlockLocatorHash(hash *chainhash.Hash) error {
if len(msg.BlockLocatorHashes)+1 > MaxBlockLocatorsPerMsg {
str := fmt.Sprintf("too many block locator hashes for message [max %v]",
MaxBlockLocatorsPerMsg)
return messageError("MsgGetBlocks.AddBlockLocatorHash", str)
}
msg.BlockLocatorHashes = append(msg.BlockLocatorHashes, hash)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetBlocks) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
err := readElement(r, &msg.ProtocolVersion)
if err != nil {
return err
}
// Read num block locator hashes and limit to max.
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
if count > MaxBlockLocatorsPerMsg {
str := fmt.Sprintf("too many block locator hashes for message "+
"[count %v, max %v]", count, MaxBlockLocatorsPerMsg)
return messageError("MsgGetBlocks.BtcDecode", str)
}
// Create a contiguous slice of hashes to deserialize into in order to
// reduce the number of allocations.
locatorHashes := make([]chainhash.Hash, count)
msg.BlockLocatorHashes = make([]*chainhash.Hash, 0, count)
for i := uint64(0); i < count; i++ {
hash := &locatorHashes[i]
err := readElement(r, hash)
if err != nil {
return err
}
msg.AddBlockLocatorHash(hash)
}
return readElement(r, &msg.HashStop)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetBlocks) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
count := len(msg.BlockLocatorHashes)
if count > MaxBlockLocatorsPerMsg {
str := fmt.Sprintf("too many block locator hashes for message "+
"[count %v, max %v]", count, MaxBlockLocatorsPerMsg)
return messageError("MsgGetBlocks.BtcEncode", str)
}
err := writeElement(w, msg.ProtocolVersion)
if err != nil {
return err
}
err = WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, hash := range msg.BlockLocatorHashes {
err = writeElement(w, hash)
if err != nil {
return err
}
}
return writeElement(w, &msg.HashStop)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetBlocks) Command() string {
return CmdGetBlocks
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetBlocks) MaxPayloadLength(pver uint32) uint32 {
// Protocol version 4 bytes + num hashes (varInt) + max block locator
// hashes + hash stop.
return 4 + MaxVarIntPayload + (MaxBlockLocatorsPerMsg * chainhash.HashSize) + chainhash.HashSize
}
// NewMsgGetBlocks returns a new bitcoin getblocks message that conforms to the
// Message interface using the passed parameters and defaults for the remaining
// fields.
func NewMsgGetBlocks(hashStop *chainhash.Hash) *MsgGetBlocks {
return &MsgGetBlocks{
ProtocolVersion: ProtocolVersion,
BlockLocatorHashes: make([]*chainhash.Hash, 0, MaxBlockLocatorsPerMsg),
HashStop: *hashStop,
}
}

View File

@ -0,0 +1,64 @@
// Copyright (c) 2018 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// MsgGetCFCheckpt is a request for filter headers at evenly spaced intervals
// throughout the blockchain history. It allows to set the FilterType field to
// get headers in the chain of basic (0x00) or extended (0x01) headers.
type MsgGetCFCheckpt struct {
FilterType FilterType
StopHash chainhash.Hash
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
err := readElement(r, &msg.FilterType)
if err != nil {
return err
}
return readElement(r, &msg.StopHash)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetCFCheckpt) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
err := writeElement(w, msg.FilterType)
if err != nil {
return err
}
return writeElement(w, &msg.StopHash)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetCFCheckpt) Command() string {
return CmdGetCFCheckpt
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetCFCheckpt) MaxPayloadLength(pver uint32) uint32 {
// Filter type + uint32 + block hash
return 1 + chainhash.HashSize
}
// NewMsgGetCFCheckpt returns a new bitcoin getcfcheckpt message that conforms
// to the Message interface using the passed parameters and defaults for the
// remaining fields.
func NewMsgGetCFCheckpt(filterType FilterType, stopHash *chainhash.Hash) *MsgGetCFCheckpt {
return &MsgGetCFCheckpt{
FilterType: filterType,
StopHash: *stopHash,
}
}

View File

@ -0,0 +1,77 @@
// Copyright (c) 2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// MsgGetCFHeaders is a message similar to MsgGetHeaders, but for committed
// filter headers. It allows to set the FilterType field to get headers in the
// chain of basic (0x00) or extended (0x01) headers.
type MsgGetCFHeaders struct {
FilterType FilterType
StartHeight uint32
StopHash chainhash.Hash
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
err := readElement(r, &msg.FilterType)
if err != nil {
return err
}
err = readElement(r, &msg.StartHeight)
if err != nil {
return err
}
return readElement(r, &msg.StopHash)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetCFHeaders) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
err := writeElement(w, msg.FilterType)
if err != nil {
return err
}
err = writeElement(w, &msg.StartHeight)
if err != nil {
return err
}
return writeElement(w, &msg.StopHash)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetCFHeaders) Command() string {
return CmdGetCFHeaders
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetCFHeaders) MaxPayloadLength(pver uint32) uint32 {
// Filter type + uint32 + block hash
return 1 + 4 + chainhash.HashSize
}
// NewMsgGetCFHeaders returns a new bitcoin getcfheader message that conforms to
// the Message interface using the passed parameters and defaults for the
// remaining fields.
func NewMsgGetCFHeaders(filterType FilterType, startHeight uint32,
stopHash *chainhash.Hash) *MsgGetCFHeaders {
return &MsgGetCFHeaders{
FilterType: filterType,
StartHeight: startHeight,
StopHash: *stopHash,
}
}

81
vendor/github.com/btcsuite/btcd/wire/msggetcfilters.go generated vendored Normal file
View File

@ -0,0 +1,81 @@
// Copyright (c) 2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// MaxGetCFiltersReqRange the maximum number of filters that may be requested in
// a getcfheaders message.
const MaxGetCFiltersReqRange = 1000
// MsgGetCFilters implements the Message interface and represents a bitcoin
// getcfilters message. It is used to request committed filters for a range of
// blocks.
type MsgGetCFilters struct {
FilterType FilterType
StartHeight uint32
StopHash chainhash.Hash
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
err := readElement(r, &msg.FilterType)
if err != nil {
return err
}
err = readElement(r, &msg.StartHeight)
if err != nil {
return err
}
return readElement(r, &msg.StopHash)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetCFilters) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
err := writeElement(w, msg.FilterType)
if err != nil {
return err
}
err = writeElement(w, &msg.StartHeight)
if err != nil {
return err
}
return writeElement(w, &msg.StopHash)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetCFilters) Command() string {
return CmdGetCFilters
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetCFilters) MaxPayloadLength(pver uint32) uint32 {
// Filter type + uint32 + block hash
return 1 + 4 + chainhash.HashSize
}
// NewMsgGetCFilters returns a new bitcoin getcfilters message that conforms to
// the Message interface using the passed parameters and defaults for the
// remaining fields.
func NewMsgGetCFilters(filterType FilterType, startHeight uint32,
stopHash *chainhash.Hash) *MsgGetCFilters {
return &MsgGetCFilters{
FilterType: filterType,
StartHeight: startHeight,
StopHash: *stopHash,
}
}

133
vendor/github.com/btcsuite/btcd/wire/msggetdata.go generated vendored Normal file
View File

@ -0,0 +1,133 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MsgGetData implements the Message interface and represents a bitcoin
// getdata message. It is used to request data such as blocks and transactions
// from another peer. It should be used in response to the inv (MsgInv) message
// to request the actual data referenced by each inventory vector the receiving
// peer doesn't already have. Each message is limited to a maximum number of
// inventory vectors, which is currently 50,000. As a result, multiple messages
// must be used to request larger amounts of data.
//
// Use the AddInvVect function to build up the list of inventory vectors when
// sending a getdata message to another peer.
type MsgGetData struct {
InvList []*InvVect
}
// AddInvVect adds an inventory vector to the message.
func (msg *MsgGetData) AddInvVect(iv *InvVect) error {
if len(msg.InvList)+1 > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [max %v]",
MaxInvPerMsg)
return messageError("MsgGetData.AddInvVect", str)
}
msg.InvList = append(msg.InvList, iv)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetData) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Limit to max inventory vectors per message.
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgGetData.BtcDecode", str)
}
// Create a contiguous slice of inventory vectors to deserialize into in
// order to reduce the number of allocations.
invList := make([]InvVect, count)
msg.InvList = make([]*InvVect, 0, count)
for i := uint64(0); i < count; i++ {
iv := &invList[i]
err := readInvVect(r, pver, iv)
if err != nil {
return err
}
msg.AddInvVect(iv)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetData) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// Limit to max inventory vectors per message.
count := len(msg.InvList)
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgGetData.BtcEncode", str)
}
err := WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, iv := range msg.InvList {
err := writeInvVect(w, pver, iv)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetData) Command() string {
return CmdGetData
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetData) MaxPayloadLength(pver uint32) uint32 {
// Num inventory vectors (varInt) + max allowed inventory vectors.
return MaxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload)
}
// NewMsgGetData returns a new bitcoin getdata message that conforms to the
// Message interface. See MsgGetData for details.
func NewMsgGetData() *MsgGetData {
return &MsgGetData{
InvList: make([]*InvVect, 0, defaultInvListAlloc),
}
}
// NewMsgGetDataSizeHint returns a new bitcoin getdata message that conforms to
// the Message interface. See MsgGetData for details. This function differs
// from NewMsgGetData in that it allows a default allocation size for the
// backing array which houses the inventory vector list. This allows callers
// who know in advance how large the inventory list will grow to avoid the
// overhead of growing the internal backing array several times when appending
// large amounts of inventory vectors with AddInvVect. Note that the specified
// hint is just that - a hint that is used for the default allocation size.
// Adding more (or less) inventory vectors will still work properly. The size
// hint is limited to MaxInvPerMsg.
func NewMsgGetDataSizeHint(sizeHint uint) *MsgGetData {
// Limit the specified hint to the maximum allow per message.
if sizeHint > MaxInvPerMsg {
sizeHint = MaxInvPerMsg
}
return &MsgGetData{
InvList: make([]*InvVect, 0, sizeHint),
}
}

136
vendor/github.com/btcsuite/btcd/wire/msggetheaders.go generated vendored Normal file
View File

@ -0,0 +1,136 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// MsgGetHeaders implements the Message interface and represents a bitcoin
// getheaders message. It is used to request a list of block headers for
// blocks starting after the last known hash in the slice of block locator
// hashes. The list is returned via a headers message (MsgHeaders) and is
// limited by a specific hash to stop at or the maximum number of block headers
// per message, which is currently 2000.
//
// Set the HashStop field to the hash at which to stop and use
// AddBlockLocatorHash to build up the list of block locator hashes.
//
// The algorithm for building the block locator hashes should be to add the
// hashes in reverse order until you reach the genesis block. In order to keep
// the list of locator hashes to a resonable number of entries, first add the
// most recent 10 block hashes, then double the step each loop iteration to
// exponentially decrease the number of hashes the further away from head and
// closer to the genesis block you get.
type MsgGetHeaders struct {
ProtocolVersion uint32
BlockLocatorHashes []*chainhash.Hash
HashStop chainhash.Hash
}
// AddBlockLocatorHash adds a new block locator hash to the message.
func (msg *MsgGetHeaders) AddBlockLocatorHash(hash *chainhash.Hash) error {
if len(msg.BlockLocatorHashes)+1 > MaxBlockLocatorsPerMsg {
str := fmt.Sprintf("too many block locator hashes for message [max %v]",
MaxBlockLocatorsPerMsg)
return messageError("MsgGetHeaders.AddBlockLocatorHash", str)
}
msg.BlockLocatorHashes = append(msg.BlockLocatorHashes, hash)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgGetHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
err := readElement(r, &msg.ProtocolVersion)
if err != nil {
return err
}
// Read num block locator hashes and limit to max.
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
if count > MaxBlockLocatorsPerMsg {
str := fmt.Sprintf("too many block locator hashes for message "+
"[count %v, max %v]", count, MaxBlockLocatorsPerMsg)
return messageError("MsgGetHeaders.BtcDecode", str)
}
// Create a contiguous slice of hashes to deserialize into in order to
// reduce the number of allocations.
locatorHashes := make([]chainhash.Hash, count)
msg.BlockLocatorHashes = make([]*chainhash.Hash, 0, count)
for i := uint64(0); i < count; i++ {
hash := &locatorHashes[i]
err := readElement(r, hash)
if err != nil {
return err
}
msg.AddBlockLocatorHash(hash)
}
return readElement(r, &msg.HashStop)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgGetHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// Limit to max block locator hashes per message.
count := len(msg.BlockLocatorHashes)
if count > MaxBlockLocatorsPerMsg {
str := fmt.Sprintf("too many block locator hashes for message "+
"[count %v, max %v]", count, MaxBlockLocatorsPerMsg)
return messageError("MsgGetHeaders.BtcEncode", str)
}
err := writeElement(w, msg.ProtocolVersion)
if err != nil {
return err
}
err = WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, hash := range msg.BlockLocatorHashes {
err := writeElement(w, hash)
if err != nil {
return err
}
}
return writeElement(w, &msg.HashStop)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgGetHeaders) Command() string {
return CmdGetHeaders
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgGetHeaders) MaxPayloadLength(pver uint32) uint32 {
// Version 4 bytes + num block locator hashes (varInt) + max allowed block
// locators + hash stop.
return 4 + MaxVarIntPayload + (MaxBlockLocatorsPerMsg *
chainhash.HashSize) + chainhash.HashSize
}
// NewMsgGetHeaders returns a new bitcoin getheaders message that conforms to
// the Message interface. See MsgGetHeaders for details.
func NewMsgGetHeaders() *MsgGetHeaders {
return &MsgGetHeaders{
BlockLocatorHashes: make([]*chainhash.Hash, 0,
MaxBlockLocatorsPerMsg),
}
}

136
vendor/github.com/btcsuite/btcd/wire/msgheaders.go generated vendored Normal file
View File

@ -0,0 +1,136 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MaxBlockHeadersPerMsg is the maximum number of block headers that can be in
// a single bitcoin headers message.
const MaxBlockHeadersPerMsg = 2000
// MsgHeaders implements the Message interface and represents a bitcoin headers
// message. It is used to deliver block header information in response
// to a getheaders message (MsgGetHeaders). The maximum number of block headers
// per message is currently 2000. See MsgGetHeaders for details on requesting
// the headers.
type MsgHeaders struct {
Headers []*BlockHeader
}
// AddBlockHeader adds a new block header to the message.
func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error {
if len(msg.Headers)+1 > MaxBlockHeadersPerMsg {
str := fmt.Sprintf("too many block headers in message [max %v]",
MaxBlockHeadersPerMsg)
return messageError("MsgHeaders.AddBlockHeader", str)
}
msg.Headers = append(msg.Headers, bh)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Limit to max block headers per message.
if count > MaxBlockHeadersPerMsg {
str := fmt.Sprintf("too many block headers for message "+
"[count %v, max %v]", count, MaxBlockHeadersPerMsg)
return messageError("MsgHeaders.BtcDecode", str)
}
// Create a contiguous slice of headers to deserialize into in order to
// reduce the number of allocations.
headers := make([]BlockHeader, count)
msg.Headers = make([]*BlockHeader, 0, count)
for i := uint64(0); i < count; i++ {
bh := &headers[i]
err := readBlockHeader(r, pver, bh)
if err != nil {
return err
}
txCount, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Ensure the transaction count is zero for headers.
if txCount > 0 {
str := fmt.Sprintf("block headers may not contain "+
"transactions [count %v]", txCount)
return messageError("MsgHeaders.BtcDecode", str)
}
msg.AddBlockHeader(bh)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// Limit to max block headers per message.
count := len(msg.Headers)
if count > MaxBlockHeadersPerMsg {
str := fmt.Sprintf("too many block headers for message "+
"[count %v, max %v]", count, MaxBlockHeadersPerMsg)
return messageError("MsgHeaders.BtcEncode", str)
}
err := WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, bh := range msg.Headers {
err := writeBlockHeader(w, pver, bh)
if err != nil {
return err
}
// The wire protocol encoding always includes a 0 for the number
// of transactions on header messages. This is really just an
// artifact of the way the original implementation serializes
// block headers, but it is required.
err = WriteVarInt(w, pver, 0)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgHeaders) Command() string {
return CmdHeaders
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgHeaders) MaxPayloadLength(pver uint32) uint32 {
// Num headers (varInt) + max allowed headers (header length + 1 byte
// for the number of transactions which is always 0).
return MaxVarIntPayload + ((MaxBlockHeaderPayload + 1) *
MaxBlockHeadersPerMsg)
}
// NewMsgHeaders returns a new bitcoin headers message that conforms to the
// Message interface. See MsgHeaders for details.
func NewMsgHeaders() *MsgHeaders {
return &MsgHeaders{
Headers: make([]*BlockHeader, 0, MaxBlockHeadersPerMsg),
}
}

141
vendor/github.com/btcsuite/btcd/wire/msginv.go generated vendored Normal file
View File

@ -0,0 +1,141 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// defaultInvListAlloc is the default size used for the backing array for an
// inventory list. The array will dynamically grow as needed, but this
// figure is intended to provide enough space for the max number of inventory
// vectors in a *typical* inventory message without needing to grow the backing
// array multiple times. Technically, the list can grow to MaxInvPerMsg, but
// rather than using that large figure, this figure more accurately reflects the
// typical case.
const defaultInvListAlloc = 1000
// MsgInv implements the Message interface and represents a bitcoin inv message.
// It is used to advertise a peer's known data such as blocks and transactions
// through inventory vectors. It may be sent unsolicited to inform other peers
// of the data or in response to a getblocks message (MsgGetBlocks). Each
// message is limited to a maximum number of inventory vectors, which is
// currently 50,000.
//
// Use the AddInvVect function to build up the list of inventory vectors when
// sending an inv message to another peer.
type MsgInv struct {
InvList []*InvVect
}
// AddInvVect adds an inventory vector to the message.
func (msg *MsgInv) AddInvVect(iv *InvVect) error {
if len(msg.InvList)+1 > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [max %v]",
MaxInvPerMsg)
return messageError("MsgInv.AddInvVect", str)
}
msg.InvList = append(msg.InvList, iv)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Limit to max inventory vectors per message.
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgInv.BtcDecode", str)
}
// Create a contiguous slice of inventory vectors to deserialize into in
// order to reduce the number of allocations.
invList := make([]InvVect, count)
msg.InvList = make([]*InvVect, 0, count)
for i := uint64(0); i < count; i++ {
iv := &invList[i]
err := readInvVect(r, pver, iv)
if err != nil {
return err
}
msg.AddInvVect(iv)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// Limit to max inventory vectors per message.
count := len(msg.InvList)
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgInv.BtcEncode", str)
}
err := WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, iv := range msg.InvList {
err := writeInvVect(w, pver, iv)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgInv) Command() string {
return CmdInv
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgInv) MaxPayloadLength(pver uint32) uint32 {
// Num inventory vectors (varInt) + max allowed inventory vectors.
return MaxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload)
}
// NewMsgInv returns a new bitcoin inv message that conforms to the Message
// interface. See MsgInv for details.
func NewMsgInv() *MsgInv {
return &MsgInv{
InvList: make([]*InvVect, 0, defaultInvListAlloc),
}
}
// NewMsgInvSizeHint returns a new bitcoin inv message that conforms to the
// Message interface. See MsgInv for details. This function differs from
// NewMsgInv in that it allows a default allocation size for the backing array
// which houses the inventory vector list. This allows callers who know in
// advance how large the inventory list will grow to avoid the overhead of
// growing the internal backing array several times when appending large amounts
// of inventory vectors with AddInvVect. Note that the specified hint is just
// that - a hint that is used for the default allocation size. Adding more
// (or less) inventory vectors will still work properly. The size hint is
// limited to MaxInvPerMsg.
func NewMsgInvSizeHint(sizeHint uint) *MsgInv {
// Limit the specified hint to the maximum allow per message.
if sizeHint > MaxInvPerMsg {
sizeHint = MaxInvPerMsg
}
return &MsgInv{
InvList: make([]*InvVect, 0, sizeHint),
}
}

60
vendor/github.com/btcsuite/btcd/wire/msgmempool.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MsgMemPool implements the Message interface and represents a bitcoin mempool
// message. It is used to request a list of transactions still in the active
// memory pool of a relay.
//
// This message has no payload and was not added until protocol versions
// starting with BIP0035Version.
type MsgMemPool struct{}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgMemPool) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < BIP0035Version {
str := fmt.Sprintf("mempool message invalid for protocol "+
"version %d", pver)
return messageError("MsgMemPool.BtcDecode", str)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgMemPool) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < BIP0035Version {
str := fmt.Sprintf("mempool message invalid for protocol "+
"version %d", pver)
return messageError("MsgMemPool.BtcEncode", str)
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgMemPool) Command() string {
return CmdMemPool
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgMemPool) MaxPayloadLength(pver uint32) uint32 {
return 0
}
// NewMsgMemPool returns a new bitcoin pong message that conforms to the Message
// interface. See MsgPong for details.
func NewMsgMemPool() *MsgMemPool {
return &MsgMemPool{}
}

159
vendor/github.com/btcsuite/btcd/wire/msgmerkleblock.go generated vendored Normal file
View File

@ -0,0 +1,159 @@
// Copyright (c) 2014-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// maxFlagsPerMerkleBlock is the maximum number of flag bytes that could
// possibly fit into a merkle block. Since each transaction is represented by
// a single bit, this is the max number of transactions per block divided by
// 8 bits per byte. Then an extra one to cover partials.
const maxFlagsPerMerkleBlock = maxTxPerBlock / 8
// MsgMerkleBlock implements the Message interface and represents a bitcoin
// merkleblock message which is used to reset a Bloom filter.
//
// This message was not added until protocol version BIP0037Version.
type MsgMerkleBlock struct {
Header BlockHeader
Transactions uint32
Hashes []*chainhash.Hash
Flags []byte
}
// AddTxHash adds a new transaction hash to the message.
func (msg *MsgMerkleBlock) AddTxHash(hash *chainhash.Hash) error {
if len(msg.Hashes)+1 > maxTxPerBlock {
str := fmt.Sprintf("too many tx hashes for message [max %v]",
maxTxPerBlock)
return messageError("MsgMerkleBlock.AddTxHash", str)
}
msg.Hashes = append(msg.Hashes, hash)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgMerkleBlock) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("merkleblock message invalid for protocol "+
"version %d", pver)
return messageError("MsgMerkleBlock.BtcDecode", str)
}
err := readBlockHeader(r, pver, &msg.Header)
if err != nil {
return err
}
err = readElement(r, &msg.Transactions)
if err != nil {
return err
}
// Read num block locator hashes and limit to max.
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
if count > maxTxPerBlock {
str := fmt.Sprintf("too many transaction hashes for message "+
"[count %v, max %v]", count, maxTxPerBlock)
return messageError("MsgMerkleBlock.BtcDecode", str)
}
// Create a contiguous slice of hashes to deserialize into in order to
// reduce the number of allocations.
hashes := make([]chainhash.Hash, count)
msg.Hashes = make([]*chainhash.Hash, 0, count)
for i := uint64(0); i < count; i++ {
hash := &hashes[i]
err := readElement(r, hash)
if err != nil {
return err
}
msg.AddTxHash(hash)
}
msg.Flags, err = ReadVarBytes(r, pver, maxFlagsPerMerkleBlock,
"merkle block flags size")
return err
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgMerkleBlock) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < BIP0037Version {
str := fmt.Sprintf("merkleblock message invalid for protocol "+
"version %d", pver)
return messageError("MsgMerkleBlock.BtcEncode", str)
}
// Read num transaction hashes and limit to max.
numHashes := len(msg.Hashes)
if numHashes > maxTxPerBlock {
str := fmt.Sprintf("too many transaction hashes for message "+
"[count %v, max %v]", numHashes, maxTxPerBlock)
return messageError("MsgMerkleBlock.BtcDecode", str)
}
numFlagBytes := len(msg.Flags)
if numFlagBytes > maxFlagsPerMerkleBlock {
str := fmt.Sprintf("too many flag bytes for message [count %v, "+
"max %v]", numFlagBytes, maxFlagsPerMerkleBlock)
return messageError("MsgMerkleBlock.BtcDecode", str)
}
err := writeBlockHeader(w, pver, &msg.Header)
if err != nil {
return err
}
err = writeElement(w, msg.Transactions)
if err != nil {
return err
}
err = WriteVarInt(w, pver, uint64(numHashes))
if err != nil {
return err
}
for _, hash := range msg.Hashes {
err = writeElement(w, hash)
if err != nil {
return err
}
}
return WriteVarBytes(w, pver, msg.Flags)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgMerkleBlock) Command() string {
return CmdMerkleBlock
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgMerkleBlock) MaxPayloadLength(pver uint32) uint32 {
return MaxBlockPayload
}
// NewMsgMerkleBlock returns a new bitcoin merkleblock message that conforms to
// the Message interface. See MsgMerkleBlock for details.
func NewMsgMerkleBlock(bh *BlockHeader) *MsgMerkleBlock {
return &MsgMerkleBlock{
Header: *bh,
Transactions: 0,
Hashes: make([]*chainhash.Hash, 0),
Flags: make([]byte, 0),
}
}

110
vendor/github.com/btcsuite/btcd/wire/msgnotfound.go generated vendored Normal file
View File

@ -0,0 +1,110 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MsgNotFound defines a bitcoin notfound message which is sent in response to
// a getdata message if any of the requested data in not available on the peer.
// Each message is limited to a maximum number of inventory vectors, which is
// currently 50,000.
//
// Use the AddInvVect function to build up the list of inventory vectors when
// sending a notfound message to another peer.
type MsgNotFound struct {
InvList []*InvVect
}
// AddInvVect adds an inventory vector to the message.
func (msg *MsgNotFound) AddInvVect(iv *InvVect) error {
if len(msg.InvList)+1 > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [max %v]",
MaxInvPerMsg)
return messageError("MsgNotFound.AddInvVect", str)
}
msg.InvList = append(msg.InvList, iv)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
count, err := ReadVarInt(r, pver)
if err != nil {
return err
}
// Limit to max inventory vectors per message.
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgNotFound.BtcDecode", str)
}
// Create a contiguous slice of inventory vectors to deserialize into in
// order to reduce the number of allocations.
invList := make([]InvVect, count)
msg.InvList = make([]*InvVect, 0, count)
for i := uint64(0); i < count; i++ {
iv := &invList[i]
err := readInvVect(r, pver, iv)
if err != nil {
return err
}
msg.AddInvVect(iv)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// Limit to max inventory vectors per message.
count := len(msg.InvList)
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgNotFound.BtcEncode", str)
}
err := WriteVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, iv := range msg.InvList {
err := writeInvVect(w, pver, iv)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgNotFound) Command() string {
return CmdNotFound
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgNotFound) MaxPayloadLength(pver uint32) uint32 {
// Max var int 9 bytes + max InvVects at 36 bytes each.
// Num inventory vectors (varInt) + max allowed inventory vectors.
return MaxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload)
}
// NewMsgNotFound returns a new bitcoin notfound message that conforms to the
// Message interface. See MsgNotFound for details.
func NewMsgNotFound() *MsgNotFound {
return &MsgNotFound{
InvList: make([]*InvVect, 0, defaultInvListAlloc),
}
}

87
vendor/github.com/btcsuite/btcd/wire/msgping.go generated vendored Normal file
View File

@ -0,0 +1,87 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"io"
)
// MsgPing implements the Message interface and represents a bitcoin ping
// message.
//
// For versions BIP0031Version and earlier, it is used primarily to confirm
// that a connection is still valid. A transmission error is typically
// interpreted as a closed connection and that the peer should be removed.
// For versions AFTER BIP0031Version it contains an identifier which can be
// returned in the pong message to determine network timing.
//
// The payload for this message just consists of a nonce used for identifying
// it later.
type MsgPing struct {
// Unique value associated with message that is used to identify
// specific ping message.
Nonce uint64
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgPing) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
// There was no nonce for BIP0031Version and earlier.
// NOTE: > is not a mistake here. The BIP0031 was defined as AFTER
// the version unlike most others.
if pver > BIP0031Version {
err := readElement(r, &msg.Nonce)
if err != nil {
return err
}
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgPing) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// There was no nonce for BIP0031Version and earlier.
// NOTE: > is not a mistake here. The BIP0031 was defined as AFTER
// the version unlike most others.
if pver > BIP0031Version {
err := writeElement(w, msg.Nonce)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgPing) Command() string {
return CmdPing
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgPing) MaxPayloadLength(pver uint32) uint32 {
plen := uint32(0)
// There was no nonce for BIP0031Version and earlier.
// NOTE: > is not a mistake here. The BIP0031 was defined as AFTER
// the version unlike most others.
if pver > BIP0031Version {
// Nonce 8 bytes.
plen += 8
}
return plen
}
// NewMsgPing returns a new bitcoin ping message that conforms to the Message
// interface. See MsgPing for details.
func NewMsgPing(nonce uint64) *MsgPing {
return &MsgPing{
Nonce: nonce,
}
}

78
vendor/github.com/btcsuite/btcd/wire/msgpong.go generated vendored Normal file
View File

@ -0,0 +1,78 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MsgPong implements the Message interface and represents a bitcoin pong
// message which is used primarily to confirm that a connection is still valid
// in response to a bitcoin ping message (MsgPing).
//
// This message was not added until protocol versions AFTER BIP0031Version.
type MsgPong struct {
// Unique value associated with message that is used to identify
// specific ping message.
Nonce uint64
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgPong) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
// NOTE: <= is not a mistake here. The BIP0031 was defined as AFTER
// the version unlike most others.
if pver <= BIP0031Version {
str := fmt.Sprintf("pong message invalid for protocol "+
"version %d", pver)
return messageError("MsgPong.BtcDecode", str)
}
return readElement(r, &msg.Nonce)
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgPong) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
// NOTE: <= is not a mistake here. The BIP0031 was defined as AFTER
// the version unlike most others.
if pver <= BIP0031Version {
str := fmt.Sprintf("pong message invalid for protocol "+
"version %d", pver)
return messageError("MsgPong.BtcEncode", str)
}
return writeElement(w, msg.Nonce)
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgPong) Command() string {
return CmdPong
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgPong) MaxPayloadLength(pver uint32) uint32 {
plen := uint32(0)
// The pong message did not exist for BIP0031Version and earlier.
// NOTE: > is not a mistake here. The BIP0031 was defined as AFTER
// the version unlike most others.
if pver > BIP0031Version {
// Nonce 8 bytes.
plen += 8
}
return plen
}
// NewMsgPong returns a new bitcoin pong message that conforms to the Message
// interface. See MsgPong for details.
func NewMsgPong(nonce uint64) *MsgPong {
return &MsgPong{
Nonce: nonce,
}
}

186
vendor/github.com/btcsuite/btcd/wire/msgreject.go generated vendored Normal file
View File

@ -0,0 +1,186 @@
// Copyright (c) 2014-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
// RejectCode represents a numeric value by which a remote peer indicates
// why a message was rejected.
type RejectCode uint8
// These constants define the various supported reject codes.
const (
RejectMalformed RejectCode = 0x01
RejectInvalid RejectCode = 0x10
RejectObsolete RejectCode = 0x11
RejectDuplicate RejectCode = 0x12
RejectNonstandard RejectCode = 0x40
RejectDust RejectCode = 0x41
RejectInsufficientFee RejectCode = 0x42
RejectCheckpoint RejectCode = 0x43
)
// Map of reject codes back strings for pretty printing.
var rejectCodeStrings = map[RejectCode]string{
RejectMalformed: "REJECT_MALFORMED",
RejectInvalid: "REJECT_INVALID",
RejectObsolete: "REJECT_OBSOLETE",
RejectDuplicate: "REJECT_DUPLICATE",
RejectNonstandard: "REJECT_NONSTANDARD",
RejectDust: "REJECT_DUST",
RejectInsufficientFee: "REJECT_INSUFFICIENTFEE",
RejectCheckpoint: "REJECT_CHECKPOINT",
}
// String returns the RejectCode in human-readable form.
func (code RejectCode) String() string {
if s, ok := rejectCodeStrings[code]; ok {
return s
}
return fmt.Sprintf("Unknown RejectCode (%d)", uint8(code))
}
// MsgReject implements the Message interface and represents a bitcoin reject
// message.
//
// This message was not added until protocol version RejectVersion.
type MsgReject struct {
// Cmd is the command for the message which was rejected such as
// as CmdBlock or CmdTx. This can be obtained from the Command function
// of a Message.
Cmd string
// RejectCode is a code indicating why the command was rejected. It
// is encoded as a uint8 on the wire.
Code RejectCode
// Reason is a human-readable string with specific details (over and
// above the reject code) about why the command was rejected.
Reason string
// Hash identifies a specific block or transaction that was rejected
// and therefore only applies the MsgBlock and MsgTx messages.
Hash chainhash.Hash
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgReject) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < RejectVersion {
str := fmt.Sprintf("reject message invalid for protocol "+
"version %d", pver)
return messageError("MsgReject.BtcDecode", str)
}
// Command that was rejected.
cmd, err := ReadVarString(r, pver)
if err != nil {
return err
}
msg.Cmd = cmd
// Code indicating why the command was rejected.
err = readElement(r, &msg.Code)
if err != nil {
return err
}
// Human readable string with specific details (over and above the
// reject code above) about why the command was rejected.
reason, err := ReadVarString(r, pver)
if err != nil {
return err
}
msg.Reason = reason
// CmdBlock and CmdTx messages have an additional hash field that
// identifies the specific block or transaction.
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
err := readElement(r, &msg.Hash)
if err != nil {
return err
}
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgReject) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < RejectVersion {
str := fmt.Sprintf("reject message invalid for protocol "+
"version %d", pver)
return messageError("MsgReject.BtcEncode", str)
}
// Command that was rejected.
err := WriteVarString(w, pver, msg.Cmd)
if err != nil {
return err
}
// Code indicating why the command was rejected.
err = writeElement(w, msg.Code)
if err != nil {
return err
}
// Human readable string with specific details (over and above the
// reject code above) about why the command was rejected.
err = WriteVarString(w, pver, msg.Reason)
if err != nil {
return err
}
// CmdBlock and CmdTx messages have an additional hash field that
// identifies the specific block or transaction.
if msg.Cmd == CmdBlock || msg.Cmd == CmdTx {
err := writeElement(w, &msg.Hash)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgReject) Command() string {
return CmdReject
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgReject) MaxPayloadLength(pver uint32) uint32 {
plen := uint32(0)
// The reject message did not exist before protocol version
// RejectVersion.
if pver >= RejectVersion {
// Unfortunately the bitcoin protocol does not enforce a sane
// limit on the length of the reason, so the max payload is the
// overall maximum message payload.
plen = MaxMessagePayload
}
return plen
}
// NewMsgReject returns a new bitcoin reject message that conforms to the
// Message interface. See MsgReject for details.
func NewMsgReject(command string, code RejectCode, reason string) *MsgReject {
return &MsgReject{
Cmd: command,
Code: code,
Reason: reason,
}
}

60
vendor/github.com/btcsuite/btcd/wire/msgsendheaders.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
// Copyright (c) 2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
)
// MsgSendHeaders implements the Message interface and represents a bitcoin
// sendheaders message. It is used to request the peer send block headers
// rather than inventory vectors.
//
// This message has no payload and was not added until protocol versions
// starting with SendHeadersVersion.
type MsgSendHeaders struct{}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgSendHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
if pver < SendHeadersVersion {
str := fmt.Sprintf("sendheaders message invalid for protocol "+
"version %d", pver)
return messageError("MsgSendHeaders.BtcDecode", str)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgSendHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
if pver < SendHeadersVersion {
str := fmt.Sprintf("sendheaders message invalid for protocol "+
"version %d", pver)
return messageError("MsgSendHeaders.BtcEncode", str)
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgSendHeaders) Command() string {
return CmdSendHeaders
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgSendHeaders) MaxPayloadLength(pver uint32) uint32 {
return 0
}
// NewMsgSendHeaders returns a new bitcoin sendheaders message that conforms to
// the Message interface. See MsgSendHeaders for details.
func NewMsgSendHeaders() *MsgSendHeaders {
return &MsgSendHeaders{}
}

1027
vendor/github.com/btcsuite/btcd/wire/msgtx.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

46
vendor/github.com/btcsuite/btcd/wire/msgverack.go generated vendored Normal file
View File

@ -0,0 +1,46 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"io"
)
// MsgVerAck defines a bitcoin verack message which is used for a peer to
// acknowledge a version message (MsgVersion) after it has used the information
// to negotiate parameters. It implements the Message interface.
//
// This message has no payload.
type MsgVerAck struct{}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgVerAck) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgVerAck) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgVerAck) Command() string {
return CmdVerAck
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgVerAck) MaxPayloadLength(pver uint32) uint32 {
return 0
}
// NewMsgVerAck returns a new bitcoin verack message that conforms to the
// Message interface.
func NewMsgVerAck() *MsgVerAck {
return &MsgVerAck{}
}

269
vendor/github.com/btcsuite/btcd/wire/msgversion.go generated vendored Normal file
View File

@ -0,0 +1,269 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"bytes"
"fmt"
"io"
"strings"
"time"
)
// MaxUserAgentLen is the maximum allowed length for the user agent field in a
// version message (MsgVersion).
const MaxUserAgentLen = 256
// DefaultUserAgent for wire in the stack
const DefaultUserAgent = "/btcwire:0.5.0/"
// MsgVersion implements the Message interface and represents a bitcoin version
// message. It is used for a peer to advertise itself as soon as an outbound
// connection is made. The remote peer then uses this information along with
// its own to negotiate. The remote peer must then respond with a version
// message of its own containing the negotiated values followed by a verack
// message (MsgVerAck). This exchange must take place before any further
// communication is allowed to proceed.
type MsgVersion struct {
// Version of the protocol the node is using.
ProtocolVersion int32
// Bitfield which identifies the enabled services.
Services ServiceFlag
// Time the message was generated. This is encoded as an int64 on the wire.
Timestamp time.Time
// Address of the remote peer.
AddrYou NetAddress
// Address of the local peer.
AddrMe NetAddress
// Unique value associated with message that is used to detect self
// connections.
Nonce uint64
// The user agent that generated messsage. This is a encoded as a varString
// on the wire. This has a max length of MaxUserAgentLen.
UserAgent string
// Last block seen by the generator of the version message.
LastBlock int32
// Don't announce transactions to peer.
DisableRelayTx bool
}
// HasService returns whether the specified service is supported by the peer
// that generated the message.
func (msg *MsgVersion) HasService(service ServiceFlag) bool {
return msg.Services&service == service
}
// AddService adds service as a supported service by the peer generating the
// message.
func (msg *MsgVersion) AddService(service ServiceFlag) {
msg.Services |= service
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// The version message is special in that the protocol version hasn't been
// negotiated yet. As a result, the pver field is ignored and any fields which
// are added in new versions are optional. This also mean that r must be a
// *bytes.Buffer so the number of remaining bytes can be ascertained.
//
// This is part of the Message interface implementation.
func (msg *MsgVersion) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
buf, ok := r.(*bytes.Buffer)
if !ok {
return fmt.Errorf("MsgVersion.BtcDecode reader is not a " +
"*bytes.Buffer")
}
err := readElements(buf, &msg.ProtocolVersion, &msg.Services,
(*int64Time)(&msg.Timestamp))
if err != nil {
return err
}
err = readNetAddress(buf, pver, &msg.AddrYou, false)
if err != nil {
return err
}
// Protocol versions >= 106 added a from address, nonce, and user agent
// field and they are only considered present if there are bytes
// remaining in the message.
if buf.Len() > 0 {
err = readNetAddress(buf, pver, &msg.AddrMe, false)
if err != nil {
return err
}
}
if buf.Len() > 0 {
err = readElement(buf, &msg.Nonce)
if err != nil {
return err
}
}
if buf.Len() > 0 {
userAgent, err := ReadVarString(buf, pver)
if err != nil {
return err
}
err = validateUserAgent(userAgent)
if err != nil {
return err
}
msg.UserAgent = userAgent
}
// Protocol versions >= 209 added a last known block field. It is only
// considered present if there are bytes remaining in the message.
if buf.Len() > 0 {
err = readElement(buf, &msg.LastBlock)
if err != nil {
return err
}
}
// There was no relay transactions field before BIP0037Version, but
// the default behavior prior to the addition of the field was to always
// relay transactions.
if buf.Len() > 0 {
// It's safe to ignore the error here since the buffer has at
// least one byte and that byte will result in a boolean value
// regardless of its value. Also, the wire encoding for the
// field is true when transactions should be relayed, so reverse
// it for the DisableRelayTx field.
var relayTx bool
readElement(r, &relayTx)
msg.DisableRelayTx = !relayTx
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgVersion) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
err := validateUserAgent(msg.UserAgent)
if err != nil {
return err
}
err = writeElements(w, msg.ProtocolVersion, msg.Services,
msg.Timestamp.Unix())
if err != nil {
return err
}
err = writeNetAddress(w, pver, &msg.AddrYou, false)
if err != nil {
return err
}
err = writeNetAddress(w, pver, &msg.AddrMe, false)
if err != nil {
return err
}
err = writeElement(w, msg.Nonce)
if err != nil {
return err
}
err = WriteVarString(w, pver, msg.UserAgent)
if err != nil {
return err
}
err = writeElement(w, msg.LastBlock)
if err != nil {
return err
}
// There was no relay transactions field before BIP0037Version. Also,
// the wire encoding for the field is true when transactions should be
// relayed, so reverse it from the DisableRelayTx field.
if pver >= BIP0037Version {
err = writeElement(w, !msg.DisableRelayTx)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgVersion) Command() string {
return CmdVersion
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgVersion) MaxPayloadLength(pver uint32) uint32 {
// XXX: <= 106 different
// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes +
// remote and local net addresses + nonce 8 bytes + length of user
// agent (varInt) + max allowed useragent length + last block 4 bytes +
// relay transactions flag 1 byte.
return 33 + (maxNetAddressPayload(pver) * 2) + MaxVarIntPayload +
MaxUserAgentLen
}
// NewMsgVersion returns a new bitcoin version message that conforms to the
// Message interface using the passed parameters and defaults for the remaining
// fields.
func NewMsgVersion(me *NetAddress, you *NetAddress, nonce uint64,
lastBlock int32) *MsgVersion {
// Limit the timestamp to one second precision since the protocol
// doesn't support better.
return &MsgVersion{
ProtocolVersion: int32(ProtocolVersion),
Services: 0,
Timestamp: time.Unix(time.Now().Unix(), 0),
AddrYou: *you,
AddrMe: *me,
Nonce: nonce,
UserAgent: DefaultUserAgent,
LastBlock: lastBlock,
DisableRelayTx: false,
}
}
// validateUserAgent checks userAgent length against MaxUserAgentLen
func validateUserAgent(userAgent string) error {
if len(userAgent) > MaxUserAgentLen {
str := fmt.Sprintf("user agent too long [len %v, max %v]",
len(userAgent), MaxUserAgentLen)
return messageError("MsgVersion", str)
}
return nil
}
// AddUserAgent adds a user agent to the user agent string for the version
// message. The version string is not defined to any strict format, although
// it is recommended to use the form "major.minor.revision" e.g. "2.6.41".
func (msg *MsgVersion) AddUserAgent(name string, version string,
comments ...string) error {
newUserAgent := fmt.Sprintf("%s:%s", name, version)
if len(comments) != 0 {
newUserAgent = fmt.Sprintf("%s(%s)", newUserAgent,
strings.Join(comments, "; "))
}
newUserAgent = fmt.Sprintf("%s%s/", msg.UserAgent, newUserAgent)
err := validateUserAgent(newUserAgent)
if err != nil {
return err
}
msg.UserAgent = newUserAgent
return nil
}

149
vendor/github.com/btcsuite/btcd/wire/netaddress.go generated vendored Normal file
View File

@ -0,0 +1,149 @@
// Copyright (c) 2013-2015 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"encoding/binary"
"io"
"net"
"time"
)
// maxNetAddressPayload returns the max payload size for a bitcoin NetAddress
// based on the protocol version.
func maxNetAddressPayload(pver uint32) uint32 {
// Services 8 bytes + ip 16 bytes + port 2 bytes.
plen := uint32(26)
// NetAddressTimeVersion added a timestamp field.
if pver >= NetAddressTimeVersion {
// Timestamp 4 bytes.
plen += 4
}
return plen
}
// NetAddress defines information about a peer on the network including the time
// it was last seen, the services it supports, its IP address, and port.
type NetAddress struct {
// Last time the address was seen. This is, unfortunately, encoded as a
// uint32 on the wire and therefore is limited to 2106. This field is
// not present in the bitcoin version message (MsgVersion) nor was it
// added until protocol version >= NetAddressTimeVersion.
Timestamp time.Time
// Bitfield which identifies the services supported by the address.
Services ServiceFlag
// IP address of the peer.
IP net.IP
// Port the peer is using. This is encoded in big endian on the wire
// which differs from most everything else.
Port uint16
}
// HasService returns whether the specified service is supported by the address.
func (na *NetAddress) HasService(service ServiceFlag) bool {
return na.Services&service == service
}
// AddService adds service as a supported service by the peer generating the
// message.
func (na *NetAddress) AddService(service ServiceFlag) {
na.Services |= service
}
// NewNetAddressIPPort returns a new NetAddress using the provided IP, port, and
// supported services with defaults for the remaining fields.
func NewNetAddressIPPort(ip net.IP, port uint16, services ServiceFlag) *NetAddress {
return NewNetAddressTimestamp(time.Now(), services, ip, port)
}
// NewNetAddressTimestamp returns a new NetAddress using the provided
// timestamp, IP, port, and supported services. The timestamp is rounded to
// single second precision.
func NewNetAddressTimestamp(
timestamp time.Time, services ServiceFlag, ip net.IP, port uint16) *NetAddress {
// Limit the timestamp to one second precision since the protocol
// doesn't support better.
na := NetAddress{
Timestamp: time.Unix(timestamp.Unix(), 0),
Services: services,
IP: ip,
Port: port,
}
return &na
}
// NewNetAddress returns a new NetAddress using the provided TCP address and
// supported services with defaults for the remaining fields.
func NewNetAddress(addr *net.TCPAddr, services ServiceFlag) *NetAddress {
return NewNetAddressIPPort(addr.IP, uint16(addr.Port), services)
}
// readNetAddress reads an encoded NetAddress from r depending on the protocol
// version and whether or not the timestamp is included per ts. Some messages
// like version do not include the timestamp.
func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
var ip [16]byte
// NOTE: The bitcoin protocol uses a uint32 for the timestamp so it will
// stop working somewhere around 2106. Also timestamp wasn't added until
// protocol version >= NetAddressTimeVersion
if ts && pver >= NetAddressTimeVersion {
err := readElement(r, (*uint32Time)(&na.Timestamp))
if err != nil {
return err
}
}
err := readElements(r, &na.Services, &ip)
if err != nil {
return err
}
// Sigh. Bitcoin protocol mixes little and big endian.
port, err := binarySerializer.Uint16(r, bigEndian)
if err != nil {
return err
}
*na = NetAddress{
Timestamp: na.Timestamp,
Services: na.Services,
IP: net.IP(ip[:]),
Port: port,
}
return nil
}
// writeNetAddress serializes a NetAddress to w depending on the protocol
// version and whether or not the timestamp is included per ts. Some messages
// like version do not include the timestamp.
func writeNetAddress(w io.Writer, pver uint32, na *NetAddress, ts bool) error {
// NOTE: The bitcoin protocol uses a uint32 for the timestamp so it will
// stop working somewhere around 2106. Also timestamp wasn't added until
// until protocol version >= NetAddressTimeVersion.
if ts && pver >= NetAddressTimeVersion {
err := writeElement(w, uint32(na.Timestamp.Unix()))
if err != nil {
return err
}
}
// Ensure to always write 16 bytes even if the ip is nil.
var ip [16]byte
if na.IP != nil {
copy(ip[:], na.IP.To16())
}
err := writeElements(w, na.Services, ip)
if err != nil {
return err
}
// Sigh. Bitcoin protocol mixes little and big endian.
return binary.Write(w, bigEndian, na.Port)
}

178
vendor/github.com/btcsuite/btcd/wire/protocol.go generated vendored Normal file
View File

@ -0,0 +1,178 @@
// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"strconv"
"strings"
)
// XXX pedro: we will probably need to bump this.
const (
// ProtocolVersion is the latest protocol version this package supports.
ProtocolVersion uint32 = 70013
// MultipleAddressVersion is the protocol version which added multiple
// addresses per message (pver >= MultipleAddressVersion).
MultipleAddressVersion uint32 = 209
// NetAddressTimeVersion is the protocol version which added the
// timestamp field (pver >= NetAddressTimeVersion).
NetAddressTimeVersion uint32 = 31402
// BIP0031Version is the protocol version AFTER which a pong message
// and nonce field in ping were added (pver > BIP0031Version).
BIP0031Version uint32 = 60000
// BIP0035Version is the protocol version which added the mempool
// message (pver >= BIP0035Version).
BIP0035Version uint32 = 60002
// BIP0037Version is the protocol version which added new connection
// bloom filtering related messages and extended the version message
// with a relay flag (pver >= BIP0037Version).
BIP0037Version uint32 = 70001
// RejectVersion is the protocol version which added a new reject
// message.
RejectVersion uint32 = 70002
// BIP0111Version is the protocol version which added the SFNodeBloom
// service flag.
BIP0111Version uint32 = 70011
// SendHeadersVersion is the protocol version which added a new
// sendheaders message.
SendHeadersVersion uint32 = 70012
// FeeFilterVersion is the protocol version which added a new
// feefilter message.
FeeFilterVersion uint32 = 70013
)
// ServiceFlag identifies services supported by a bitcoin peer.
type ServiceFlag uint64
const (
// SFNodeNetwork is a flag used to indicate a peer is a full node.
SFNodeNetwork ServiceFlag = 1 << iota
// SFNodeGetUTXO is a flag used to indicate a peer supports the
// getutxos and utxos commands (BIP0064).
SFNodeGetUTXO
// SFNodeBloom is a flag used to indicate a peer supports bloom
// filtering.
SFNodeBloom
// SFNodeWitness is a flag used to indicate a peer supports blocks
// and transactions including witness data (BIP0144).
SFNodeWitness
// SFNodeXthin is a flag used to indicate a peer supports xthin blocks.
SFNodeXthin
// SFNodeBit5 is a flag used to indicate a peer supports a service
// defined by bit 5.
SFNodeBit5
// SFNodeCF is a flag used to indicate a peer supports committed
// filters (CFs).
SFNodeCF
// SFNode2X is a flag used to indicate a peer is running the Segwit2X
// software.
SFNode2X
)
// Map of service flags back to their constant names for pretty printing.
var sfStrings = map[ServiceFlag]string{
SFNodeNetwork: "SFNodeNetwork",
SFNodeGetUTXO: "SFNodeGetUTXO",
SFNodeBloom: "SFNodeBloom",
SFNodeWitness: "SFNodeWitness",
SFNodeXthin: "SFNodeXthin",
SFNodeBit5: "SFNodeBit5",
SFNodeCF: "SFNodeCF",
SFNode2X: "SFNode2X",
}
// orderedSFStrings is an ordered list of service flags from highest to
// lowest.
var orderedSFStrings = []ServiceFlag{
SFNodeNetwork,
SFNodeGetUTXO,
SFNodeBloom,
SFNodeWitness,
SFNodeXthin,
SFNodeBit5,
SFNodeCF,
SFNode2X,
}
// String returns the ServiceFlag in human-readable form.
func (f ServiceFlag) String() string {
// No flags are set.
if f == 0 {
return "0x0"
}
// Add individual bit flags.
s := ""
for _, flag := range orderedSFStrings {
if f&flag == flag {
s += sfStrings[flag] + "|"
f -= flag
}
}
// Add any remaining flags which aren't accounted for as hex.
s = strings.TrimRight(s, "|")
if f != 0 {
s += "|0x" + strconv.FormatUint(uint64(f), 16)
}
s = strings.TrimLeft(s, "|")
return s
}
// BitcoinNet represents which bitcoin network a message belongs to.
type BitcoinNet uint32
// Constants used to indicate the message bitcoin network. They can also be
// used to seek to the next message when a stream's state is unknown, but
// this package does not provide that functionality since it's generally a
// better idea to simply disconnect clients that are misbehaving over TCP.
const (
// MainNet represents the main bitcoin network.
MainNet BitcoinNet = 0xd9b4bef9
// TestNet represents the regression test network.
TestNet BitcoinNet = 0xdab5bffa
// TestNet3 represents the test network (version 3).
TestNet3 BitcoinNet = 0x0709110b
// SimNet represents the simulation test network.
SimNet BitcoinNet = 0x12141c16
)
// bnStrings is a map of bitcoin networks back to their constant names for
// pretty printing.
var bnStrings = map[BitcoinNet]string{
MainNet: "MainNet",
TestNet: "TestNet",
TestNet3: "TestNet3",
SimNet: "SimNet",
}
// String returns the BitcoinNet in human-readable form.
func (n BitcoinNet) String() string {
if s, ok := bnStrings[n]; ok {
return s
}
return fmt.Sprintf("Unknown BitcoinNet (%d)", uint32(n))
}

28
vendor/github.com/btcsuite/btclog/.gitignore generated vendored Normal file
View File

@ -0,0 +1,28 @@
# Temp files
*~
# Log files
*.log
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe

13
vendor/github.com/btcsuite/btclog/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,13 @@
language: go
go:
- 1.7.x
- 1.8.x
sudo: false
install:
- go get -d -t -v ./...
- go get -v golang.org/x/tools/cmd/cover
- go get -v github.com/bradfitz/goimports
- go get -v github.com/golang/lint/golint
script:
- export PATH=$PATH:$HOME/gopath/bin
- ./goclean.sh

15
vendor/github.com/btcsuite/btclog/LICENSE generated vendored Normal file
View File

@ -0,0 +1,15 @@
ISC License
Copyright (c) 2013-2014 Conformal Systems LLC.
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Some files were not shown because too many files have changed in this diff Show More