From 556620fea68b464f53b25cb1dc2e041e8040653b Mon Sep 17 00:00:00 2001 From: Gustavo Chain Date: Tue, 9 Mar 2021 10:37:31 +0100 Subject: [PATCH 01/18] rpcserver: Fix Error message returned by processRequest When processRequest can't find a rpc command, standardCmdResult returns a `btcjson.ErrRPCMethodNotFound` but it gets ignored and a `btcjson.ErrRPCInvalidRequest` is returned instead. This makes processRequest return the right error message. --- rpcserver.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/rpcserver.go b/rpcserver.go index 8e351bd27c..1cd3d69cf4 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -4066,9 +4066,13 @@ func (s *rpcServer) processRequest(request *btcjson.Request, isAdmin bool, close result, err = s.standardCmdResult(parsedCmd, closeChan) if err != nil { - jsonErr = &btcjson.RPCError{ - Code: btcjson.ErrRPCInvalidRequest.Code, - Message: "Invalid request: malformed", + if rpcErr, ok := err.(*btcjson.RPCError); ok { + jsonErr = rpcErr + } else { + jsonErr = &btcjson.RPCError{ + Code: btcjson.ErrRPCInvalidRequest.Code, + Message: "Invalid request: malformed", + } } } } From fdb479f1213f892fc52a17dde311d5b441a4cbf8 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Thu, 11 Mar 2021 18:24:13 -0800 Subject: [PATCH 02/18] peer: allow external testing of peer.Peer The previous use of allowSelfConns prevented this, as users aren't able to invoke peer.TstAllowSelfConns themselves due to being part of a test file, which aren't exported at the library level, leading to a "disconnecting peer connected to self" error upon establishing a mock connection between two peers. By including the option at the config level instead (false by default, prevents connections to self) we enable users of the peer library to properly test the behavior of the peer.Peer struct externally. --- peer/example_test.go | 2 ++ peer/export_test.go | 18 ------------------ peer/peer.go | 12 ++++++------ peer/peer_test.go | 12 +++++++----- 4 files changed, 15 insertions(+), 29 deletions(-) delete mode 100644 peer/export_test.go diff --git a/peer/example_test.go b/peer/example_test.go index cb67683bae..d4662a2b4c 100644 --- a/peer/example_test.go +++ b/peer/example_test.go @@ -25,6 +25,7 @@ func mockRemotePeer() error { UserAgentVersion: "1.0.0", // User agent version to advertise. ChainParams: &chaincfg.SimNetParams, TrickleInterval: time.Second * 10, + AllowSelfConns: true, } // Accept connections on the simnet port. @@ -81,6 +82,7 @@ func Example_newOutboundPeer() { verack <- struct{}{} }, }, + AllowSelfConns: true, } p, err := peer.NewOutboundPeer(peerCfg, "127.0.0.1:18555") if err != nil { diff --git a/peer/export_test.go b/peer/export_test.go deleted file mode 100644 index 06ec78a1a5..0000000000 --- a/peer/export_test.go +++ /dev/null @@ -1,18 +0,0 @@ -// 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. - -/* -This test file is part of the peer package rather than than the peer_test -package so it can bridge access to the internals to properly test cases which -are either not possible or can't reliably be tested via the public interface. -The functions are only exported while the tests are being run. -*/ - -package peer - -// TstAllowSelfConns allows the test package to allow self connections by -// disabling the detection logic. -func TstAllowSelfConns() { - allowSelfConns = true -} diff --git a/peer/peer.go b/peer/peer.go index 5b083a7467..92ac3d27e8 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -84,11 +84,6 @@ var ( // sentNonces houses the unique nonces that are generated when pushing // version messages that are used to detect self connections. sentNonces = lru.NewCache(50) - - // allowSelfConns is only used to allow the tests to bypass the self - // connection detecting and disconnect logic since they intentionally - // do so for testing purposes. - allowSelfConns bool ) // MessageListeners defines callback function pointers to invoke with message @@ -276,6 +271,11 @@ type Config struct { // TrickleInterval is the duration of the ticker which trickles down the // inventory to a peer. TrickleInterval time.Duration + + // AllowSelfConns is only used to allow the tests to bypass the self + // connection detecting and disconnect logic since they intentionally + // do so for testing purposes. + AllowSelfConns bool } // minUint32 is a helper function to return the minimum of two uint32s. @@ -1896,7 +1896,7 @@ func (p *Peer) readRemoteVersionMsg() error { } // Detect self connections. - if !allowSelfConns && sentNonces.Contains(msg.Nonce) { + if !p.cfg.AllowSelfConns && sentNonces.Contains(msg.Nonce) { return errors.New("disconnecting peer connected to self") } diff --git a/peer/peer_test.go b/peer/peer_test.go index 6cc3113d1e..dd7f36aa3a 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -238,6 +238,7 @@ func TestPeerConnection(t *testing.T) { ProtocolVersion: wire.RejectVersion, // Configure with older version Services: 0, TrickleInterval: time.Second * 10, + AllowSelfConns: true, } peer2Cfg := &peer.Config{ Listeners: peer1Cfg.Listeners, @@ -247,6 +248,7 @@ func TestPeerConnection(t *testing.T) { ChainParams: &chaincfg.MainNetParams, Services: wire.SFNodeNetwork | wire.SFNodeWitness, TrickleInterval: time.Second * 10, + AllowSelfConns: true, } wantStats1 := peerStats{ @@ -452,6 +454,7 @@ func TestPeerListeners(t *testing.T) { ChainParams: &chaincfg.MainNetParams, Services: wire.SFNodeBloom, TrickleInterval: time.Second * 10, + AllowSelfConns: true, } inConn, outConn := pipe( &conn{raddr: "10.0.0.1:8333"}, @@ -623,6 +626,7 @@ func TestOutboundPeer(t *testing.T) { ChainParams: &chaincfg.MainNetParams, Services: 0, TrickleInterval: time.Second * 10, + AllowSelfConns: true, } r, w := io.Pipe() @@ -764,6 +768,7 @@ func TestUnsupportedVersionPeer(t *testing.T) { ChainParams: &chaincfg.MainNetParams, Services: 0, TrickleInterval: time.Second * 10, + AllowSelfConns: true, } localNA := wire.NewNetAddressIPPort( @@ -874,6 +879,7 @@ func TestDuplicateVersionMsg(t *testing.T) { UserAgentVersion: "1.0", ChainParams: &chaincfg.MainNetParams, Services: 0, + AllowSelfConns: true, } inConn, outConn := pipe( &conn{laddr: "10.0.0.1:9108", raddr: "10.0.0.2:9108"}, @@ -935,6 +941,7 @@ func TestUpdateLastBlockHeight(t *testing.T) { UserAgentVersion: "1.0", ChainParams: &chaincfg.MainNetParams, Services: 0, + AllowSelfConns: true, } remotePeerCfg := peerCfg remotePeerCfg.NewestBlock = func() (*chainhash.Hash, int32, error) { @@ -982,8 +989,3 @@ func TestUpdateLastBlockHeight(t *testing.T) { remotePeerHeight+1) } } - -func init() { - // Allow self connection when running the tests. - peer.TstAllowSelfConns() -} From f86ae60936d7134fad9bf0ab1b3a1c261abe79b7 Mon Sep 17 00:00:00 2001 From: Gustavo Chain Date: Tue, 9 Mar 2021 18:22:04 +0100 Subject: [PATCH 03/18] addrmgr: Use RLock/RUnlock when possible --- addrmgr/addrmanager.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index a8a8fb3338..fa8f27bcae 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -30,7 +30,7 @@ import ( // AddrManager provides a concurrency safe address manager for caching potential // peers on the bitcoin network. type AddrManager struct { - mtx sync.Mutex + mtx sync.RWMutex peersFile string lookupFunc func(string) ([]net.IP, error) rand *rand.Rand @@ -645,8 +645,8 @@ func (a *AddrManager) numAddresses() int { // NumAddresses returns the number of addresses known to the address manager. func (a *AddrManager) NumAddresses() int { - a.mtx.Lock() - defer a.mtx.Unlock() + a.mtx.RLock() + defer a.mtx.RUnlock() return a.numAddresses() } @@ -654,8 +654,8 @@ func (a *AddrManager) NumAddresses() int { // NeedMoreAddresses returns whether or not the address manager needs more // addresses. func (a *AddrManager) NeedMoreAddresses() bool { - a.mtx.Lock() - defer a.mtx.Unlock() + a.mtx.RLock() + defer a.mtx.RUnlock() return a.numAddresses() < needAddressThreshold } @@ -685,8 +685,8 @@ func (a *AddrManager) AddressCache() []*wire.NetAddress { // getAddresses returns all of the addresses currently found within the // manager's address cache. func (a *AddrManager) getAddresses() []*wire.NetAddress { - a.mtx.Lock() - defer a.mtx.Unlock() + a.mtx.RLock() + defer a.mtx.RUnlock() addrIndexLen := len(a.addrIndex) if addrIndexLen == 0 { From f133593b932d1eee4d21623d6044760958e69953 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Mon, 25 Jan 2021 14:13:18 -0800 Subject: [PATCH 04/18] build: update btcutil dependency --- go.mod | 2 +- go.sum | 5 +++-- integration/rpctest/memwallet.go | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index c53b23d222..049b97fe6c 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/btcsuite/btcd require ( github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f - github.com/btcsuite/btcutil v1.0.2 + github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd github.com/btcsuite/goleveldb v1.0.0 github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 diff --git a/go.sum b/go.sum index 392d70f1b7..e259d0ec77 100644 --- a/go.sum +++ b/go.sum @@ -5,8 +5,8 @@ github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9 github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce h1:YtWJF7RHm2pYCvA5t0RPmAaLUhREsKuKd+SLhxFbFeQ= +github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce/go.mod h1:0DVlHczLPewLcPGEIeUEzfOJhqGPQ0mJJRDBtD307+o= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd h1:R/opQEbFEy9JGkIguV40SvRY1uliPX8ifOvi6ICsFCw= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd h1:qdGvebPBDuYDPGi1WCPjy1tGyMpmDK8IEapSsszn7HE= @@ -22,6 +22,7 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0 h1:J9B4L7e3oqhXOcm+2IuNApwzQec85lE+QaikUcCs+dk= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/decred/dcrd/lru v1.0.0 h1:Kbsb1SFDsIlaupWPwsPp+dkxiBY1frcS07PCPgotKz8= diff --git a/integration/rpctest/memwallet.go b/integration/rpctest/memwallet.go index f16130750a..59b0ef4c08 100644 --- a/integration/rpctest/memwallet.go +++ b/integration/rpctest/memwallet.go @@ -125,7 +125,7 @@ func newMemWallet(net *chaincfg.Params, harnessID uint32) (*memWallet, error) { // The first child key from the hd root is reserved as the coinbase // generation address. - coinbaseChild, err := hdRoot.Child(0) + coinbaseChild, err := hdRoot.Derive(0) if err != nil { return nil, err } @@ -337,7 +337,7 @@ func (m *memWallet) unwindBlock(update *chainUpdate) { func (m *memWallet) newAddress() (btcutil.Address, error) { index := m.hdIndex - childKey, err := m.hdRoot.Child(index) + childKey, err := m.hdRoot.Derive(index) if err != nil { return nil, err } @@ -509,7 +509,7 @@ func (m *memWallet) CreateTransaction(outputs []*wire.TxOut, outPoint := txIn.PreviousOutPoint utxo := m.utxos[outPoint] - extendedKey, err := m.hdRoot.Child(utxo.keyIndex) + extendedKey, err := m.hdRoot.Derive(utxo.keyIndex) if err != nil { return nil, err } From 540786fda6c6d9328eacf005fa84aef5ed1ec725 Mon Sep 17 00:00:00 2001 From: Jake Sylvestre Date: Tue, 13 Apr 2021 09:02:41 -0400 Subject: [PATCH 05/18] rpcclient: fix documentation typo --- rpcclient/net.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcclient/net.go b/rpcclient/net.go index 8f781e4ed8..8c191ff66f 100644 --- a/rpcclient/net.go +++ b/rpcclient/net.go @@ -90,7 +90,7 @@ func (c *Client) NodeAsync(command btcjson.NodeSubCmd, host string, // 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 +// whether we are targeting 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 { From 2d7825cf709fc6ac15921cecfd4d62ec78ccbba2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A8le=20Oul=C3=A8s?= Date: Sun, 21 Mar 2021 19:54:48 +0000 Subject: [PATCH 06/18] btcjson: Updated TxRawResult.Version from int32 to uint32 --- btcjson/chainsvrresults.go | 2 +- rpcserver.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/btcjson/chainsvrresults.go b/btcjson/chainsvrresults.go index 9799494ca3..59f18c74c8 100644 --- a/btcjson/chainsvrresults.go +++ b/btcjson/chainsvrresults.go @@ -712,7 +712,7 @@ type TxRawResult struct { Size int32 `json:"size,omitempty"` Vsize int32 `json:"vsize,omitempty"` Weight int32 `json:"weight,omitempty"` - Version int32 `json:"version"` + Version uint32 `json:"version"` LockTime uint32 `json:"locktime"` Vin []Vin `json:"vin"` Vout []Vout `json:"vout"` diff --git a/rpcserver.go b/rpcserver.go index 1cd3d69cf4..2c9a518543 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -764,7 +764,7 @@ func createTxRawResult(chainParams *chaincfg.Params, mtx *wire.MsgTx, Weight: int32(blockchain.GetTransactionWeight(btcutil.NewTx(mtx))), Vin: createVinList(mtx), Vout: createVoutList(mtx, chainParams, nil), - Version: mtx.Version, + Version: uint32(mtx.Version), LockTime: mtx.LockTime, } From 73ecb5997bcf3d69482bd3780c02472f0bde699a Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Thu, 24 Dec 2020 16:51:59 +0100 Subject: [PATCH 07/18] wire+chaincfg: add signet params This commit adds all necessary chain parameters for connecting to the public signet network. Reference: https://github.com/bitcoin/bitcoin/pull/18267 --- chaincfg/genesis.go | 28 +++++++++ chaincfg/genesis_test.go | 68 ++++++++++++++++++++ chaincfg/params.go | 132 +++++++++++++++++++++++++++++++++++++++ chaincfg/params_test.go | 49 +++++++++++++++ 4 files changed, 277 insertions(+) diff --git a/chaincfg/genesis.go b/chaincfg/genesis.go index ee47b84ce4..73d286102b 100644 --- a/chaincfg/genesis.go +++ b/chaincfg/genesis.go @@ -170,3 +170,31 @@ var simNetGenesisBlock = wire.MsgBlock{ }, Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, } + +// sigNetGenesisHash is the hash of the first block in the block chain for the +// signet test network. +var sigNetGenesisHash = chainhash.Hash{ + 0xf6, 0x1e, 0xee, 0x3b, 0x63, 0xa3, 0x80, 0xa4, + 0x77, 0xa0, 0x63, 0xaf, 0x32, 0xb2, 0xbb, 0xc9, + 0x7c, 0x9f, 0xf9, 0xf0, 0x1f, 0x2c, 0x42, 0x25, + 0xe9, 0x73, 0x98, 0x81, 0x08, 0x00, 0x00, 0x00, +} + +// sigNetGenesisMerkleRoot is the hash of the first transaction in the genesis +// block for the signet test network. It is the same as the merkle root for +// the main network. +var sigNetGenesisMerkleRoot = genesisMerkleRoot + +// sigNetGenesisBlock defines the genesis block of the block chain which serves +// as the public transaction ledger for the signet test network. +var sigNetGenesisBlock = wire.MsgBlock{ + Header: wire.BlockHeader{ + Version: 1, + PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000 + MerkleRoot: sigNetGenesisMerkleRoot, // 4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b + Timestamp: time.Unix(1598918400, 0), // 2020-09-01 00:00:00 +0000 UTC + Bits: 0x1e0377ae, // 503543726 [00000377ae000000000000000000000000000000000000000000000000000000] + Nonce: 52613770, + }, + Transactions: []*wire.MsgTx{&genesisCoinbaseTx}, +} diff --git a/chaincfg/genesis_test.go b/chaincfg/genesis_test.go index d04a72f758..1daf847916 100644 --- a/chaincfg/genesis_test.go +++ b/chaincfg/genesis_test.go @@ -118,6 +118,33 @@ func TestSimNetGenesisBlock(t *testing.T) { } } +// TestSigNetGenesisBlock tests the genesis block of the signet test network for +// validity by checking the encoded bytes and hashes. +func TestSigNetGenesisBlock(t *testing.T) { + // Encode the genesis block to raw bytes. + var buf bytes.Buffer + err := SigNetParams.GenesisBlock.Serialize(&buf) + if err != nil { + t.Fatalf("TestSigNetGenesisBlock: %v", err) + } + + // Ensure the encoded block matches the expected bytes. + if !bytes.Equal(buf.Bytes(), sigNetGenesisBlockBytes) { + t.Fatalf("TestSigNetGenesisBlock: Genesis block does not "+ + "appear valid - got %v, want %v", + spew.Sdump(buf.Bytes()), + spew.Sdump(sigNetGenesisBlockBytes)) + } + + // Check hash of the block against expected hash. + hash := SigNetParams.GenesisBlock.BlockHash() + if !SigNetParams.GenesisHash.IsEqual(&hash) { + t.Fatalf("TestSigNetGenesisBlock: Genesis block hash does "+ + "not appear valid - got %v, want %v", spew.Sdump(hash), + spew.Sdump(SigNetParams.GenesisHash)) + } +} + // genesisBlockBytes are the wire encoded bytes for the genesis block of the // main network as of protocol version 60002. var genesisBlockBytes = []byte{ @@ -281,3 +308,44 @@ var simNetGenesisBlockBytes = []byte{ 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |.Lp+k.._|*/ 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ } + +// sigNetGenesisBlockBytes are the wire encoded bytes for the genesis block of +// the signet test network as of protocol version 70002. +var sigNetGenesisBlockBytes = []byte{ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |...@....| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x3b, 0xa3, 0xed, 0xfd, /* |........| */ + 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, /* |....;...| */ + 0x67, 0x76, 0x8f, 0x61, 0x7f, 0xc8, 0x1b, 0xc3, /* |z{..z.,>| */ + 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, /* |gv.a....| */ + 0x4b, 0x1e, 0x5e, 0x4a, 0x00, 0x8f, 0x4d, 0x5f, /* |..Q2:...| */ + 0xae, 0x77, 0x03, 0x1e, 0x8a, 0xd2, 0x22, 0x03, /* |K.^J..M_| */ + 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |.w....".| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */ + 0xff, 0xff, 0x4d, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |........| */ + 0x01, 0x04, 0x45, 0x54, 0x68, 0x65, 0x20, 0x54, /* |..M.....| */ + 0x69, 0x6d, 0x65, 0x73, 0x20, 0x30, 0x33, 0x2f, /* |..EThe T| */ + 0x4a, 0x61, 0x6e, 0x2f, 0x32, 0x30, 0x30, 0x39, /* |imes 03/| */ + 0x20, 0x43, 0x68, 0x61, 0x6e, 0x63, 0x65, 0x6c, /* |Jan/2009| */ + 0x6c, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x20, 0x62, /* | Chancel| */ + 0x72, 0x69, 0x6e, 0x6b, 0x20, 0x6f, 0x66, 0x20, /* |lor on b| */ + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x20, 0x62, /* |rink of| */ + 0x61, 0x69, 0x6c, 0x6f, 0x75, 0x74, 0x20, 0x66, /* |second b| */ + 0x6f, 0x72, 0x20, 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |ailout f| */ + 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |or banks| */ + 0x2a, 0x01, 0x00, 0x00, 0x00, 0x43, 0x41, 0x04, /* |........| */ + 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48, 0x27, /* |*....CA.| */ + 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7, 0x10, /* |g....UH'| */ + 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09, 0xa6, /* |.g..q0..| */ + 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde, 0xb6, /* |\..(.9..| */ + 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38, 0xc4, /* |yb...a..| */ + 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12, 0xde, /* |I..?L.8.| */ + 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d, 0x57, /* |.U......| */ + 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d, 0x5f, /* |\8M....W| */ + 0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ +} diff --git a/chaincfg/params.go b/chaincfg/params.go index 7e4327984c..cb1568632c 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -5,6 +5,8 @@ package chaincfg import ( + "encoding/binary" + "encoding/hex" "errors" "math" "math/big" @@ -38,6 +40,30 @@ var ( // 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) + + // sigNetPowLimit is the highest proof of work value a bitcoin block can + // have for the signet test network. It is the value 0x0377ae << 216. + sigNetPowLimit = new(big.Int).Lsh(new(big.Int).SetInt64(0x0377ae), 216) + + // DefaultSignetChallenge is the byte representation of the signet + // challenge for the default (public, Taproot enabled) signet network. + // This is the binary equivalent of the bitcoin script + // 1 03ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430 + // 0359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c4 2 + // OP_CHECKMULTISIG + DefaultSignetChallenge, _ = hex.DecodeString( + "512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d" + + "1e086be430210359ef5021964fe22d6f8e05b2463c9540ce9688" + + "3fe3b278760f048f5189f2e6c452ae", + ) + + // DefaultSignetDNSSeeds is the list of seed nodes for the default + // (public, Taproot enabled) signet network. + DefaultSignetDNSSeeds = []DNSSeed{ + {"178.128.221.177", false}, + {"2a01:7c8:d005:390::5", false}, + {"v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:38333", false}, + } ) // Checkpoint identifies a known good point in the block chain. Using @@ -96,6 +122,11 @@ const ( // includes the deployment of BIPS 141, 142, 144, 145, 147 and 173. DeploymentSegwit + // DeploymentTaproot defines the rule change deployment ID for the + // Taproot (+Schnorr) soft-fork package. The taproot package includes + // the deployment of BIPS 340, 341 and 342. + DeploymentTaproot + // NOTE: DefinedDeployments must always come last since it is used to // determine how many defined deployments there currently are. @@ -578,6 +609,107 @@ var SimNetParams = Params{ HDCoinType: 115, // ASCII for s } +// SigNetParams defines the network parameters for the default public signet +// Bitcoin network. Not to be confused with the regression test network, this +// network is sometimes simply called "signet" or "taproot signet". +var SigNetParams = CustomSignetParams( + DefaultSignetChallenge, DefaultSignetDNSSeeds, +) + +// CustomSignetParams creates network parameters for a custom signet network +// from a challenge. The challenge is the binary compiled version of the block +// challenge script. +func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params { + // The message start is defined as the first four bytes of the sha256d + // of the challenge script, as a single push (i.e. prefixed with the + // challenge script length). + challengeLength := byte(len(challenge)) + hashDouble := chainhash.DoubleHashB( + append([]byte{challengeLength}, challenge...), + ) + + // We use little endian encoding of the hash prefix to be in line with + // the other wire network identities. + net := binary.LittleEndian.Uint32(hashDouble[0:4]) + return Params{ + Name: "signet", + Net: wire.BitcoinNet(net), + DefaultPort: "38333", + DNSSeeds: dnsSeeds, + + // Chain parameters + GenesisBlock: &sigNetGenesisBlock, + GenesisHash: &sigNetGenesisHash, + PowLimit: sigNetPowLimit, + PowLimitBits: 0x1e0377ae, + BIP0034Height: 1, + BIP0065Height: 1, + BIP0066Height: 1, + 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: time.Minute * 20, // TargetTimePerBlock * 2 + GenerateSupported: false, + + // 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: 1916, // 95% of 2016 + MinerConfirmationWindow: 2016, + Deployments: [DefinedDeployments]ConsensusDeployment{ + DeploymentTestDummy: { + BitNumber: 28, + StartTime: 1199145601, // January 1, 2008 UTC + ExpireTime: 1230767999, // December 31, 2008 UTC + }, + 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. + }, + DeploymentTaproot: { + BitNumber: 2, + StartTime: 0, // Always available for vote + ExpireTime: math.MaxInt64, // Never expires. + }, + }, + + // Mempool parameters + RelayNonStdTxs: false, + + // 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, + } +} + var ( // ErrDuplicateNet describes an error where the parameters for a Bitcoin // network could not be set due to the network already being a standard diff --git a/chaincfg/params_test.go b/chaincfg/params_test.go index d9e1516812..4166ce0a23 100644 --- a/chaincfg/params_test.go +++ b/chaincfg/params_test.go @@ -6,6 +6,8 @@ package chaincfg import ( "bytes" + "encoding/hex" + "math/big" "testing" ) @@ -84,3 +86,50 @@ func TestInvalidHDKeyID(t *testing.T) { t.Fatalf("HDPrivateKeyToPublicKeyID: want err ErrUnknownHDKeyID, got %v", err) } } + +func TestSigNetPowLimit(t *testing.T) { + sigNetPowLimitHex, _ := hex.DecodeString( + "00000377ae000000000000000000000000000000000000000000000000000000", + ) + powLimit := new(big.Int).SetBytes(sigNetPowLimitHex) + if sigNetPowLimit.Cmp(powLimit) != 0 { + t.Fatalf("Signet PoW limit bits (%s) not equal to big int (%s)", + sigNetPowLimit.Text(16), powLimit.Text(16)) + } + + if compactToBig(sigNetGenesisBlock.Header.Bits).Cmp(powLimit) != 0 { + t.Fatalf("Signet PoW limit header bits (%d) not equal to big "+ + "int (%s)", sigNetGenesisBlock.Header.Bits, + powLimit.Text(16)) + } +} + +// compactToBig is a copy of the blockchain.CompactToBig function. We copy it +// here so we don't run into a circular dependency just because of a test. +func compactToBig(compact uint32) *big.Int { + // Extract the mantissa, sign bit, and exponent. + mantissa := compact & 0x007fffff + isNegative := compact&0x00800000 != 0 + exponent := uint(compact >> 24) + + // Since the base for the exponent is 256, the exponent can be treated + // as the number of bytes to represent the full 256-bit number. So, + // treat the exponent as the number of bytes and shift the mantissa + // right or left accordingly. This is equivalent to: + // N = mantissa * 256^(exponent-3) + var bn *big.Int + if exponent <= 3 { + mantissa >>= 8 * (3 - exponent) + bn = big.NewInt(int64(mantissa)) + } else { + bn = big.NewInt(int64(mantissa)) + bn.Lsh(bn, 8*(exponent-3)) + } + + // Make it negative if the sign bit is set. + if isNegative { + bn = bn.Neg(bn) + } + + return bn +} From 3eac153437340fc90ec8a17d3e0fc6c64bc979b3 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Sun, 14 Feb 2021 15:49:11 +0100 Subject: [PATCH 08/18] config+params: add signet config option This commit adds the --signet command line flag (or signet config option) for starting btcd in signet mode. --- config.go | 52 ++++++++++++++++++++++++++++++++++++++++++++++++---- doc.go | 2 +- params.go | 7 +++++++ 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/config.go b/config.go index c44f3a837f..7124fe9290 100644 --- a/config.go +++ b/config.go @@ -8,6 +8,7 @@ import ( "bufio" "crypto/rand" "encoding/base64" + "encoding/hex" "errors" "fmt" "io" @@ -159,6 +160,9 @@ type config struct { RPCUser string `short:"u" long:"rpcuser" description:"Username for RPC connections"` SigCacheMaxSize uint `long:"sigcachemaxsize" description:"The maximum number of entries in the signature verification cache"` SimNet bool `long:"simnet" description:"Use the simulation test network"` + SigNet bool `long:"signet" description:"Use the signet test network"` + SigNetChallenge string `long:"signetchallenge" description:"Connect to a custom signet network defined by this challenge instead of using the global default signet test network -- Can be specified multiple times"` + SigNetSeedNode []string `long:"signetseednode" description:"Specify a seed node for the signet network instead of using the global default signet network seed nodes"` TestNet3 bool `long:"testnet" description:"Use the test network"` TorIsolation bool `long:"torisolation" description:"Enable Tor stream isolation by randomizing user credentials for each connection."` TrickleInterval time.Duration `long:"trickleinterval" description:"Minimum time between attempts to send new inventory to a connected peer"` @@ -475,8 +479,8 @@ func loadConfig() (*config, []string, error) { // Load additional config from file. var configFileError error parser := newConfigParser(&cfg, &serviceOpts, flags.Default) - if !(preCfg.RegressionTest || preCfg.SimNet) || preCfg.ConfigFile != - defaultConfigFile { + if !(preCfg.RegressionTest || preCfg.SimNet || preCfg.SigNet) || + preCfg.ConfigFile != defaultConfigFile { if _, err := os.Stat(preCfg.ConfigFile); os.IsNotExist(err) { err := createDefaultConfigFile(preCfg.ConfigFile) @@ -550,9 +554,49 @@ func loadConfig() (*config, []string, error) { activeNetParams = &simNetParams cfg.DisableDNSSeed = true } + if cfg.SigNet { + numNets++ + activeNetParams = &sigNetParams + + // Let the user overwrite the default signet parameters. The + // challenge defines the actual signet network to join and the + // seed nodes are needed for network discovery. + sigNetChallenge := chaincfg.DefaultSignetChallenge + sigNetSeeds := chaincfg.DefaultSignetDNSSeeds + if cfg.SigNetChallenge != "" { + challenge, err := hex.DecodeString(cfg.SigNetChallenge) + if err != nil { + str := "%s: Invalid signet challenge, hex " + + "decode failed: %v" + err := fmt.Errorf(str, funcName, err) + fmt.Fprintln(os.Stderr, err) + fmt.Fprintln(os.Stderr, usageMessage) + return nil, nil, err + } + sigNetChallenge = challenge + } + + if len(cfg.SigNetSeedNode) > 0 { + sigNetSeeds = make( + []chaincfg.DNSSeed, len(cfg.SigNetSeedNode), + ) + for idx, seed := range cfg.SigNetSeedNode { + sigNetSeeds[idx] = chaincfg.DNSSeed{ + Host: seed, + HasFiltering: false, + } + } + } + + chainParams := chaincfg.CustomSignetParams( + sigNetChallenge, sigNetSeeds, + ) + activeNetParams.Params = &chainParams + } if numNets > 1 { - str := "%s: The testnet, regtest, segnet, and simnet params " + - "can't be used together -- choose one of the four" + str := "%s: The testnet, regtest, segnet, signet and simnet " + + "params can't be used together -- choose one of the " + + "five" err := fmt.Errorf(str, funcName) fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, usageMessage) diff --git a/doc.go b/doc.go index 8b9b99773a..70d0d9e45c 100644 --- a/doc.go +++ b/doc.go @@ -72,7 +72,7 @@ Application Options: minute (default: 15) --listen= Add an interface/port to listen for connections (default all interfaces port: 8333, testnet: - 18333) + 18333, signet: 38333) --logdir= Directory to log output --maxorphantx= Max number of orphan transactions to keep in memory (default: 100) diff --git a/params.go b/params.go index 14eeff0717..b4d1453dfb 100644 --- a/params.go +++ b/params.go @@ -55,6 +55,13 @@ var simNetParams = params{ rpcPort: "18556", } +// sigNetParams contains parameters specific to the Signet network +// (wire.SigNet). +var sigNetParams = params{ + Params: &chaincfg.SigNetParams, + rpcPort: "38332", +} + // netName returns the name used when referring to a bitcoin network. At the // time of writing, btcd currently places blocks for testnet version 3 in the // data and log directory "testnet", which does not match the Name field of the From 8a62cf0ef5e3deb27f042543e2748b0b2b120da0 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Wed, 17 Feb 2021 11:07:12 +0100 Subject: [PATCH 09/18] rpcserver: add taproot deployment to getblockchaininfo --- rpcserver.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rpcserver.go b/rpcserver.go index 2c9a518543..d184072942 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1256,6 +1256,9 @@ func handleGetBlockChainInfo(s *rpcServer, cmd interface{}, closeChan <-chan str case chaincfg.DeploymentSegwit: forkName = "segwit" + case chaincfg.DeploymentTaproot: + forkName = "taproot" + default: return nil, &btcjson.RPCError{ Code: btcjson.ErrRPCInternal.Code, From 7d1ab0b4d769cd86cfd63b0b7c52601b32011edb Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Mon, 22 Mar 2021 18:26:58 +0100 Subject: [PATCH 10/18] btcctl: add signet param This commit adds the --signet command line flag to the btcctl utility. --- cmd/btcctl/config.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cmd/btcctl/config.go b/cmd/btcctl/config.go index 939b6a8699..1cc2a260f3 100644 --- a/cmd/btcctl/config.go +++ b/cmd/btcctl/config.go @@ -107,6 +107,7 @@ type config struct { SimNet bool `long:"simnet" description:"Connect to the simulation test network"` TLSSkipVerify bool `long:"skipverify" description:"Do not verify tls certificates (not recommended!)"` TestNet3 bool `long:"testnet" description:"Connect to testnet"` + SigNet bool `long:"signet" description:"Connect to signet"` ShowVersion bool `short:"V" long:"version" description:"Display version information and exit"` Wallet bool `long:"wallet" description:"Connect to wallet"` } @@ -138,6 +139,12 @@ func normalizeAddress(addr string, chain *chaincfg.Params, useWallet bool) (stri } else { defaultPort = "18334" } + case &chaincfg.SigNetParams: + if useWallet { + defaultPort = "38332" + } else { + defaultPort = "38332" + } default: if useWallet { defaultPort = "8332" @@ -273,6 +280,10 @@ func loadConfig() (*config, []string, error) { numNets++ network = &chaincfg.RegressionNetParams } + if cfg.SigNet { + numNets++ + network = &chaincfg.SigNetParams + } if numNets > 1 { str := "%s: Multiple network params can't be used " + From f0f4784c1ccf8cdafb3c72b8f251fa5290174297 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Mon, 26 Apr 2021 13:53:22 +0200 Subject: [PATCH 11/18] mining: extract witness commitment add into method --- mining/mining.go | 78 +++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/mining/mining.go b/mining/mining.go index 44ec7dc761..e918328df8 100644 --- a/mining/mining.go +++ b/mining/mining.go @@ -803,40 +803,7 @@ mempoolLoop: // OP_RETURN output within the coinbase transaction. var witnessCommitment []byte if witnessIncluded { - // The witness of the coinbase transaction MUST be exactly 32-bytes - // of all zeroes. - var witnessNonce [blockchain.CoinbaseWitnessDataLen]byte - coinbaseTx.MsgTx().TxIn[0].Witness = wire.TxWitness{witnessNonce[:]} - - // Next, obtain the merkle root of a tree which consists of the - // wtxid of all transactions in the block. The coinbase - // transaction will have a special wtxid of all zeroes. - witnessMerkleTree := blockchain.BuildMerkleTreeStore(blockTxns, - true) - witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1] - - // The preimage to the witness commitment is: - // witnessRoot || coinbaseWitness - var witnessPreimage [64]byte - copy(witnessPreimage[:32], witnessMerkleRoot[:]) - copy(witnessPreimage[32:], witnessNonce[:]) - - // The witness commitment itself is the double-sha256 of the - // witness preimage generated above. With the commitment - // generated, the witness script for the output is: OP_RETURN - // OP_DATA_36 {0xaa21a9ed || witnessCommitment}. The leading - // prefix is referred to as the "witness magic bytes". - witnessCommitment = chainhash.DoubleHashB(witnessPreimage[:]) - witnessScript := append(blockchain.WitnessMagicBytes, witnessCommitment...) - - // Finally, create the OP_RETURN carrying witness commitment - // output as an additional output within the coinbase. - commitmentOutput := &wire.TxOut{ - Value: 0, - PkScript: witnessScript, - } - coinbaseTx.MsgTx().TxOut = append(coinbaseTx.MsgTx().TxOut, - commitmentOutput) + witnessCommitment = AddWitnessCommitment(coinbaseTx, blockTxns) } // Calculate the required difficulty for the block. The timestamp @@ -895,6 +862,49 @@ mempoolLoop: }, nil } +// AddWitnessCommitment adds the witness commitment as an OP_RETURN outpout +// within the coinbase tx. The raw commitment is returned. +func AddWitnessCommitment(coinbaseTx *btcutil.Tx, + blockTxns []*btcutil.Tx) []byte { + + // The witness of the coinbase transaction MUST be exactly 32-bytes + // of all zeroes. + var witnessNonce [blockchain.CoinbaseWitnessDataLen]byte + coinbaseTx.MsgTx().TxIn[0].Witness = wire.TxWitness{witnessNonce[:]} + + // Next, obtain the merkle root of a tree which consists of the + // wtxid of all transactions in the block. The coinbase + // transaction will have a special wtxid of all zeroes. + witnessMerkleTree := blockchain.BuildMerkleTreeStore(blockTxns, + true) + witnessMerkleRoot := witnessMerkleTree[len(witnessMerkleTree)-1] + + // The preimage to the witness commitment is: + // witnessRoot || coinbaseWitness + var witnessPreimage [64]byte + copy(witnessPreimage[:32], witnessMerkleRoot[:]) + copy(witnessPreimage[32:], witnessNonce[:]) + + // The witness commitment itself is the double-sha256 of the + // witness preimage generated above. With the commitment + // generated, the witness script for the output is: OP_RETURN + // OP_DATA_36 {0xaa21a9ed || witnessCommitment}. The leading + // prefix is referred to as the "witness magic bytes". + witnessCommitment := chainhash.DoubleHashB(witnessPreimage[:]) + witnessScript := append(blockchain.WitnessMagicBytes, witnessCommitment...) + + // Finally, create the OP_RETURN carrying witness commitment + // output as an additional output within the coinbase. + commitmentOutput := &wire.TxOut{ + Value: 0, + PkScript: witnessScript, + } + coinbaseTx.MsgTx().TxOut = append(coinbaseTx.MsgTx().TxOut, + commitmentOutput) + + return witnessCommitment +} + // UpdateBlockTime updates the timestamp in the header of the passed block to // the current time while taking into account the median time of the last // several blocks to ensure the new time is after that time per the chain From 37a6e8485b69f9514d74d153843477c73d1b0473 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Mon, 26 Apr 2021 13:53:51 +0200 Subject: [PATCH 12/18] rpctest: add witness commitment when calling CreateBlock If we tried to include transactions having witnesses, the block would be invalid since the witness commitment was not added. --- integration/rpctest/blockgen.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/integration/rpctest/blockgen.go b/integration/rpctest/blockgen.go index de5821b0c1..0d802f5a48 100644 --- a/integration/rpctest/blockgen.go +++ b/integration/rpctest/blockgen.go @@ -14,6 +14,7 @@ import ( "github.com/btcsuite/btcd/blockchain" "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/mining" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcutil" @@ -181,6 +182,21 @@ func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx, if inclusionTxs != nil { blockTxns = append(blockTxns, inclusionTxs...) } + + // We must add the witness commitment to the coinbase if any + // transactions are segwit. + witnessIncluded := false + for i := 1; i < len(blockTxns); i++ { + if blockTxns[i].MsgTx().HasWitness() { + witnessIncluded = true + break + } + } + + if witnessIncluded { + _ = mining.AddWitnessCommitment(coinbaseTx, blockTxns) + } + merkles := blockchain.BuildMerkleTreeStore(blockTxns, false) var block wire.MsgBlock block.Header = wire.BlockHeader{ From 0ec4bdc1b8e162efffed446a80f297c188543088 Mon Sep 17 00:00:00 2001 From: "John C. Vernaleo" Date: Sun, 18 Apr 2021 16:46:27 -0400 Subject: [PATCH 13/18] Don't reference the readme that we don't produce --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index 62fa223aae..957369a239 100644 --- a/README.md +++ b/README.md @@ -40,8 +40,6 @@ which are both under active development. ## Installation -#### Windows - MSI Available - https://github.com/btcsuite/btcd/releases #### Linux/BSD/MacOSX/POSIX - Build from Source @@ -74,10 +72,6 @@ $ GO111MODULE=on go install -v . ./cmd/... ## Updating -#### Windows - -Install a newer MSI - #### Linux/BSD/MacOSX/POSIX - Build from Source - Run the following commands to update btcd, all dependencies, and install it: @@ -94,10 +88,6 @@ btcd has several configuration options available to tweak how it runs, but all of the basic operations described in the intro section work with zero configuration. -#### Windows (Installed from MSI) - -Launch btcd from your Start menu. - #### Linux/BSD/POSIX/Source ```bash From 7b6c2b342379f3cba880d9f3cc14c77fc7500969 Mon Sep 17 00:00:00 2001 From: Oliver Gugger Date: Tue, 11 May 2021 14:22:09 +0200 Subject: [PATCH 14/18] chaincfg: fix deployment bit numbers On signet all previous soft forks and also taproot are always activated, meaning the version is always 0x20000000 for all blocks. To make sure they activate properly in `btcd` we therefore need to use the correct bit to mask the version. This means that on any custom signet there would need to be 2016 blocks mined before SegWit or Taproot can be used. --- chaincfg/params.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/chaincfg/params.go b/chaincfg/params.go index cb1568632c..a6d8d3e551 100644 --- a/chaincfg/params.go +++ b/chaincfg/params.go @@ -670,17 +670,17 @@ func CustomSignetParams(challenge []byte, dnsSeeds []DNSSeed) Params { ExpireTime: 1230767999, // December 31, 2008 UTC }, DeploymentCSV: { - BitNumber: 0, + BitNumber: 29, StartTime: 0, // Always available for vote ExpireTime: math.MaxInt64, // Never expires }, DeploymentSegwit: { - BitNumber: 1, + BitNumber: 29, StartTime: 0, // Always available for vote ExpireTime: math.MaxInt64, // Never expires. }, DeploymentTaproot: { - BitNumber: 2, + BitNumber: 29, StartTime: 0, // Always available for vote ExpireTime: math.MaxInt64, // Never expires. }, From ee5896bad5be6b35d9308d1698aee2fb77863279 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Wed, 12 May 2021 17:47:26 -0700 Subject: [PATCH 15/18] mempool: add additional test case for inherited RBF replacement In this commit, we add an additional test case for inherited RBF replacement. This test case asserts that if a parent is marked as being replaceable, but the child isn't, then the child can still be replaced as according to BIP 125 it shoudl _inhreit_ the replaceability of its parent. The addition of this test case was prompted by the recently discovered Bitcoin Core "CVE" [1]. It turns out that bitcoind doesn't properly implement BIP 125. Namely it fails to allow a child to "inherit" replaceability if its parent is also replaceable. Our implementation makes this trait rather explicit due to its recursive implementation. Kudos to the original implementer @wpaulino for getting this correct. [1]: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-May/018893.html. --- mempool/mempool_test.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/mempool/mempool_test.go b/mempool/mempool_test.go index 6d43cfd86e..96d5054417 100644 --- a/mempool/mempool_test.go +++ b/mempool/mempool_test.go @@ -1749,6 +1749,47 @@ func TestRBF(t *testing.T) { }, err: "", }, + { + // A transaction that doesn't signal replacement, can + // be replaced if the parent signals replacement. + name: "inherited replacement", + setup: func(ctx *testContext) (*btcutil.Tx, []*btcutil.Tx) { + coinbase := ctx.addCoinbaseTx(1) + + // Create an initial parent transaction that + // marks replacement, we won't be replacing + // this directly however. + coinbaseOut := txOutToSpendableOut(coinbase, 0) + outs := []spendableOutput{coinbaseOut} + parent := ctx.addSignedTx( + outs, 1, defaultFee, true, false, + ) + + // Now create a transaction that spends that + // parent transaction, which is marked as NOT + // being RBF-able. + parentOut := txOutToSpendableOut(parent, 0) + parentOuts := []spendableOutput{parentOut} + childNoReplace := ctx.addSignedTx( + parentOuts, 1, defaultFee, false, false, + ) + + // Now we'll create another transaction that + // replaces the *child* only. This should work + // as the parent has been marked for RBF, even + // though the child hasn't. + respendOuts := []spendableOutput{parentOut} + childReplace, err := ctx.harness.CreateSignedTx( + respendOuts, 1, defaultFee*3, false, + ) + if err != nil { + ctx.t.Fatalf("unable to create child tx: %v", err) + } + + return childReplace, []*btcutil.Tx{childNoReplace} + }, + err: "", + }, } for _, testCase := range testCases { From 418f9204f49c71e6a481653237f00a781c29ea77 Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Wed, 26 May 2021 03:17:24 +0530 Subject: [PATCH 16/18] Update CHANGES file for 0.22.0 release --- CHANGES | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d38897b339..6c5be7fa3a 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,126 @@ User visible changes for btcd A full-node bitcoin implementation written in Go ============================================================================ +Changes in 0.22.0 (Thu May 27 2021) + - Protocol and network-related changes: + - Add support for witness tx and block in notfound msg (#1625) + - Add support for receiving sendaddrv2 messages from a peer (#1670) + - Fix bug in peer package causing last block height to go backwards + (#1606) + - Add chain parameters for connecting to the public Signet network + (#1692, #1718) + - Crypto changes: + - Fix bug causing panic due to bad R and S signature components in + btcec.RecoverCompact (#1691) + - Set the name (secp256k1) in the CurveParams of the S256 curve + (#1565) + - Notable developer-related package changes: + - Remove unknown block version warning in the blockchain package, + due to false positives triggered by AsicBoost (#1463) + - Add chaincfg.RegisterHDKeyID function to populate HD key ID pairs + (#1617) + - Add new method mining.AddWitnessCommitment to add the witness + commitment as an OP_RETURN output within the coinbase transaction. + (#1716) + - RPC changes: + - Support Batch JSON-RPC in rpcclient and server (#1583) + - Add rpcclient method to invoke getdescriptorinfo JSON-RPC command + (#1578) + - Update the rpcserver handler for validateaddress JSON-RPC command to + have parity with the bitcoind 0.20.0 interface (#1613) + - Add rpcclient method to invoke getblockfilter JSON-RPC command + (#1579) + - Add signmessagewithprivkey JSON-RPC command in rpcserver (#1585) + - Add rpcclient method to invoke importmulti JSON-RPC command (#1579) + - Add watchOnly argument in rpcclient method to invoke + listtransactions JSON-RPC command (#1628) + - Update btcjson.ListTransactionsResult for compatibility with Bitcoin + Core 0.20.0 (#1626) + - Support nullable optional JSON-RPC parameters (#1594) + - Add rpcclient and server method to invoke getnodeaddresses JSON-RPC + command (#1590) + - Add rpcclient methods to invoke PSBT JSON-RPC commands (#1596) + - Add rpcclient method to invoke listsinceblock with the + include_watchonly parameter enabled (#1451) + - Add rpcclient method to invoke deriveaddresses JSON-RPC command + (#1631) + - Add rpcclient method to invoke getblocktemplate JSON-RPC command + (#1629) + - Add rpcclient method to invoke getaddressinfo JSON-RPC command + (#1633) + - Add rpcclient method to invoke getwalletinfo JSON-RPC command + (#1638) + - Fix error message in rpcserver when an unknown RPC command is + encountered (#1695) + - Fix error message returned by estimatefee when the number of blocks + exceeds the max depth (#1678) + - Update btcjson.GetBlockChainInfoResult to include new fields in + Bitcoin Core (#1676) + - Add ExtraHeaders in rpcclient.ConnConfig struct (#1669) + - Fix bitcoind compatibility issue with the sendrawtransaction + JSON-RPC command (#1659) + - Add new JSON-RPC errors to btcjson package, and documented them + (#1648) + - Add rpcclient method to invoke createwallet JSON-RPC command + (#1650) + - Add rpcclient methods to invoke backupwallet, dumpwallet, loadwallet + and unloadwallet JSON-RPC commands (#1645) + - Fix unmarshalling error in getmininginfo JSON-RPC command, for valid + integers in scientific notation (#1644) + - Add rpcclient method to invoke gettxoutsetinfo JSON-RPC command + (#1641) + - Add rpcclient method to invoke signrawtransactionwithwallet JSON-RPC + command (#1642) + - Add txid to getblocktemplate response of rpcserver (#1639) + - Fix monetary unit used in createrawtransaction JSON-RPC command in + rpcserver (#1614) + - Add rawtx field to btcjson.GetBlockVerboseTxResult to provide + backwards compatibility with older versions of Bitcoin Core (#1677) + - Misc changes: + - Update btcutil dependency (#1704) + - Add Dockerfile to build and run btcd on Docker (#1465) + - Rework documentation and publish on https://btcd.readthedocs.io (#1468) + - Add support for Go 1.15 (#1619) + - Add Go 1.14 as the minimum supported version of Golang (#1621) + - Contributors (alphabetical order): + - 10gic + - Andrew Tugarinov + - Anirudha Bose + - Appelberg-s + - Armando Ochoa + - Aurèle Oulès + - Calvin Kim + - Christian Lehmann + - Conner Fromknecht + - Dan Cline + - David Mazary + - Elliott Minns + - Federico Bond + - Friedger Müffke + - Gustavo Chain + - Hanjun Kim + - Henry Fisher + - Iskander Sharipov + - Jake Sylvestre + - Johan T. Halseth + - John C. Vernaleo + - Liran Sharir + - Mikael Lindlof + - Olaoluwa Osuntokun + - Oliver Gugger + - Rjected + - Steven Kreuzer + - Torkel Rogstad + - Tristyn + - Victor Lavaud + - Vinayak Borkar + - Wilmer Paulino + - Yaacov Akiba Slama + - ebiiim + - ipriver + - wakiyamap + - yyforyongyu + Changes in 0.21.0 (Thu Aug 27 2020) - Network-related changes: - Handle notfound messages from peers in netsync package (#1603) @@ -26,7 +146,7 @@ Changes in 0.21.0 (Thu Aug 27 2020) - Fix panic in fieldVal.SetByteSlice when called with large values, and improve the method to be 35% faster (#1602) - btcctl changes: - - Added -regtest mode to btcctl (#1556) + - Add -regtest mode to btcctl (#1556) - Misc changes: - Fix a bug due to a deadlock in connmgr's dynamic ban scoring (#1509) - Add blockchain.NewUtxoEntry() to directly create entries for From aaf19b26f3abfc5b0374042881d8e43cf1d95a8c Mon Sep 17 00:00:00 2001 From: "John C. Vernaleo" Date: Wed, 26 May 2021 11:13:28 -0400 Subject: [PATCH 17/18] btcd: bump version to v0.22.0-beta --- cmd/btcctl/version.go | 2 +- version.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/btcctl/version.go b/cmd/btcctl/version.go index f3a3e0b830..edb42dbe7d 100644 --- a/cmd/btcctl/version.go +++ b/cmd/btcctl/version.go @@ -17,7 +17,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr // versioning 2.0.0 spec (http://semver.org/). const ( appMajor uint = 0 - appMinor uint = 21 + appMinor uint = 22 appPatch uint = 0 // appPreRelease MUST only contain characters from semanticAlphabet diff --git a/version.go b/version.go index ac294de232..d6ff9171aa 100644 --- a/version.go +++ b/version.go @@ -17,7 +17,7 @@ const semanticAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqr // versioning 2.0.0 spec (http://semver.org/). const ( appMajor uint = 0 - appMinor uint = 21 + appMinor uint = 22 appPatch uint = 0 // appPreRelease MUST only contain characters from semanticAlphabet From 63438c6d3661a7dec09013f7731035abdf1eb4bc Mon Sep 17 00:00:00 2001 From: Anirudha Bose Date: Tue, 1 Jun 2021 21:27:38 +0530 Subject: [PATCH 18/18] Update release date for v0.22.0-beta in CHANGES file --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 6c5be7fa3a..fd59a88672 100644 --- a/CHANGES +++ b/CHANGES @@ -3,7 +3,7 @@ User visible changes for btcd A full-node bitcoin implementation written in Go ============================================================================ -Changes in 0.22.0 (Thu May 27 2021) +Changes in 0.22.0 (Tue Jun 01 2021) - Protocol and network-related changes: - Add support for witness tx and block in notfound msg (#1625) - Add support for receiving sendaddrv2 messages from a peer (#1670)