func initManager(mgr_cfg *ManagerConfig) (adaptor.Manager, error) { options := make([]func(*manager.Manager), 0) if mgr_cfg.Connection_limit != 0 { limit := mgr_cfg.Connection_limit options = append(options, manager.SetConnectionLimit(limit)) } if mgr_cfg.Connection_rate != 0 { rate := time.Second / time.Duration(mgr_cfg.Connection_rate) options = append(options, manager.SetConnectionRate(rate)) } if mgr_cfg.Protocol_magic != 0 { magic := wire.BitcoinNet(mgr_cfg.Protocol_magic) options = append(options, manager.SetProtocolMagic(magic)) } if mgr_cfg.Protocol_version != 0 { version := mgr_cfg.Protocol_version options = append(options, manager.SetProtocolVersion(version)) } if mgr_cfg.Ticker_interval != 0 { interval := time.Second * time.Duration(mgr_cfg.Ticker_interval) options = append(options, manager.SetTickerInterval(interval)) } return manager.New(options...) }
func initNetwork(jnw JNetwork) (*dnsseeder, error) { if jnw.Port == 0 { return nil, fmt.Errorf("Invalid port supplied: %v", jnw.Port) } if jnw.DNSName == "" { return nil, fmt.Errorf("No DNS Hostname supplied") } // init the seeder seeder := &dnsseeder{} seeder.theList = make(map[string]*node) seeder.port = jnw.Port seeder.pver = jnw.Pver seeder.ttl = jnw.TTL seeder.name = jnw.Name seeder.desc = jnw.Desc seeder.dnsHost = jnw.DNSName // conver the network magic number to a Uint32 t1, err := strconv.ParseUint(jnw.ID, 0, 32) if err != nil { return nil, fmt.Errorf("Error converting Network Magic number: %v", err) } seeder.id = wire.BitcoinNet(t1) seeder.initialIP = jnw.InitialIP // load the seeder dns seeder.seeders = make([]string, 3) seeder.seeders[0] = jnw.Seeder1 seeder.seeders[1] = jnw.Seeder2 seeder.seeders[2] = jnw.Seeder3 // add some checks to the start & delay values to keep them sane seeder.maxStart = []uint32{20, 20, 20, 30} seeder.delay = []int64{210, 789, 234, 1876} seeder.maxSize = 1250 // initialize the stats counters seeder.counts.NdStatus = make([]uint32, maxStatusTypes) seeder.counts.NdStarts = make([]uint32, maxStatusTypes) seeder.counts.DNSCounts = make([]uint32, maxDNSTypes) // some sanity checks on the loaded config options if seeder.ttl < 60 { seeder.ttl = 60 } if dup, err := isDuplicateSeeder(seeder); dup == true { return nil, err } return seeder, nil }
// 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 }
// TestElementWire tests wire encode and decode for various element types. This // is mainly to test the "fast" paths in readElement and writeElement which use // type assertions to avoid reflection when possible. func TestElementWire(t *testing.T) { type writeElementReflect int32 tests := []struct { in interface{} // Value to encode buf []byte // Wire encoding }{ {int32(1), []byte{0x01, 0x00, 0x00, 0x00}}, {uint32(256), []byte{0x00, 0x01, 0x00, 0x00}}, { int64(65536), []byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, }, { uint64(4294967296), []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}, }, { true, []byte{0x01}, }, { false, []byte{0x00}, }, { [4]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, }, { [wire.CommandSize]byte{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, }, []byte{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, }, }, { [16]byte{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, }, []byte{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, }, }, { (*wire.ShaHash)(&[wire.HashSize]byte{ // Make go vet happy. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, }), []byte{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, }, }, { wire.ServiceFlag(wire.SFNodeNetwork), []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }, { wire.InvType(wire.InvTypeTx), []byte{0x01, 0x00, 0x00, 0x00}, }, { wire.BitcoinNet(wire.MainNet), []byte{0xf9, 0xbe, 0xb4, 0xd9}, }, // Type not supported by the "fast" path and requires reflection. { writeElementReflect(1), []byte{0x01, 0x00, 0x00, 0x00}, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Write to wire format. var buf bytes.Buffer err := wire.TstWriteElement(&buf, test.in) if err != nil { t.Errorf("writeElement #%d error %v", i, err) continue } if !bytes.Equal(buf.Bytes(), test.buf) { t.Errorf("writeElement #%d\n got: %s want: %s", i, spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) continue } // Read from wire format. rbuf := bytes.NewReader(test.buf) val := test.in if reflect.ValueOf(test.in).Kind() != reflect.Ptr { val = reflect.New(reflect.TypeOf(test.in)).Interface() } err = wire.TstReadElement(rbuf, val) if err != nil { t.Errorf("readElement #%d error %v", i, err) continue } ival := val if reflect.ValueOf(test.in).Kind() != reflect.Ptr { ival = reflect.Indirect(reflect.ValueOf(val)).Interface() } if !reflect.DeepEqual(ival, test.in) { t.Errorf("readElement #%d\n got: %s want: %s", i, spew.Sdump(ival), spew.Sdump(test.in)) continue } } }
// TestElementWireErrors performs negative tests against wire encode and decode // of various element types to confirm error paths work correctly. func TestElementWireErrors(t *testing.T) { tests := []struct { in interface{} // Value to encode max int // Max size of fixed buffer to induce errors writeErr error // Expected write error readErr error // Expected read error }{ {int32(1), 0, io.ErrShortWrite, io.EOF}, {uint32(256), 0, io.ErrShortWrite, io.EOF}, {int64(65536), 0, io.ErrShortWrite, io.EOF}, {true, 0, io.ErrShortWrite, io.EOF}, {[4]byte{0x01, 0x02, 0x03, 0x04}, 0, io.ErrShortWrite, io.EOF}, { [wire.CommandSize]byte{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, }, 0, io.ErrShortWrite, io.EOF, }, { [16]byte{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, }, 0, io.ErrShortWrite, io.EOF, }, { (*wire.ShaHash)(&[wire.HashSize]byte{ // Make go vet happy. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, }), 0, io.ErrShortWrite, io.EOF, }, {wire.ServiceFlag(wire.SFNodeNetwork), 0, io.ErrShortWrite, io.EOF}, {wire.InvType(wire.InvTypeTx), 0, io.ErrShortWrite, io.EOF}, {wire.BitcoinNet(wire.MainNet), 0, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) err := wire.TstWriteElement(w, test.in) if err != test.writeErr { t.Errorf("writeElement #%d wrong error got: %v, want: %v", i, err, test.writeErr) continue } // Decode from wire format. r := newFixedReader(test.max, nil) val := test.in if reflect.ValueOf(test.in).Kind() != reflect.Ptr { val = reflect.New(reflect.TypeOf(test.in)).Interface() } err = wire.TstReadElement(r, val) if err != test.readErr { t.Errorf("readElement #%d wrong error got: %v, want: %v", i, err, test.readErr) continue } } }
func readElement(r io.Reader, element interface{}) error { var err error switch e := element.(type) { case *uint8: var b [1]uint8 _, err = r.Read(b[:]) if err != nil { return err } *e = b[0] return nil case *uint16: var b [2]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint16(b[:]) return nil case *CreditsAmount: var b [4]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = CreditsAmount(int32(binary.BigEndian.Uint32(b[:]))) return nil case *uint32: var b [4]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint32(b[:]) return nil case *uint64: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = binary.BigEndian.Uint64(b[:]) return nil case *HTLCKey: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = HTLCKey(binary.BigEndian.Uint64(b[:])) return nil case *btcutil.Amount: var b [8]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = btcutil.Amount(int64(binary.BigEndian.Uint64(b[:]))) return nil case **wire.ShaHash: var b wire.ShaHash _, err = io.ReadFull(r, b[:]) if err != nil { return err } *e = &b return nil case **btcec.PublicKey: var b [33]byte _, err = io.ReadFull(r, b[:]) if err != nil { return err } x, err := btcec.ParsePubKey(b[:], btcec.S256()) if err != nil { return err } *e = &*x return nil case *[]uint64: var numItems uint16 err = readElement(r, &numItems) if err != nil { return err } // if numItems > 65535 { // return fmt.Errorf("Too many items in []uint64") // } // Read the number of items var items []uint64 for i := uint16(0); i < numItems; i++ { var item uint64 err = readElement(r, &item) if err != nil { return err } items = append(items, item) } *e = *&items return nil case *[]*btcec.Signature: var numSigs uint8 err = readElement(r, &numSigs) if err != nil { return err } if numSigs > 127 { return fmt.Errorf("Too many signatures!") } // Read that number of signatures var sigs []*btcec.Signature for i := uint8(0); i < numSigs; i++ { sig := new(btcec.Signature) err = readElement(r, &sig) if err != nil { return err } sigs = append(sigs, sig) } *e = *&sigs return nil case **btcec.Signature: var sigLength uint8 err = readElement(r, &sigLength) if err != nil { return err } if sigLength > 73 { return fmt.Errorf("Signature too long!") } // Read the sig length l := io.LimitReader(r, int64(sigLength)) sig, err := ioutil.ReadAll(l) if err != nil { return err } if len(sig) != int(sigLength) { return fmt.Errorf("EOF: Signature length mismatch.") } btcecSig, err := btcec.ParseSignature(sig, btcec.S256()) if err != nil { return err } *e = &*btcecSig return nil case *[]*[20]byte: // How many to read var sliceSize uint16 err = readElement(r, &sliceSize) if err != nil { return err } var data []*[20]byte // Append the actual for i := uint16(0); i < sliceSize; i++ { var element [20]byte err = readElement(r, &element) if err != nil { return err } data = append(data, &element) } *e = data return nil case *[20]byte: _, err = io.ReadFull(r, e[:]) if err != nil { return err } return nil case *wire.BitcoinNet: var b [4]byte _, err := io.ReadFull(r, b[:]) if err != nil { return err } *e = wire.BitcoinNet(binary.BigEndian.Uint32(b[:])) return nil case *[]byte: // Get the blob length first var blobLength uint16 err = readElement(r, &blobLength) if err != nil { return err } // Shouldn't need to do this, since it's uint16, but we // might have a different value for MAX_SLICE_LENGTH... if int(blobLength) > MAX_SLICE_LENGTH { return fmt.Errorf("Slice length too long!") } // Read the slice length l := io.LimitReader(r, int64(blobLength)) *e, err = ioutil.ReadAll(l) if err != nil { return err } if len(*e) != int(blobLength) { return fmt.Errorf("EOF: Slice length mismatch.") } return nil case *PkScript: // Get the script length first var scriptLength uint8 err = readElement(r, &scriptLength) if err != nil { return err } if scriptLength > 25 { return fmt.Errorf("PkScript too long!") } // Read the script length l := io.LimitReader(r, int64(scriptLength)) *e, err = ioutil.ReadAll(l) if err != nil { return err } if len(*e) != int(scriptLength) { return fmt.Errorf("EOF: Signature length mismatch.") } return nil case *string: // Get the string length first var strlen uint16 err = readElement(r, &strlen) if err != nil { return err } // Read the string for the length l := io.LimitReader(r, int64(strlen)) b, err := ioutil.ReadAll(l) if len(b) != int(strlen) { return fmt.Errorf("EOF: String length mismatch.") } *e = string(b) if err != nil { return err } return nil case *[]*wire.TxIn: // Read the size (1-byte number of txins) var numScripts uint8 err = readElement(r, &numScripts) if err != nil { return err } if numScripts > 127 { return fmt.Errorf("Too many txins") } // Append the actual TxIns var txins []*wire.TxIn for i := uint8(0); i < numScripts; i++ { outpoint := new(wire.OutPoint) txin := wire.NewTxIn(outpoint, nil) err = readElement(r, &txin) if err != nil { return err } txins = append(txins, txin) } *e = *&txins return nil case **wire.TxIn: // Hash var h [32]byte _, err = io.ReadFull(r, h[:]) if err != nil { return err } hash, err := wire.NewShaHash(h[:]) if err != nil { return err } (*e).PreviousOutPoint.Hash = *hash // Index var idxBytes [4]byte _, err = io.ReadFull(r, idxBytes[:]) if err != nil { return err } (*e).PreviousOutPoint.Index = binary.BigEndian.Uint32(idxBytes[:]) return nil default: return fmt.Errorf("Unknown type in readElement: %T", e) } return nil }
import ( "bytes" "encoding/hex" "fmt" "reflect" "testing" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" "github.com/btcsuite/golangcrypto/ripemd160" ) // invalidNet is an invalid bitcoin network. const invalidNet = wire.BitcoinNet(0xffffffff) func TestAddresses(t *testing.T) { tests := []struct { name string addr string encoded string valid bool result btcutil.Address f func() (btcutil.Address, error) net *chaincfg.Params }{ // Positive P2PKH tests. { name: "mainnet p2pkh", addr: "1MirQ9bwyQcGVJPwKUgapu5ouK2E2Ey4gX",