From 8107c4478b77ddc351a17131395a876cae0be4e3 Mon Sep 17 00:00:00 2001 From: Manu Herrera Date: Mon, 9 Nov 2020 10:05:29 -0300 Subject: [PATCH] Release v0.3.0 --- go.mod | 13 +- go.sum | 179 +- keys_generator.go | 18 +- main.go | 241 + recovery_tool.go | 263 +- sweeper.go | 54 + vendor/github.com/aead/chacha20/.gitignore | 25 + vendor/github.com/aead/chacha20/.travis.yml | 25 + vendor/github.com/aead/chacha20/LICENSE | 21 + vendor/github.com/aead/chacha20/README.md | 82 + .../github.com/aead/chacha20/chacha/chacha.go | 197 + .../aead/chacha20/chacha/chachaAVX2_amd64.s | 406 + .../aead/chacha20/chacha/chacha_386.go | 60 + .../aead/chacha20/chacha/chacha_386.s | 163 + .../aead/chacha20/chacha/chacha_amd64.go | 76 + .../aead/chacha20/chacha/chacha_amd64.s | 1072 + .../aead/chacha20/chacha/chacha_generic.go | 319 + .../aead/chacha20/chacha/chacha_ref.go | 33 + .../github.com/aead/chacha20/chacha/const.s | 53 + .../github.com/aead/chacha20/chacha/macro.s | 163 + vendor/github.com/aead/chacha20/chacha20.go | 41 + .../btcsuite/btcd/blockchain/chainio.go | 13 +- .../btcsuite/btcd/blockchain/utxoviewpoint.go | 16 + .../github.com/btcsuite/btcd/btcec/field.go | 20 +- .../btcsuite/btcd/btcjson/btcdextcmds.go | 18 + .../btcsuite/btcd/btcjson/chainsvrcmds.go | 114 +- .../btcsuite/btcd/btcjson/chainsvrresults.go | 182 +- .../btcsuite/btcd/btcjson/chainsvrwscmds.go | 20 +- .../btcsuite/btcd/btcjson/chainsvrwsntfns.go | 36 +- .../btcsuite/btcd/btcjson/jsonrpc.go | 4 +- .../btcsuite/btcd/btcjson/jsonrpcerr.go | 1 + .../btcsuite/btcd/btcjson/register.go | 2 +- .../btcsuite/btcd/btcjson/walletsvrcmds.go | 35 + .../btcsuite/btcd/btcjson/walletsvrresults.go | 14 + .../btcsuite/btcd/connmgr/dynamicbanscore.go | 2 +- .../btcd/integration/rpctest/README.md | 30 + .../btcd/integration/rpctest/blockgen.go | 207 + .../btcsuite/btcd/integration/rpctest/btcd.go | 62 + .../btcsuite/btcd/integration/rpctest/doc.go | 12 + .../btcd/integration/rpctest/memwallet.go | 591 + .../btcsuite/btcd/integration/rpctest/node.go | 287 + .../btcd/integration/rpctest/rpc_harness.go | 500 + .../btcd/integration/rpctest/utils.go | 164 + .../btcsuite/btcd/peer/mruinvmap.go | 127 - .../btcsuite/btcd/peer/mrunoncemap.go | 125 - vendor/github.com/btcsuite/btcd/peer/peer.go | 15 +- .../btcsuite/btcd/rpcclient/chain.go | 268 +- .../btcsuite/btcd/rpcclient/cookiefile.go | 38 + .../github.com/btcsuite/btcd/rpcclient/doc.go | 2 +- .../btcsuite/btcd/rpcclient/infrastructure.go | 133 +- .../btcsuite/btcd/rpcclient/mining.go | 47 + .../btcsuite/btcd/rpcclient/notify.go | 34 +- .../btcd/rpcclient/rawtransactions.go | 53 +- .../btcsuite/btcd/rpcclient/wallet.go | 166 +- .../btcsuite/btcd/txscript/engine.go | 2 +- vendor/github.com/btcsuite/btcutil/go.mod | 11 + vendor/github.com/btcsuite/btcutil/go.sum | 54 + .../github.com/btcsuite/btcutil/psbt/LICENSE | 16 + .../github.com/btcsuite/btcutil/psbt/bip32.go | 77 + .../btcsuite/btcutil/psbt/creator.go | 63 + .../btcsuite/btcutil/psbt/extractor.go | 81 + .../btcsuite/btcutil/psbt/finalizer.go | 462 + .../github.com/btcsuite/btcutil/psbt/go.mod | 9 + .../github.com/btcsuite/btcutil/psbt/go.sum | 36 + .../btcsuite/btcutil/psbt/partial_input.go | 367 + .../btcsuite/btcutil/psbt/partial_output.go | 139 + .../btcsuite/btcutil/psbt/partialsig.go | 58 + .../github.com/btcsuite/btcutil/psbt/psbt.go | 407 + .../btcsuite/btcutil/psbt/signer.go | 152 + .../github.com/btcsuite/btcutil/psbt/types.go | 149 + .../btcsuite/btcutil/psbt/updater.go | 367 + .../github.com/btcsuite/btcutil/psbt/utils.go | 277 + .../btcsuite/btcutil/txsort/README.md | 31 + .../github.com/btcsuite/btcutil/txsort/doc.go | 20 + .../btcsuite/btcutil/txsort/txsort.go | 95 + .../btcsuite/btcwallet/chain/bitcoind_conn.go | 99 +- .../btcsuite/btcwallet/chain/neutrino.go | 9 +- .../internal/legacy/keystore/keystore.go | 3241 + .../internal/legacy/rename/rename_unix.go | 17 + .../internal/legacy/rename/rename_windows.go | 71 + .../btcwallet/internal/prompt/prompt.go | 323 + .../btcsuite/btcwallet/waddrmgr/README.md | 3 +- .../btcsuite/btcwallet/waddrmgr/db.go | 4 + .../btcsuite/btcwallet/waddrmgr/manager.go | 386 +- .../btcwallet/waddrmgr/scoped_manager.go | 112 +- .../btcsuite/btcwallet/wallet/README.md | 31 + .../btcsuite/btcwallet/wallet/chainntfns.go | 485 + .../btcsuite/btcwallet/wallet/common.go | 88 + .../btcsuite/btcwallet/wallet/createtx.go | 290 + .../btcsuite/btcwallet/wallet/disksync.go | 31 + .../btcsuite/btcwallet/wallet/doc.go | 12 + .../btcsuite/btcwallet/wallet/loader.go | 284 + .../btcsuite/btcwallet/wallet/log.go | 65 + .../btcsuite/btcwallet/wallet/mock.go | 85 + .../btcsuite/btcwallet/wallet/multisig.go | 114 + .../btcwallet/wallet/notifications.go | 637 + .../btcsuite/btcwallet/wallet/recovery.go | 410 + .../btcsuite/btcwallet/wallet/rescan.go | 318 + .../btcwallet/wallet/txauthor/LICENSE | 16 + .../btcwallet/wallet/txauthor/author.go | 367 + .../btcwallet/wallet/txauthor/cprng.go | 39 + .../btcsuite/btcwallet/wallet/txauthor/go.mod | 14 + .../btcsuite/btcwallet/wallet/txauthor/go.sum | 66 + .../btcsuite/btcwallet/wallet/txrules/LICENSE | 16 + .../btcsuite/btcwallet/wallet/txrules/go.mod | 8 + .../btcsuite/btcwallet/wallet/txrules/go.sum | 33 + .../btcwallet/wallet/txrules/rules.go | 98 + .../btcsuite/btcwallet/wallet/txsizes/LICENSE | 16 + .../btcsuite/btcwallet/wallet/txsizes/go.mod | 17 + .../btcsuite/btcwallet/wallet/txsizes/go.sum | 65 + .../btcsuite/btcwallet/wallet/txsizes/size.go | 190 + .../btcsuite/btcwallet/wallet/unstable.go | 44 + .../btcsuite/btcwallet/wallet/utxos.go | 90 + .../btcsuite/btcwallet/wallet/wallet.go | 3847 + .../btcsuite/btcwallet/walletdb/bdb/db.go | 32 +- .../btcsuite/btcwallet/walletdb/go.mod | 4 +- .../btcsuite/btcwallet/walletdb/go.sum | 10 +- .../btcsuite/btcwallet/walletdb/interface.go | 62 +- .../btcsuite/btcwallet/wtxmgr/db.go | 133 +- .../btcsuite/btcwallet/wtxmgr/go.mod | 4 +- .../btcsuite/btcwallet/wtxmgr/go.sum | 22 +- .../btcsuite/btcwallet/wtxmgr/query.go | 89 +- .../btcsuite/btcwallet/wtxmgr/tx.go | 327 +- vendor/github.com/coreos/bbolt/bolt_arm.go | 28 - vendor/github.com/decred/dcrd/lru/LICENSE | 17 + vendor/github.com/decred/dcrd/lru/README.md | 40 + vendor/github.com/decred/dcrd/lru/cache.go | 104 + vendor/github.com/decred/dcrd/lru/doc.go | 24 + vendor/github.com/decred/dcrd/lru/go.mod | 3 + .../golang/protobuf/proto/buffer.go | 324 + .../github.com/golang/protobuf/proto/clone.go | 253 - .../golang/protobuf/proto/decode.go | 427 - .../golang/protobuf/proto/defaults.go | 63 + .../golang/protobuf/proto/deprecated.go | 126 +- .../golang/protobuf/proto/discard.go | 356 +- .../golang/protobuf/proto/encode.go | 203 - .../github.com/golang/protobuf/proto/equal.go | 301 - .../golang/protobuf/proto/extensions.go | 845 +- .../github.com/golang/protobuf/proto/lib.go | 965 - .../golang/protobuf/proto/message_set.go | 181 - .../golang/protobuf/proto/pointer_reflect.go | 360 - .../golang/protobuf/proto/pointer_unsafe.go | 313 - .../golang/protobuf/proto/properties.go | 652 +- .../github.com/golang/protobuf/proto/proto.go | 167 + .../golang/protobuf/proto/registry.go | 323 + .../golang/protobuf/proto/table_marshal.go | 2776 - .../golang/protobuf/proto/table_merge.go | 654 - .../golang/protobuf/proto/table_unmarshal.go | 2053 - .../github.com/golang/protobuf/proto/text.go | 843 - .../golang/protobuf/proto/text_decode.go | 801 + .../golang/protobuf/proto/text_encode.go | 560 + .../golang/protobuf/proto/text_parser.go | 880 - .../github.com/golang/protobuf/proto/wire.go | 78 + .../golang/protobuf/proto/wrappers.go | 34 + vendor/github.com/jinzhu/gorm/.gitignore | 3 + vendor/github.com/jinzhu/gorm/License | 21 + vendor/github.com/jinzhu/gorm/README.md | 5 + vendor/github.com/jinzhu/gorm/association.go | 377 + vendor/github.com/jinzhu/gorm/callback.go | 250 + .../github.com/jinzhu/gorm/callback_create.go | 197 + .../github.com/jinzhu/gorm/callback_delete.go | 63 + .../github.com/jinzhu/gorm/callback_query.go | 109 + .../jinzhu/gorm/callback_query_preload.go | 410 + .../jinzhu/gorm/callback_row_query.go | 41 + .../github.com/jinzhu/gorm/callback_save.go | 170 + .../github.com/jinzhu/gorm/callback_update.go | 121 + vendor/github.com/jinzhu/gorm/dialect.go | 147 + .../github.com/jinzhu/gorm/dialect_common.go | 196 + .../github.com/jinzhu/gorm/dialect_mysql.go | 246 + .../jinzhu/gorm/dialect_postgres.go | 147 + .../github.com/jinzhu/gorm/dialect_sqlite3.go | 107 + .../jinzhu/gorm/dialects/sqlite/sqlite.go | 3 + .../github.com/jinzhu/gorm/docker-compose.yml | 30 + vendor/github.com/jinzhu/gorm/errors.go | 72 + vendor/github.com/jinzhu/gorm/field.go | 66 + vendor/github.com/jinzhu/gorm/go.mod | 14 + vendor/github.com/jinzhu/gorm/go.sum | 33 + vendor/github.com/jinzhu/gorm/interface.go | 24 + .../jinzhu/gorm/join_table_handler.go | 211 + vendor/github.com/jinzhu/gorm/logger.go | 141 + vendor/github.com/jinzhu/gorm/main.go | 886 + vendor/github.com/jinzhu/gorm/model.go | 14 + vendor/github.com/jinzhu/gorm/model_struct.go | 677 + vendor/github.com/jinzhu/gorm/naming.go | 124 + vendor/github.com/jinzhu/gorm/scope.go | 1425 + vendor/github.com/jinzhu/gorm/search.go | 203 + vendor/github.com/jinzhu/gorm/test_all.sh | 5 + vendor/github.com/jinzhu/gorm/utils.go | 226 + vendor/github.com/jinzhu/gorm/wercker.yml | 149 + vendor/github.com/jinzhu/inflection/LICENSE | 21 + vendor/github.com/jinzhu/inflection/README.md | 55 + vendor/github.com/jinzhu/inflection/go.mod | 1 + .../jinzhu/inflection/inflections.go | 273 + .../github.com/jinzhu/inflection/wercker.yml | 23 + vendor/github.com/jrick/logrotate/LICENSE | 26 + .../jrick/logrotate/rotator/rotator.go | 235 + vendor/github.com/lightninglabs/gozmq/zmq.go | 97 +- .../lightning-onion/.gitignore | 2 + .../lightning-onion/.travis.yml | 17 + .../lightningnetwork/lightning-onion/LICENSE | 19 + .../lightning-onion/README.md | 66 + .../lightningnetwork/lightning-onion/batch.go | 100 + .../lightning-onion/crypto.go | 289 + .../lightningnetwork/lightning-onion/error.go | 27 + .../lightningnetwork/lightning-onion/go.mod | 13 + .../lightningnetwork/lightning-onion/go.sum | 42 + .../lightning-onion/hornet.go | 114 + .../lightningnetwork/lightning-onion/log.go | 42 + .../lightning-onion/obfuscation.go | 126 + .../lightning-onion/packetfiller.go | 61 + .../lightningnetwork/lightning-onion/path.go | 395 + .../lightning-onion/replay_set.go | 81 + .../lightning-onion/replaylog.go | 188 + .../lightning-onion/sphinx.go | 778 + .../lightning-onion/varint.go | 109 + .../lightningnetwork/lnd/build/deployment.go | 36 + .../lnd/build/deployment_dev.go | 6 + .../lnd/build/deployment_prod.go | 6 + .../lightningnetwork/lnd/build/log.go | 200 + .../lightningnetwork/lnd/build/log_default.go | 18 + .../lightningnetwork/lnd/build/log_nolog.go | 11 + .../lightningnetwork/lnd/build/log_stdlog.go | 14 + .../lnd/build/loglevel_critical.go | 6 + .../lnd/build/loglevel_debug.go | 6 + .../lnd/build/loglevel_default.go | 6 + .../lnd/build/loglevel_error.go | 6 + .../lnd/build/loglevel_info.go | 6 + .../lnd/build/loglevel_off.go | 6 + .../lnd/build/loglevel_trace.go | 6 + .../lnd/build/loglevel_warn.go | 6 + .../lightningnetwork/lnd/build/logrotator.go | 151 + .../lightningnetwork/lnd/build/prefix_log.go | 112 + .../lightningnetwork/lnd/build/version.go | 90 + .../lightningnetwork/lnd/chainntnfs/README.md | 30 + .../lnd/chainntnfs/height_hint_cache.go | 296 + .../lnd/chainntnfs/interface.go | 705 + .../lnd/chainntnfs/interface_dev.go | 15 + .../lightningnetwork/lnd/chainntnfs/log.go | 29 + .../lnd/chainntnfs/test_utils.go | 304 + .../lnd/chainntnfs/txnotifier.go | 1963 + .../lightningnetwork/lnd/channeldb/README.md | 24 + .../lightningnetwork/lnd/channeldb/addr.go | 221 + .../lightningnetwork/lnd/channeldb/channel.go | 3331 + .../lnd/channeldb/channel_cache.go | 50 + .../lightningnetwork/lnd/channeldb/codec.go | 454 + .../lightningnetwork/lnd/channeldb/db.go | 1323 + .../lightningnetwork/lnd/channeldb/doc.go | 1 + .../lnd/channeldb/duplicate_payments.go | 246 + .../lightningnetwork/lnd/channeldb/error.go | 133 + .../lightningnetwork/lnd/channeldb/fees.go | 1 + .../lnd/channeldb/forwarding_log.go | 274 + .../lnd/channeldb/forwarding_package.go | 928 + .../lightningnetwork/lnd/channeldb/graph.go | 4077 + .../lnd/channeldb/invoices.go | 1597 + .../lnd/channeldb/kvdb/bbolt.go | 10 + .../lnd/channeldb/kvdb/interface.go | 90 + .../lnd/channeldb/legacy_serialization.go | 55 + .../lightningnetwork/lnd/channeldb/log.go | 34 + .../lightningnetwork/lnd/channeldb/meta.go | 80 + .../lnd/channeldb/migration12/invoices.go | 318 + .../lnd/channeldb/migration12/log.go | 14 + .../lnd/channeldb/migration12/migration.go | 74 + .../lnd/channeldb/migration13/log.go | 14 + .../lnd/channeldb/migration13/migration.go | 202 + .../lnd/channeldb/migration_01_to_11/addr.go | 221 + .../channeldb/migration_01_to_11/channel.go | 751 + .../lnd/channeldb/migration_01_to_11/codec.go | 448 + .../lnd/channeldb/migration_01_to_11/db.go | 216 + .../lnd/channeldb/migration_01_to_11/error.go | 56 + .../lnd/channeldb/migration_01_to_11/graph.go | 1179 + .../channeldb/migration_01_to_11/invoices.go | 550 + .../legacy_serialization.go | 55 + .../lnd/channeldb/migration_01_to_11/log.go | 14 + .../lnd/channeldb/migration_01_to_11/meta.go | 39 + .../migration_09_legacy_serialization.go | 496 + .../migration_10_route_tlv_records.go | 235 + .../migration_11_invoices.go | 230 + .../migration_01_to_11/migrations.go | 938 + .../channeldb/migration_01_to_11/options.go | 41 + .../migration_01_to_11/payment_control.go | 21 + .../channeldb/migration_01_to_11/payments.go | 621 + .../lnd/channeldb/migration_01_to_11/route.go | 330 + .../lnd/channeldb/mp_payment.go | 299 + .../lightningnetwork/lnd/channeldb/nodes.go | 316 + .../lightningnetwork/lnd/channeldb/options.go | 87 + .../lnd/channeldb/payment_control.go | 678 + .../lnd/channeldb/payments.go | 909 + .../lnd/channeldb/reject_cache.go | 95 + .../lnd/channeldb/waitingproof.go | 251 + .../lnd/channeldb/witness_cache.go | 229 + .../lightningnetwork/lnd/clock/LICENSE | 19 + .../lnd/clock/default_clock.go | 24 + .../lightningnetwork/lnd/clock/go.mod | 3 + .../lightningnetwork/lnd/clock/interface.go | 16 + .../lightningnetwork/lnd/clock/test_clock.go | 96 + .../lnd/htlcswitch/hop/error_encryptor.go | 205 + .../lnd/htlcswitch/hop/forwarding_info.go | 29 + .../lnd/htlcswitch/hop/iterator.go | 393 + .../lnd/htlcswitch/hop/log.go | 16 + .../lnd/htlcswitch/hop/network.go | 28 + .../lnd/htlcswitch/hop/payload.go | 291 + .../lnd/htlcswitch/hop/type.go | 13 + .../lightningnetwork/lnd/input/input.go | 200 + .../lnd/input/script_utils.go | 1298 + .../lnd/input/signdescriptor.go | 226 + .../lightningnetwork/lnd/input/signer.go | 42 + .../lightningnetwork/lnd/input/size.go | 588 + .../lightningnetwork/lnd/input/test_utils.go | 191 + .../lightningnetwork/lnd/input/txout.go | 46 + .../lightningnetwork/lnd/input/witnessgen.go | 443 + .../lnd/keychain/btcwallet.go | 373 + .../lnd/keychain/derivation.go | 198 + .../lightningnetwork/lnd/lntypes/hash.go | 52 + .../lightningnetwork/lnd/lntypes/preimage.go | 60 + .../lightningnetwork/lnd/lnwallet/README.md | 26 + .../lnd/lnwallet/chainfee/estimator.go | 731 + .../lnd/lnwallet/chainfee/log.go | 29 + .../lnd/lnwallet/chainfee/rates.go | 58 + .../lnd/lnwallet/chanfunding/assembler.go | 137 + .../lnwallet/chanfunding/canned_assembler.go | 207 + .../lnd/lnwallet/chanfunding/coin_select.go | 216 + .../lnd/lnwallet/chanfunding/log.go | 29 + .../lnwallet/chanfunding/psbt_assembler.go | 524 + .../lnwallet/chanfunding/wallet_assembler.go | 343 + .../lightningnetwork/lnd/lnwallet/channel.go | 6700 + .../lnd/lnwallet/chanvalidate/validate.go | 205 + .../lnd/lnwallet/commit_sort.go | 114 + .../lnd/lnwallet/commitment.go | 774 + .../lightningnetwork/lnd/lnwallet/config.go | 59 + .../lightningnetwork/lnd/lnwallet/errors.go | 189 + .../lnd/lnwallet/interface.go | 372 + .../lightningnetwork/lnd/lnwallet/log.go | 55 + .../lnd/lnwallet/parameters.go | 13 + .../lnd/lnwallet/reservation.go | 690 + .../lightningnetwork/lnd/lnwallet/sigpool.go | 307 + .../lnd/lnwallet/test_utils.go | 516 + .../lnd/lnwallet/transactions.go | 210 + .../lightningnetwork/lnd/lnwallet/wallet.go | 1816 + .../lnd/lnwire/accept_channel.go | 28 +- .../lightningnetwork/lnd/lnwire/channel_id.go | 14 +- .../lightningnetwork/lnd/lnwire/features.go | 172 +- .../lnd/lnwire/init_message.go | 24 +- .../lightningnetwork/lnd/lnwire/lnwire.go | 4 +- .../lightningnetwork/lnd/lnwire/msat.go | 12 +- .../lnd/lnwire/node_announcement.go | 8 - .../lnd/lnwire/onion_error.go | 95 + .../lnd/lnwire/open_channel.go | 29 +- .../lnd/lnwire/query_channel_range.go | 12 + .../lnd/lnwire/query_short_chan_ids.go | 100 +- .../lnd/lnwire/reply_channel_range.go | 8 +- .../lightningnetwork/lnd/lnwire/shutdown.go | 16 +- .../lightningnetwork/lnd/lnwire/signature.go | 3 +- .../lnd/netann/chan_status_manager.go | 607 + .../lnd/netann/channel_announcement.go | 86 + .../lnd/netann/channel_state.go | 75 + .../lnd/netann/channel_update.go | 148 + .../lightningnetwork/lnd/netann/interface.go | 23 + .../lightningnetwork/lnd/netann/log.go | 45 + .../lnd/netann/node_announcement.go | 60 + .../lnd/netann/node_signer.go | 83 + .../lightningnetwork/lnd/netann/sign.go | 37 + .../lnd/queue/circular_buf.go | 116 + .../lightningnetwork/lnd/queue/gc_queue.go | 2 - .../lightningnetwork/lnd/queue/go.mod | 2 + .../lightningnetwork/lnd/queue/go.sum | 2 - .../lnd/queue/priority_queue.go | 76 + .../lightningnetwork/lnd/queue/queue.go | 48 +- .../lightningnetwork/lnd/record/amp.go | 107 + .../lnd/record/custom_records.go | 24 + .../lnd/record/experimental.go | 6 + .../lightningnetwork/lnd/record/hop.go | 47 + .../lightningnetwork/lnd/record/mpp.go | 109 + .../lnd/routing/route/route.go | 492 + .../lightningnetwork/lnd/shachain/element.go | 167 + .../lightningnetwork/lnd/shachain/producer.go | 90 + .../lightningnetwork/lnd/shachain/store.go | 184 + .../lightningnetwork/lnd/shachain/utils.go | 74 + .../lightningnetwork/lnd/tlv/primitive.go | 309 + .../lightningnetwork/lnd/tlv/record.go | 251 + .../lightningnetwork/lnd/tlv/stream.go | 318 + .../lightningnetwork/lnd/tlv/truncated.go | 207 + .../lightningnetwork/lnd/tlv/varint.go | 116 + .../lightningnetwork/lnd/tor/README.md | 4 +- .../lightningnetwork/lnd/tor/add_onion.go | 217 + .../lightningnetwork/lnd/tor/controller.go | 324 +- .../lightningnetwork/lnd/zpay32/invoice.go | 178 +- vendor/github.com/ltcsuite/ltcd/LICENSE | 16 + .../ltcsuite/ltcd/chaincfg/README.md | 87 + .../ltcd/chaincfg/chainhash/README.md | 41 + .../ltcsuite/ltcd/chaincfg/chainhash/doc.go | 5 + .../ltcsuite/ltcd/chaincfg/chainhash/hash.go | 128 + .../ltcd/chaincfg/chainhash/hashfuncs.go | 33 + .../github.com/ltcsuite/ltcd/chaincfg/doc.go | 61 + .../ltcsuite/ltcd/chaincfg/genesis.go | 178 + .../ltcsuite/ltcd/chaincfg/params.go | 696 + .../github.com/ltcsuite/ltcd/wire/README.md | 113 + .../ltcsuite/ltcd/wire/blockheader.go | 147 + .../github.com/ltcsuite/ltcd/wire/common.go | 689 + vendor/github.com/ltcsuite/ltcd/wire/doc.go | 162 + vendor/github.com/ltcsuite/ltcd/wire/error.go | 34 + .../github.com/ltcsuite/ltcd/wire/invvect.go | 86 + .../github.com/ltcsuite/ltcd/wire/message.go | 436 + .../github.com/ltcsuite/ltcd/wire/msgaddr.go | 143 + .../github.com/ltcsuite/ltcd/wire/msgalert.go | 407 + .../github.com/ltcsuite/ltcd/wire/msgblock.go | 290 + .../ltcsuite/ltcd/wire/msgcfcheckpt.go | 164 + .../ltcsuite/ltcd/wire/msgcfheaders.go | 180 + .../ltcsuite/ltcd/wire/msgcfilter.go | 119 + .../ltcsuite/ltcd/wire/msgfeefilter.go | 64 + .../ltcsuite/ltcd/wire/msgfilteradd.go | 81 + .../ltcsuite/ltcd/wire/msgfilterclear.go | 59 + .../ltcsuite/ltcd/wire/msgfilterload.go | 136 + .../ltcsuite/ltcd/wire/msggetaddr.go | 47 + .../ltcsuite/ltcd/wire/msggetblocks.go | 139 + .../ltcsuite/ltcd/wire/msggetcfcheckpt.go | 64 + .../ltcsuite/ltcd/wire/msggetcfheaders.go | 77 + .../ltcsuite/ltcd/wire/msggetcfilters.go | 81 + .../ltcsuite/ltcd/wire/msggetdata.go | 133 + .../ltcsuite/ltcd/wire/msggetheaders.go | 136 + .../ltcsuite/ltcd/wire/msgheaders.go | 136 + .../github.com/ltcsuite/ltcd/wire/msginv.go | 141 + .../ltcsuite/ltcd/wire/msgmempool.go | 60 + .../ltcsuite/ltcd/wire/msgmerkleblock.go | 159 + .../ltcsuite/ltcd/wire/msgnotfound.go | 110 + .../github.com/ltcsuite/ltcd/wire/msgping.go | 87 + .../github.com/ltcsuite/ltcd/wire/msgpong.go | 78 + .../ltcsuite/ltcd/wire/msgreject.go | 186 + .../ltcsuite/ltcd/wire/msgsendheaders.go | 60 + vendor/github.com/ltcsuite/ltcd/wire/msgtx.go | 1027 + .../ltcsuite/ltcd/wire/msgverack.go | 46 + .../ltcsuite/ltcd/wire/msgversion.go | 269 + .../ltcsuite/ltcd/wire/netaddress.go | 149 + .../github.com/ltcsuite/ltcd/wire/protocol.go | 182 + vendor/github.com/mattn/go-sqlite3/.gitignore | 14 + .../github.com/mattn/go-sqlite3/.travis.yml | 35 + vendor/github.com/mattn/go-sqlite3/LICENSE | 21 + vendor/github.com/mattn/go-sqlite3/README.md | 588 + vendor/github.com/mattn/go-sqlite3/backup.go | 85 + .../github.com/mattn/go-sqlite3/callback.go | 398 + vendor/github.com/mattn/go-sqlite3/convert.go | 299 + vendor/github.com/mattn/go-sqlite3/doc.go | 112 + vendor/github.com/mattn/go-sqlite3/error.go | 150 + vendor/github.com/mattn/go-sqlite3/go.mod | 8 + vendor/github.com/mattn/go-sqlite3/go.sum | 13 + .../mattn/go-sqlite3/sqlite3-binding.c | 229976 +++++++++++++++ .../mattn/go-sqlite3/sqlite3-binding.h | 12269 + vendor/github.com/mattn/go-sqlite3/sqlite3.go | 2136 + .../mattn/go-sqlite3/sqlite3_context.go | 103 + .../mattn/go-sqlite3/sqlite3_func_crypt.go | 120 + .../mattn/go-sqlite3/sqlite3_go18.go | 70 + .../mattn/go-sqlite3/sqlite3_libsqlite3.go | 18 + .../go-sqlite3/sqlite3_load_extension.go | 84 + .../go-sqlite3/sqlite3_load_extension_omit.go | 24 + .../sqlite3_opt_allow_uri_authority.go | 15 + .../mattn/go-sqlite3/sqlite3_opt_app_armor.go | 16 + .../go-sqlite3/sqlite3_opt_foreign_keys.go | 15 + .../mattn/go-sqlite3/sqlite3_opt_fts5.go | 14 + .../mattn/go-sqlite3/sqlite3_opt_icu.go | 17 + .../go-sqlite3/sqlite3_opt_introspect.go | 15 + .../mattn/go-sqlite3/sqlite3_opt_json1.go | 13 + .../mattn/go-sqlite3/sqlite3_opt_preupdate.go | 20 + .../go-sqlite3/sqlite3_opt_preupdate_hook.go | 112 + .../go-sqlite3/sqlite3_opt_preupdate_omit.go | 21 + .../go-sqlite3/sqlite3_opt_secure_delete.go | 15 + .../sqlite3_opt_secure_delete_fast.go | 15 + .../mattn/go-sqlite3/sqlite3_opt_stat4.go | 15 + .../go-sqlite3/sqlite3_opt_unlock_notify.c | 85 + .../go-sqlite3/sqlite3_opt_unlock_notify.go | 93 + .../mattn/go-sqlite3/sqlite3_opt_userauth.go | 289 + .../go-sqlite3/sqlite3_opt_userauth_omit.go | 152 + .../go-sqlite3/sqlite3_opt_vacuum_full.go | 15 + .../go-sqlite3/sqlite3_opt_vacuum_incr.go | 15 + .../mattn/go-sqlite3/sqlite3_opt_vtable.go | 650 + .../mattn/go-sqlite3/sqlite3_other.go | 17 + .../mattn/go-sqlite3/sqlite3_solaris.go | 14 + .../mattn/go-sqlite3/sqlite3_trace.go | 287 + .../mattn/go-sqlite3/sqlite3_type.go | 62 + .../go-sqlite3/sqlite3_usleep_windows.go | 39 + .../mattn/go-sqlite3/sqlite3_windows.go | 18 + .../github.com/mattn/go-sqlite3/sqlite3ext.h | 664 + .../mattn/go-sqlite3/static_mock.go | 37 + vendor/github.com/miekg/dns/.codecov.yml | 8 + vendor/github.com/miekg/dns/.travis.yml | 15 +- vendor/github.com/miekg/dns/CODEOWNERS | 1 + vendor/github.com/miekg/dns/LICENSE | 6 +- vendor/github.com/miekg/dns/Makefile.release | 52 + vendor/github.com/miekg/dns/README.md | 73 +- vendor/github.com/miekg/dns/acceptfunc.go | 61 + vendor/github.com/miekg/dns/client.go | 236 +- vendor/github.com/miekg/dns/clientconfig.go | 16 +- vendor/github.com/miekg/dns/defaults.go | 137 +- vendor/github.com/miekg/dns/dns.go | 71 +- vendor/github.com/miekg/dns/dnssec.go | 232 +- vendor/github.com/miekg/dns/dnssec_keygen.go | 58 +- vendor/github.com/miekg/dns/dnssec_keyscan.go | 249 +- vendor/github.com/miekg/dns/dnssec_privkey.go | 21 +- vendor/github.com/miekg/dns/doc.go | 112 +- vendor/github.com/miekg/dns/duplicate.go | 37 + vendor/github.com/miekg/dns/edns.go | 171 +- vendor/github.com/miekg/dns/format.go | 8 +- vendor/github.com/miekg/dns/fuzz.go | 11 +- vendor/github.com/miekg/dns/generate.go | 316 +- vendor/github.com/miekg/dns/go.mod | 11 + vendor/github.com/miekg/dns/go.sum | 39 + .../miekg/dns/internal/socket/cmsghdr.go | 7 - .../internal/socket/cmsghdr_linux_64bit.go | 20 - .../dns/internal/socket/cmsghdr_other.go | 13 - .../dns/internal/socket/controlmessage.go | 118 - .../miekg/dns/internal/socket/socket.go | 4 - .../miekg/dns/internal/socket/sys.go | 14 - vendor/github.com/miekg/dns/labels.go | 75 +- vendor/github.com/miekg/dns/listen_go111.go | 44 + .../github.com/miekg/dns/listen_go_not111.go | 23 + vendor/github.com/miekg/dns/msg.go | 847 +- vendor/github.com/miekg/dns/msg_helpers.go | 282 +- vendor/github.com/miekg/dns/msg_truncate.go | 111 + vendor/github.com/miekg/dns/nsecx.go | 49 +- vendor/github.com/miekg/dns/privaterr.go | 132 +- vendor/github.com/miekg/dns/rawmsg.go | 49 - vendor/github.com/miekg/dns/reverse.go | 14 + vendor/github.com/miekg/dns/sanitize.go | 10 +- vendor/github.com/miekg/dns/scan.go | 1135 +- vendor/github.com/miekg/dns/scan_rr.go | 1987 +- vendor/github.com/miekg/dns/scanner.go | 56 - vendor/github.com/miekg/dns/serve_mux.go | 122 + vendor/github.com/miekg/dns/server.go | 705 +- vendor/github.com/miekg/dns/sig0.go | 31 +- vendor/github.com/miekg/dns/singleinflight.go | 10 +- vendor/github.com/miekg/dns/smimea.go | 5 +- vendor/github.com/miekg/dns/tlsa.go | 5 +- vendor/github.com/miekg/dns/tsig.go | 31 +- vendor/github.com/miekg/dns/types.go | 432 +- vendor/github.com/miekg/dns/udp.go | 67 +- vendor/github.com/miekg/dns/udp_linux.go | 220 - vendor/github.com/miekg/dns/udp_other.go | 17 - vendor/github.com/miekg/dns/udp_windows.go | 13 +- vendor/github.com/miekg/dns/update.go | 14 +- vendor/github.com/miekg/dns/version.go | 15 + vendor/github.com/miekg/dns/xfr.go | 64 +- vendor/github.com/miekg/dns/zcompress.go | 119 - vendor/github.com/miekg/dns/zduplicate.go | 1157 + vendor/github.com/miekg/dns/zmsg.go | 2064 +- vendor/github.com/miekg/dns/ztypes.go | 512 +- vendor/github.com/muun/libwallet/.gitignore | 18 +- vendor/github.com/muun/libwallet/V1.go | 54 +- vendor/github.com/muun/libwallet/V2.go | 98 +- vendor/github.com/muun/libwallet/V3.go | 98 +- vendor/github.com/muun/libwallet/V4.go | 89 +- vendor/github.com/muun/libwallet/address.go | 93 +- .../muun/libwallet/addresses/addresses.go | 59 + .../github.com/muun/libwallet/addresses/v1.go | 24 + .../github.com/muun/libwallet/addresses/v2.go | 57 + .../github.com/muun/libwallet/addresses/v3.go | 55 + .../github.com/muun/libwallet/addresses/v4.go | 36 + .../libwallet/{aes.go => aescbc/aescbc.go} | 29 +- vendor/github.com/muun/libwallet/bip70.pb.go | 751 +- vendor/github.com/muun/libwallet/bip70.proto | 36 +- .../muun/libwallet/challenge_keys.go | 25 +- .../muun/libwallet/challenge_public_key.go | 37 +- .../muun/libwallet/derivationpath.go | 79 - .../muun/libwallet/emergency_kit.go | 32 + .../muun/libwallet/emergencykit/content.go | 268 + .../muun/libwallet/emergencykit/css.go | 157 + .../libwallet/emergencykit/emergencykit.go | 91 + vendor/github.com/muun/libwallet/encrypt.go | 413 + vendor/github.com/muun/libwallet/fees.go | 57 + vendor/github.com/muun/libwallet/fees/fees.go | 113 + vendor/github.com/muun/libwallet/go.mod | 22 +- vendor/github.com/muun/libwallet/go.sum | 228 +- .../github.com/muun/libwallet/hdkeycommon.go | 29 - .../muun/libwallet/hdpath/hdpath.go | 128 + .../github.com/muun/libwallet/hdprivatekey.go | 42 +- .../github.com/muun/libwallet/hdpublickey.go | 22 +- .../muun/libwallet/incoming_swap.go | 278 + vendor/github.com/muun/libwallet/init.go | 21 + vendor/github.com/muun/libwallet/invoice.go | 30 +- vendor/github.com/muun/libwallet/invoices.go | 356 + .../muun/libwallet/keycrypt/keycrypt.go | 174 + .../github.com/muun/libwallet/keycrypter.go | 152 +- vendor/github.com/muun/libwallet/network.go | 4 - .../libwallet/partiallysignedtransaction.go | 436 +- vendor/github.com/muun/libwallet/publickey.go | 19 + .../github.com/muun/libwallet/recoverycode.go | 40 + .../libwallet/recoverycode/recoverycode.go | 162 + vendor/github.com/muun/libwallet/ripemd160.go | 2 +- vendor/github.com/muun/libwallet/segwit.go | 12 +- .../muun/libwallet/sphinx/sphinx.go | 58 + .../muun/libwallet/submarineSwap.go | 53 +- .../muun/libwallet/submarineSwapV1.go | 186 +- .../muun/libwallet/submarineSwapV2.go | 247 +- .../github.com/muun/libwallet/swaps/swaps.go | 107 + vendor/github.com/muun/libwallet/swaps/v1.go | 151 + vendor/github.com/muun/libwallet/swaps/v2.go | 205 + .../muun/libwallet/walletdb/walletdb.go | 121 + vendor/github.com/pkg/errors/.travis.yml | 11 +- vendor/github.com/pkg/errors/Makefile | 44 + vendor/github.com/pkg/errors/README.md | 11 +- vendor/github.com/pkg/errors/errors.go | 8 +- vendor/github.com/pkg/errors/go113.go | 38 + vendor/github.com/pkg/errors/stack.go | 58 +- .../coreos => go.etcd.io}/bbolt/.gitignore | 0 .../coreos => go.etcd.io}/bbolt/.travis.yml | 2 +- .../coreos => go.etcd.io}/bbolt/LICENSE | 0 .../coreos => go.etcd.io}/bbolt/Makefile | 0 .../coreos => go.etcd.io}/bbolt/README.md | 15 +- .../coreos => go.etcd.io}/bbolt/bolt_386.go | 3 - .../coreos => go.etcd.io}/bbolt/bolt_amd64.go | 3 - vendor/go.etcd.io/bbolt/bolt_arm.go | 7 + .../coreos => go.etcd.io}/bbolt/bolt_arm64.go | 3 - .../coreos => go.etcd.io}/bbolt/bolt_linux.go | 0 .../bbolt/bolt_mips64x.go | 3 - .../coreos => go.etcd.io}/bbolt/bolt_mipsx.go | 3 - .../bbolt/bolt_openbsd.go | 0 .../coreos => go.etcd.io}/bbolt/bolt_ppc.go | 3 - .../coreos => go.etcd.io}/bbolt/bolt_ppc64.go | 3 - .../bbolt/bolt_ppc64le.go | 3 - .../bbolt/bolt_riscv64.go | 3 - .../coreos => go.etcd.io}/bbolt/bolt_s390x.go | 3 - .../coreos => go.etcd.io}/bbolt/bolt_unix.go | 2 +- vendor/go.etcd.io/bbolt/bolt_unix_aix.go | 90 + .../bbolt/bolt_unix_solaris.go | 0 .../bbolt/bolt_windows.go | 0 .../bbolt/boltsync_unix.go | 0 .../coreos => go.etcd.io}/bbolt/bucket.go | 34 +- .../coreos => go.etcd.io}/bbolt/cursor.go | 2 +- .../coreos => go.etcd.io}/bbolt/db.go | 4 +- .../coreos => go.etcd.io}/bbolt/doc.go | 0 .../coreos => go.etcd.io}/bbolt/errors.go | 0 .../coreos => go.etcd.io}/bbolt/freelist.go | 38 +- .../bbolt/freelist_hmap.go | 2 +- vendor/go.etcd.io/bbolt/go.mod | 5 + vendor/go.etcd.io/bbolt/go.sum | 2 + .../coreos => go.etcd.io}/bbolt/node.go | 56 +- .../coreos => go.etcd.io}/bbolt/page.go | 41 +- .../coreos => go.etcd.io}/bbolt/tx.go | 18 +- vendor/go.etcd.io/bbolt/unsafe.go | 39 + vendor/golang.org/x/crypto/ed25519/ed25519.go | 222 + .../x/crypto/ed25519/ed25519_go113.go | 73 + .../ed25519/internal/edwards25519/const.go | 1422 + .../internal/edwards25519/edwards25519.go | 1793 + .../x/crypto/poly1305/bits_compat.go | 39 + .../x/crypto/poly1305/bits_go1.13.go | 21 + .../golang.org/x/crypto/poly1305/mac_noasm.go | 4 +- .../golang.org/x/crypto/poly1305/poly1305.go | 34 +- .../golang.org/x/crypto/poly1305/sum_amd64.go | 65 +- .../golang.org/x/crypto/poly1305/sum_amd64.s | 42 +- .../golang.org/x/crypto/poly1305/sum_arm.go | 22 - vendor/golang.org/x/crypto/poly1305/sum_arm.s | 427 - .../x/crypto/poly1305/sum_generic.go | 374 +- .../golang.org/x/crypto/poly1305/sum_noasm.go | 16 - .../x/crypto/poly1305/sum_ppc64le.go | 65 +- .../x/crypto/poly1305/sum_ppc64le.s | 68 +- .../golang.org/x/crypto/poly1305/sum_s390x.go | 83 +- .../golang.org/x/crypto/poly1305/sum_s390x.s | 633 +- .../x/crypto/poly1305/sum_vmsl_s390x.s | 909 - .../x/crypto/ssh/terminal/terminal.go | 987 + .../golang.org/x/crypto/ssh/terminal/util.go | 114 + .../x/crypto/ssh/terminal/util_aix.go | 12 + .../x/crypto/ssh/terminal/util_bsd.go | 12 + .../x/crypto/ssh/terminal/util_linux.go | 10 + .../x/crypto/ssh/terminal/util_plan9.go | 58 + .../x/crypto/ssh/terminal/util_solaris.go | 124 + .../x/crypto/ssh/terminal/util_windows.go | 105 + vendor/golang.org/x/net/bpf/asm.go | 41 + vendor/golang.org/x/net/bpf/constants.go | 222 + vendor/golang.org/x/net/bpf/doc.go | 82 + vendor/golang.org/x/net/bpf/instructions.go | 726 + vendor/golang.org/x/net/bpf/setter.go | 10 + vendor/golang.org/x/net/bpf/vm.go | 150 + .../golang.org/x/net/bpf/vm_instructions.go | 182 + .../golang.org/x/net/internal/iana/const.go | 223 + .../x/net/internal/socket/cmsghdr.go | 11 + .../x/net/internal/socket/cmsghdr_bsd.go | 13 + .../internal/socket/cmsghdr_linux_32bit.go | 14 +- .../internal/socket/cmsghdr_linux_64bit.go | 14 + .../internal/socket/cmsghdr_solaris_64bit.go | 14 + .../x/net/internal/socket/cmsghdr_stub.go | 17 + .../golang.org/x/net/internal/socket/empty.s | 7 + .../x/net/internal/socket/error_unix.go | 31 + .../x/net/internal/socket/error_windows.go | 26 + .../x/net/internal/socket/iovec_32bit.go | 19 + .../x/net/internal/socket/iovec_64bit.go | 19 + .../internal/socket/iovec_solaris_64bit.go | 19 + .../x/net/internal/socket/iovec_stub.go | 11 + .../x/net/internal/socket/mmsghdr_stub.go | 21 + .../x/net/internal/socket/mmsghdr_unix.go | 42 + .../x/net/internal/socket/msghdr_bsd.go | 39 + .../x/net/internal/socket/msghdr_bsdvar.go | 16 + .../x/net/internal/socket/msghdr_linux.go | 36 + .../net/internal/socket/msghdr_linux_32bit.go | 24 + .../net/internal/socket/msghdr_linux_64bit.go | 24 + .../x/net/internal/socket/msghdr_openbsd.go | 14 + .../internal/socket/msghdr_solaris_64bit.go | 36 + .../x/net/internal/socket/msghdr_stub.go | 14 + .../x/net/internal/socket/norace.go | 12 + .../golang.org/x/net/internal/socket/race.go | 37 + .../x/net/internal/socket/rawconn.go | 64 + .../x/net/internal/socket/rawconn_mmsg.go | 79 + .../x/net/internal/socket/rawconn_msg.go | 78 + .../x/net/internal/socket/rawconn_nommsg.go | 15 + .../x/net/internal/socket/rawconn_nomsg.go | 15 + .../x/net/internal/socket/socket.go | 288 + .../golang.org/x/net/internal/socket/sys.go | 33 + .../x/net/internal/socket/sys_bsd.go | 15 + .../x/net/internal/socket/sys_bsdvar.go | 23 + .../x/net/internal/socket/sys_const_unix.go | 17 + .../x/net/internal/socket/sys_darwin.go | 7 + .../x/net/internal/socket/sys_dragonfly.go | 32 + .../net/internal/socket/sys_go1_11_darwin.go | 33 + .../x/net/internal/socket/sys_linkname.go | 42 + .../x/net/internal/socket/sys_linux.go | 27 + .../x/net/internal/socket/sys_linux_386.go | 55 + .../x/net/internal/socket/sys_linux_386.s | 11 + .../x/net/internal/socket/sys_linux_amd64.go | 10 + .../x/net/internal/socket/sys_linux_arm.go | 10 + .../x/net/internal/socket/sys_linux_arm64.go | 10 + .../x/net/internal/socket/sys_linux_mips.go | 10 + .../x/net/internal/socket/sys_linux_mips64.go | 10 + .../net/internal/socket/sys_linux_mips64le.go | 10 + .../x/net/internal/socket/sys_linux_mipsle.go | 10 + .../x/net/internal/socket/sys_linux_ppc64.go | 10 + .../net/internal/socket/sys_linux_ppc64le.go | 10 + .../net/internal/socket/sys_linux_riscv64.go | 12 + .../x/net/internal/socket/sys_linux_s390x.go | 55 + .../x/net/internal/socket/sys_linux_s390x.s | 11 + .../x/net/internal/socket/sys_netbsd.go | 25 + .../x/net/internal/socket/sys_posix.go | 183 + .../x/net/internal/socket/sys_solaris.go | 70 + .../x/net/internal/socket/sys_solaris_amd64.s | 11 + .../x/net/internal/socket/sys_stub.go | 63 + .../x/net/internal/socket/sys_unix.go | 33 + .../x/net/internal/socket/sys_windows.go | 71 + .../x/net/internal/socket/zsys_aix_ppc64.go | 60 + .../x/net/internal/socket/zsys_darwin_386.go | 51 + .../net/internal/socket/zsys_darwin_amd64.go | 53 + .../x/net/internal/socket/zsys_darwin_arm.go | 51 + .../net/internal/socket/zsys_darwin_arm64.go | 53 + .../internal/socket/zsys_dragonfly_amd64.go | 53 + .../x/net/internal/socket/zsys_freebsd_386.go | 51 + .../net/internal/socket/zsys_freebsd_amd64.go | 53 + .../x/net/internal/socket/zsys_freebsd_arm.go | 51 + .../net/internal/socket/zsys_freebsd_arm64.go | 53 + .../x/net/internal/socket/zsys_linux_386.go | 54 + .../x/net/internal/socket/zsys_linux_amd64.go | 57 + .../x/net/internal/socket/zsys_linux_arm.go | 55 + .../x/net/internal/socket/zsys_linux_arm64.go | 58 + .../x/net/internal/socket/zsys_linux_mips.go | 55 + .../net/internal/socket/zsys_linux_mips64.go | 58 + .../internal/socket/zsys_linux_mips64le.go | 58 + .../net/internal/socket/zsys_linux_mipsle.go | 55 + .../x/net/internal/socket/zsys_linux_ppc64.go | 58 + .../net/internal/socket/zsys_linux_ppc64le.go | 58 + .../net/internal/socket/zsys_linux_riscv64.go | 59 + .../x/net/internal/socket/zsys_linux_s390x.go | 58 + .../x/net/internal/socket/zsys_netbsd_386.go | 57 + .../net/internal/socket/zsys_netbsd_amd64.go | 60 + .../x/net/internal/socket/zsys_netbsd_arm.go | 57 + .../net/internal/socket/zsys_netbsd_arm64.go | 59 + .../x/net/internal/socket/zsys_openbsd_386.go | 51 + .../net/internal/socket/zsys_openbsd_amd64.go | 53 + .../x/net/internal/socket/zsys_openbsd_arm.go | 51 + .../net/internal/socket/zsys_openbsd_arm64.go | 53 + .../net/internal/socket/zsys_solaris_amd64.go | 52 + .../golang.org/x/net/internal/socks/socks.go | 2 +- vendor/golang.org/x/net/ipv4/batch.go | 194 + vendor/golang.org/x/net/ipv4/control.go | 144 + vendor/golang.org/x/net/ipv4/control_bsd.go | 41 + .../golang.org/x/net/ipv4/control_pktinfo.go | 39 + vendor/golang.org/x/net/ipv4/control_stub.go | 13 + vendor/golang.org/x/net/ipv4/control_unix.go | 73 + .../golang.org/x/net/ipv4/control_windows.go | 12 + vendor/golang.org/x/net/ipv4/dgramopt.go | 264 + vendor/golang.org/x/net/ipv4/doc.go | 244 + vendor/golang.org/x/net/ipv4/endpoint.go | 186 + vendor/golang.org/x/net/ipv4/genericopt.go | 55 + vendor/golang.org/x/net/ipv4/header.go | 173 + vendor/golang.org/x/net/ipv4/helper.go | 77 + vendor/golang.org/x/net/ipv4/iana.go | 38 + vendor/golang.org/x/net/ipv4/icmp.go | 57 + vendor/golang.org/x/net/ipv4/icmp_linux.go | 25 + vendor/golang.org/x/net/ipv4/icmp_stub.go | 25 + vendor/golang.org/x/net/ipv4/packet.go | 117 + vendor/golang.org/x/net/ipv4/payload.go | 23 + vendor/golang.org/x/net/ipv4/payload_cmsg.go | 84 + .../golang.org/x/net/ipv4/payload_nocmsg.go | 39 + vendor/golang.org/x/net/ipv4/sockopt.go | 44 + vendor/golang.org/x/net/ipv4/sockopt_posix.go | 71 + vendor/golang.org/x/net/ipv4/sockopt_stub.go | 42 + vendor/golang.org/x/net/ipv4/sys_aix.go | 38 + vendor/golang.org/x/net/ipv4/sys_asmreq.go | 122 + .../golang.org/x/net/ipv4/sys_asmreq_stub.go | 25 + vendor/golang.org/x/net/ipv4/sys_asmreqn.go | 42 + .../golang.org/x/net/ipv4/sys_asmreqn_stub.go | 21 + vendor/golang.org/x/net/ipv4/sys_bpf.go | 24 + vendor/golang.org/x/net/ipv4/sys_bpf_stub.go | 16 + vendor/golang.org/x/net/ipv4/sys_bsd.go | 37 + vendor/golang.org/x/net/ipv4/sys_darwin.go | 65 + vendor/golang.org/x/net/ipv4/sys_dragonfly.go | 35 + vendor/golang.org/x/net/ipv4/sys_freebsd.go | 76 + vendor/golang.org/x/net/ipv4/sys_linux.go | 60 + vendor/golang.org/x/net/ipv4/sys_solaris.go | 57 + vendor/golang.org/x/net/ipv4/sys_ssmreq.go | 52 + .../golang.org/x/net/ipv4/sys_ssmreq_stub.go | 21 + vendor/golang.org/x/net/ipv4/sys_stub.go | 13 + vendor/golang.org/x/net/ipv4/sys_windows.go | 67 + .../golang.org/x/net/ipv4/zsys_aix_ppc64.go | 33 + vendor/golang.org/x/net/ipv4/zsys_darwin.go | 99 + .../golang.org/x/net/ipv4/zsys_dragonfly.go | 31 + .../golang.org/x/net/ipv4/zsys_freebsd_386.go | 93 + .../x/net/ipv4/zsys_freebsd_amd64.go | 95 + .../golang.org/x/net/ipv4/zsys_freebsd_arm.go | 95 + .../x/net/ipv4/zsys_freebsd_arm64.go | 93 + .../golang.org/x/net/ipv4/zsys_linux_386.go | 130 + .../golang.org/x/net/ipv4/zsys_linux_amd64.go | 132 + .../golang.org/x/net/ipv4/zsys_linux_arm.go | 130 + .../golang.org/x/net/ipv4/zsys_linux_arm64.go | 132 + .../golang.org/x/net/ipv4/zsys_linux_mips.go | 130 + .../x/net/ipv4/zsys_linux_mips64.go | 132 + .../x/net/ipv4/zsys_linux_mips64le.go | 132 + .../x/net/ipv4/zsys_linux_mipsle.go | 130 + .../golang.org/x/net/ipv4/zsys_linux_ppc.go | 130 + .../golang.org/x/net/ipv4/zsys_linux_ppc64.go | 132 + .../x/net/ipv4/zsys_linux_ppc64le.go | 132 + .../x/net/ipv4/zsys_linux_riscv64.go | 134 + .../golang.org/x/net/ipv4/zsys_linux_s390x.go | 132 + vendor/golang.org/x/net/ipv4/zsys_netbsd.go | 30 + vendor/golang.org/x/net/ipv4/zsys_openbsd.go | 30 + vendor/golang.org/x/net/ipv4/zsys_solaris.go | 100 + vendor/golang.org/x/net/ipv6/batch.go | 116 + vendor/golang.org/x/net/ipv6/control.go | 187 + .../x/net/ipv6/control_rfc2292_unix.go | 48 + .../x/net/ipv6/control_rfc3542_unix.go | 94 + vendor/golang.org/x/net/ipv6/control_stub.go | 13 + vendor/golang.org/x/net/ipv6/control_unix.go | 55 + .../golang.org/x/net/ipv6/control_windows.go | 12 + vendor/golang.org/x/net/ipv6/dgramopt.go | 301 + vendor/golang.org/x/net/ipv6/doc.go | 243 + vendor/golang.org/x/net/ipv6/endpoint.go | 127 + vendor/golang.org/x/net/ipv6/genericopt.go | 56 + vendor/golang.org/x/net/ipv6/header.go | 55 + vendor/golang.org/x/net/ipv6/helper.go | 58 + vendor/golang.org/x/net/ipv6/iana.go | 86 + vendor/golang.org/x/net/ipv6/icmp.go | 60 + vendor/golang.org/x/net/ipv6/icmp_bsd.go | 29 + vendor/golang.org/x/net/ipv6/icmp_linux.go | 27 + vendor/golang.org/x/net/ipv6/icmp_solaris.go | 27 + vendor/golang.org/x/net/ipv6/icmp_stub.go | 23 + vendor/golang.org/x/net/ipv6/icmp_windows.go | 22 + vendor/golang.org/x/net/ipv6/payload.go | 23 + vendor/golang.org/x/net/ipv6/payload_cmsg.go | 70 + .../golang.org/x/net/ipv6/payload_nocmsg.go | 38 + vendor/golang.org/x/net/ipv6/sockopt.go | 43 + vendor/golang.org/x/net/ipv6/sockopt_posix.go | 89 + vendor/golang.org/x/net/ipv6/sockopt_stub.go | 46 + vendor/golang.org/x/net/ipv6/sys_aix.go | 77 + vendor/golang.org/x/net/ipv6/sys_asmreq.go | 24 + .../golang.org/x/net/ipv6/sys_asmreq_stub.go | 17 + vendor/golang.org/x/net/ipv6/sys_bpf.go | 24 + vendor/golang.org/x/net/ipv6/sys_bpf_stub.go | 16 + vendor/golang.org/x/net/ipv6/sys_bsd.go | 57 + vendor/golang.org/x/net/ipv6/sys_darwin.go | 78 + vendor/golang.org/x/net/ipv6/sys_freebsd.go | 92 + vendor/golang.org/x/net/ipv6/sys_linux.go | 75 + vendor/golang.org/x/net/ipv6/sys_solaris.go | 74 + vendor/golang.org/x/net/ipv6/sys_ssmreq.go | 54 + .../golang.org/x/net/ipv6/sys_ssmreq_stub.go | 21 + vendor/golang.org/x/net/ipv6/sys_stub.go | 13 + vendor/golang.org/x/net/ipv6/sys_windows.go | 75 + .../golang.org/x/net/ipv6/zsys_aix_ppc64.go | 103 + vendor/golang.org/x/net/ipv6/zsys_darwin.go | 131 + .../golang.org/x/net/ipv6/zsys_dragonfly.go | 88 + .../golang.org/x/net/ipv6/zsys_freebsd_386.go | 122 + .../x/net/ipv6/zsys_freebsd_amd64.go | 124 + .../golang.org/x/net/ipv6/zsys_freebsd_arm.go | 124 + .../x/net/ipv6/zsys_freebsd_arm64.go | 122 + .../golang.org/x/net/ipv6/zsys_linux_386.go | 152 + .../golang.org/x/net/ipv6/zsys_linux_amd64.go | 154 + .../golang.org/x/net/ipv6/zsys_linux_arm.go | 152 + .../golang.org/x/net/ipv6/zsys_linux_arm64.go | 154 + .../golang.org/x/net/ipv6/zsys_linux_mips.go | 152 + .../x/net/ipv6/zsys_linux_mips64.go | 154 + .../x/net/ipv6/zsys_linux_mips64le.go | 154 + .../x/net/ipv6/zsys_linux_mipsle.go | 152 + .../golang.org/x/net/ipv6/zsys_linux_ppc.go | 152 + .../golang.org/x/net/ipv6/zsys_linux_ppc64.go | 154 + .../x/net/ipv6/zsys_linux_ppc64le.go | 154 + .../x/net/ipv6/zsys_linux_riscv64.go | 156 + .../golang.org/x/net/ipv6/zsys_linux_s390x.go | 154 + vendor/golang.org/x/net/ipv6/zsys_netbsd.go | 84 + vendor/golang.org/x/net/ipv6/zsys_openbsd.go | 93 + vendor/golang.org/x/net/ipv6/zsys_solaris.go | 131 + vendor/golang.org/x/net/proxy/dial.go | 54 + vendor/golang.org/x/net/proxy/direct.go | 15 +- vendor/golang.org/x/net/proxy/per_host.go | 15 + vendor/golang.org/x/net/proxy/proxy.go | 24 +- vendor/golang.org/x/net/proxy/socks5.go | 10 +- vendor/golang.org/x/sys/cpu/byteorder.go | 38 +- vendor/golang.org/x/sys/cpu/cpu.go | 45 + vendor/golang.org/x/sys/cpu/cpu_arm.go | 33 +- vendor/golang.org/x/sys/cpu/cpu_arm64.go | 138 + vendor/golang.org/x/sys/cpu/cpu_arm64.s | 31 + vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go | 11 + .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 11 + .../sys/cpu/{cpu_gccgo.c => cpu_gccgo_x86.c} | 0 .../cpu/{cpu_gccgo.go => cpu_gccgo_x86.go} | 0 vendor/golang.org/x/sys/cpu/cpu_linux.go | 48 +- vendor/golang.org/x/sys/cpu/cpu_linux_arm.go | 39 + .../golang.org/x/sys/cpu/cpu_linux_arm64.go | 8 +- .../golang.org/x/sys/cpu/cpu_linux_mips64x.go | 22 + .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 9 + vendor/golang.org/x/sys/cpu/cpu_mips64x.go | 2 - vendor/golang.org/x/sys/cpu/cpu_mipsx.go | 2 - .../golang.org/x/sys/cpu/cpu_other_arm64.go | 2 - vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 9 + vendor/golang.org/x/sys/cpu/cpu_wasm.go | 2 - vendor/golang.org/x/sys/cpu/hwcap_linux.go | 56 + vendor/golang.org/x/sys/unix/README.md | 15 +- .../golang.org/x/sys/unix/asm_linux_riscv64.s | 7 - .../golang.org/x/sys/unix/bluetooth_linux.go | 1 + .../x/sys/unix/errors_freebsd_386.go | 6 + .../x/sys/unix/errors_freebsd_amd64.go | 6 + .../x/sys/unix/errors_freebsd_arm64.go | 17 + vendor/golang.org/x/sys/unix/fcntl.go | 12 +- vendor/golang.org/x/sys/unix/fdset.go | 29 + vendor/golang.org/x/sys/unix/mkall.sh | 19 +- vendor/golang.org/x/sys/unix/mkerrors.sh | 70 +- .../x/sys/unix/sockcmsg_dragonfly.go | 16 + .../golang.org/x/sys/unix/sockcmsg_linux.go | 2 +- vendor/golang.org/x/sys/unix/sockcmsg_unix.go | 36 +- .../x/sys/unix/sockcmsg_unix_other.go | 38 + .../golang.org/x/sys/unix/syscall_aix_ppc.go | 4 + .../x/sys/unix/syscall_aix_ppc64.go | 4 + vendor/golang.org/x/sys/unix/syscall_bsd.go | 23 +- .../x/sys/unix/syscall_darwin.1_12.go | 29 + .../x/sys/unix/syscall_darwin.1_13.go | 101 + .../golang.org/x/sys/unix/syscall_darwin.go | 23 +- .../x/sys/unix/syscall_darwin_386.1_11.go | 9 + .../x/sys/unix/syscall_darwin_386.go | 5 +- .../x/sys/unix/syscall_darwin_amd64.1_11.go | 9 + .../x/sys/unix/syscall_darwin_amd64.go | 5 +- .../x/sys/unix/syscall_darwin_arm.1_11.go | 11 + .../x/sys/unix/syscall_darwin_arm.go | 8 +- .../x/sys/unix/syscall_darwin_arm64.1_11.go | 11 + .../x/sys/unix/syscall_darwin_arm64.go | 8 +- .../x/sys/unix/syscall_darwin_libSystem.go | 2 + .../x/sys/unix/syscall_dragonfly.go | 24 +- .../x/sys/unix/syscall_dragonfly_amd64.go | 4 + .../golang.org/x/sys/unix/syscall_freebsd.go | 23 +- .../x/sys/unix/syscall_freebsd_386.go | 14 + .../x/sys/unix/syscall_freebsd_amd64.go | 14 + .../x/sys/unix/syscall_freebsd_arm.go | 10 + .../x/sys/unix/syscall_freebsd_arm64.go | 10 + .../golang.org/x/sys/unix/syscall_illumos.go | 57 + vendor/golang.org/x/sys/unix/syscall_linux.go | 299 +- .../x/sys/unix/syscall_linux_386.go | 8 +- .../x/sys/unix/syscall_linux_amd64.go | 8 +- .../x/sys/unix/syscall_linux_arm.go | 8 +- .../x/sys/unix/syscall_linux_arm64.go | 8 +- .../x/sys/unix/syscall_linux_mips64x.go | 12 +- .../x/sys/unix/syscall_linux_mipsx.go | 8 +- .../x/sys/unix/syscall_linux_ppc64x.go | 8 +- .../x/sys/unix/syscall_linux_riscv64.go | 8 +- .../x/sys/unix/syscall_linux_s390x.go | 8 +- .../x/sys/unix/syscall_linux_sparc64.go | 8 +- .../golang.org/x/sys/unix/syscall_netbsd.go | 32 +- .../x/sys/unix/syscall_netbsd_386.go | 4 + .../x/sys/unix/syscall_netbsd_amd64.go | 4 + .../x/sys/unix/syscall_netbsd_arm.go | 4 + .../x/sys/unix/syscall_netbsd_arm64.go | 4 + .../golang.org/x/sys/unix/syscall_openbsd.go | 33 +- .../x/sys/unix/syscall_openbsd_386.go | 4 + .../x/sys/unix/syscall_openbsd_amd64.go | 4 + .../x/sys/unix/syscall_openbsd_arm.go | 4 + .../x/sys/unix/syscall_openbsd_arm64.go | 4 + .../golang.org/x/sys/unix/syscall_solaris.go | 4 +- .../x/sys/unix/syscall_solaris_amd64.go | 4 + vendor/golang.org/x/sys/unix/syscall_unix.go | 2 +- .../golang.org/x/sys/unix/zerrors_aix_ppc.go | 12 +- .../x/sys/unix/zerrors_aix_ppc64.go | 12 +- .../x/sys/unix/zerrors_darwin_386.go | 3 +- .../x/sys/unix/zerrors_darwin_amd64.go | 3 +- .../x/sys/unix/zerrors_darwin_arm.go | 3 +- .../x/sys/unix/zerrors_darwin_arm64.go | 3 +- .../x/sys/unix/zerrors_dragonfly_amd64.go | 1 + .../x/sys/unix/zerrors_freebsd_386.go | 163 +- .../x/sys/unix/zerrors_freebsd_amd64.go | 161 +- .../x/sys/unix/zerrors_freebsd_arm.go | 19 +- .../x/sys/unix/zerrors_freebsd_arm64.go | 162 +- vendor/golang.org/x/sys/unix/zerrors_linux.go | 2469 + .../x/sys/unix/zerrors_linux_386.go | 3235 +- .../x/sys/unix/zerrors_linux_amd64.go | 3235 +- .../x/sys/unix/zerrors_linux_arm.go | 3247 +- .../x/sys/unix/zerrors_linux_arm64.go | 3219 +- .../x/sys/unix/zerrors_linux_mips.go | 3239 +- .../x/sys/unix/zerrors_linux_mips64.go | 3239 +- .../x/sys/unix/zerrors_linux_mips64le.go | 3239 +- .../x/sys/unix/zerrors_linux_mipsle.go | 3239 +- .../x/sys/unix/zerrors_linux_ppc64.go | 3358 +- .../x/sys/unix/zerrors_linux_ppc64le.go | 3358 +- .../x/sys/unix/zerrors_linux_riscv64.go | 3209 +- .../x/sys/unix/zerrors_linux_s390x.go | 3355 +- .../x/sys/unix/zerrors_linux_sparc64.go | 3336 +- .../x/sys/unix/zerrors_netbsd_386.go | 3 +- .../x/sys/unix/zerrors_netbsd_amd64.go | 3 +- .../x/sys/unix/zerrors_netbsd_arm.go | 3 +- .../x/sys/unix/zerrors_netbsd_arm64.go | 3 +- .../x/sys/unix/zerrors_openbsd_386.go | 17 +- .../x/sys/unix/zerrors_openbsd_amd64.go | 6 +- .../x/sys/unix/zerrors_openbsd_arm.go | 11 +- .../x/sys/unix/zerrors_openbsd_arm64.go | 1 + .../x/sys/unix/zerrors_solaris_amd64.go | 3 +- ...acearm_linux.go => zptrace_armnn_linux.go} | 2 +- .../x/sys/unix/zptrace_linux_arm64.go | 17 + ...emips_linux.go => zptrace_mipsnn_linux.go} | 2 +- ...sle_linux.go => zptrace_mipsnnle_linux.go} | 2 +- ...trace386_linux.go => zptrace_x86_linux.go} | 2 +- .../x/sys/unix/zsyscall_darwin_386.1_11.go | 95 +- .../x/sys/unix/zsyscall_darwin_386.1_13.go | 41 + .../x/sys/unix/zsyscall_darwin_386.1_13.s | 12 + .../x/sys/unix/zsyscall_darwin_386.go | 116 +- .../x/sys/unix/zsyscall_darwin_386.s | 12 +- .../x/sys/unix/zsyscall_darwin_amd64.1_11.go | 115 +- .../x/sys/unix/zsyscall_darwin_amd64.1_13.go | 41 + .../x/sys/unix/zsyscall_darwin_amd64.1_13.s | 12 + .../x/sys/unix/zsyscall_darwin_amd64.go | 101 +- .../x/sys/unix/zsyscall_darwin_amd64.s | 10 +- .../x/sys/unix/zsyscall_darwin_arm.1_11.go | 71 +- .../x/sys/unix/zsyscall_darwin_arm.1_13.go | 41 + .../x/sys/unix/zsyscall_darwin_arm.1_13.s | 12 + .../x/sys/unix/zsyscall_darwin_arm.go | 94 +- .../x/sys/unix/zsyscall_darwin_arm.s | 10 +- .../x/sys/unix/zsyscall_darwin_arm64.1_11.go | 71 +- .../x/sys/unix/zsyscall_darwin_arm64.1_13.go | 41 + .../x/sys/unix/zsyscall_darwin_arm64.1_13.s | 12 + .../x/sys/unix/zsyscall_darwin_arm64.go | 94 +- .../x/sys/unix/zsyscall_darwin_arm64.s | 10 +- .../x/sys/unix/zsyscall_dragonfly_amd64.go | 16 +- .../x/sys/unix/zsyscall_freebsd_386.go | 70 +- .../x/sys/unix/zsyscall_freebsd_amd64.go | 68 +- .../x/sys/unix/zsyscall_freebsd_arm.go | 56 +- .../x/sys/unix/zsyscall_freebsd_arm64.go | 58 +- .../x/sys/unix/zsyscall_illumos_amd64.go | 87 + .../golang.org/x/sys/unix/zsyscall_linux.go | 1825 + .../x/sys/unix/zsyscall_linux_386.go | 1704 +- .../x/sys/unix/zsyscall_linux_amd64.go | 1704 +- .../x/sys/unix/zsyscall_linux_arm.go | 1704 +- .../x/sys/unix/zsyscall_linux_arm64.go | 1704 +- .../x/sys/unix/zsyscall_linux_mips.go | 1704 +- .../x/sys/unix/zsyscall_linux_mips64.go | 1704 +- .../x/sys/unix/zsyscall_linux_mips64le.go | 1704 +- .../x/sys/unix/zsyscall_linux_mipsle.go | 1704 +- .../x/sys/unix/zsyscall_linux_ppc64.go | 1704 +- .../x/sys/unix/zsyscall_linux_ppc64le.go | 1704 +- .../x/sys/unix/zsyscall_linux_riscv64.go | 1704 +- .../x/sys/unix/zsyscall_linux_s390x.go | 1704 +- .../x/sys/unix/zsyscall_linux_sparc64.go | 1704 +- .../x/sys/unix/zsyscall_netbsd_386.go | 83 +- .../x/sys/unix/zsyscall_netbsd_amd64.go | 83 +- .../x/sys/unix/zsyscall_netbsd_arm.go | 83 +- .../x/sys/unix/zsyscall_netbsd_arm64.go | 83 +- .../x/sys/unix/zsyscall_openbsd_386.go | 62 +- .../x/sys/unix/zsyscall_openbsd_amd64.go | 62 +- .../x/sys/unix/zsyscall_openbsd_arm.go | 62 +- .../x/sys/unix/zsyscall_openbsd_arm64.go | 62 +- .../x/sys/unix/zsyscall_solaris_amd64.go | 5 +- .../x/sys/unix/zsysnum_linux_386.go | 4 + .../x/sys/unix/zsysnum_linux_amd64.go | 4 + .../x/sys/unix/zsysnum_linux_arm.go | 4 + .../x/sys/unix/zsysnum_linux_arm64.go | 4 + .../x/sys/unix/zsysnum_linux_mips.go | 4 + .../x/sys/unix/zsysnum_linux_mips64.go | 4 + .../x/sys/unix/zsysnum_linux_mips64le.go | 4 + .../x/sys/unix/zsysnum_linux_mipsle.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64.go | 4 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 4 + .../x/sys/unix/zsysnum_linux_riscv64.go | 4 + .../x/sys/unix/zsysnum_linux_s390x.go | 4 + .../x/sys/unix/zsysnum_linux_sparc64.go | 3 + .../x/sys/unix/ztypes_dragonfly_amd64.go | 10 + .../x/sys/unix/ztypes_freebsd_386.go | 51 +- .../x/sys/unix/ztypes_freebsd_amd64.go | 36 +- .../x/sys/unix/ztypes_freebsd_arm.go | 12 +- .../x/sys/unix/ztypes_freebsd_arm64.go | 66 +- vendor/golang.org/x/sys/unix/ztypes_linux.go | 2340 + .../golang.org/x/sys/unix/ztypes_linux_386.go | 2015 +- .../x/sys/unix/ztypes_linux_amd64.go | 2016 +- .../golang.org/x/sys/unix/ztypes_linux_arm.go | 2016 +- .../x/sys/unix/ztypes_linux_arm64.go | 2016 +- .../x/sys/unix/ztypes_linux_mips.go | 2016 +- .../x/sys/unix/ztypes_linux_mips64.go | 2017 +- .../x/sys/unix/ztypes_linux_mips64le.go | 2017 +- .../x/sys/unix/ztypes_linux_mipsle.go | 2016 +- .../x/sys/unix/ztypes_linux_ppc64.go | 2016 +- .../x/sys/unix/ztypes_linux_ppc64le.go | 2016 +- .../x/sys/unix/ztypes_linux_riscv64.go | 2016 +- .../x/sys/unix/ztypes_linux_s390x.go | 2016 +- .../x/sys/unix/ztypes_linux_sparc64.go | 2016 +- .../x/sys/unix/ztypes_netbsd_386.go | 32 + .../x/sys/unix/ztypes_netbsd_amd64.go | 33 + .../x/sys/unix/ztypes_netbsd_arm.go | 32 + .../x/sys/unix/ztypes_netbsd_arm64.go | 33 + .../x/sys/unix/ztypes_solaris_amd64.go | 7 + vendor/golang.org/x/sys/windows/aliases.go | 13 + .../golang.org/x/sys/windows/dll_windows.go | 386 + vendor/golang.org/x/sys/windows/empty.s | 8 + .../golang.org/x/sys/windows/env_windows.go | 61 + vendor/golang.org/x/sys/windows/eventlog.go | 20 + .../golang.org/x/sys/windows/exec_windows.go | 97 + .../x/sys/windows/memory_windows.go | 26 + vendor/golang.org/x/sys/windows/mkerrors.bash | 63 + .../x/sys/windows/mkknownfolderids.bash | 27 + vendor/golang.org/x/sys/windows/mksyscall.go | 9 + vendor/golang.org/x/sys/windows/race.go | 30 + vendor/golang.org/x/sys/windows/race0.go | 25 + .../x/sys/windows/security_windows.go | 1396 + vendor/golang.org/x/sys/windows/service.go | 229 + vendor/golang.org/x/sys/windows/str.go | 22 + vendor/golang.org/x/sys/windows/syscall.go | 74 + .../x/sys/windows/syscall_windows.go | 1454 + .../golang.org/x/sys/windows/types_windows.go | 1786 + .../x/sys/windows/types_windows_386.go | 22 + .../x/sys/windows/types_windows_amd64.go | 22 + .../x/sys/windows/types_windows_arm.go | 22 + .../x/sys/windows/zerrors_windows.go | 6853 + .../x/sys/windows/zknownfolderids_windows.go | 149 + .../x/sys/windows/zsyscall_windows.go | 4051 + vendor/google.golang.org/protobuf/AUTHORS | 3 + .../google.golang.org/protobuf/CONTRIBUTORS | 3 + vendor/google.golang.org/protobuf/LICENSE | 27 + vendor/google.golang.org/protobuf/PATENTS | 22 + .../protobuf/encoding/prototext/decode.go | 791 + .../protobuf/encoding/prototext/doc.go | 7 + .../protobuf/encoding/prototext/encode.go | 433 + .../protobuf/encoding/protowire/wire.go | 538 + .../protobuf/internal/descfmt/stringer.go | 316 + .../protobuf/internal/descopts/options.go | 29 + .../protobuf/internal/detrand/rand.go | 61 + .../internal/encoding/defval/default.go | 213 + .../encoding/messageset/messageset.go | 258 + .../protobuf/internal/encoding/tag/tag.go | 207 + .../protobuf/internal/encoding/text/decode.go | 665 + .../internal/encoding/text/decode_number.go | 190 + .../internal/encoding/text/decode_string.go | 161 + .../internal/encoding/text/decode_token.go | 373 + .../protobuf/internal/encoding/text/doc.go | 29 + .../protobuf/internal/encoding/text/encode.go | 267 + .../protobuf/internal/errors/errors.go | 89 + .../protobuf/internal/errors/is_go112.go | 39 + .../protobuf/internal/errors/is_go113.go | 12 + .../protobuf/internal/fieldsort/fieldsort.go | 40 + .../protobuf/internal/filedesc/build.go | 155 + .../protobuf/internal/filedesc/desc.go | 614 + .../protobuf/internal/filedesc/desc_init.go | 471 + .../protobuf/internal/filedesc/desc_lazy.go | 704 + .../protobuf/internal/filedesc/desc_list.go | 282 + .../internal/filedesc/desc_list_gen.go | 345 + .../protobuf/internal/filedesc/placeholder.go | 107 + .../protobuf/internal/filetype/build.go | 297 + .../protobuf/internal/flags/flags.go | 24 + .../internal/flags/proto_legacy_disable.go | 9 + .../internal/flags/proto_legacy_enable.go | 9 + .../protobuf/internal/genid/any_gen.go | 34 + .../protobuf/internal/genid/api_gen.go | 106 + .../protobuf/internal/genid/descriptor_gen.go | 829 + .../protobuf/internal/genid/doc.go | 11 + .../protobuf/internal/genid/duration_gen.go | 34 + .../protobuf/internal/genid/empty_gen.go | 19 + .../protobuf/internal/genid/field_mask_gen.go | 31 + .../protobuf/internal/genid/goname.go | 25 + .../protobuf/internal/genid/map_entry.go | 16 + .../internal/genid/source_context_gen.go | 31 + .../protobuf/internal/genid/struct_gen.go | 116 + .../protobuf/internal/genid/timestamp_gen.go | 34 + .../protobuf/internal/genid/type_gen.go | 184 + .../protobuf/internal/genid/wrappers.go | 13 + .../protobuf/internal/genid/wrappers_gen.go | 175 + .../protobuf/internal/impl/api_export.go | 177 + .../protobuf/internal/impl/checkinit.go | 141 + .../protobuf/internal/impl/codec_extension.go | 223 + .../protobuf/internal/impl/codec_field.go | 828 + .../protobuf/internal/impl/codec_gen.go | 5637 + .../protobuf/internal/impl/codec_map.go | 389 + .../protobuf/internal/impl/codec_map_go111.go | 37 + .../protobuf/internal/impl/codec_map_go112.go | 11 + .../protobuf/internal/impl/codec_message.go | 159 + .../internal/impl/codec_messageset.go | 120 + .../protobuf/internal/impl/codec_reflect.go | 209 + .../protobuf/internal/impl/codec_tables.go | 557 + .../protobuf/internal/impl/codec_unsafe.go | 17 + .../protobuf/internal/impl/convert.go | 467 + .../protobuf/internal/impl/convert_list.go | 141 + .../protobuf/internal/impl/convert_map.go | 121 + .../protobuf/internal/impl/decode.go | 274 + .../protobuf/internal/impl/encode.go | 199 + .../protobuf/internal/impl/enum.go | 21 + .../protobuf/internal/impl/extension.go | 156 + .../protobuf/internal/impl/legacy_enum.go | 219 + .../protobuf/internal/impl/legacy_export.go | 92 + .../internal/impl/legacy_extension.go | 175 + .../protobuf/internal/impl/legacy_file.go | 81 + .../protobuf/internal/impl/legacy_message.go | 502 + .../protobuf/internal/impl/merge.go | 176 + .../protobuf/internal/impl/merge_gen.go | 209 + .../protobuf/internal/impl/message.go | 215 + .../protobuf/internal/impl/message_reflect.go | 364 + .../internal/impl/message_reflect_field.go | 466 + .../internal/impl/message_reflect_gen.go | 249 + .../protobuf/internal/impl/pointer_reflect.go | 177 + .../protobuf/internal/impl/pointer_unsafe.go | 173 + .../protobuf/internal/impl/validate.go | 576 + .../protobuf/internal/impl/weak.go | 74 + .../protobuf/internal/mapsort/mapsort.go | 43 + .../protobuf/internal/pragma/pragma.go | 29 + .../protobuf/internal/set/ints.go | 58 + .../protobuf/internal/strs/strings.go | 196 + .../protobuf/internal/strs/strings_pure.go | 27 + .../protobuf/internal/strs/strings_unsafe.go | 94 + .../protobuf/internal/version/version.go | 79 + .../protobuf/proto/checkinit.go | 71 + .../protobuf/proto/decode.go | 274 + .../protobuf/proto/decode_gen.go | 603 + .../google.golang.org/protobuf/proto/doc.go | 94 + .../protobuf/proto/encode.go | 346 + .../protobuf/proto/encode_gen.go | 97 + .../google.golang.org/protobuf/proto/equal.go | 154 + .../protobuf/proto/extension.go | 92 + .../google.golang.org/protobuf/proto/merge.go | 139 + .../protobuf/proto/messageset.go | 88 + .../google.golang.org/protobuf/proto/proto.go | 34 + .../protobuf/proto/proto_methods.go | 19 + .../protobuf/proto/proto_reflect.go | 19 + .../google.golang.org/protobuf/proto/reset.go | 43 + .../google.golang.org/protobuf/proto/size.go | 97 + .../protobuf/proto/size_gen.go | 55 + .../protobuf/proto/wrappers.go | 29 + .../protobuf/reflect/protoreflect/methods.go | 77 + .../protobuf/reflect/protoreflect/proto.go | 504 + .../protobuf/reflect/protoreflect/source.go | 52 + .../protobuf/reflect/protoreflect/type.go | 631 + .../protobuf/reflect/protoreflect/value.go | 285 + .../reflect/protoreflect/value_pure.go | 59 + .../reflect/protoreflect/value_union.go | 411 + .../reflect/protoreflect/value_unsafe.go | 98 + .../reflect/protoregistry/registry.go | 800 + .../protobuf/runtime/protoiface/legacy.go | 15 + .../protobuf/runtime/protoiface/methods.go | 167 + .../protobuf/runtime/protoimpl/impl.go | 44 + .../protobuf/runtime/protoimpl/version.go | 56 + vendor/gopkg.in/gormigrate.v1/.editorconfig | 14 + vendor/gopkg.in/gormigrate.v1/.gitattributes | 1 + vendor/gopkg.in/gormigrate.v1/.gitignore | 29 + vendor/gopkg.in/gormigrate.v1/.sample.env | 4 + vendor/gopkg.in/gormigrate.v1/.travis.yml | 28 + vendor/gopkg.in/gormigrate.v1/CHANGELOG.md | 57 + vendor/gopkg.in/gormigrate.v1/Dockerfile | 6 + vendor/gopkg.in/gormigrate.v1/LICENSE | 8 + vendor/gopkg.in/gormigrate.v1/README.md | 200 + vendor/gopkg.in/gormigrate.v1/Taskfile.yml | 60 + vendor/gopkg.in/gormigrate.v1/appveyor.yml | 51 + vendor/gopkg.in/gormigrate.v1/doc.go | 68 + .../gopkg.in/gormigrate.v1/docker-compose.yml | 35 + vendor/gopkg.in/gormigrate.v1/go.mod | 19 + vendor/gopkg.in/gormigrate.v1/go.sum | 38 + vendor/gopkg.in/gormigrate.v1/gormigrate.go | 465 + vendor/modules.txt | 141 +- 1265 files changed, 440488 insertions(+), 107809 deletions(-) create mode 100644 main.go create mode 100644 sweeper.go create mode 100644 vendor/github.com/aead/chacha20/.gitignore create mode 100644 vendor/github.com/aead/chacha20/.travis.yml create mode 100644 vendor/github.com/aead/chacha20/LICENSE create mode 100644 vendor/github.com/aead/chacha20/README.md create mode 100644 vendor/github.com/aead/chacha20/chacha/chacha.go create mode 100644 vendor/github.com/aead/chacha20/chacha/chachaAVX2_amd64.s create mode 100644 vendor/github.com/aead/chacha20/chacha/chacha_386.go create mode 100644 vendor/github.com/aead/chacha20/chacha/chacha_386.s create mode 100644 vendor/github.com/aead/chacha20/chacha/chacha_amd64.go create mode 100644 vendor/github.com/aead/chacha20/chacha/chacha_amd64.s create mode 100644 vendor/github.com/aead/chacha20/chacha/chacha_generic.go create mode 100644 vendor/github.com/aead/chacha20/chacha/chacha_ref.go create mode 100644 vendor/github.com/aead/chacha20/chacha/const.s create mode 100644 vendor/github.com/aead/chacha20/chacha/macro.s create mode 100644 vendor/github.com/aead/chacha20/chacha20.go create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/README.md create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/blockgen.go create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/btcd.go create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/doc.go create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/memwallet.go create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/node.go create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/rpc_harness.go create mode 100644 vendor/github.com/btcsuite/btcd/integration/rpctest/utils.go delete mode 100644 vendor/github.com/btcsuite/btcd/peer/mruinvmap.go delete mode 100644 vendor/github.com/btcsuite/btcd/peer/mrunoncemap.go create mode 100644 vendor/github.com/btcsuite/btcd/rpcclient/cookiefile.go create mode 100644 vendor/github.com/btcsuite/btcutil/go.mod create mode 100644 vendor/github.com/btcsuite/btcutil/go.sum create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/LICENSE create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/bip32.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/creator.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/extractor.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/finalizer.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/go.mod create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/go.sum create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/partial_input.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/partial_output.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/partialsig.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/psbt.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/signer.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/types.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/updater.go create mode 100644 vendor/github.com/btcsuite/btcutil/psbt/utils.go create mode 100644 vendor/github.com/btcsuite/btcutil/txsort/README.md create mode 100644 vendor/github.com/btcsuite/btcutil/txsort/doc.go create mode 100644 vendor/github.com/btcsuite/btcutil/txsort/txsort.go create mode 100644 vendor/github.com/btcsuite/btcwallet/internal/legacy/keystore/keystore.go create mode 100644 vendor/github.com/btcsuite/btcwallet/internal/legacy/rename/rename_unix.go create mode 100644 vendor/github.com/btcsuite/btcwallet/internal/legacy/rename/rename_windows.go create mode 100644 vendor/github.com/btcsuite/btcwallet/internal/prompt/prompt.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/README.md create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/chainntfns.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/common.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/createtx.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/disksync.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/doc.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/loader.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/log.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/mock.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/multisig.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/notifications.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/recovery.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/rescan.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txauthor/LICENSE create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txauthor/author.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txauthor/cprng.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txauthor/go.mod create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txauthor/go.sum create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txrules/LICENSE create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txrules/go.mod create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txrules/go.sum create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txrules/rules.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txsizes/LICENSE create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txsizes/go.mod create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txsizes/go.sum create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/txsizes/size.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/unstable.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/utxos.go create mode 100644 vendor/github.com/btcsuite/btcwallet/wallet/wallet.go delete mode 100644 vendor/github.com/coreos/bbolt/bolt_arm.go create mode 100644 vendor/github.com/decred/dcrd/lru/LICENSE create mode 100644 vendor/github.com/decred/dcrd/lru/README.md create mode 100644 vendor/github.com/decred/dcrd/lru/cache.go create mode 100644 vendor/github.com/decred/dcrd/lru/doc.go create mode 100644 vendor/github.com/decred/dcrd/lru/go.mod create mode 100644 vendor/github.com/golang/protobuf/proto/buffer.go delete mode 100644 vendor/github.com/golang/protobuf/proto/clone.go delete mode 100644 vendor/github.com/golang/protobuf/proto/decode.go create mode 100644 vendor/github.com/golang/protobuf/proto/defaults.go delete mode 100644 vendor/github.com/golang/protobuf/proto/encode.go delete mode 100644 vendor/github.com/golang/protobuf/proto/equal.go delete mode 100644 vendor/github.com/golang/protobuf/proto/lib.go delete mode 100644 vendor/github.com/golang/protobuf/proto/message_set.go delete mode 100644 vendor/github.com/golang/protobuf/proto/pointer_reflect.go delete mode 100644 vendor/github.com/golang/protobuf/proto/pointer_unsafe.go create mode 100644 vendor/github.com/golang/protobuf/proto/proto.go create mode 100644 vendor/github.com/golang/protobuf/proto/registry.go delete mode 100644 vendor/github.com/golang/protobuf/proto/table_marshal.go delete mode 100644 vendor/github.com/golang/protobuf/proto/table_merge.go delete mode 100644 vendor/github.com/golang/protobuf/proto/table_unmarshal.go delete mode 100644 vendor/github.com/golang/protobuf/proto/text.go create mode 100644 vendor/github.com/golang/protobuf/proto/text_decode.go create mode 100644 vendor/github.com/golang/protobuf/proto/text_encode.go delete mode 100644 vendor/github.com/golang/protobuf/proto/text_parser.go create mode 100644 vendor/github.com/golang/protobuf/proto/wire.go create mode 100644 vendor/github.com/golang/protobuf/proto/wrappers.go create mode 100644 vendor/github.com/jinzhu/gorm/.gitignore create mode 100644 vendor/github.com/jinzhu/gorm/License create mode 100644 vendor/github.com/jinzhu/gorm/README.md create mode 100644 vendor/github.com/jinzhu/gorm/association.go create mode 100644 vendor/github.com/jinzhu/gorm/callback.go create mode 100644 vendor/github.com/jinzhu/gorm/callback_create.go create mode 100644 vendor/github.com/jinzhu/gorm/callback_delete.go create mode 100644 vendor/github.com/jinzhu/gorm/callback_query.go create mode 100644 vendor/github.com/jinzhu/gorm/callback_query_preload.go create mode 100644 vendor/github.com/jinzhu/gorm/callback_row_query.go create mode 100644 vendor/github.com/jinzhu/gorm/callback_save.go create mode 100644 vendor/github.com/jinzhu/gorm/callback_update.go create mode 100644 vendor/github.com/jinzhu/gorm/dialect.go create mode 100644 vendor/github.com/jinzhu/gorm/dialect_common.go create mode 100644 vendor/github.com/jinzhu/gorm/dialect_mysql.go create mode 100644 vendor/github.com/jinzhu/gorm/dialect_postgres.go create mode 100644 vendor/github.com/jinzhu/gorm/dialect_sqlite3.go create mode 100644 vendor/github.com/jinzhu/gorm/dialects/sqlite/sqlite.go create mode 100644 vendor/github.com/jinzhu/gorm/docker-compose.yml create mode 100644 vendor/github.com/jinzhu/gorm/errors.go create mode 100644 vendor/github.com/jinzhu/gorm/field.go create mode 100644 vendor/github.com/jinzhu/gorm/go.mod create mode 100644 vendor/github.com/jinzhu/gorm/go.sum create mode 100644 vendor/github.com/jinzhu/gorm/interface.go create mode 100644 vendor/github.com/jinzhu/gorm/join_table_handler.go create mode 100644 vendor/github.com/jinzhu/gorm/logger.go create mode 100644 vendor/github.com/jinzhu/gorm/main.go create mode 100644 vendor/github.com/jinzhu/gorm/model.go create mode 100644 vendor/github.com/jinzhu/gorm/model_struct.go create mode 100644 vendor/github.com/jinzhu/gorm/naming.go create mode 100644 vendor/github.com/jinzhu/gorm/scope.go create mode 100644 vendor/github.com/jinzhu/gorm/search.go create mode 100644 vendor/github.com/jinzhu/gorm/test_all.sh create mode 100644 vendor/github.com/jinzhu/gorm/utils.go create mode 100644 vendor/github.com/jinzhu/gorm/wercker.yml create mode 100644 vendor/github.com/jinzhu/inflection/LICENSE create mode 100644 vendor/github.com/jinzhu/inflection/README.md create mode 100644 vendor/github.com/jinzhu/inflection/go.mod create mode 100644 vendor/github.com/jinzhu/inflection/inflections.go create mode 100644 vendor/github.com/jinzhu/inflection/wercker.yml create mode 100644 vendor/github.com/jrick/logrotate/LICENSE create mode 100644 vendor/github.com/jrick/logrotate/rotator/rotator.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/.gitignore create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/.travis.yml create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/LICENSE create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/README.md create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/batch.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/crypto.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/error.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/go.mod create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/go.sum create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/hornet.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/log.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/obfuscation.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/packetfiller.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/path.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/replay_set.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/replaylog.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/sphinx.go create mode 100644 vendor/github.com/lightningnetwork/lightning-onion/varint.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/deployment.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/deployment_dev.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/deployment_prod.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/log_default.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/log_nolog.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/log_stdlog.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_critical.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_debug.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_default.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_error.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_info.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_off.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_trace.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/loglevel_warn.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/logrotator.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/prefix_log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/build/version.go create mode 100644 vendor/github.com/lightningnetwork/lnd/chainntnfs/README.md create mode 100644 vendor/github.com/lightningnetwork/lnd/chainntnfs/height_hint_cache.go create mode 100644 vendor/github.com/lightningnetwork/lnd/chainntnfs/interface.go create mode 100644 vendor/github.com/lightningnetwork/lnd/chainntnfs/interface_dev.go create mode 100644 vendor/github.com/lightningnetwork/lnd/chainntnfs/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/chainntnfs/test_utils.go create mode 100644 vendor/github.com/lightningnetwork/lnd/chainntnfs/txnotifier.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/README.md create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/addr.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/channel.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/channel_cache.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/codec.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/db.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/doc.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/duplicate_payments.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/error.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/fees.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/forwarding_log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/forwarding_package.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/graph.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/invoices.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/kvdb/bbolt.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/kvdb/interface.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/legacy_serialization.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/meta.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration12/invoices.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration12/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration12/migration.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration13/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration13/migration.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/addr.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/channel.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/codec.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/db.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/error.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/graph.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/invoices.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/legacy_serialization.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/meta.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/migration_09_legacy_serialization.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/migration_10_route_tlv_records.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/migration_11_invoices.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/migrations.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/options.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/payment_control.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/payments.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/migration_01_to_11/route.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/mp_payment.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/nodes.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/options.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/payment_control.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/payments.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/reject_cache.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/waitingproof.go create mode 100644 vendor/github.com/lightningnetwork/lnd/channeldb/witness_cache.go create mode 100644 vendor/github.com/lightningnetwork/lnd/clock/LICENSE create mode 100644 vendor/github.com/lightningnetwork/lnd/clock/default_clock.go create mode 100644 vendor/github.com/lightningnetwork/lnd/clock/go.mod create mode 100644 vendor/github.com/lightningnetwork/lnd/clock/interface.go create mode 100644 vendor/github.com/lightningnetwork/lnd/clock/test_clock.go create mode 100644 vendor/github.com/lightningnetwork/lnd/htlcswitch/hop/error_encryptor.go create mode 100644 vendor/github.com/lightningnetwork/lnd/htlcswitch/hop/forwarding_info.go create mode 100644 vendor/github.com/lightningnetwork/lnd/htlcswitch/hop/iterator.go create mode 100644 vendor/github.com/lightningnetwork/lnd/htlcswitch/hop/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/htlcswitch/hop/network.go create mode 100644 vendor/github.com/lightningnetwork/lnd/htlcswitch/hop/payload.go create mode 100644 vendor/github.com/lightningnetwork/lnd/htlcswitch/hop/type.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/input.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/script_utils.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/signdescriptor.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/signer.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/size.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/test_utils.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/txout.go create mode 100644 vendor/github.com/lightningnetwork/lnd/input/witnessgen.go create mode 100644 vendor/github.com/lightningnetwork/lnd/keychain/btcwallet.go create mode 100644 vendor/github.com/lightningnetwork/lnd/keychain/derivation.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lntypes/hash.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lntypes/preimage.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/README.md create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chainfee/estimator.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chainfee/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chainfee/rates.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chanfunding/assembler.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chanfunding/canned_assembler.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chanfunding/coin_select.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chanfunding/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chanfunding/psbt_assembler.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chanfunding/wallet_assembler.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/channel.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/chanvalidate/validate.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/commit_sort.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/commitment.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/config.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/errors.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/interface.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/parameters.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/reservation.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/sigpool.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/test_utils.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/transactions.go create mode 100644 vendor/github.com/lightningnetwork/lnd/lnwallet/wallet.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/chan_status_manager.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/channel_announcement.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/channel_state.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/channel_update.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/interface.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/log.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/node_announcement.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/node_signer.go create mode 100644 vendor/github.com/lightningnetwork/lnd/netann/sign.go create mode 100644 vendor/github.com/lightningnetwork/lnd/queue/circular_buf.go create mode 100644 vendor/github.com/lightningnetwork/lnd/queue/priority_queue.go create mode 100644 vendor/github.com/lightningnetwork/lnd/record/amp.go create mode 100644 vendor/github.com/lightningnetwork/lnd/record/custom_records.go create mode 100644 vendor/github.com/lightningnetwork/lnd/record/experimental.go create mode 100644 vendor/github.com/lightningnetwork/lnd/record/hop.go create mode 100644 vendor/github.com/lightningnetwork/lnd/record/mpp.go create mode 100644 vendor/github.com/lightningnetwork/lnd/routing/route/route.go create mode 100644 vendor/github.com/lightningnetwork/lnd/shachain/element.go create mode 100644 vendor/github.com/lightningnetwork/lnd/shachain/producer.go create mode 100644 vendor/github.com/lightningnetwork/lnd/shachain/store.go create mode 100644 vendor/github.com/lightningnetwork/lnd/shachain/utils.go create mode 100644 vendor/github.com/lightningnetwork/lnd/tlv/primitive.go create mode 100644 vendor/github.com/lightningnetwork/lnd/tlv/record.go create mode 100644 vendor/github.com/lightningnetwork/lnd/tlv/stream.go create mode 100644 vendor/github.com/lightningnetwork/lnd/tlv/truncated.go create mode 100644 vendor/github.com/lightningnetwork/lnd/tlv/varint.go create mode 100644 vendor/github.com/lightningnetwork/lnd/tor/add_onion.go create mode 100644 vendor/github.com/ltcsuite/ltcd/LICENSE create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/README.md create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/chainhash/README.md create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/chainhash/doc.go create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/chainhash/hash.go create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/chainhash/hashfuncs.go create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/doc.go create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/genesis.go create mode 100644 vendor/github.com/ltcsuite/ltcd/chaincfg/params.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/README.md create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/blockheader.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/common.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/doc.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/error.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/invvect.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/message.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgaddr.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgalert.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgblock.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgcfcheckpt.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgcfheaders.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgcfilter.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgfeefilter.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgfilteradd.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgfilterclear.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgfilterload.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msggetaddr.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msggetblocks.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msggetcfcheckpt.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msggetcfheaders.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msggetcfilters.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msggetdata.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msggetheaders.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgheaders.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msginv.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgmempool.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgmerkleblock.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgnotfound.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgping.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgpong.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgreject.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgsendheaders.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgtx.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgverack.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/msgversion.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/netaddress.go create mode 100644 vendor/github.com/ltcsuite/ltcd/wire/protocol.go create mode 100644 vendor/github.com/mattn/go-sqlite3/.gitignore create mode 100644 vendor/github.com/mattn/go-sqlite3/.travis.yml create mode 100644 vendor/github.com/mattn/go-sqlite3/LICENSE create mode 100644 vendor/github.com/mattn/go-sqlite3/README.md create mode 100644 vendor/github.com/mattn/go-sqlite3/backup.go create mode 100644 vendor/github.com/mattn/go-sqlite3/callback.go create mode 100644 vendor/github.com/mattn/go-sqlite3/convert.go create mode 100644 vendor/github.com/mattn/go-sqlite3/doc.go create mode 100644 vendor/github.com/mattn/go-sqlite3/error.go create mode 100644 vendor/github.com/mattn/go-sqlite3/go.mod create mode 100644 vendor/github.com/mattn/go-sqlite3/go.sum create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_context.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_go18.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_libsqlite3.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_load_extension_omit.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_allow_uri_authority.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_app_armor.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_foreign_keys.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_fts5.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_icu.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_introspect.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_json1.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_hook.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_preupdate_omit.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_secure_delete_fast.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_stat4.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_userauth.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_userauth_omit.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_full.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vacuum_incr.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_opt_vtable.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_other.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_solaris.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_trace.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_type.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_usleep_windows.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3_windows.go create mode 100644 vendor/github.com/mattn/go-sqlite3/sqlite3ext.h create mode 100644 vendor/github.com/mattn/go-sqlite3/static_mock.go create mode 100644 vendor/github.com/miekg/dns/.codecov.yml create mode 100644 vendor/github.com/miekg/dns/CODEOWNERS create mode 100644 vendor/github.com/miekg/dns/Makefile.release create mode 100644 vendor/github.com/miekg/dns/acceptfunc.go create mode 100644 vendor/github.com/miekg/dns/duplicate.go create mode 100644 vendor/github.com/miekg/dns/go.mod create mode 100644 vendor/github.com/miekg/dns/go.sum delete mode 100644 vendor/github.com/miekg/dns/internal/socket/cmsghdr.go delete mode 100644 vendor/github.com/miekg/dns/internal/socket/cmsghdr_linux_64bit.go delete mode 100644 vendor/github.com/miekg/dns/internal/socket/cmsghdr_other.go delete mode 100644 vendor/github.com/miekg/dns/internal/socket/controlmessage.go delete mode 100644 vendor/github.com/miekg/dns/internal/socket/socket.go delete mode 100644 vendor/github.com/miekg/dns/internal/socket/sys.go create mode 100644 vendor/github.com/miekg/dns/listen_go111.go create mode 100644 vendor/github.com/miekg/dns/listen_go_not111.go create mode 100644 vendor/github.com/miekg/dns/msg_truncate.go delete mode 100644 vendor/github.com/miekg/dns/rawmsg.go delete mode 100644 vendor/github.com/miekg/dns/scanner.go create mode 100644 vendor/github.com/miekg/dns/serve_mux.go delete mode 100644 vendor/github.com/miekg/dns/udp_linux.go delete mode 100644 vendor/github.com/miekg/dns/udp_other.go create mode 100644 vendor/github.com/miekg/dns/version.go delete mode 100644 vendor/github.com/miekg/dns/zcompress.go create mode 100644 vendor/github.com/miekg/dns/zduplicate.go create mode 100644 vendor/github.com/muun/libwallet/addresses/addresses.go create mode 100644 vendor/github.com/muun/libwallet/addresses/v1.go create mode 100644 vendor/github.com/muun/libwallet/addresses/v2.go create mode 100644 vendor/github.com/muun/libwallet/addresses/v3.go create mode 100644 vendor/github.com/muun/libwallet/addresses/v4.go rename vendor/github.com/muun/libwallet/{aes.go => aescbc/aescbc.go} (66%) delete mode 100644 vendor/github.com/muun/libwallet/derivationpath.go create mode 100644 vendor/github.com/muun/libwallet/emergency_kit.go create mode 100644 vendor/github.com/muun/libwallet/emergencykit/content.go create mode 100644 vendor/github.com/muun/libwallet/emergencykit/css.go create mode 100644 vendor/github.com/muun/libwallet/emergencykit/emergencykit.go create mode 100644 vendor/github.com/muun/libwallet/encrypt.go create mode 100644 vendor/github.com/muun/libwallet/fees.go create mode 100644 vendor/github.com/muun/libwallet/fees/fees.go delete mode 100644 vendor/github.com/muun/libwallet/hdkeycommon.go create mode 100644 vendor/github.com/muun/libwallet/hdpath/hdpath.go create mode 100644 vendor/github.com/muun/libwallet/incoming_swap.go create mode 100644 vendor/github.com/muun/libwallet/init.go create mode 100644 vendor/github.com/muun/libwallet/invoices.go create mode 100644 vendor/github.com/muun/libwallet/keycrypt/keycrypt.go create mode 100644 vendor/github.com/muun/libwallet/publickey.go create mode 100644 vendor/github.com/muun/libwallet/recoverycode.go create mode 100644 vendor/github.com/muun/libwallet/recoverycode/recoverycode.go create mode 100644 vendor/github.com/muun/libwallet/sphinx/sphinx.go create mode 100644 vendor/github.com/muun/libwallet/swaps/swaps.go create mode 100644 vendor/github.com/muun/libwallet/swaps/v1.go create mode 100644 vendor/github.com/muun/libwallet/swaps/v2.go create mode 100644 vendor/github.com/muun/libwallet/walletdb/walletdb.go create mode 100644 vendor/github.com/pkg/errors/Makefile create mode 100644 vendor/github.com/pkg/errors/go113.go rename vendor/{github.com/coreos => go.etcd.io}/bbolt/.gitignore (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/.travis.yml (96%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/LICENSE (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/Makefile (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/README.md (97%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_386.go (72%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_amd64.go (73%) create mode 100644 vendor/go.etcd.io/bbolt/bolt_arm.go rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_arm64.go (75%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_linux.go (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_mips64x.go (75%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_mipsx.go (74%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_openbsd.go (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_ppc.go (74%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_ppc64.go (75%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_ppc64le.go (75%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_riscv64.go (75%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_s390x.go (75%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_unix.go (98%) create mode 100644 vendor/go.etcd.io/bbolt/bolt_unix_aix.go rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_unix_solaris.go (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bolt_windows.go (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/boltsync_unix.go (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/bucket.go (95%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/cursor.go (99%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/db.go (99%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/doc.go (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/errors.go (100%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/freelist.go (92%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/freelist_hmap.go (99%) create mode 100644 vendor/go.etcd.io/bbolt/go.mod create mode 100644 vendor/go.etcd.io/bbolt/go.sum rename vendor/{github.com/coreos => go.etcd.io}/bbolt/node.go (92%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/page.go (77%) rename vendor/{github.com/coreos => go.etcd.io}/bbolt/tx.go (98%) create mode 100644 vendor/go.etcd.io/bbolt/unsafe.go create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go create mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519_go113.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/const.go create mode 100644 vendor/golang.org/x/crypto/ed25519/internal/edwards25519/edwards25519.go create mode 100644 vendor/golang.org/x/crypto/poly1305/bits_compat.go create mode 100644 vendor/golang.org/x/crypto/poly1305/bits_go1.13.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/sum_arm.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/sum_arm.s delete mode 100644 vendor/golang.org/x/crypto/poly1305/sum_noasm.go delete mode 100644 vendor/golang.org/x/crypto/poly1305/sum_vmsl_s390x.s create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/terminal.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_aix.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_bsd.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_linux.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_plan9.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_solaris.go create mode 100644 vendor/golang.org/x/crypto/ssh/terminal/util_windows.go create mode 100644 vendor/golang.org/x/net/bpf/asm.go create mode 100644 vendor/golang.org/x/net/bpf/constants.go create mode 100644 vendor/golang.org/x/net/bpf/doc.go create mode 100644 vendor/golang.org/x/net/bpf/instructions.go create mode 100644 vendor/golang.org/x/net/bpf/setter.go create mode 100644 vendor/golang.org/x/net/bpf/vm.go create mode 100644 vendor/golang.org/x/net/bpf/vm_instructions.go create mode 100644 vendor/golang.org/x/net/internal/iana/const.go create mode 100644 vendor/golang.org/x/net/internal/socket/cmsghdr.go create mode 100644 vendor/golang.org/x/net/internal/socket/cmsghdr_bsd.go rename vendor/{github.com/miekg/dns => golang.org/x/net}/internal/socket/cmsghdr_linux_32bit.go (51%) create mode 100644 vendor/golang.org/x/net/internal/socket/cmsghdr_linux_64bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/cmsghdr_solaris_64bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/cmsghdr_stub.go create mode 100644 vendor/golang.org/x/net/internal/socket/empty.s create mode 100644 vendor/golang.org/x/net/internal/socket/error_unix.go create mode 100644 vendor/golang.org/x/net/internal/socket/error_windows.go create mode 100644 vendor/golang.org/x/net/internal/socket/iovec_32bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/iovec_64bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/iovec_solaris_64bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/iovec_stub.go create mode 100644 vendor/golang.org/x/net/internal/socket/mmsghdr_stub.go create mode 100644 vendor/golang.org/x/net/internal/socket/mmsghdr_unix.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_bsd.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_bsdvar.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_linux.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_linux_32bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_linux_64bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_openbsd.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_solaris_64bit.go create mode 100644 vendor/golang.org/x/net/internal/socket/msghdr_stub.go create mode 100644 vendor/golang.org/x/net/internal/socket/norace.go create mode 100644 vendor/golang.org/x/net/internal/socket/race.go create mode 100644 vendor/golang.org/x/net/internal/socket/rawconn.go create mode 100644 vendor/golang.org/x/net/internal/socket/rawconn_mmsg.go create mode 100644 vendor/golang.org/x/net/internal/socket/rawconn_msg.go create mode 100644 vendor/golang.org/x/net/internal/socket/rawconn_nommsg.go create mode 100644 vendor/golang.org/x/net/internal/socket/rawconn_nomsg.go create mode 100644 vendor/golang.org/x/net/internal/socket/socket.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_bsd.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_bsdvar.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_const_unix.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_darwin.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_dragonfly.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_go1_11_darwin.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linkname.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_386.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_386.s create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_amd64.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_arm.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_mips.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_mips64.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_mips64le.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_mipsle.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_ppc64.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_ppc64le.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_s390x.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_linux_s390x.s create mode 100644 vendor/golang.org/x/net/internal/socket/sys_netbsd.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_posix.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_solaris.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_solaris_amd64.s create mode 100644 vendor/golang.org/x/net/internal/socket/sys_stub.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_unix.go create mode 100644 vendor/golang.org/x/net/internal/socket/sys_windows.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_aix_ppc64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_darwin_amd64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_darwin_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_dragonfly_amd64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_freebsd_386.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_freebsd_amd64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_freebsd_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_386.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_amd64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_arm.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_mips.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_mips64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_mips64le.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_mipsle.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_ppc64le.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_linux_s390x.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_netbsd_386.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_netbsd_amd64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_netbsd_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_openbsd_386.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_openbsd_amd64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_openbsd_arm64.go create mode 100644 vendor/golang.org/x/net/internal/socket/zsys_solaris_amd64.go create mode 100644 vendor/golang.org/x/net/ipv4/batch.go create mode 100644 vendor/golang.org/x/net/ipv4/control.go create mode 100644 vendor/golang.org/x/net/ipv4/control_bsd.go create mode 100644 vendor/golang.org/x/net/ipv4/control_pktinfo.go create mode 100644 vendor/golang.org/x/net/ipv4/control_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/control_unix.go create mode 100644 vendor/golang.org/x/net/ipv4/control_windows.go create mode 100644 vendor/golang.org/x/net/ipv4/dgramopt.go create mode 100644 vendor/golang.org/x/net/ipv4/doc.go create mode 100644 vendor/golang.org/x/net/ipv4/endpoint.go create mode 100644 vendor/golang.org/x/net/ipv4/genericopt.go create mode 100644 vendor/golang.org/x/net/ipv4/header.go create mode 100644 vendor/golang.org/x/net/ipv4/helper.go create mode 100644 vendor/golang.org/x/net/ipv4/iana.go create mode 100644 vendor/golang.org/x/net/ipv4/icmp.go create mode 100644 vendor/golang.org/x/net/ipv4/icmp_linux.go create mode 100644 vendor/golang.org/x/net/ipv4/icmp_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/packet.go create mode 100644 vendor/golang.org/x/net/ipv4/payload.go create mode 100644 vendor/golang.org/x/net/ipv4/payload_cmsg.go create mode 100644 vendor/golang.org/x/net/ipv4/payload_nocmsg.go create mode 100644 vendor/golang.org/x/net/ipv4/sockopt.go create mode 100644 vendor/golang.org/x/net/ipv4/sockopt_posix.go create mode 100644 vendor/golang.org/x/net/ipv4/sockopt_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_aix.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_asmreq.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_asmreq_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_asmreqn.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_asmreqn_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_bpf.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_bpf_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_bsd.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_darwin.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_dragonfly.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_freebsd.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_linux.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_solaris.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_ssmreq.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_ssmreq_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_stub.go create mode 100644 vendor/golang.org/x/net/ipv4/sys_windows.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_aix_ppc64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_darwin.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_dragonfly.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_freebsd_386.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_freebsd_amd64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_freebsd_arm.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_freebsd_arm64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_386.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_amd64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_arm.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_arm64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_mips.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_mips64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_mips64le.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_mipsle.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_ppc.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_ppc64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_ppc64le.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_linux_s390x.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_netbsd.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_openbsd.go create mode 100644 vendor/golang.org/x/net/ipv4/zsys_solaris.go create mode 100644 vendor/golang.org/x/net/ipv6/batch.go create mode 100644 vendor/golang.org/x/net/ipv6/control.go create mode 100644 vendor/golang.org/x/net/ipv6/control_rfc2292_unix.go create mode 100644 vendor/golang.org/x/net/ipv6/control_rfc3542_unix.go create mode 100644 vendor/golang.org/x/net/ipv6/control_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/control_unix.go create mode 100644 vendor/golang.org/x/net/ipv6/control_windows.go create mode 100644 vendor/golang.org/x/net/ipv6/dgramopt.go create mode 100644 vendor/golang.org/x/net/ipv6/doc.go create mode 100644 vendor/golang.org/x/net/ipv6/endpoint.go create mode 100644 vendor/golang.org/x/net/ipv6/genericopt.go create mode 100644 vendor/golang.org/x/net/ipv6/header.go create mode 100644 vendor/golang.org/x/net/ipv6/helper.go create mode 100644 vendor/golang.org/x/net/ipv6/iana.go create mode 100644 vendor/golang.org/x/net/ipv6/icmp.go create mode 100644 vendor/golang.org/x/net/ipv6/icmp_bsd.go create mode 100644 vendor/golang.org/x/net/ipv6/icmp_linux.go create mode 100644 vendor/golang.org/x/net/ipv6/icmp_solaris.go create mode 100644 vendor/golang.org/x/net/ipv6/icmp_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/icmp_windows.go create mode 100644 vendor/golang.org/x/net/ipv6/payload.go create mode 100644 vendor/golang.org/x/net/ipv6/payload_cmsg.go create mode 100644 vendor/golang.org/x/net/ipv6/payload_nocmsg.go create mode 100644 vendor/golang.org/x/net/ipv6/sockopt.go create mode 100644 vendor/golang.org/x/net/ipv6/sockopt_posix.go create mode 100644 vendor/golang.org/x/net/ipv6/sockopt_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_aix.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_asmreq.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_asmreq_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_bpf.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_bpf_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_bsd.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_darwin.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_freebsd.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_linux.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_solaris.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_ssmreq.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_ssmreq_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_stub.go create mode 100644 vendor/golang.org/x/net/ipv6/sys_windows.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_aix_ppc64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_darwin.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_dragonfly.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_freebsd_386.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_freebsd_amd64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_freebsd_arm.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_freebsd_arm64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_386.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_amd64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_arm.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_arm64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_mips.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_mips64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_mips64le.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_mipsle.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_ppc.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_ppc64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_ppc64le.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_riscv64.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_linux_s390x.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_netbsd.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_openbsd.go create mode 100644 vendor/golang.org/x/net/ipv6/zsys_solaris.go create mode 100644 vendor/golang.org/x/net/proxy/dial.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go rename vendor/golang.org/x/sys/cpu/{cpu_gccgo.c => cpu_gccgo_x86.c} (100%) rename vendor/golang.org/x/sys/cpu/{cpu_gccgo.go => cpu_gccgo_x86.go} (100%) create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/hwcap_linux.go create mode 100644 vendor/golang.org/x/sys/unix/errors_freebsd_arm64.go create mode 100644 vendor/golang.org/x/sys/unix/fdset.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_dragonfly.go create mode 100644 vendor/golang.org/x/sys/unix/sockcmsg_unix_other.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_12.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_386.1_11.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_amd64.1_11.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm.1_11.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_darwin_arm64.1_11.go create mode 100644 vendor/golang.org/x/sys/unix/syscall_illumos.go create mode 100644 vendor/golang.org/x/sys/unix/zerrors_linux.go rename vendor/golang.org/x/sys/unix/{zptracearm_linux.go => zptrace_armnn_linux.go} (93%) create mode 100644 vendor/golang.org/x/sys/unix/zptrace_linux_arm64.go rename vendor/golang.org/x/sys/unix/{zptracemips_linux.go => zptrace_mipsnn_linux.go} (93%) rename vendor/golang.org/x/sys/unix/{zptracemipsle_linux.go => zptrace_mipsnnle_linux.go} (93%) rename vendor/golang.org/x/sys/unix/{zptrace386_linux.go => zptrace_x86_linux.go} (95%) create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_386.1_13.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.1_13.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm.1_13.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.1_13.s create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go create mode 100644 vendor/golang.org/x/sys/unix/zsyscall_linux.go create mode 100644 vendor/golang.org/x/sys/unix/ztypes_linux.go create mode 100644 vendor/golang.org/x/sys/windows/aliases.go create mode 100644 vendor/golang.org/x/sys/windows/dll_windows.go create mode 100644 vendor/golang.org/x/sys/windows/empty.s create mode 100644 vendor/golang.org/x/sys/windows/env_windows.go create mode 100644 vendor/golang.org/x/sys/windows/eventlog.go create mode 100644 vendor/golang.org/x/sys/windows/exec_windows.go create mode 100644 vendor/golang.org/x/sys/windows/memory_windows.go create mode 100644 vendor/golang.org/x/sys/windows/mkerrors.bash create mode 100644 vendor/golang.org/x/sys/windows/mkknownfolderids.bash create mode 100644 vendor/golang.org/x/sys/windows/mksyscall.go create mode 100644 vendor/golang.org/x/sys/windows/race.go create mode 100644 vendor/golang.org/x/sys/windows/race0.go create mode 100644 vendor/golang.org/x/sys/windows/security_windows.go create mode 100644 vendor/golang.org/x/sys/windows/service.go create mode 100644 vendor/golang.org/x/sys/windows/str.go create mode 100644 vendor/golang.org/x/sys/windows/syscall.go create mode 100644 vendor/golang.org/x/sys/windows/syscall_windows.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows_386.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows_amd64.go create mode 100644 vendor/golang.org/x/sys/windows/types_windows_arm.go create mode 100644 vendor/golang.org/x/sys/windows/zerrors_windows.go create mode 100644 vendor/golang.org/x/sys/windows/zknownfolderids_windows.go create mode 100644 vendor/golang.org/x/sys/windows/zsyscall_windows.go create mode 100644 vendor/google.golang.org/protobuf/AUTHORS create mode 100644 vendor/google.golang.org/protobuf/CONTRIBUTORS create mode 100644 vendor/google.golang.org/protobuf/LICENSE create mode 100644 vendor/google.golang.org/protobuf/PATENTS create mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/decode.go create mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/doc.go create mode 100644 vendor/google.golang.org/protobuf/encoding/prototext/encode.go create mode 100644 vendor/google.golang.org/protobuf/encoding/protowire/wire.go create mode 100644 vendor/google.golang.org/protobuf/internal/descfmt/stringer.go create mode 100644 vendor/google.golang.org/protobuf/internal/descopts/options.go create mode 100644 vendor/google.golang.org/protobuf/internal/detrand/rand.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/defval/default.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/messageset/messageset.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/tag/tag.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_number.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_string.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/decode_token.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/doc.go create mode 100644 vendor/google.golang.org/protobuf/internal/encoding/text/encode.go create mode 100644 vendor/google.golang.org/protobuf/internal/errors/errors.go create mode 100644 vendor/google.golang.org/protobuf/internal/errors/is_go112.go create mode 100644 vendor/google.golang.org/protobuf/internal/errors/is_go113.go create mode 100644 vendor/google.golang.org/protobuf/internal/fieldsort/fieldsort.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/build.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/desc_list_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/filedesc/placeholder.go create mode 100644 vendor/google.golang.org/protobuf/internal/filetype/build.go create mode 100644 vendor/google.golang.org/protobuf/internal/flags/flags.go create mode 100644 vendor/google.golang.org/protobuf/internal/flags/proto_legacy_disable.go create mode 100644 vendor/google.golang.org/protobuf/internal/flags/proto_legacy_enable.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/any_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/api_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/doc.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/duration_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/empty_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/goname.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/map_entry.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/struct_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/type_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/api_export.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/checkinit.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_extension.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_field.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map_go111.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_map_go112.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_message.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_messageset.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_reflect.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_tables.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/codec_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert_list.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/convert_map.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/decode.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/encode.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/enum.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/extension.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_enum.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_export.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_extension.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_file.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/legacy_message.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/merge.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/merge_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/pointer_reflect.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/pointer_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/validate.go create mode 100644 vendor/google.golang.org/protobuf/internal/impl/weak.go create mode 100644 vendor/google.golang.org/protobuf/internal/mapsort/mapsort.go create mode 100644 vendor/google.golang.org/protobuf/internal/pragma/pragma.go create mode 100644 vendor/google.golang.org/protobuf/internal/set/ints.go create mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings.go create mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings_pure.go create mode 100644 vendor/google.golang.org/protobuf/internal/strs/strings_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/internal/version/version.go create mode 100644 vendor/google.golang.org/protobuf/proto/checkinit.go create mode 100644 vendor/google.golang.org/protobuf/proto/decode.go create mode 100644 vendor/google.golang.org/protobuf/proto/decode_gen.go create mode 100644 vendor/google.golang.org/protobuf/proto/doc.go create mode 100644 vendor/google.golang.org/protobuf/proto/encode.go create mode 100644 vendor/google.golang.org/protobuf/proto/encode_gen.go create mode 100644 vendor/google.golang.org/protobuf/proto/equal.go create mode 100644 vendor/google.golang.org/protobuf/proto/extension.go create mode 100644 vendor/google.golang.org/protobuf/proto/merge.go create mode 100644 vendor/google.golang.org/protobuf/proto/messageset.go create mode 100644 vendor/google.golang.org/protobuf/proto/proto.go create mode 100644 vendor/google.golang.org/protobuf/proto/proto_methods.go create mode 100644 vendor/google.golang.org/protobuf/proto/proto_reflect.go create mode 100644 vendor/google.golang.org/protobuf/proto/reset.go create mode 100644 vendor/google.golang.org/protobuf/proto/size.go create mode 100644 vendor/google.golang.org/protobuf/proto/size_gen.go create mode 100644 vendor/google.golang.org/protobuf/proto/wrappers.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/methods.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/source.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/type.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_pure.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_union.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoreflect/value_unsafe.go create mode 100644 vendor/google.golang.org/protobuf/reflect/protoregistry/registry.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoiface/legacy.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoiface/methods.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoimpl/impl.go create mode 100644 vendor/google.golang.org/protobuf/runtime/protoimpl/version.go create mode 100644 vendor/gopkg.in/gormigrate.v1/.editorconfig create mode 100644 vendor/gopkg.in/gormigrate.v1/.gitattributes create mode 100644 vendor/gopkg.in/gormigrate.v1/.gitignore create mode 100644 vendor/gopkg.in/gormigrate.v1/.sample.env create mode 100644 vendor/gopkg.in/gormigrate.v1/.travis.yml create mode 100644 vendor/gopkg.in/gormigrate.v1/CHANGELOG.md create mode 100644 vendor/gopkg.in/gormigrate.v1/Dockerfile create mode 100644 vendor/gopkg.in/gormigrate.v1/LICENSE create mode 100644 vendor/gopkg.in/gormigrate.v1/README.md create mode 100644 vendor/gopkg.in/gormigrate.v1/Taskfile.yml create mode 100644 vendor/gopkg.in/gormigrate.v1/appveyor.yml create mode 100644 vendor/gopkg.in/gormigrate.v1/doc.go create mode 100644 vendor/gopkg.in/gormigrate.v1/docker-compose.yml create mode 100644 vendor/gopkg.in/gormigrate.v1/go.mod create mode 100644 vendor/gopkg.in/gormigrate.v1/go.sum create mode 100644 vendor/gopkg.in/gormigrate.v1/gormigrate.go diff --git a/go.mod b/go.mod index 184030b..0a9b04f 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,14 @@ module github.com/muun/recovery_tool go 1.12 require ( - github.com/btcsuite/btcd v0.20.1-beta + github.com/btcsuite/btcd v0.21.0-beta github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f - github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d - github.com/btcsuite/btcwallet v0.10.0 - github.com/btcsuite/btcwallet/walletdb v1.1.0 - github.com/lightninglabs/neutrino v0.10.0 - github.com/muun/libwallet v0.2.0 + github.com/btcsuite/btcutil v1.0.2 + github.com/btcsuite/btcwallet v0.11.1-0.20200612012534-48addcd5591a + github.com/btcsuite/btcwallet/walletdb v1.3.3 + github.com/lightninglabs/neutrino v0.11.1-0.20200316235139-bffc52e8f200 + github.com/muun/libwallet v0.5.0 + github.com/pkg/errors v0.9.1 // indirect ) replace github.com/lightninglabs/neutrino => github.com/muun/neutrino v0.0.0-20190914162326-7082af0fa257 diff --git a/go.sum b/go.sum index 30c45ff..34227a8 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,21 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= git.schwanenlied.me/yawning/bsaes.git v0.0.0-20180720073208-c0276d75487e/go.mod h1:BWqTsj8PgcPriQJGl7el20J/7TuT1d/hSyFDXMEpoEo= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/NebulousLabs/fastrand v0.0.0-20181203155948-6fb6489aac4e/go.mod h1:Bdzq+51GR4/0DIhaICZEOm+OHvXGwwB2trKZ8B4Y6eQ= github.com/NebulousLabs/go-upnp v0.0.0-20180202185039-29b680b06c82/go.mod h1:GbuBk21JqF+driLX3XtJYNZjGa45YDoa9IqCTzNSfEc= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/Yawning/aez v0.0.0-20180114000226-4dad034d9db2/go.mod h1:9pIqrY6SXNL8vjRQE5Hd/OL5GyK/9MrGUWs87z/eFfk= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/btcsuite/btcd v0.0.0-20190629003639-c26ffa870fd8/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= @@ -16,49 +23,87 @@ github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcug github.com/btcsuite/btcd v0.20.0-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.20.1-beta.0.20200513120220-b470eee47728/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.20.1-beta.0.20200515232429-9f0179fd2c46/go.mod h1:Yktc19YNjh/Iz2//CX0vfRTS4IJKM/RKO5YZ9Fn+Pgo= +github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= 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/psbt v1.0.2 h1:gCVY3KxdoEVU7Q6TjusPO+GANIwVgr9yTLqM+a6CZr8= +github.com/btcsuite/btcutil/psbt v1.0.2/go.mod h1:LVveMu4VaNSkIRTZu2+ut0HDBRuYjqGocxDMNS1KuGQ= github.com/btcsuite/btcwallet v0.10.0 h1:fFZncfYJ7VByePTGttzJc3qfCyDzU95ucZYk0M912lU= github.com/btcsuite/btcwallet v0.10.0/go.mod h1:4TqBEuceheGNdeLNrelliLHJzmXauMM2vtWfuy1pFiM= github.com/btcsuite/btcwallet v0.10.1-0.20191109031858-c49e7ef3ecf1/go.mod h1:4TqBEuceheGNdeLNrelliLHJzmXauMM2vtWfuy1pFiM= +github.com/btcsuite/btcwallet v0.11.1-0.20200612012534-48addcd5591a h1:AZ1Mf0gd9mgJqrTTIFUc17ep9EKUbQusVAIzJ6X+x3Q= +github.com/btcsuite/btcwallet v0.11.1-0.20200612012534-48addcd5591a/go.mod h1:9+AH3V5mcTtNXTKe+fe63fDLKGOwQbZqmvOVUef+JFE= +github.com/btcsuite/btcwallet/wallet/txauthor v1.0.0 h1:KGHMW5sd7yDdDMkCZ/JpP0KltolFsQcB973brBnfj4c= github.com/btcsuite/btcwallet/wallet/txauthor v1.0.0/go.mod h1:VufDts7bd/zs3GV13f/lXc/0lXrPnvxD/NvmpG/FEKU= +github.com/btcsuite/btcwallet/wallet/txrules v1.0.0 h1:2VsfS0sBedcM5KmDzRMT3+b6xobqWveZGvjb+jFez5w= github.com/btcsuite/btcwallet/wallet/txrules v1.0.0/go.mod h1:UwQE78yCerZ313EXZwEiu3jNAtfXj2n2+c8RWiE/WNA= +github.com/btcsuite/btcwallet/wallet/txsizes v1.0.0 h1:6DxkcoMnCPY4E9cUDPB5tbuuf40SmmMkSQkoE8vCT+s= github.com/btcsuite/btcwallet/wallet/txsizes v1.0.0/go.mod h1:pauEU8UuMFiThe5PB3EO+gO5kx87Me5NvdQDsTuq6cs= github.com/btcsuite/btcwallet/walletdb v1.0.0/go.mod h1:bZTy9RyYZh9fLnSua+/CD48TJtYJSHjjYcSaszuxCCk= github.com/btcsuite/btcwallet/walletdb v1.1.0 h1:JHAL7wZ8pX4SULabeAv/wPO9sseRWMGzE80lfVmRw6Y= github.com/btcsuite/btcwallet/walletdb v1.1.0/go.mod h1:bZTy9RyYZh9fLnSua+/CD48TJtYJSHjjYcSaszuxCCk= +github.com/btcsuite/btcwallet/walletdb v1.3.1/go.mod h1:9cwc1Yyg4uvd4ZdfdoMnALji+V9gfWSMfxEdLdR5Vwc= +github.com/btcsuite/btcwallet/walletdb v1.3.2/go.mod h1:GZCMPNpUu5KE3ASoVd+k06p/1OW8OwNGCCaNWRto2cQ= +github.com/btcsuite/btcwallet/walletdb v1.3.3 h1:u6e7vRIKBF++cJy+hOHaMGg+88ZTwvpaY27AFvtB668= +github.com/btcsuite/btcwallet/walletdb v1.3.3/go.mod h1:oJDxAEUHVtnmIIBaa22wSBPTVcs6hUp5NKWmI8xDwwU= github.com/btcsuite/btcwallet/wtxmgr v1.0.0 h1:aIHgViEmZmZfe0tQQqF1xyd2qBqFWxX5vZXkkbjtbeA= github.com/btcsuite/btcwallet/wtxmgr v1.0.0/go.mod h1:vc4gBprll6BP0UJ+AIGDaySoc7MdAmZf8kelfNb8CFY= +github.com/btcsuite/btcwallet/wtxmgr v1.2.0 h1:ZUYPsSv8GjF9KK7lboB2OVHF0uYEcHxgrCfFWqPd9NA= +github.com/btcsuite/btcwallet/wtxmgr v1.2.0/go.mod h1:h8hkcKUE3X7lMPzTUoGnNiw5g7VhGrKEW3KpR2r0VnY= github.com/btcsuite/fastsha256 v0.0.0-20160815193821-637e65642941/go.mod h1:QcFA8DZHtuIAdYKCq/BzELOaznRsCvwf4zTPmaYwaig= 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/golangcrypto v0.0.0-20150304025918-53f62d9b43e8/go.mod h1:tYvUd8KLhm/oXvUeSEs2VlLghFjQt9+ZaF9ghH0JNjc= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0 h1:Tvd0BfvqX9o823q1j2UZ/epQo09eJh6dTcRp79ilIN4= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0 h1:ZxaA6lo2EpxGddsA8JwWOcxlzRybb444sgmeJQMJGQE= github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792 h1:R8vQdOQdZ9Y3SkEwmHoWBmX1DNXhXZqlTpq6s4tyJGc= github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY= github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= 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= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -66,15 +111,42 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.1-0.20190312032427-6f77996f0c42/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v0.0.0-20170724004829-f2862b476edc/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/grpc-ecosystem/grpc-gateway v1.8.6/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= github.com/jackpal/go-nat-pmp v0.0.0-20170405195558-28a68d0c24ad/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= +github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc= +github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/juju/clock v0.0.0-20190205081909-9c5c9712527c/go.mod h1:nD0vlnrUjcjJhqN5WuCWZyzfd5AHZAC9/ajvbSx69xA= github.com/juju/errors v0.0.0-20190806202954-0232dcc7464d/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= @@ -93,22 +165,44 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lightninglabs/gozmq v0.0.0-20190710231225-cea2a031735d h1:tt8hwvxl6fksSfchjBGaWu+pnWJQfG1OWiCM20qOSAE= github.com/lightninglabs/gozmq v0.0.0-20190710231225-cea2a031735d/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk= +github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf h1:HZKvJUHlcXI/f/O0Avg7t8sqkPo78HFzjmeYFl6DPnc= +github.com/lightninglabs/gozmq v0.0.0-20191113021534-d20a764486bf/go.mod h1:vxmQPeIQxPf6Jf9rM8R+B4rKBqLA2AjttNxkFBL2Plk= +github.com/lightninglabs/protobuf-hex-display v1.3.3-0.20191212020323-b444784ce75d/go.mod h1:KDb67YMzoh4eudnzClmvs2FbiLG9vxISmLApUkCa4uI= github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4= +github.com/lightningnetwork/lightning-onion v1.0.1 h1:qChGgS5+aPxFeR6JiUsGvanei1bn6WJpYbvosw/1604= +github.com/lightningnetwork/lightning-onion v1.0.1/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4= github.com/lightningnetwork/lnd v0.8.0-beta h1:HmmhSRTq48qobqQF8YLqNa8eKU8dDBNbWWpr2VzycJM= github.com/lightningnetwork/lnd v0.8.0-beta/go.mod h1:nq06y2BDv7vwWeMmwgB7P3pT7/Uj7sGf5FzHISVD6t4= +github.com/lightningnetwork/lnd v0.10.4-beta h1:Af2zOCPePeaU8Tkl8IqtTjr4BP3zYfi+hAtQYcCMM58= +github.com/lightningnetwork/lnd v0.10.4-beta/go.mod h1:4d02pduRVtZwgTJ+EimKJTsEAY0jDwi0SPE9h5aRneM= +github.com/lightningnetwork/lnd/cert v1.0.2/go.mod h1:fmtemlSMf5t4hsQmcprSoOykypAPp+9c+0d0iqTScMo= +github.com/lightningnetwork/lnd/clock v1.0.1 h1:QQod8+m3KgqHdvVMV+2DRNNZS1GRFir8mHZYA+Z2hFo= +github.com/lightningnetwork/lnd/clock v1.0.1/go.mod h1:KnQudQ6w0IAMZi1SgvecLZQZ43ra2vpDNj7H/aasemg= github.com/lightningnetwork/lnd/queue v1.0.1 h1:jzJKcTy3Nj5lQrooJ3aaw9Lau3I0IwvQR5sqtjdv2R0= github.com/lightningnetwork/lnd/queue v1.0.1/go.mod h1:vaQwexir73flPW43Mrm7JOgJHmcEFBWWSl9HlyASoms= +github.com/lightningnetwork/lnd/queue v1.0.4 h1:8Dq3vxAFSACPy+pKN88oPFhuCpCoAAChPBwa4BJxH4k= +github.com/lightningnetwork/lnd/queue v1.0.4/go.mod h1:YTkTVZCxz8tAYreH27EO3s8572ODumWrNdYW2E/YKxg= github.com/lightningnetwork/lnd/ticker v1.0.0 h1:S1b60TEGoTtCe2A0yeB+ecoj/kkS4qpwh6l+AkQEZwU= github.com/lightningnetwork/lnd/ticker v1.0.0/go.mod h1:iaLXJiVgI1sPANIF2qYYUJXjoksPNvGNYowB8aRbpX0= +github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796 h1:sjOGyegMIhvgfq5oaue6Td+hxZuf3tDC8lAPrFldqFw= github.com/ltcsuite/ltcd v0.0.0-20190101042124-f37f8bf35796/go.mod h1:3p7ZTf9V1sNPI5H8P3NkTFF4LuwMdPl2DodF60qAKqY= github.com/ltcsuite/ltcutil v0.0.0-20181217130922-17f3b04680b6/go.mod h1:8Vg/LTOO0KYa/vlHWJ6XZAevPQThGH5sufO0Hrou/lA= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v0.0.0-20171125082028-79bfde677fa8 h1:PRMAcldsl4mXKJeRNB/KVNz6TlbS6hk2Rs42PqgU3Ws= github.com/miekg/dns v0.0.0-20171125082028-79bfde677fa8/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/muun/libwallet v0.2.0 h1:Y64skcAZnwuxuSmoDPDui9RQv+3fxShDMN3UiROQ7CA= -github.com/muun/libwallet v0.2.0/go.mod h1:eOp7//0x8kWLXWuUyRtQlJ5WN0ZIaQNhL9++LOincrM= +github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg= +github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/muun/libwallet v0.5.0 h1:3YcUuQsnViXdrXntBwV3sLH2RKHC5uNODhuawp+2dg8= +github.com/muun/libwallet v0.5.0/go.mod h1:EdLg8d1sGJ4q4VUKRJyfNDBnbWc+rs5b8pHHu6KF5LY= github.com/muun/neutrino v0.0.0-20190914162326-7082af0fa257 h1:NW17wq2gZlEFeW3/Zx3wSmqlD0wKGf7YvhpP+CNCsbE= github.com/muun/neutrino v0.0.0-20190914162326-7082af0fa257/go.mod h1:awTrhbCWjWNH4yVwZ4IE7nZbvpQ27e7OyD+jao7wRxA= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -120,45 +214,87 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tv42/zbase32 v0.0.0-20160707012821-501572607d02/go.mod h1:tHlrkM198S068ZqfrO6S8HsoJq2bF3ETfTL+kt4tInY= github.com/urfave/cli v1.18.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5-0.20200615073812-232d8fc87f50 h1:ASw9n1EHMftwnP3Az4XW6e308+gNsrHzmdhd0Olz9Hs= +go.etcd.io/bbolt v1.3.5-0.20200615073812-232d8fc87f50/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7 h1:0hQKqeLdqlt5iIwVOBErRisrHJAN57yOiPRQItI20fU= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20200720140940-1a48f808d81f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -169,24 +305,63 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd h1:DBH9mDw0zluJT/R+nGuV3jWFWLFaHyYZWD4tOT+cjn0= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY= +golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190201180003-4b09977fb922/go.mod h1:L3J43x8/uS+qIUoksaLKe6OS3nUKxOKuIFz1sl2/jx4= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v1 v1.0.1/go.mod h1:3NjfXwocQRYAPTq4/fzX+CwUhPRcR/azYRhj8G+LqMo= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gormigrate.v1 v1.6.0 h1:XpYM6RHQPmzwY7Uyu+t+xxMXc86JYFJn4nEc9HzQjsI= +gopkg.in/gormigrate.v1 v1.6.0/go.mod h1:Lf00lQrHqfSYWiTtPcyQabsDdM6ejZaMgV0OU6JMSlw= gopkg.in/macaroon-bakery.v2 v2.0.1/go.mod h1:B4/T17l+ZWGwxFSZQmlBwp25x+og7OkhETfr3S9MbIA= gopkg.in/macaroon.v2 v2.0.0/go.mod h1:+I6LnTMkm/uV5ew/0nsulNjL16SK4+C8yDmRUzHR17I= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/keys_generator.go b/keys_generator.go index dcba06d..d03461d 100644 --- a/keys_generator.go +++ b/keys_generator.go @@ -8,24 +8,24 @@ import ( ) func buildExtendedKey(rawKey, recoveryCode string) *libwallet.DecryptedPrivateKey { - recoveryCodeBytes := extractBytes(recoveryCode) salt := extractSalt(rawKey) - privKey := libwallet.NewChallengePrivateKey(recoveryCodeBytes, salt) + decryptionKey, err := libwallet.RecoveryCodeToKey(recoveryCode, salt) + if err != nil { + log.Fatalf("failed to process recovery code: %v", err) + } - key, err := privKey.DecryptKey(rawKey, libwallet.Mainnet()) + walletKey, err := decryptionKey.DecryptKey(rawKey, libwallet.Mainnet()) if err != nil { log.Fatalf("failed to decrypt key: %v", err) } - return key + return walletKey } -func extractSalt(rawKey string) []byte { +func extractSalt(rawKey string) string { bytes := base58.Decode(rawKey) - return bytes[len(bytes)-8:] -} + saltBytes := bytes[len(bytes)-8:] -func extractBytes(recoveryCode string) []byte { - return []byte(recoveryCode) + return string(saltBytes) } diff --git a/main.go b/main.go new file mode 100644 index 0000000..4df334e --- /dev/null +++ b/main.go @@ -0,0 +1,241 @@ +package main + +import ( + "fmt" + "log" + "os" + "strconv" + "strings" + + "github.com/btcsuite/btcutil" +) + +func main() { + chainService, close, _ := startChainService() + defer close() + + printWelcomeMessage() + + recoveryCode := readRecoveryCode() + + userRawKey := readKey("first encrypted private key", 147) + userKey := buildExtendedKey(userRawKey, recoveryCode) + userKey.Key.Path = "m/1'/1'" + + muunRawKey := readKey("second encrypted private key", 147) + muunKey := buildExtendedKey(muunRawKey, recoveryCode) + + sweepAddress := readSweepAddress() + + fmt.Println("") + fmt.Println("Preparing to scan the blockchain from your wallet creation block") + fmt.Println("Note that only confirmed transactions can be detected") + fmt.Println("\nThis may take a while") + + sweeper := Sweeper{ + ChainService: chainService, + UserKey: userKey.Key, + MuunKey: muunKey.Key, + Birthday: muunKey.Birthday, + SweepAddress: sweepAddress, + } + + utxos := sweeper.GetUTXOs() + + fmt.Println("") + + if len(utxos) > 0 { + fmt.Printf("The recovery tool has found the following confirmed UTXOs:\n%v", utxos) + } else { + fmt.Printf("No confirmed UTXOs found") + fmt.Println() + return + } + fmt.Println() + + txOutputAmount, txWeightInBytes, err := sweeper.GetSweepTxAmountAndWeightInBytes(utxos) + if err != nil { + printError(err) + } + + fee := readFee(txOutputAmount, txWeightInBytes) + + // Then we re-build the sweep tx with the actual fee + sweepTx, err := sweeper.BuildSweepTx(utxos, fee) + if err != nil { + printError(err) + } + + fmt.Println("Transaction ready to be sent") + + err = sweeper.BroadcastTx(sweepTx) + if err != nil { + printError(err) + } + + fmt.Printf("Transaction sent! You can check the status here: https://blockstream.info/tx/%v", sweepTx.TxHash().String()) + fmt.Println("") + fmt.Printf("We appreciate all kinds of feedback. If you have any, send it to contact@muun.com") + fmt.Println("") +} + +func printError(err error) { + log.Printf("The recovery tool failed with the following error: %v", err.Error()) + log.Printf("") + log.Printf("You can try again or contact us at support@muun.com") + panic(err) +} + +func printWelcomeMessage() { + fmt.Println("Welcome to Muun's Recovery Tool") + fmt.Println("") + fmt.Println("You can use this tool to transfer all funds from your Muun account to an") + fmt.Println("address of your choosing.") + fmt.Println("") + fmt.Println("To do this you will need:") + fmt.Println("1. Your Recovery Code, which you wrote down during your security setup") + fmt.Println("2. Your two encrypted private keys, which you exported from your wallet") + fmt.Println("3. A destination bitcoin address where all your funds will be sent") + fmt.Println("") + fmt.Println("If you have any questions, we'll be happy to answer them. Contact us at support@muun.com") + fmt.Println("") +} + +func readRecoveryCode() string { + fmt.Println("") + fmt.Printf("Enter your Recovery Code") + fmt.Println() + fmt.Println("(it looks like this: 'ABCD-1234-POW2-R561-P120-JK26-12RW-45TT')") + fmt.Print("> ") + var userInput string + fmt.Scan(&userInput) + userInput = strings.TrimSpace(userInput) + + finalRC := strings.ToUpper(userInput) + + if strings.Count(finalRC, "-") != 7 { + fmt.Printf("Invalid recovery code. Did you add the '-' separator between each 4-characters segment?") + fmt.Println() + fmt.Println("Please, try again") + + return readRecoveryCode() + } + + if len(finalRC) != 39 { + fmt.Println("Your recovery code must have 39 characters") + fmt.Println("Please, try again") + + return readRecoveryCode() + } + + return finalRC +} + +func readKey(keyType string, characters int) string { + fmt.Println("") + fmt.Printf("Enter your %v", keyType) + fmt.Println() + fmt.Println("(it looks like this: '9xzpc7y6sNtRvh8Fh...')") + fmt.Print("> ") + + userInput := scanMultiline(characters) + + if len(userInput) != characters { + fmt.Printf("Your %v must have %v characters", keyType, characters) + fmt.Println("") + fmt.Println("Please, try again") + + return readKey(keyType, characters) + } + + return userInput +} + +func readSweepAddress() btcutil.Address { + fmt.Println("") + fmt.Println("Enter your destination bitcoin address") + fmt.Print("> ") + var userInput string + fmt.Scan(&userInput) + userInput = strings.TrimSpace(userInput) + + addr, err := btcutil.DecodeAddress(userInput, &chainParams) + if err != nil { + fmt.Println("This is not a valid bitcoin address") + fmt.Println("") + fmt.Println("Please, try again") + + return readSweepAddress() + } + + return addr +} + +func readFee(totalBalance, weight int64) int64 { + fmt.Println("") + fmt.Printf("Enter the fee in satoshis per byte. Tx weight: %v bytes. You can check the status of the mempool here: https://bitcoinfees.earn.com/#fees", weight) + fmt.Println() + fmt.Println("(Example: 5)") + fmt.Print("> ") + var userInput string + fmt.Scan(&userInput) + feeInSatsPerByte, err := strconv.ParseInt(userInput, 10, 64) + if err != nil || feeInSatsPerByte <= 0 { + fmt.Printf("The fee must be a number") + fmt.Println("") + fmt.Println("Please, try again") + + return readFee(totalBalance, weight) + } + + totalFee := feeInSatsPerByte * weight + + if totalBalance-totalFee < 546 { + fmt.Printf("The fee is too high. The amount left must be higher than dust") + fmt.Println("") + fmt.Println("Please, try again") + + return readFee(totalBalance, weight) + } + + return totalFee +} + +func readConfirmation(value, fee int64, address string) { + fmt.Println("") + fmt.Printf("About to send %v satoshis with fee: %v satoshis to %v", value, fee, address) + fmt.Println() + fmt.Println("Confirm? (y/n)") + fmt.Print("> ") + var userInput string + fmt.Scan(&userInput) + + if userInput == "y" || userInput == "Y" { + return + } + + if userInput == "n" || userInput == "N" { + log.Println() + log.Printf("Recovery tool stopped") + log.Println() + log.Printf("You can try again or contact us at support@muun.com") + os.Exit(1) + } + + fmt.Println() + fmt.Println("You can only enter 'y' to accept or 'n' to cancel") + readConfirmation(value, fee, address) +} + +func scanMultiline(minChars int) string { + var result strings.Builder + + for result.Len() < minChars { + var line string + fmt.Scan(&line) + + result.WriteString(strings.TrimSpace(line)) + } + + return result.String() +} diff --git a/recovery_tool.go b/recovery_tool.go index 5d205ff..e87b789 100644 --- a/recovery_tool.go +++ b/recovery_tool.go @@ -2,12 +2,7 @@ package main import ( "bytes" - "encoding/hex" "fmt" - "log" - "os" - "strconv" - "strings" "github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/wire" @@ -16,80 +11,7 @@ import ( "github.com/muun/libwallet" ) -func main() { - chainService, close, _ := startChainService() - defer close() - - printWelcomeMessage() - - recoveryCode := readRecoveryCode() - - userRawKey := readKey("first encrypted private key", 147) - userKey := buildExtendedKey(userRawKey, recoveryCode) - userKey.Key.Path = "m/1'/1'" - - muunRawKey := readKey("second encrypted private key", 147) - muunKey := buildExtendedKey(muunRawKey, recoveryCode) - derivedMuunKey, err := muunKey.Key.DeriveTo("m/1'/1'") - if err != nil { - printError(err) - } - - sweepAddress := readSweepAddress() - - fmt.Println("") - fmt.Println("Starting to scan the blockchain. This may take a while.") - - g := NewAddressGenerator(userKey.Key, muunKey.Key) - g.Generate() - - birthday := muunKey.Birthday - if birthday == 0xFFFF { - birthday = 0 - } - - utxos := startRescan(chainService, g.Addresses(), birthday) - fmt.Println("") - - if len(utxos) > 0 { - fmt.Printf("The recovery tool has found the following utxos: %v", utxos) - } else { - fmt.Printf("No utxos found") - fmt.Println() - return - } - fmt.Println() - - // This is fun: - // First we build a sweep tx with 0 fee with the only purpouse of seeing its signed size - zeroFeehexSweepTx := buildSweepTx(utxos, sweepAddress, 0) - zeroFeeSweepTx, err := buildSignedTx(utxos, zeroFeehexSweepTx, userKey.Key, derivedMuunKey) - if err != nil { - printError(err) - } - weightInBytes := int64(zeroFeeSweepTx.SerializeSize()) - fee := readFee(zeroFeeSweepTx.TxOut[0].Value, weightInBytes) - // Then we re-build the sweep tx with the actual fee - hexSweepTx := buildSweepTx(utxos, sweepAddress, fee) - tx, err := buildSignedTx(utxos, hexSweepTx, userKey.Key, derivedMuunKey) - if err != nil { - printError(err) - } - fmt.Println("Transaction ready to be sent") - - err = chainService.SendTransaction(tx) - if err != nil { - printError(err) - } - - fmt.Printf("Transaction sent! You can check the status here: https://blockstream.info/tx/%v", tx.TxHash().String()) - fmt.Println("") - fmt.Printf("If you have any feedback, feel free to share it with us. Our email is contact@muun.com") - fmt.Println("") - -} - -func buildSweepTx(utxos []*RelevantTx, sweepAddress btcutil.Address, fee int64) string { +func buildSweepTx(utxos []*RelevantTx, sweepAddress btcutil.Address, fee int64) []byte { tx := wire.NewMsgTx(2) value := int64(0) @@ -121,32 +43,26 @@ func buildSweepTx(utxos []*RelevantTx, sweepAddress btcutil.Address, fee int64) readConfirmation(value, fee, sweepAddress.String()) } - return hex.EncodeToString(writer.Bytes()) + return writer.Bytes() } -func buildSignedTx(utxos []*RelevantTx, hexSweepTx string, userKey *libwallet.HDPrivateKey, +func buildSignedTx(utxos []*RelevantTx, sweepTx []byte, userKey *libwallet.HDPrivateKey, muunKey *libwallet.HDPrivateKey) (*wire.MsgTx, error) { - pstx, err := libwallet.NewPartiallySignedTransaction(hexSweepTx) + inputList := &libwallet.InputList{} + for _, utxo := range utxos { + inputList.Add(&input{ + utxo, + []byte{}, + }) + } + + pstx, err := libwallet.NewPartiallySignedTransaction(inputList, sweepTx) if err != nil { printError(err) } - for index, utxo := range utxos { - input := &input{ - utxo, - []byte{}, - } - - pstx.AddInput(input) - sig, err := pstx.MuunSignatureForInput(index, userKey.PublicKey(), muunKey) - if err != nil { - panic(err) - } - input.muunSignature = sig - } - - signedTx, err := pstx.Sign(userKey, muunKey.PublicKey()) + signedTx, err := pstx.FullySign(userKey, muunKey) if err != nil { return nil, err } @@ -156,155 +72,6 @@ func buildSignedTx(utxos []*RelevantTx, hexSweepTx string, userKey *libwallet.HD return wireTx, nil } -func printError(err error) { - log.Printf("The recovery tool failed with the following error: %v", err.Error()) - log.Printf("") - log.Printf("You can try again or contact us at support@muun.com") - panic(err) -} - -func printWelcomeMessage() { - fmt.Println("Welcome to Muun's Recovery Tool") - fmt.Println("") - fmt.Println("You can use this tool to swipe all the balance in your muun account to an") - fmt.Println("address of your choosing.") - fmt.Println("") - fmt.Println("To do this you will need:") - fmt.Println("* The recovery code, that you set up when you created your muun account") - fmt.Println("* The two encrypted private keys that you exported from your muun wallet") - fmt.Println("* A destination bitcoin address where all your funds will be sent") - fmt.Println("") - fmt.Println("If you have any questions, contact us at contact@muun.com") - fmt.Println("") -} - -func readRecoveryCode() string { - fmt.Println("") - fmt.Printf("Enter your Recovery Code") - fmt.Println() - fmt.Println("(it looks like this: 'ABCD-1234-POW2-R561-P120-JK26-12RW-45TT')") - fmt.Print("> ") - var userInput string - fmt.Scan(&userInput) - userInput = strings.TrimSpace(userInput) - - finalRC := strings.ToUpper(userInput) - - if strings.Count(finalRC, "-") != 7 { - fmt.Printf("Wrong recovery code, remember to add the '-' separator between the 4 characters chunks") - fmt.Println() - fmt.Println("Please, try again") - - return readRecoveryCode() - } - - if len(finalRC) != 39 { - fmt.Println("Your recovery code must have 39 characters") - fmt.Println("Please, try again") - - return readRecoveryCode() - } - - return finalRC -} - -func readKey(keyType string, characters int) string { - fmt.Println("") - fmt.Printf("Enter your %v", keyType) - fmt.Println() - fmt.Println("(it looks like this: '9xzpc7y6sNtRvh8Fh...')") - fmt.Print("> ") - var userInput string - fmt.Scan(&userInput) - userInput = strings.TrimSpace(userInput) - - if len(userInput) != characters { - fmt.Printf("Your %v must have %v characters", keyType, characters) - fmt.Println("") - fmt.Println("Please, try again") - - return readKey(keyType, characters) - } - - return userInput -} - -func readSweepAddress() btcutil.Address { - fmt.Println("") - fmt.Println("Enter your destination bitcoin address") - fmt.Print("> ") - var userInput string - fmt.Scan(&userInput) - userInput = strings.TrimSpace(userInput) - - addr, err := btcutil.DecodeAddress(userInput, &chainParams) - if err != nil { - fmt.Println("This is not a valid bitcoin address") - fmt.Println("") - fmt.Println("Please, try again") - - return readSweepAddress() - } - - return addr -} - -func readFee(totalBalance, weight int64) int64 { - fmt.Println("") - fmt.Printf("Enter the fee in satoshis per byte. Tx weight: %v bytes. You can check the status of the mempool here: https://bitcoinfees.earn.com/#fees", weight) - fmt.Println() - fmt.Println("(Example: 5)") - fmt.Print("> ") - var userInput string - fmt.Scan(&userInput) - feeInSatsPerByte, err := strconv.ParseInt(userInput, 10, 64) - if err != nil || feeInSatsPerByte <= 0 { - fmt.Printf("The fee must be a number") - fmt.Println("") - fmt.Println("Please, try again") - - return readFee(totalBalance, weight) - } - - totalFee := feeInSatsPerByte * weight - - if totalBalance-totalFee < 546 { - fmt.Printf("The fee is too high. The amount left must be higher than dust") - fmt.Println("") - fmt.Println("Please, try again") - - return readFee(totalBalance, weight) - } - - return totalFee -} - -func readConfirmation(value, fee int64, address string) { - fmt.Println("") - fmt.Printf("About to send %v satoshis with fee: %v satoshis to %v", value, fee, address) - fmt.Println() - fmt.Println("Confirm? (y/n)") - fmt.Print("> ") - var userInput string - fmt.Scan(&userInput) - - if userInput == "y" || userInput == "Y" { - return - } - - if userInput == "n" || userInput == "N" { - log.Println() - log.Printf("Recovery tool stopped") - log.Println() - log.Printf("You can try again or contact us at support@muun.com") - os.Exit(1) - } - - fmt.Println() - fmt.Println("You can only enter 'y' to accept or 'n' to cancel") - readConfirmation(value, fee, address) -} - type input struct { tx *RelevantTx muunSignature []byte @@ -334,6 +101,10 @@ func (i *input) SubmarineSwapV2() libwallet.InputSubmarineSwapV2 { return nil } +func (i *input) IncomingSwap() libwallet.InputIncomingSwap { + return nil +} + type outpoint struct { tx *RelevantTx } diff --git a/sweeper.go b/sweeper.go new file mode 100644 index 0000000..1848f15 --- /dev/null +++ b/sweeper.go @@ -0,0 +1,54 @@ +package main + +import ( + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" + "github.com/lightninglabs/neutrino" + "github.com/muun/libwallet" +) + +type Sweeper struct { + ChainService *neutrino.ChainService + UserKey *libwallet.HDPrivateKey + MuunKey *libwallet.HDPrivateKey + Birthday int + SweepAddress btcutil.Address +} + +func (s *Sweeper) GetUTXOs() []*RelevantTx { + g := NewAddressGenerator(s.UserKey, s.MuunKey) + g.Generate() + + birthday := s.Birthday + if birthday == 0xFFFF { + birthday = 0 + } + + return startRescan(s.ChainService, g.Addresses(), birthday) +} + +func (s *Sweeper) GetSweepTxAmountAndWeightInBytes(utxos []*RelevantTx) (outputAmount int64, weightInBytes int64, err error) { + // we build a sweep tx with 0 fee with the only purpose of checking its signed size + zeroFeeSweepTx, err := s.BuildSweepTx(utxos, 0) + if err != nil { + return 0, 0, err + } + + outputAmount = zeroFeeSweepTx.TxOut[0].Value + weightInBytes = int64(zeroFeeSweepTx.SerializeSize()) + + return outputAmount, weightInBytes, nil +} + +func (s *Sweeper) BuildSweepTx(utxos []*RelevantTx, fee int64) (*wire.MsgTx, error) { + derivedMuunKey, err := s.MuunKey.DeriveTo("m/1'/1'") + if err != nil { + return nil, err + } + sweepTx := buildSweepTx(utxos, s.SweepAddress, fee) + return buildSignedTx(utxos, sweepTx, s.UserKey, derivedMuunKey) +} + +func (s *Sweeper) BroadcastTx(tx *wire.MsgTx) error { + return s.ChainService.SendTransaction(tx) +} diff --git a/vendor/github.com/aead/chacha20/.gitignore b/vendor/github.com/aead/chacha20/.gitignore new file mode 100644 index 0000000..9d3d843 --- /dev/null +++ b/vendor/github.com/aead/chacha20/.gitignore @@ -0,0 +1,25 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test +.vscode + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendor/github.com/aead/chacha20/.travis.yml b/vendor/github.com/aead/chacha20/.travis.yml new file mode 100644 index 0000000..99199e0 --- /dev/null +++ b/vendor/github.com/aead/chacha20/.travis.yml @@ -0,0 +1,25 @@ +language: go + +go: + - "1.8.x" + - "1.9.x" + - "1.10.x" + +env: + - TRAVIS_GOARCH=amd64 + - TRAVIS_GOARCH=386 + +before_install: +- export GOARCH=$TRAVIS_GOARCH + +branches: + only: + - master + +before_script: +- go get -u github.com/klauspost/asmfmt/cmd/asmfmt + +script: +- diff -au <(gofmt -d .) <(printf "") +- diff -au <(asmfmt -d .) <(printf "") +- go test -v ./... diff --git a/vendor/github.com/aead/chacha20/LICENSE b/vendor/github.com/aead/chacha20/LICENSE new file mode 100644 index 0000000..b6a9210 --- /dev/null +++ b/vendor/github.com/aead/chacha20/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Andreas Auernhammer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/aead/chacha20/README.md b/vendor/github.com/aead/chacha20/README.md new file mode 100644 index 0000000..b369424 --- /dev/null +++ b/vendor/github.com/aead/chacha20/README.md @@ -0,0 +1,82 @@ +[![Godoc Reference](https://godoc.org/github.com/aead/chacha20?status.svg)](https://godoc.org/github.com/aead/chacha20) +[![Build Status](https://travis-ci.org/aead/chacha20.svg?branch=master)](https://travis-ci.org/aead/chacha20) +[![Go Report Card](https://goreportcard.com/badge/aead/chacha20)](https://goreportcard.com/report/aead/chacha20) + +## The ChaCha20 stream cipher + +ChaCha is a stream cipher family created by Daniel J. Bernstein. +The most common ChaCha variant is ChaCha20 (20 rounds). ChaCha20 is +standardized in [RFC 7539](https://tools.ietf.org/html/rfc7539 "RFC 7539"). + +This package provides implementations of three ChaCha versions: +- ChaCha20 with a 64 bit nonce (can en/decrypt up to 2^64 * 64 bytes for one key-nonce combination) +- ChaCha20 with a 96 bit nonce (can en/decrypt up to 2^32 * 64 bytes ~ 256 GB for one key-nonce combination) +- XChaCha20 with a 192 bit nonce (can en/decrypt up to 2^64 * 64 bytes for one key-nonce combination) + +Furthermore the chacha sub package implements ChaCha20/12 and ChaCha20/8. +These versions use 12 or 8 rounds instead of 20. +But it's recommended to use ChaCha20 (with 20 rounds) - it will be fast enough for almost all purposes. + +### Installation +Install in your GOPATH: `go get -u github.com/aead/chacha20` + +### Requirements +All go versions >= 1.8.7 are supported. +The code may also work on Go 1.7 but this is not tested. + +### Performance + +#### AMD64 +Hardware: Intel i7-6500U 2.50GHz x 2 +System: Linux Ubuntu 16.04 - kernel: 4.4.0-62-generic +Go version: 1.8.0 +``` +AVX2 +name speed cpb +ChaCha20_64-4 573MB/s ± 0% 4.16 +ChaCha20_1K-4 2.19GB/s ± 0% 1.06 +XChaCha20_64-4 261MB/s ± 0% 9.13 +XChaCha20_1K-4 1.69GB/s ± 4% 1.37 +XORKeyStream64-4 474MB/s ± 2% 5.02 +XORKeyStream1K-4 2.09GB/s ± 1% 1.11 +XChaCha20_XORKeyStream64-4 262MB/s ± 0% 9.09 +XChaCha20_XORKeyStream1K-4 1.71GB/s ± 1% 1.36 + +SSSE3 +name speed cpb +ChaCha20_64-4 583MB/s ± 0% 4.08 +ChaCha20_1K-4 1.15GB/s ± 1% 2.02 +XChaCha20_64-4 267MB/s ± 0% 8.92 +XChaCha20_1K-4 984MB/s ± 5% 2.42 +XORKeyStream64-4 492MB/s ± 1% 4.84 +XORKeyStream1K-4 1.10GB/s ± 5% 2.11 +XChaCha20_XORKeyStream64-4 266MB/s ± 0% 8.96 +XChaCha20_XORKeyStream1K-4 1.00GB/s ± 2% 2.32 +``` +#### 386 +Hardware: Intel i7-6500U 2.50GHz x 2 +System: Linux Ubuntu 16.04 - kernel: 4.4.0-62-generic +Go version: 1.8.0 +``` +SSSE3 +name                        speed cpb +ChaCha20_64-4               570MB/s ± 0% 4.18 +ChaCha20_1K-4               650MB/s ± 0% 3.66 +XChaCha20_64-4              223MB/s ± 0% 10.69 +XChaCha20_1K-4              584MB/s ± 1% 4.08 +XORKeyStream64-4            392MB/s ± 1% 6.08 +XORKeyStream1K-4            629MB/s ± 1% 3.79 +XChaCha20_XORKeyStream64-4  222MB/s ± 0% 10.73 +XChaCha20_XORKeyStream1K-4  585MB/s ± 0% 4.07 + +SSE2 +name speed cpb +ChaCha20_64-4 509MB/s ± 0% 4.68 +ChaCha20_1K-4 553MB/s ± 2% 4.31 +XChaCha20_64-4 201MB/s ± 0% 11.86 +XChaCha20_1K-4 498MB/s ± 4% 4.78 +XORKeyStream64-4 359MB/s ± 1% 6.64 +XORKeyStream1K-4 545MB/s ± 0% 4.37 +XChaCha20_XORKeyStream64-4 201MB/s ± 1% 11.86 +XChaCha20_XORKeyStream1K-4 507MB/s ± 0% 4.70 +``` diff --git a/vendor/github.com/aead/chacha20/chacha/chacha.go b/vendor/github.com/aead/chacha20/chacha/chacha.go new file mode 100644 index 0000000..c2b39da --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chacha.go @@ -0,0 +1,197 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// Package chacha implements some low-level functions of the +// ChaCha cipher family. +package chacha // import "github.com/aead/chacha20/chacha" + +import ( + "encoding/binary" + "errors" + "math" +) + +const ( + // NonceSize is the size of the ChaCha20 nonce in bytes. + NonceSize = 8 + + // INonceSize is the size of the IETF-ChaCha20 nonce in bytes. + INonceSize = 12 + + // XNonceSize is the size of the XChaCha20 nonce in bytes. + XNonceSize = 24 + + // KeySize is the size of the key in bytes. + KeySize = 32 +) + +var ( + useSSE2 bool + useSSSE3 bool + useAVX bool + useAVX2 bool +) + +var ( + errKeySize = errors.New("chacha20/chacha: bad key length") + errInvalidNonce = errors.New("chacha20/chacha: bad nonce length") +) + +func setup(state *[64]byte, nonce, key []byte) (err error) { + if len(key) != KeySize { + err = errKeySize + return + } + var Nonce [16]byte + switch len(nonce) { + case NonceSize: + copy(Nonce[8:], nonce) + initialize(state, key, &Nonce) + case INonceSize: + copy(Nonce[4:], nonce) + initialize(state, key, &Nonce) + case XNonceSize: + var tmpKey [32]byte + var hNonce [16]byte + + copy(hNonce[:], nonce[:16]) + copy(tmpKey[:], key) + HChaCha20(&tmpKey, &hNonce, &tmpKey) + copy(Nonce[8:], nonce[16:]) + initialize(state, tmpKey[:], &Nonce) + + // BUG(aead): A "good" compiler will remove this (optimizations) + // But using the provided key instead of tmpKey, + // will change the key (-> probably confuses users) + for i := range tmpKey { + tmpKey[i] = 0 + } + default: + err = errInvalidNonce + } + return +} + +// XORKeyStream crypts bytes from src to dst using the given nonce and key. +// The length of the nonce determinds the version of ChaCha20: +// - NonceSize: ChaCha20/r with a 64 bit nonce and a 2^64 * 64 byte period. +// - INonceSize: ChaCha20/r as defined in RFC 7539 and a 2^32 * 64 byte period. +// - XNonceSize: XChaCha20/r with a 192 bit nonce and a 2^64 * 64 byte period. +// The rounds argument specifies the number of rounds performed for keystream +// generation - valid values are 8, 12 or 20. The src and dst may be the same slice +// but otherwise should not overlap. If len(dst) < len(src) this function panics. +// If the nonce is neither 64, 96 nor 192 bits long, this function panics. +func XORKeyStream(dst, src, nonce, key []byte, rounds int) { + if rounds != 20 && rounds != 12 && rounds != 8 { + panic("chacha20/chacha: bad number of rounds") + } + if len(dst) < len(src) { + panic("chacha20/chacha: dst buffer is to small") + } + if len(nonce) == INonceSize && uint64(len(src)) > (1<<38) { + panic("chacha20/chacha: src is too large") + } + + var block, state [64]byte + if err := setup(&state, nonce, key); err != nil { + panic(err) + } + xorKeyStream(dst, src, &block, &state, rounds) +} + +// Cipher implements ChaCha20/r (XChaCha20/r) for a given number of rounds r. +type Cipher struct { + state, block [64]byte + off int + rounds int // 20 for ChaCha20 + noncesize int +} + +// NewCipher returns a new *chacha.Cipher implementing the ChaCha20/r or XChaCha20/r +// (r = 8, 12 or 20) stream cipher. The nonce must be unique for one key for all time. +// The length of the nonce determinds the version of ChaCha20: +// - NonceSize: ChaCha20/r with a 64 bit nonce and a 2^64 * 64 byte period. +// - INonceSize: ChaCha20/r as defined in RFC 7539 and a 2^32 * 64 byte period. +// - XNonceSize: XChaCha20/r with a 192 bit nonce and a 2^64 * 64 byte period. +// If the nonce is neither 64, 96 nor 192 bits long, a non-nil error is returned. +func NewCipher(nonce, key []byte, rounds int) (*Cipher, error) { + if rounds != 20 && rounds != 12 && rounds != 8 { + panic("chacha20/chacha: bad number of rounds") + } + + c := new(Cipher) + if err := setup(&(c.state), nonce, key); err != nil { + return nil, err + } + c.rounds = rounds + + if len(nonce) == INonceSize { + c.noncesize = INonceSize + } else { + c.noncesize = NonceSize + } + + return c, nil +} + +// XORKeyStream crypts bytes from src to dst. Src and dst may be the same slice +// but otherwise should not overlap. If len(dst) < len(src) the function panics. +func (c *Cipher) XORKeyStream(dst, src []byte) { + if len(dst) < len(src) { + panic("chacha20/chacha: dst buffer is to small") + } + + if c.off > 0 { + n := len(c.block[c.off:]) + if len(src) <= n { + for i, v := range src { + dst[i] = v ^ c.block[c.off] + c.off++ + } + if c.off == 64 { + c.off = 0 + } + return + } + + for i, v := range c.block[c.off:] { + dst[i] = src[i] ^ v + } + src = src[n:] + dst = dst[n:] + c.off = 0 + } + + // check for counter overflow + blocksToXOR := len(src) / 64 + if len(src)%64 != 0 { + blocksToXOR++ + } + var overflow bool + if c.noncesize == INonceSize { + overflow = binary.LittleEndian.Uint32(c.state[48:]) > math.MaxUint32-uint32(blocksToXOR) + } else { + overflow = binary.LittleEndian.Uint64(c.state[48:]) > math.MaxUint64-uint64(blocksToXOR) + } + if overflow { + panic("chacha20/chacha: counter overflow") + } + + c.off += xorKeyStream(dst, src, &(c.block), &(c.state), c.rounds) +} + +// SetCounter skips ctr * 64 byte blocks. SetCounter(0) resets the cipher. +// This function always skips the unused keystream of the current 64 byte block. +func (c *Cipher) SetCounter(ctr uint64) { + if c.noncesize == INonceSize { + binary.LittleEndian.PutUint32(c.state[48:], uint32(ctr)) + } else { + binary.LittleEndian.PutUint64(c.state[48:], ctr) + } + c.off = 0 +} + +// HChaCha20 generates 32 pseudo-random bytes from a 128 bit nonce and a 256 bit secret key. +// It can be used as a key-derivation-function (KDF). +func HChaCha20(out *[32]byte, nonce *[16]byte, key *[32]byte) { hChaCha20(out, nonce, key) } diff --git a/vendor/github.com/aead/chacha20/chacha/chachaAVX2_amd64.s b/vendor/github.com/aead/chacha20/chacha/chachaAVX2_amd64.s new file mode 100644 index 0000000..c2b5f52 --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chachaAVX2_amd64.s @@ -0,0 +1,406 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build amd64,!gccgo,!appengine,!nacl + +#include "const.s" +#include "macro.s" + +#define TWO 0(SP) +#define C16 32(SP) +#define C8 64(SP) +#define STATE_0 96(SP) +#define STATE_1 128(SP) +#define STATE_2 160(SP) +#define STATE_3 192(SP) +#define TMP_0 224(SP) +#define TMP_1 256(SP) + +// func xorKeyStreamAVX(dst, src []byte, block, state *[64]byte, rounds int) int +TEXT ·xorKeyStreamAVX2(SB), 4, $320-80 + MOVQ dst_base+0(FP), DI + MOVQ src_base+24(FP), SI + MOVQ block+48(FP), BX + MOVQ state+56(FP), AX + MOVQ rounds+64(FP), DX + MOVQ src_len+32(FP), CX + + MOVQ SP, R8 + ADDQ $32, SP + ANDQ $-32, SP + + VMOVDQU 0(AX), Y2 + VMOVDQU 32(AX), Y3 + VPERM2I128 $0x22, Y2, Y0, Y0 + VPERM2I128 $0x33, Y2, Y1, Y1 + VPERM2I128 $0x22, Y3, Y2, Y2 + VPERM2I128 $0x33, Y3, Y3, Y3 + + TESTQ CX, CX + JZ done + + VMOVDQU ·one_AVX2<>(SB), Y4 + VPADDD Y4, Y3, Y3 + + VMOVDQA Y0, STATE_0 + VMOVDQA Y1, STATE_1 + VMOVDQA Y2, STATE_2 + VMOVDQA Y3, STATE_3 + + VMOVDQU ·rol16_AVX2<>(SB), Y4 + VMOVDQU ·rol8_AVX2<>(SB), Y5 + VMOVDQU ·two_AVX2<>(SB), Y6 + VMOVDQA Y4, Y14 + VMOVDQA Y5, Y15 + VMOVDQA Y4, C16 + VMOVDQA Y5, C8 + VMOVDQA Y6, TWO + + CMPQ CX, $64 + JBE between_0_and_64 + CMPQ CX, $192 + JBE between_64_and_192 + CMPQ CX, $320 + JBE between_192_and_320 + CMPQ CX, $448 + JBE between_320_and_448 + +at_least_512: + VMOVDQA Y0, Y4 + VMOVDQA Y1, Y5 + VMOVDQA Y2, Y6 + VPADDQ TWO, Y3, Y7 + VMOVDQA Y0, Y8 + VMOVDQA Y1, Y9 + VMOVDQA Y2, Y10 + VPADDQ TWO, Y7, Y11 + VMOVDQA Y0, Y12 + VMOVDQA Y1, Y13 + VMOVDQA Y2, Y14 + VPADDQ TWO, Y11, Y15 + + MOVQ DX, R9 + +chacha_loop_512: + VMOVDQA Y8, TMP_0 + CHACHA_QROUND_AVX(Y0, Y1, Y2, Y3, Y8, C16, C8) + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y8, C16, C8) + VMOVDQA TMP_0, Y8 + VMOVDQA Y0, TMP_0 + CHACHA_QROUND_AVX(Y8, Y9, Y10, Y11, Y0, C16, C8) + CHACHA_QROUND_AVX(Y12, Y13, Y14, Y15, Y0, C16, C8) + CHACHA_SHUFFLE_AVX(Y1, Y2, Y3) + CHACHA_SHUFFLE_AVX(Y5, Y6, Y7) + CHACHA_SHUFFLE_AVX(Y9, Y10, Y11) + CHACHA_SHUFFLE_AVX(Y13, Y14, Y15) + + CHACHA_QROUND_AVX(Y12, Y13, Y14, Y15, Y0, C16, C8) + CHACHA_QROUND_AVX(Y8, Y9, Y10, Y11, Y0, C16, C8) + VMOVDQA TMP_0, Y0 + VMOVDQA Y8, TMP_0 + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y8, C16, C8) + CHACHA_QROUND_AVX(Y0, Y1, Y2, Y3, Y8, C16, C8) + VMOVDQA TMP_0, Y8 + CHACHA_SHUFFLE_AVX(Y3, Y2, Y1) + CHACHA_SHUFFLE_AVX(Y7, Y6, Y5) + CHACHA_SHUFFLE_AVX(Y11, Y10, Y9) + CHACHA_SHUFFLE_AVX(Y15, Y14, Y13) + SUBQ $2, R9 + JA chacha_loop_512 + + VMOVDQA Y12, TMP_0 + VMOVDQA Y13, TMP_1 + VPADDD STATE_0, Y0, Y0 + VPADDD STATE_1, Y1, Y1 + VPADDD STATE_2, Y2, Y2 + VPADDD STATE_3, Y3, Y3 + XOR_AVX2(DI, SI, 0, Y0, Y1, Y2, Y3, Y12, Y13) + VMOVDQA STATE_0, Y0 + VMOVDQA STATE_1, Y1 + VMOVDQA STATE_2, Y2 + VMOVDQA STATE_3, Y3 + VPADDQ TWO, Y3, Y3 + + VPADDD Y0, Y4, Y4 + VPADDD Y1, Y5, Y5 + VPADDD Y2, Y6, Y6 + VPADDD Y3, Y7, Y7 + XOR_AVX2(DI, SI, 128, Y4, Y5, Y6, Y7, Y12, Y13) + VPADDQ TWO, Y3, Y3 + + VPADDD Y0, Y8, Y8 + VPADDD Y1, Y9, Y9 + VPADDD Y2, Y10, Y10 + VPADDD Y3, Y11, Y11 + XOR_AVX2(DI, SI, 256, Y8, Y9, Y10, Y11, Y12, Y13) + VPADDQ TWO, Y3, Y3 + + VPADDD TMP_0, Y0, Y12 + VPADDD TMP_1, Y1, Y13 + VPADDD Y2, Y14, Y14 + VPADDD Y3, Y15, Y15 + VPADDQ TWO, Y3, Y3 + + CMPQ CX, $512 + JB less_than_512 + + XOR_AVX2(DI, SI, 384, Y12, Y13, Y14, Y15, Y4, Y5) + VMOVDQA Y3, STATE_3 + ADDQ $512, SI + ADDQ $512, DI + SUBQ $512, CX + CMPQ CX, $448 + JA at_least_512 + + TESTQ CX, CX + JZ done + + VMOVDQA C16, Y14 + VMOVDQA C8, Y15 + + CMPQ CX, $64 + JBE between_0_and_64 + CMPQ CX, $192 + JBE between_64_and_192 + CMPQ CX, $320 + JBE between_192_and_320 + JMP between_320_and_448 + +less_than_512: + XOR_UPPER_AVX2(DI, SI, 384, Y12, Y13, Y14, Y15, Y4, Y5) + EXTRACT_LOWER(BX, Y12, Y13, Y14, Y15, Y4) + ADDQ $448, SI + ADDQ $448, DI + SUBQ $448, CX + JMP finalize + +between_320_and_448: + VMOVDQA Y0, Y4 + VMOVDQA Y1, Y5 + VMOVDQA Y2, Y6 + VPADDQ TWO, Y3, Y7 + VMOVDQA Y0, Y8 + VMOVDQA Y1, Y9 + VMOVDQA Y2, Y10 + VPADDQ TWO, Y7, Y11 + + MOVQ DX, R9 + +chacha_loop_384: + CHACHA_QROUND_AVX(Y0, Y1, Y2, Y3, Y13, Y14, Y15) + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y13, Y14, Y15) + CHACHA_QROUND_AVX(Y8, Y9, Y10, Y11, Y13, Y14, Y15) + CHACHA_SHUFFLE_AVX(Y1, Y2, Y3) + CHACHA_SHUFFLE_AVX(Y5, Y6, Y7) + CHACHA_SHUFFLE_AVX(Y9, Y10, Y11) + CHACHA_QROUND_AVX(Y0, Y1, Y2, Y3, Y13, Y14, Y15) + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y13, Y14, Y15) + CHACHA_QROUND_AVX(Y8, Y9, Y10, Y11, Y13, Y14, Y15) + CHACHA_SHUFFLE_AVX(Y3, Y2, Y1) + CHACHA_SHUFFLE_AVX(Y7, Y6, Y5) + CHACHA_SHUFFLE_AVX(Y11, Y10, Y9) + SUBQ $2, R9 + JA chacha_loop_384 + + VPADDD STATE_0, Y0, Y0 + VPADDD STATE_1, Y1, Y1 + VPADDD STATE_2, Y2, Y2 + VPADDD STATE_3, Y3, Y3 + XOR_AVX2(DI, SI, 0, Y0, Y1, Y2, Y3, Y12, Y13) + VMOVDQA STATE_0, Y0 + VMOVDQA STATE_1, Y1 + VMOVDQA STATE_2, Y2 + VMOVDQA STATE_3, Y3 + VPADDQ TWO, Y3, Y3 + + VPADDD Y0, Y4, Y4 + VPADDD Y1, Y5, Y5 + VPADDD Y2, Y6, Y6 + VPADDD Y3, Y7, Y7 + XOR_AVX2(DI, SI, 128, Y4, Y5, Y6, Y7, Y12, Y13) + VPADDQ TWO, Y3, Y3 + + VPADDD Y0, Y8, Y8 + VPADDD Y1, Y9, Y9 + VPADDD Y2, Y10, Y10 + VPADDD Y3, Y11, Y11 + VPADDQ TWO, Y3, Y3 + + CMPQ CX, $384 + JB less_than_384 + + XOR_AVX2(DI, SI, 256, Y8, Y9, Y10, Y11, Y12, Y13) + SUBQ $384, CX + TESTQ CX, CX + JE done + + ADDQ $384, SI + ADDQ $384, DI + JMP between_0_and_64 + +less_than_384: + XOR_UPPER_AVX2(DI, SI, 256, Y8, Y9, Y10, Y11, Y12, Y13) + EXTRACT_LOWER(BX, Y8, Y9, Y10, Y11, Y12) + ADDQ $320, SI + ADDQ $320, DI + SUBQ $320, CX + JMP finalize + +between_192_and_320: + VMOVDQA Y0, Y4 + VMOVDQA Y1, Y5 + VMOVDQA Y2, Y6 + VMOVDQA Y3, Y7 + VMOVDQA Y0, Y8 + VMOVDQA Y1, Y9 + VMOVDQA Y2, Y10 + VPADDQ TWO, Y3, Y11 + + MOVQ DX, R9 + +chacha_loop_256: + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y13, Y14, Y15) + CHACHA_QROUND_AVX(Y8, Y9, Y10, Y11, Y13, Y14, Y15) + CHACHA_SHUFFLE_AVX(Y5, Y6, Y7) + CHACHA_SHUFFLE_AVX(Y9, Y10, Y11) + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y13, Y14, Y15) + CHACHA_QROUND_AVX(Y8, Y9, Y10, Y11, Y13, Y14, Y15) + CHACHA_SHUFFLE_AVX(Y7, Y6, Y5) + CHACHA_SHUFFLE_AVX(Y11, Y10, Y9) + SUBQ $2, R9 + JA chacha_loop_256 + + VPADDD Y0, Y4, Y4 + VPADDD Y1, Y5, Y5 + VPADDD Y2, Y6, Y6 + VPADDD Y3, Y7, Y7 + VPADDQ TWO, Y3, Y3 + XOR_AVX2(DI, SI, 0, Y4, Y5, Y6, Y7, Y12, Y13) + VPADDD Y0, Y8, Y8 + VPADDD Y1, Y9, Y9 + VPADDD Y2, Y10, Y10 + VPADDD Y3, Y11, Y11 + VPADDQ TWO, Y3, Y3 + + CMPQ CX, $256 + JB less_than_256 + + XOR_AVX2(DI, SI, 128, Y8, Y9, Y10, Y11, Y12, Y13) + SUBQ $256, CX + TESTQ CX, CX + JE done + + ADDQ $256, SI + ADDQ $256, DI + JMP between_0_and_64 + +less_than_256: + XOR_UPPER_AVX2(DI, SI, 128, Y8, Y9, Y10, Y11, Y12, Y13) + EXTRACT_LOWER(BX, Y8, Y9, Y10, Y11, Y12) + ADDQ $192, SI + ADDQ $192, DI + SUBQ $192, CX + JMP finalize + +between_64_and_192: + VMOVDQA Y0, Y4 + VMOVDQA Y1, Y5 + VMOVDQA Y2, Y6 + VMOVDQA Y3, Y7 + + MOVQ DX, R9 + +chacha_loop_128: + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y13, Y14, Y15) + CHACHA_SHUFFLE_AVX(Y5, Y6, Y7) + CHACHA_QROUND_AVX(Y4, Y5, Y6, Y7, Y13, Y14, Y15) + CHACHA_SHUFFLE_AVX(Y7, Y6, Y5) + SUBQ $2, R9 + JA chacha_loop_128 + + VPADDD Y0, Y4, Y4 + VPADDD Y1, Y5, Y5 + VPADDD Y2, Y6, Y6 + VPADDD Y3, Y7, Y7 + VPADDQ TWO, Y3, Y3 + + CMPQ CX, $128 + JB less_than_128 + + XOR_AVX2(DI, SI, 0, Y4, Y5, Y6, Y7, Y12, Y13) + SUBQ $128, CX + TESTQ CX, CX + JE done + + ADDQ $128, SI + ADDQ $128, DI + JMP between_0_and_64 + +less_than_128: + XOR_UPPER_AVX2(DI, SI, 0, Y4, Y5, Y6, Y7, Y12, Y13) + EXTRACT_LOWER(BX, Y4, Y5, Y6, Y7, Y13) + ADDQ $64, SI + ADDQ $64, DI + SUBQ $64, CX + JMP finalize + +between_0_and_64: + VMOVDQA X0, X4 + VMOVDQA X1, X5 + VMOVDQA X2, X6 + VMOVDQA X3, X7 + + MOVQ DX, R9 + +chacha_loop_64: + CHACHA_QROUND_AVX(X4, X5, X6, X7, X13, X14, X15) + CHACHA_SHUFFLE_AVX(X5, X6, X7) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X13, X14, X15) + CHACHA_SHUFFLE_AVX(X7, X6, X5) + SUBQ $2, R9 + JA chacha_loop_64 + + VPADDD X0, X4, X4 + VPADDD X1, X5, X5 + VPADDD X2, X6, X6 + VPADDD X3, X7, X7 + VMOVDQU ·one<>(SB), X0 + VPADDQ X0, X3, X3 + + CMPQ CX, $64 + JB less_than_64 + + XOR_AVX(DI, SI, 0, X4, X5, X6, X7, X13) + SUBQ $64, CX + JMP done + +less_than_64: + VMOVDQU X4, 0(BX) + VMOVDQU X5, 16(BX) + VMOVDQU X6, 32(BX) + VMOVDQU X7, 48(BX) + +finalize: + XORQ R11, R11 + XORQ R12, R12 + MOVQ CX, BP + +xor_loop: + MOVB 0(SI), R11 + MOVB 0(BX), R12 + XORQ R11, R12 + MOVB R12, 0(DI) + INCQ SI + INCQ BX + INCQ DI + DECQ BP + JA xor_loop + +done: + VMOVDQU X3, 48(AX) + VZEROUPPER + MOVQ R8, SP + MOVQ CX, ret+72(FP) + RET + diff --git a/vendor/github.com/aead/chacha20/chacha/chacha_386.go b/vendor/github.com/aead/chacha20/chacha/chacha_386.go new file mode 100644 index 0000000..97e533d --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chacha_386.go @@ -0,0 +1,60 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build 386,!gccgo,!appengine,!nacl + +package chacha + +import ( + "encoding/binary" + + "golang.org/x/sys/cpu" +) + +func init() { + useSSE2 = cpu.X86.HasSSE2 + useSSSE3 = cpu.X86.HasSSSE3 + useAVX = false + useAVX2 = false +} + +func initialize(state *[64]byte, key []byte, nonce *[16]byte) { + binary.LittleEndian.PutUint32(state[0:], sigma[0]) + binary.LittleEndian.PutUint32(state[4:], sigma[1]) + binary.LittleEndian.PutUint32(state[8:], sigma[2]) + binary.LittleEndian.PutUint32(state[12:], sigma[3]) + copy(state[16:], key[:]) + copy(state[48:], nonce[:]) +} + +// This function is implemented in chacha_386.s +//go:noescape +func hChaCha20SSE2(out *[32]byte, nonce *[16]byte, key *[32]byte) + +// This function is implemented in chacha_386.s +//go:noescape +func hChaCha20SSSE3(out *[32]byte, nonce *[16]byte, key *[32]byte) + +// This function is implemented in chacha_386.s +//go:noescape +func xorKeyStreamSSE2(dst, src []byte, block, state *[64]byte, rounds int) int + +func hChaCha20(out *[32]byte, nonce *[16]byte, key *[32]byte) { + switch { + case useSSSE3: + hChaCha20SSSE3(out, nonce, key) + case useSSE2: + hChaCha20SSE2(out, nonce, key) + default: + hChaCha20Generic(out, nonce, key) + } +} + +func xorKeyStream(dst, src []byte, block, state *[64]byte, rounds int) int { + if useSSE2 { + return xorKeyStreamSSE2(dst, src, block, state, rounds) + } else { + return xorKeyStreamGeneric(dst, src, block, state, rounds) + } +} diff --git a/vendor/github.com/aead/chacha20/chacha/chacha_386.s b/vendor/github.com/aead/chacha20/chacha/chacha_386.s new file mode 100644 index 0000000..262fc86 --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chacha_386.s @@ -0,0 +1,163 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build 386,!gccgo,!appengine,!nacl + +#include "const.s" +#include "macro.s" + +// FINALIZE xors len bytes from src and block using +// the temp. registers t0 and t1 and writes the result +// to dst. +#define FINALIZE(dst, src, block, len, t0, t1) \ + XORL t0, t0; \ + XORL t1, t1; \ + FINALIZE_LOOP:; \ + MOVB 0(src), t0; \ + MOVB 0(block), t1; \ + XORL t0, t1; \ + MOVB t1, 0(dst); \ + INCL src; \ + INCL block; \ + INCL dst; \ + DECL len; \ + JG FINALIZE_LOOP \ + +#define Dst DI +#define Nonce AX +#define Key BX +#define Rounds DX + +// func hChaCha20SSE2(out *[32]byte, nonce *[16]byte, key *[32]byte) +TEXT ·hChaCha20SSE2(SB), 4, $0-12 + MOVL out+0(FP), Dst + MOVL nonce+4(FP), Nonce + MOVL key+8(FP), Key + + MOVOU ·sigma<>(SB), X0 + MOVOU 0*16(Key), X1 + MOVOU 1*16(Key), X2 + MOVOU 0*16(Nonce), X3 + MOVL $20, Rounds + +chacha_loop: + CHACHA_QROUND_SSE2(X0, X1, X2, X3, X4) + CHACHA_SHUFFLE_SSE(X1, X2, X3) + CHACHA_QROUND_SSE2(X0, X1, X2, X3, X4) + CHACHA_SHUFFLE_SSE(X3, X2, X1) + SUBL $2, Rounds + JNZ chacha_loop + + MOVOU X0, 0*16(Dst) + MOVOU X3, 1*16(Dst) + RET + +// func hChaCha20SSSE3(out *[32]byte, nonce *[16]byte, key *[32]byte) +TEXT ·hChaCha20SSSE3(SB), 4, $0-12 + MOVL out+0(FP), Dst + MOVL nonce+4(FP), Nonce + MOVL key+8(FP), Key + + MOVOU ·sigma<>(SB), X0 + MOVOU 0*16(Key), X1 + MOVOU 1*16(Key), X2 + MOVOU 0*16(Nonce), X3 + MOVL $20, Rounds + + MOVOU ·rol16<>(SB), X5 + MOVOU ·rol8<>(SB), X6 + +chacha_loop: + CHACHA_QROUND_SSSE3(X0, X1, X2, X3, X4, X5, X6) + CHACHA_SHUFFLE_SSE(X1, X2, X3) + CHACHA_QROUND_SSSE3(X0, X1, X2, X3, X4, X5, X6) + CHACHA_SHUFFLE_SSE(X3, X2, X1) + SUBL $2, Rounds + JNZ chacha_loop + + MOVOU X0, 0*16(Dst) + MOVOU X3, 1*16(Dst) + RET + +#undef Dst +#undef Nonce +#undef Key +#undef Rounds + +#define State AX +#define Dst DI +#define Src SI +#define Len DX +#define Tmp0 BX +#define Tmp1 BP + +// func xorKeyStreamSSE2(dst, src []byte, block, state *[64]byte, rounds int) int +TEXT ·xorKeyStreamSSE2(SB), 4, $0-40 + MOVL dst_base+0(FP), Dst + MOVL src_base+12(FP), Src + MOVL state+28(FP), State + MOVL src_len+16(FP), Len + MOVL $0, ret+36(FP) // Number of bytes written to the keystream buffer - 0 iff len mod 64 == 0 + + MOVOU 0*16(State), X0 + MOVOU 1*16(State), X1 + MOVOU 2*16(State), X2 + MOVOU 3*16(State), X3 + TESTL Len, Len + JZ DONE + +GENERATE_KEYSTREAM: + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X3, X7 + MOVL rounds+32(FP), Tmp0 + +CHACHA_LOOP: + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X0) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X0) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBL $2, Tmp0 + JA CHACHA_LOOP + + MOVOU 0*16(State), X0 // Restore X0 from state + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + MOVOU ·one<>(SB), X0 + PADDQ X0, X3 + + CMPL Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X0) + MOVOU 0*16(State), X0 // Restore X0 from state + ADDL $64, Src + ADDL $64, Dst + SUBL $64, Len + JZ DONE + JMP GENERATE_KEYSTREAM // There is at least one more plaintext byte + +BUFFER_KEYSTREAM: + MOVL block+24(FP), State + MOVOU X4, 0(State) + MOVOU X5, 16(State) + MOVOU X6, 32(State) + MOVOU X7, 48(State) + MOVL Len, ret+36(FP) // Number of bytes written to the keystream buffer - 0 < Len < 64 + FINALIZE(Dst, Src, State, Len, Tmp0, Tmp1) + +DONE: + MOVL state+28(FP), State + MOVOU X3, 3*16(State) + RET + +#undef State +#undef Dst +#undef Src +#undef Len +#undef Tmp0 +#undef Tmp1 diff --git a/vendor/github.com/aead/chacha20/chacha/chacha_amd64.go b/vendor/github.com/aead/chacha20/chacha/chacha_amd64.go new file mode 100644 index 0000000..635f7de --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chacha_amd64.go @@ -0,0 +1,76 @@ +// Copyright (c) 2017 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build go1.7,amd64,!gccgo,!appengine,!nacl + +package chacha + +import "golang.org/x/sys/cpu" + +func init() { + useSSE2 = cpu.X86.HasSSE2 + useSSSE3 = cpu.X86.HasSSSE3 + useAVX = cpu.X86.HasAVX + useAVX2 = cpu.X86.HasAVX2 +} + +// This function is implemented in chacha_amd64.s +//go:noescape +func initialize(state *[64]byte, key []byte, nonce *[16]byte) + +// This function is implemented in chacha_amd64.s +//go:noescape +func hChaCha20SSE2(out *[32]byte, nonce *[16]byte, key *[32]byte) + +// This function is implemented in chacha_amd64.s +//go:noescape +func hChaCha20SSSE3(out *[32]byte, nonce *[16]byte, key *[32]byte) + +// This function is implemented in chachaAVX2_amd64.s +//go:noescape +func hChaCha20AVX(out *[32]byte, nonce *[16]byte, key *[32]byte) + +// This function is implemented in chacha_amd64.s +//go:noescape +func xorKeyStreamSSE2(dst, src []byte, block, state *[64]byte, rounds int) int + +// This function is implemented in chacha_amd64.s +//go:noescape +func xorKeyStreamSSSE3(dst, src []byte, block, state *[64]byte, rounds int) int + +// This function is implemented in chacha_amd64.s +//go:noescape +func xorKeyStreamAVX(dst, src []byte, block, state *[64]byte, rounds int) int + +// This function is implemented in chachaAVX2_amd64.s +//go:noescape +func xorKeyStreamAVX2(dst, src []byte, block, state *[64]byte, rounds int) int + +func hChaCha20(out *[32]byte, nonce *[16]byte, key *[32]byte) { + switch { + case useAVX: + hChaCha20AVX(out, nonce, key) + case useSSSE3: + hChaCha20SSSE3(out, nonce, key) + case useSSE2: + hChaCha20SSE2(out, nonce, key) + default: + hChaCha20Generic(out, nonce, key) + } +} + +func xorKeyStream(dst, src []byte, block, state *[64]byte, rounds int) int { + switch { + case useAVX2: + return xorKeyStreamAVX2(dst, src, block, state, rounds) + case useAVX: + return xorKeyStreamAVX(dst, src, block, state, rounds) + case useSSSE3: + return xorKeyStreamSSSE3(dst, src, block, state, rounds) + case useSSE2: + return xorKeyStreamSSE2(dst, src, block, state, rounds) + default: + return xorKeyStreamGeneric(dst, src, block, state, rounds) + } +} diff --git a/vendor/github.com/aead/chacha20/chacha/chacha_amd64.s b/vendor/github.com/aead/chacha20/chacha/chacha_amd64.s new file mode 100644 index 0000000..26a2383 --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chacha_amd64.s @@ -0,0 +1,1072 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build amd64,!gccgo,!appengine,!nacl + +#include "const.s" +#include "macro.s" + +// FINALIZE xors len bytes from src and block using +// the temp. registers t0 and t1 and writes the result +// to dst. +#define FINALIZE(dst, src, block, len, t0, t1) \ + XORQ t0, t0; \ + XORQ t1, t1; \ + FINALIZE_LOOP:; \ + MOVB 0(src), t0; \ + MOVB 0(block), t1; \ + XORQ t0, t1; \ + MOVB t1, 0(dst); \ + INCQ src; \ + INCQ block; \ + INCQ dst; \ + DECQ len; \ + JG FINALIZE_LOOP \ + +#define Dst DI +#define Nonce AX +#define Key BX +#define Rounds DX + +// func initialize(state *[64]byte, key []byte, nonce *[16]byte) +TEXT ·initialize(SB), 4, $0-40 + MOVQ state+0(FP), Dst + MOVQ key+8(FP), Key + MOVQ nonce+32(FP), Nonce + + MOVOU ·sigma<>(SB), X0 + MOVOU 0*16(Key), X1 + MOVOU 1*16(Key), X2 + MOVOU 0*16(Nonce), X3 + + MOVOU X0, 0*16(Dst) + MOVOU X1, 1*16(Dst) + MOVOU X2, 2*16(Dst) + MOVOU X3, 3*16(Dst) + RET + +// func hChaCha20AVX(out *[32]byte, nonce *[16]byte, key *[32]byte) +TEXT ·hChaCha20AVX(SB), 4, $0-24 + MOVQ out+0(FP), Dst + MOVQ nonce+8(FP), Nonce + MOVQ key+16(FP), Key + + VMOVDQU ·sigma<>(SB), X0 + VMOVDQU 0*16(Key), X1 + VMOVDQU 1*16(Key), X2 + VMOVDQU 0*16(Nonce), X3 + VMOVDQU ·rol16_AVX2<>(SB), X5 + VMOVDQU ·rol8_AVX2<>(SB), X6 + MOVQ $20, Rounds + +CHACHA_LOOP: + CHACHA_QROUND_AVX(X0, X1, X2, X3, X4, X5, X6) + CHACHA_SHUFFLE_AVX(X1, X2, X3) + CHACHA_QROUND_AVX(X0, X1, X2, X3, X4, X5, X6) + CHACHA_SHUFFLE_AVX(X3, X2, X1) + SUBQ $2, Rounds + JNZ CHACHA_LOOP + + VMOVDQU X0, 0*16(Dst) + VMOVDQU X3, 1*16(Dst) + VZEROUPPER + RET + +// func hChaCha20SSE2(out *[32]byte, nonce *[16]byte, key *[32]byte) +TEXT ·hChaCha20SSE2(SB), 4, $0-24 + MOVQ out+0(FP), Dst + MOVQ nonce+8(FP), Nonce + MOVQ key+16(FP), Key + + MOVOU ·sigma<>(SB), X0 + MOVOU 0*16(Key), X1 + MOVOU 1*16(Key), X2 + MOVOU 0*16(Nonce), X3 + MOVQ $20, Rounds + +CHACHA_LOOP: + CHACHA_QROUND_SSE2(X0, X1, X2, X3, X4) + CHACHA_SHUFFLE_SSE(X1, X2, X3) + CHACHA_QROUND_SSE2(X0, X1, X2, X3, X4) + CHACHA_SHUFFLE_SSE(X3, X2, X1) + SUBQ $2, Rounds + JNZ CHACHA_LOOP + + MOVOU X0, 0*16(Dst) + MOVOU X3, 1*16(Dst) + RET + +// func hChaCha20SSSE3(out *[32]byte, nonce *[16]byte, key *[32]byte) +TEXT ·hChaCha20SSSE3(SB), 4, $0-24 + MOVQ out+0(FP), Dst + MOVQ nonce+8(FP), Nonce + MOVQ key+16(FP), Key + + MOVOU ·sigma<>(SB), X0 + MOVOU 0*16(Key), X1 + MOVOU 1*16(Key), X2 + MOVOU 0*16(Nonce), X3 + MOVOU ·rol16<>(SB), X5 + MOVOU ·rol8<>(SB), X6 + MOVQ $20, Rounds + +chacha_loop: + CHACHA_QROUND_SSSE3(X0, X1, X2, X3, X4, X5, X6) + CHACHA_SHUFFLE_SSE(X1, X2, X3) + CHACHA_QROUND_SSSE3(X0, X1, X2, X3, X4, X5, X6) + CHACHA_SHUFFLE_SSE(X3, X2, X1) + SUBQ $2, Rounds + JNZ chacha_loop + + MOVOU X0, 0*16(Dst) + MOVOU X3, 1*16(Dst) + RET + +#undef Dst +#undef Nonce +#undef Key +#undef Rounds + +#define Dst DI +#define Src SI +#define Len R12 +#define Rounds DX +#define Buffer BX +#define State AX +#define Stack SP +#define SavedSP R8 +#define Tmp0 R9 +#define Tmp1 R10 +#define Tmp2 R11 + +// func xorKeyStreamSSE2(dst, src []byte, block, state *[64]byte, rounds int) int +TEXT ·xorKeyStreamSSE2(SB), 4, $112-80 + MOVQ dst_base+0(FP), Dst + MOVQ src_base+24(FP), Src + MOVQ block+48(FP), Buffer + MOVQ state+56(FP), State + MOVQ rounds+64(FP), Rounds + MOVQ src_len+32(FP), Len + + MOVOU 0*16(State), X0 + MOVOU 1*16(State), X1 + MOVOU 2*16(State), X2 + MOVOU 3*16(State), X3 + + MOVQ Stack, SavedSP + ADDQ $16, Stack + ANDQ $-16, Stack + + TESTQ Len, Len + JZ DONE + + MOVOU ·one<>(SB), X4 + MOVO X0, 0*16(Stack) + MOVO X1, 1*16(Stack) + MOVO X2, 2*16(Stack) + MOVO X3, 3*16(Stack) + MOVO X4, 4*16(Stack) + + CMPQ Len, $64 + JLE GENERATE_KEYSTREAM_64 + CMPQ Len, $128 + JLE GENERATE_KEYSTREAM_128 + CMPQ Len, $192 + JLE GENERATE_KEYSTREAM_192 + +GENERATE_KEYSTREAM_256: + MOVO X0, X12 + MOVO X1, X13 + MOVO X2, X14 + MOVO X3, X15 + PADDQ 4*16(Stack), X15 + MOVO X0, X8 + MOVO X1, X9 + MOVO X2, X10 + MOVO X15, X11 + PADDQ 4*16(Stack), X11 + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X11, X7 + PADDQ 4*16(Stack), X7 + MOVQ Rounds, Tmp0 + + MOVO X3, 3*16(Stack) // Save X3 + +CHACHA_LOOP_256: + MOVO X4, 5*16(Stack) + CHACHA_QROUND_SSE2(X0, X1, X2, X3, X4) + CHACHA_QROUND_SSE2(X12, X13, X14, X15, X4) + MOVO 5*16(Stack), X4 + MOVO X0, 5*16(Stack) + CHACHA_QROUND_SSE2(X8, X9, X10, X11, X0) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X0) + MOVO 5*16(Stack), X0 + CHACHA_SHUFFLE_SSE(X1, X2, X3) + CHACHA_SHUFFLE_SSE(X13, X14, X15) + CHACHA_SHUFFLE_SSE(X9, X10, X11) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + MOVO X4, 5*16(Stack) + CHACHA_QROUND_SSE2(X0, X1, X2, X3, X4) + CHACHA_QROUND_SSE2(X12, X13, X14, X15, X4) + MOVO 5*16(Stack), X4 + MOVO X0, 5*16(Stack) + CHACHA_QROUND_SSE2(X8, X9, X10, X11, X0) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X0) + MOVO 5*16(Stack), X0 + CHACHA_SHUFFLE_SSE(X3, X2, X1) + CHACHA_SHUFFLE_SSE(X15, X14, X13) + CHACHA_SHUFFLE_SSE(X11, X10, X9) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_256 + + PADDL 0*16(Stack), X0 + PADDL 1*16(Stack), X1 + PADDL 2*16(Stack), X2 + PADDL 3*16(Stack), X3 + MOVO X4, 5*16(Stack) // Save X4 + XOR_SSE(Dst, Src, 0, X0, X1, X2, X3, X4) + MOVO 5*16(Stack), X4 // Restore X4 + + MOVO 0*16(Stack), X0 + MOVO 1*16(Stack), X1 + MOVO 2*16(Stack), X2 + MOVO 3*16(Stack), X3 + PADDQ 4*16(Stack), X3 + + PADDL X0, X12 + PADDL X1, X13 + PADDL X2, X14 + PADDL X3, X15 + PADDQ 4*16(Stack), X3 + PADDL X0, X8 + PADDL X1, X9 + PADDL X2, X10 + PADDL X3, X11 + PADDQ 4*16(Stack), X3 + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + XOR_SSE(Dst, Src, 64, X12, X13, X14, X15, X0) + XOR_SSE(Dst, Src, 128, X8, X9, X10, X11, X0) + MOVO 0*16(Stack), X0 // Restore X0 + ADDQ $192, Dst + ADDQ $192, Src + SUBQ $192, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE + CMPQ Len, $64 // If Len <= 64 -> gen. only 64 byte keystream. + JLE GENERATE_KEYSTREAM_64 + CMPQ Len, $128 // If 64 < Len <= 128 -> gen. only 128 byte keystream. + JLE GENERATE_KEYSTREAM_128 + CMPQ Len, $192 // If Len > 192 -> repeat, otherwise Len > 128 && Len <= 192 -> gen. 192 byte keystream + JG GENERATE_KEYSTREAM_256 + +GENERATE_KEYSTREAM_192: + MOVO X0, X12 + MOVO X1, X13 + MOVO X2, X14 + MOVO X3, X15 + MOVO X0, X8 + MOVO X1, X9 + MOVO X2, X10 + MOVO X3, X11 + PADDQ 4*16(Stack), X11 + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X11, X7 + PADDQ 4*16(Stack), X7 + MOVQ Rounds, Tmp0 + +CHACHA_LOOP_192: + CHACHA_QROUND_SSE2(X12, X13, X14, X15, X0) + CHACHA_QROUND_SSE2(X8, X9, X10, X11, X0) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X0) + CHACHA_SHUFFLE_SSE(X13, X14, X15) + CHACHA_SHUFFLE_SSE(X9, X10, X11) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + CHACHA_QROUND_SSE2(X12, X13, X14, X15, X0) + CHACHA_QROUND_SSE2(X8, X9, X10, X11, X0) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X0) + CHACHA_SHUFFLE_SSE(X15, X14, X13) + CHACHA_SHUFFLE_SSE(X11, X10, X9) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_192 + + MOVO 0*16(Stack), X0 // Restore X0 + PADDL X0, X12 + PADDL X1, X13 + PADDL X2, X14 + PADDL X3, X15 + PADDQ 4*16(Stack), X3 + PADDL X0, X8 + PADDL X1, X9 + PADDL X2, X10 + PADDL X3, X11 + PADDQ 4*16(Stack), X3 + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + XOR_SSE(Dst, Src, 0, X12, X13, X14, X15, X0) + XOR_SSE(Dst, Src, 64, X8, X9, X10, X11, X0) + MOVO 0*16(Stack), X0 // Restore X0 + ADDQ $128, Dst + ADDQ $128, Src + SUBQ $128, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE + CMPQ Len, $64 // If Len <= 64 -> gen. only 64 byte keystream. + JLE GENERATE_KEYSTREAM_64 + +GENERATE_KEYSTREAM_128: + MOVO X0, X8 + MOVO X1, X9 + MOVO X2, X10 + MOVO X3, X11 + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X3, X7 + PADDQ 4*16(Stack), X7 + MOVQ Rounds, Tmp0 + +CHACHA_LOOP_128: + CHACHA_QROUND_SSE2(X8, X9, X10, X11, X12) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X12) + CHACHA_SHUFFLE_SSE(X9, X10, X11) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + CHACHA_QROUND_SSE2(X8, X9, X10, X11, X12) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X12) + CHACHA_SHUFFLE_SSE(X11, X10, X9) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_128 + + PADDL X0, X8 + PADDL X1, X9 + PADDL X2, X10 + PADDL X3, X11 + PADDQ 4*16(Stack), X3 + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + XOR_SSE(Dst, Src, 0, X8, X9, X10, X11, X12) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE // If Len == 0 -> DONE, otherwise Len <= 64 -> gen 64 byte keystream + +GENERATE_KEYSTREAM_64: + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X3, X7 + MOVQ Rounds, Tmp0 + +CHACHA_LOOP_64: + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X8) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + CHACHA_QROUND_SSE2(X4, X5, X6, X7, X8) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_64 + + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Src + ADDQ $64, Dst + SUBQ $64, Len + JMP DONE // jump directly to DONE - there is no keystream to buffer, Len == 0 always true. + +BUFFER_KEYSTREAM: + MOVOU X4, 0*16(Buffer) + MOVOU X5, 1*16(Buffer) + MOVOU X6, 2*16(Buffer) + MOVOU X7, 3*16(Buffer) + MOVQ Len, Tmp0 + FINALIZE(Dst, Src, Buffer, Tmp0, Tmp1, Tmp2) + +DONE: + MOVQ SavedSP, Stack // Restore stack pointer + MOVOU X3, 3*16(State) + MOVQ Len, ret+72(FP) + RET + +// func xorKeyStreamSSSE3(dst, src []byte, block, state *[64]byte, rounds int) int +TEXT ·xorKeyStreamSSSE3(SB), 4, $144-80 + MOVQ dst_base+0(FP), Dst + MOVQ src_base+24(FP), Src + MOVQ block+48(FP), Buffer + MOVQ state+56(FP), State + MOVQ rounds+64(FP), Rounds + MOVQ src_len+32(FP), Len + + MOVOU 0*16(State), X0 + MOVOU 1*16(State), X1 + MOVOU 2*16(State), X2 + MOVOU 3*16(State), X3 + + MOVQ Stack, SavedSP + ADDQ $16, Stack + ANDQ $-16, Stack + + TESTQ Len, Len + JZ DONE + + MOVOU ·one<>(SB), X4 + MOVOU ·rol16<>(SB), X5 + MOVOU ·rol8<>(SB), X6 + MOVO X0, 0*16(Stack) + MOVO X1, 1*16(Stack) + MOVO X2, 2*16(Stack) + MOVO X3, 3*16(Stack) + MOVO X4, 4*16(Stack) + MOVO X5, 6*16(Stack) + MOVO X6, 7*16(Stack) + + CMPQ Len, $64 + JLE GENERATE_KEYSTREAM_64 + CMPQ Len, $128 + JLE GENERATE_KEYSTREAM_128 + CMPQ Len, $192 + JLE GENERATE_KEYSTREAM_192 + +GENERATE_KEYSTREAM_256: + MOVO X0, X12 + MOVO X1, X13 + MOVO X2, X14 + MOVO X3, X15 + PADDQ 4*16(Stack), X15 + MOVO X0, X8 + MOVO X1, X9 + MOVO X2, X10 + MOVO X15, X11 + PADDQ 4*16(Stack), X11 + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X11, X7 + PADDQ 4*16(Stack), X7 + MOVQ Rounds, Tmp0 + + MOVO X3, 3*16(Stack) // Save X3 + +CHACHA_LOOP_256: + MOVO X4, 5*16(Stack) + CHACHA_QROUND_SSSE3(X0, X1, X2, X3, X4, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_SSSE3(X12, X13, X14, X15, X4, 6*16(Stack), 7*16(Stack)) + MOVO 5*16(Stack), X4 + MOVO X0, 5*16(Stack) + CHACHA_QROUND_SSSE3(X8, X9, X10, X11, X0, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X0, 6*16(Stack), 7*16(Stack)) + MOVO 5*16(Stack), X0 + CHACHA_SHUFFLE_SSE(X1, X2, X3) + CHACHA_SHUFFLE_SSE(X13, X14, X15) + CHACHA_SHUFFLE_SSE(X9, X10, X11) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + MOVO X4, 5*16(Stack) + CHACHA_QROUND_SSSE3(X0, X1, X2, X3, X4, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_SSSE3(X12, X13, X14, X15, X4, 6*16(Stack), 7*16(Stack)) + MOVO 5*16(Stack), X4 + MOVO X0, 5*16(Stack) + CHACHA_QROUND_SSSE3(X8, X9, X10, X11, X0, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X0, 6*16(Stack), 7*16(Stack)) + MOVO 5*16(Stack), X0 + CHACHA_SHUFFLE_SSE(X3, X2, X1) + CHACHA_SHUFFLE_SSE(X15, X14, X13) + CHACHA_SHUFFLE_SSE(X11, X10, X9) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_256 + + PADDL 0*16(Stack), X0 + PADDL 1*16(Stack), X1 + PADDL 2*16(Stack), X2 + PADDL 3*16(Stack), X3 + MOVO X4, 5*16(Stack) // Save X4 + XOR_SSE(Dst, Src, 0, X0, X1, X2, X3, X4) + MOVO 5*16(Stack), X4 // Restore X4 + + MOVO 0*16(Stack), X0 + MOVO 1*16(Stack), X1 + MOVO 2*16(Stack), X2 + MOVO 3*16(Stack), X3 + PADDQ 4*16(Stack), X3 + + PADDL X0, X12 + PADDL X1, X13 + PADDL X2, X14 + PADDL X3, X15 + PADDQ 4*16(Stack), X3 + PADDL X0, X8 + PADDL X1, X9 + PADDL X2, X10 + PADDL X3, X11 + PADDQ 4*16(Stack), X3 + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + XOR_SSE(Dst, Src, 64, X12, X13, X14, X15, X0) + XOR_SSE(Dst, Src, 128, X8, X9, X10, X11, X0) + MOVO 0*16(Stack), X0 // Restore X0 + ADDQ $192, Dst + ADDQ $192, Src + SUBQ $192, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE + CMPQ Len, $64 // If Len <= 64 -> gen. only 64 byte keystream. + JLE GENERATE_KEYSTREAM_64 + CMPQ Len, $128 // If 64 < Len <= 128 -> gen. only 128 byte keystream. + JLE GENERATE_KEYSTREAM_128 + CMPQ Len, $192 // If Len > 192 -> repeat, otherwise Len > 128 && Len <= 192 -> gen. 192 byte keystream + JG GENERATE_KEYSTREAM_256 + +GENERATE_KEYSTREAM_192: + MOVO X0, X12 + MOVO X1, X13 + MOVO X2, X14 + MOVO X3, X15 + MOVO X0, X8 + MOVO X1, X9 + MOVO X2, X10 + MOVO X3, X11 + PADDQ 4*16(Stack), X11 + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X11, X7 + PADDQ 4*16(Stack), X7 + MOVQ Rounds, Tmp0 + + MOVO 6*16(Stack), X1 // Load 16 bit rotate-left constant + MOVO 7*16(Stack), X2 // Load 8 bit rotate-left constant + +CHACHA_LOOP_192: + CHACHA_QROUND_SSSE3(X12, X13, X14, X15, X0, X1, X2) + CHACHA_QROUND_SSSE3(X8, X9, X10, X11, X0, X1, X2) + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X0, X1, X2) + CHACHA_SHUFFLE_SSE(X13, X14, X15) + CHACHA_SHUFFLE_SSE(X9, X10, X11) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + CHACHA_QROUND_SSSE3(X12, X13, X14, X15, X0, X1, X2) + CHACHA_QROUND_SSSE3(X8, X9, X10, X11, X0, X1, X2) + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X0, X1, X2) + CHACHA_SHUFFLE_SSE(X15, X14, X13) + CHACHA_SHUFFLE_SSE(X11, X10, X9) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_192 + + MOVO 0*16(Stack), X0 // Restore X0 + MOVO 1*16(Stack), X1 // Restore X1 + MOVO 2*16(Stack), X2 // Restore X2 + PADDL X0, X12 + PADDL X1, X13 + PADDL X2, X14 + PADDL X3, X15 + PADDQ 4*16(Stack), X3 + PADDL X0, X8 + PADDL X1, X9 + PADDL X2, X10 + PADDL X3, X11 + PADDQ 4*16(Stack), X3 + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + XOR_SSE(Dst, Src, 0, X12, X13, X14, X15, X0) + XOR_SSE(Dst, Src, 64, X8, X9, X10, X11, X0) + MOVO 0*16(Stack), X0 // Restore X0 + ADDQ $128, Dst + ADDQ $128, Src + SUBQ $128, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE + CMPQ Len, $64 // If Len <= 64 -> gen. only 64 byte keystream. + JLE GENERATE_KEYSTREAM_64 + +GENERATE_KEYSTREAM_128: + MOVO X0, X8 + MOVO X1, X9 + MOVO X2, X10 + MOVO X3, X11 + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X3, X7 + PADDQ 4*16(Stack), X7 + MOVQ Rounds, Tmp0 + + MOVO 6*16(Stack), X13 // Load 16 bit rotate-left constant + MOVO 7*16(Stack), X14 // Load 8 bit rotate-left constant + +CHACHA_LOOP_128: + CHACHA_QROUND_SSSE3(X8, X9, X10, X11, X12, X13, X14) + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X12, X13, X14) + CHACHA_SHUFFLE_SSE(X9, X10, X11) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + CHACHA_QROUND_SSSE3(X8, X9, X10, X11, X12, X13, X14) + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X12, X13, X14) + CHACHA_SHUFFLE_SSE(X11, X10, X9) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_128 + + PADDL X0, X8 + PADDL X1, X9 + PADDL X2, X10 + PADDL X3, X11 + PADDQ 4*16(Stack), X3 + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + XOR_SSE(Dst, Src, 0, X8, X9, X10, X11, X12) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE // If Len == 0 -> DONE, otherwise Len <= 64 -> gen 64 byte keystream + +GENERATE_KEYSTREAM_64: + MOVO X0, X4 + MOVO X1, X5 + MOVO X2, X6 + MOVO X3, X7 + MOVQ Rounds, Tmp0 + + MOVO 6*16(Stack), X9 // Load 16 bit rotate-left constant + MOVO 7*16(Stack), X10 // Load 8 bit rotate-left constant + +CHACHA_LOOP_64: + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10) + CHACHA_SHUFFLE_SSE(X5, X6, X7) + CHACHA_QROUND_SSSE3(X4, X5, X6, X7, X8, X9, X10) + CHACHA_SHUFFLE_SSE(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_64 + + PADDL X0, X4 + PADDL X1, X5 + PADDL X2, X6 + PADDL X3, X7 + PADDQ 4*16(Stack), X3 + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_SSE(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Src + ADDQ $64, Dst + SUBQ $64, Len + JMP DONE // jump directly to DONE - there is no keystream to buffer, Len == 0 always true. + +BUFFER_KEYSTREAM: + MOVOU X4, 0*16(Buffer) + MOVOU X5, 1*16(Buffer) + MOVOU X6, 2*16(Buffer) + MOVOU X7, 3*16(Buffer) + MOVQ Len, Tmp0 + FINALIZE(Dst, Src, Buffer, Tmp0, Tmp1, Tmp2) + +DONE: + MOVQ SavedSP, Stack // Restore stack pointer + MOVOU X3, 3*16(State) + MOVQ Len, ret+72(FP) + RET + +// func xorKeyStreamAVX(dst, src []byte, block, state *[64]byte, rounds int) int +TEXT ·xorKeyStreamAVX(SB), 4, $144-80 + MOVQ dst_base+0(FP), Dst + MOVQ src_base+24(FP), Src + MOVQ block+48(FP), Buffer + MOVQ state+56(FP), State + MOVQ rounds+64(FP), Rounds + MOVQ src_len+32(FP), Len + + VMOVDQU 0*16(State), X0 + VMOVDQU 1*16(State), X1 + VMOVDQU 2*16(State), X2 + VMOVDQU 3*16(State), X3 + + MOVQ Stack, SavedSP + ADDQ $16, Stack + ANDQ $-16, Stack + + TESTQ Len, Len + JZ DONE + + VMOVDQU ·one<>(SB), X4 + VMOVDQU ·rol16<>(SB), X5 + VMOVDQU ·rol8<>(SB), X6 + VMOVDQA X0, 0*16(Stack) + VMOVDQA X1, 1*16(Stack) + VMOVDQA X2, 2*16(Stack) + VMOVDQA X3, 3*16(Stack) + VMOVDQA X4, 4*16(Stack) + VMOVDQA X5, 6*16(Stack) + VMOVDQA X6, 7*16(Stack) + + CMPQ Len, $64 + JLE GENERATE_KEYSTREAM_64 + CMPQ Len, $128 + JLE GENERATE_KEYSTREAM_128 + CMPQ Len, $192 + JLE GENERATE_KEYSTREAM_192 + +GENERATE_KEYSTREAM_256: + VMOVDQA X0, X12 + VMOVDQA X1, X13 + VMOVDQA X2, X14 + VMOVDQA X3, X15 + VPADDQ 4*16(Stack), X15, X15 + VMOVDQA X0, X8 + VMOVDQA X1, X9 + VMOVDQA X2, X10 + VMOVDQA X15, X11 + VPADDQ 4*16(Stack), X11, X11 + VMOVDQA X0, X4 + VMOVDQA X1, X5 + VMOVDQA X2, X6 + VMOVDQA X11, X7 + VPADDQ 4*16(Stack), X7, X7 + MOVQ Rounds, Tmp0 + + VMOVDQA X3, 3*16(Stack) // Save X3 + +CHACHA_LOOP_256: + VMOVDQA X4, 5*16(Stack) + CHACHA_QROUND_AVX(X0, X1, X2, X3, X4, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_AVX(X12, X13, X14, X15, X4, 6*16(Stack), 7*16(Stack)) + VMOVDQA 5*16(Stack), X4 + VMOVDQA X0, 5*16(Stack) + CHACHA_QROUND_AVX(X8, X9, X10, X11, X0, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X0, 6*16(Stack), 7*16(Stack)) + VMOVDQA 5*16(Stack), X0 + CHACHA_SHUFFLE_AVX(X1, X2, X3) + CHACHA_SHUFFLE_AVX(X13, X14, X15) + CHACHA_SHUFFLE_AVX(X9, X10, X11) + CHACHA_SHUFFLE_AVX(X5, X6, X7) + VMOVDQA X4, 5*16(Stack) + CHACHA_QROUND_AVX(X0, X1, X2, X3, X4, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_AVX(X12, X13, X14, X15, X4, 6*16(Stack), 7*16(Stack)) + VMOVDQA 5*16(Stack), X4 + VMOVDQA X0, 5*16(Stack) + CHACHA_QROUND_AVX(X8, X9, X10, X11, X0, 6*16(Stack), 7*16(Stack)) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X0, 6*16(Stack), 7*16(Stack)) + VMOVDQA 5*16(Stack), X0 + CHACHA_SHUFFLE_AVX(X3, X2, X1) + CHACHA_SHUFFLE_AVX(X15, X14, X13) + CHACHA_SHUFFLE_AVX(X11, X10, X9) + CHACHA_SHUFFLE_AVX(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_256 + + VPADDD 0*16(Stack), X0, X0 + VPADDD 1*16(Stack), X1, X1 + VPADDD 2*16(Stack), X2, X2 + VPADDD 3*16(Stack), X3, X3 + VMOVDQA X4, 5*16(Stack) // Save X4 + XOR_AVX(Dst, Src, 0, X0, X1, X2, X3, X4) + VMOVDQA 5*16(Stack), X4 // Restore X4 + + VMOVDQA 0*16(Stack), X0 + VMOVDQA 1*16(Stack), X1 + VMOVDQA 2*16(Stack), X2 + VMOVDQA 3*16(Stack), X3 + VPADDQ 4*16(Stack), X3, X3 + + VPADDD X0, X12, X12 + VPADDD X1, X13, X13 + VPADDD X2, X14, X14 + VPADDD X3, X15, X15 + VPADDQ 4*16(Stack), X3, X3 + VPADDD X0, X8, X8 + VPADDD X1, X9, X9 + VPADDD X2, X10, X10 + VPADDD X3, X11, X11 + VPADDQ 4*16(Stack), X3, X3 + VPADDD X0, X4, X4 + VPADDD X1, X5, X5 + VPADDD X2, X6, X6 + VPADDD X3, X7, X7 + VPADDQ 4*16(Stack), X3, X3 + + XOR_AVX(Dst, Src, 64, X12, X13, X14, X15, X0) + XOR_AVX(Dst, Src, 128, X8, X9, X10, X11, X0) + VMOVDQA 0*16(Stack), X0 // Restore X0 + ADDQ $192, Dst + ADDQ $192, Src + SUBQ $192, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_AVX(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE + CMPQ Len, $64 // If Len <= 64 -> gen. only 64 byte keystream. + JLE GENERATE_KEYSTREAM_64 + CMPQ Len, $128 // If 64 < Len <= 128 -> gen. only 128 byte keystream. + JLE GENERATE_KEYSTREAM_128 + CMPQ Len, $192 // If Len > 192 -> repeat, otherwise Len > 128 && Len <= 192 -> gen. 192 byte keystream + JG GENERATE_KEYSTREAM_256 + +GENERATE_KEYSTREAM_192: + VMOVDQA X0, X12 + VMOVDQA X1, X13 + VMOVDQA X2, X14 + VMOVDQA X3, X15 + VMOVDQA X0, X8 + VMOVDQA X1, X9 + VMOVDQA X2, X10 + VMOVDQA X3, X11 + VPADDQ 4*16(Stack), X11, X11 + VMOVDQA X0, X4 + VMOVDQA X1, X5 + VMOVDQA X2, X6 + VMOVDQA X11, X7 + VPADDQ 4*16(Stack), X7, X7 + MOVQ Rounds, Tmp0 + + VMOVDQA 6*16(Stack), X1 // Load 16 bit rotate-left constant + VMOVDQA 7*16(Stack), X2 // Load 8 bit rotate-left constant + +CHACHA_LOOP_192: + CHACHA_QROUND_AVX(X12, X13, X14, X15, X0, X1, X2) + CHACHA_QROUND_AVX(X8, X9, X10, X11, X0, X1, X2) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X0, X1, X2) + CHACHA_SHUFFLE_AVX(X13, X14, X15) + CHACHA_SHUFFLE_AVX(X9, X10, X11) + CHACHA_SHUFFLE_AVX(X5, X6, X7) + CHACHA_QROUND_AVX(X12, X13, X14, X15, X0, X1, X2) + CHACHA_QROUND_AVX(X8, X9, X10, X11, X0, X1, X2) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X0, X1, X2) + CHACHA_SHUFFLE_AVX(X15, X14, X13) + CHACHA_SHUFFLE_AVX(X11, X10, X9) + CHACHA_SHUFFLE_AVX(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_192 + + VMOVDQA 0*16(Stack), X0 // Restore X0 + VMOVDQA 1*16(Stack), X1 // Restore X1 + VMOVDQA 2*16(Stack), X2 // Restore X2 + VPADDD X0, X12, X12 + VPADDD X1, X13, X13 + VPADDD X2, X14, X14 + VPADDD X3, X15, X15 + VPADDQ 4*16(Stack), X3, X3 + VPADDD X0, X8, X8 + VPADDD X1, X9, X9 + VPADDD X2, X10, X10 + VPADDD X3, X11, X11 + VPADDQ 4*16(Stack), X3, X3 + VPADDD X0, X4, X4 + VPADDD X1, X5, X5 + VPADDD X2, X6, X6 + VPADDD X3, X7, X7 + VPADDQ 4*16(Stack), X3, X3 + + XOR_AVX(Dst, Src, 0, X12, X13, X14, X15, X0) + XOR_AVX(Dst, Src, 64, X8, X9, X10, X11, X0) + VMOVDQA 0*16(Stack), X0 // Restore X0 + ADDQ $128, Dst + ADDQ $128, Src + SUBQ $128, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_AVX(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE + CMPQ Len, $64 // If Len <= 64 -> gen. only 64 byte keystream. + JLE GENERATE_KEYSTREAM_64 + +GENERATE_KEYSTREAM_128: + VMOVDQA X0, X8 + VMOVDQA X1, X9 + VMOVDQA X2, X10 + VMOVDQA X3, X11 + VMOVDQA X0, X4 + VMOVDQA X1, X5 + VMOVDQA X2, X6 + VMOVDQA X3, X7 + VPADDQ 4*16(Stack), X7, X7 + MOVQ Rounds, Tmp0 + + VMOVDQA 6*16(Stack), X13 // Load 16 bit rotate-left constant + VMOVDQA 7*16(Stack), X14 // Load 8 bit rotate-left constant + +CHACHA_LOOP_128: + CHACHA_QROUND_AVX(X8, X9, X10, X11, X12, X13, X14) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X12, X13, X14) + CHACHA_SHUFFLE_AVX(X9, X10, X11) + CHACHA_SHUFFLE_AVX(X5, X6, X7) + CHACHA_QROUND_AVX(X8, X9, X10, X11, X12, X13, X14) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X12, X13, X14) + CHACHA_SHUFFLE_AVX(X11, X10, X9) + CHACHA_SHUFFLE_AVX(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_128 + + VPADDD X0, X8, X8 + VPADDD X1, X9, X9 + VPADDD X2, X10, X10 + VPADDD X3, X11, X11 + VPADDQ 4*16(Stack), X3, X3 + VPADDD X0, X4, X4 + VPADDD X1, X5, X5 + VPADDD X2, X6, X6 + VPADDD X3, X7, X7 + VPADDQ 4*16(Stack), X3, X3 + + XOR_AVX(Dst, Src, 0, X8, X9, X10, X11, X12) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_AVX(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Dst + ADDQ $64, Src + SUBQ $64, Len + JZ DONE // If Len == 0 -> DONE, otherwise Len <= 64 -> gen 64 byte keystream + +GENERATE_KEYSTREAM_64: + VMOVDQA X0, X4 + VMOVDQA X1, X5 + VMOVDQA X2, X6 + VMOVDQA X3, X7 + MOVQ Rounds, Tmp0 + + VMOVDQA 6*16(Stack), X9 // Load 16 bit rotate-left constant + VMOVDQA 7*16(Stack), X10 // Load 8 bit rotate-left constant + +CHACHA_LOOP_64: + CHACHA_QROUND_AVX(X4, X5, X6, X7, X8, X9, X10) + CHACHA_SHUFFLE_AVX(X5, X6, X7) + CHACHA_QROUND_AVX(X4, X5, X6, X7, X8, X9, X10) + CHACHA_SHUFFLE_AVX(X7, X6, X5) + SUBQ $2, Tmp0 + JNZ CHACHA_LOOP_64 + + VPADDD X0, X4, X4 + VPADDD X1, X5, X5 + VPADDD X2, X6, X6 + VPADDD X3, X7, X7 + VPADDQ 4*16(Stack), X3, X3 + + CMPQ Len, $64 + JL BUFFER_KEYSTREAM + + XOR_AVX(Dst, Src, 0, X4, X5, X6, X7, X8) + ADDQ $64, Src + ADDQ $64, Dst + SUBQ $64, Len + JMP DONE // jump directly to DONE - there is no keystream to buffer, Len == 0 always true. + +BUFFER_KEYSTREAM: + VMOVDQU X4, 0*16(Buffer) + VMOVDQU X5, 1*16(Buffer) + VMOVDQU X6, 2*16(Buffer) + VMOVDQU X7, 3*16(Buffer) + MOVQ Len, Tmp0 + FINALIZE(Dst, Src, Buffer, Tmp0, Tmp1, Tmp2) + +DONE: + MOVQ SavedSP, Stack // Restore stack pointer + VMOVDQU X3, 3*16(State) + VZEROUPPER + MOVQ Len, ret+72(FP) + RET + +#undef Dst +#undef Src +#undef Len +#undef Rounds +#undef Buffer +#undef State +#undef Stack +#undef SavedSP +#undef Tmp0 +#undef Tmp1 +#undef Tmp2 diff --git a/vendor/github.com/aead/chacha20/chacha/chacha_generic.go b/vendor/github.com/aead/chacha20/chacha/chacha_generic.go new file mode 100644 index 0000000..8832d5b --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chacha_generic.go @@ -0,0 +1,319 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +package chacha + +import "encoding/binary" + +var sigma = [4]uint32{0x61707865, 0x3320646e, 0x79622d32, 0x6b206574} + +func xorKeyStreamGeneric(dst, src []byte, block, state *[64]byte, rounds int) int { + for len(src) >= 64 { + chachaGeneric(block, state, rounds) + + for i, v := range block { + dst[i] = src[i] ^ v + } + src = src[64:] + dst = dst[64:] + } + + n := len(src) + if n > 0 { + chachaGeneric(block, state, rounds) + for i, v := range src { + dst[i] = v ^ block[i] + } + } + return n +} + +func chachaGeneric(dst *[64]byte, state *[64]byte, rounds int) { + v00 := binary.LittleEndian.Uint32(state[0:]) + v01 := binary.LittleEndian.Uint32(state[4:]) + v02 := binary.LittleEndian.Uint32(state[8:]) + v03 := binary.LittleEndian.Uint32(state[12:]) + v04 := binary.LittleEndian.Uint32(state[16:]) + v05 := binary.LittleEndian.Uint32(state[20:]) + v06 := binary.LittleEndian.Uint32(state[24:]) + v07 := binary.LittleEndian.Uint32(state[28:]) + v08 := binary.LittleEndian.Uint32(state[32:]) + v09 := binary.LittleEndian.Uint32(state[36:]) + v10 := binary.LittleEndian.Uint32(state[40:]) + v11 := binary.LittleEndian.Uint32(state[44:]) + v12 := binary.LittleEndian.Uint32(state[48:]) + v13 := binary.LittleEndian.Uint32(state[52:]) + v14 := binary.LittleEndian.Uint32(state[56:]) + v15 := binary.LittleEndian.Uint32(state[60:]) + + s00, s01, s02, s03, s04, s05, s06, s07 := v00, v01, v02, v03, v04, v05, v06, v07 + s08, s09, s10, s11, s12, s13, s14, s15 := v08, v09, v10, v11, v12, v13, v14, v15 + + for i := 0; i < rounds; i += 2 { + v00 += v04 + v12 ^= v00 + v12 = (v12 << 16) | (v12 >> 16) + v08 += v12 + v04 ^= v08 + v04 = (v04 << 12) | (v04 >> 20) + v00 += v04 + v12 ^= v00 + v12 = (v12 << 8) | (v12 >> 24) + v08 += v12 + v04 ^= v08 + v04 = (v04 << 7) | (v04 >> 25) + v01 += v05 + v13 ^= v01 + v13 = (v13 << 16) | (v13 >> 16) + v09 += v13 + v05 ^= v09 + v05 = (v05 << 12) | (v05 >> 20) + v01 += v05 + v13 ^= v01 + v13 = (v13 << 8) | (v13 >> 24) + v09 += v13 + v05 ^= v09 + v05 = (v05 << 7) | (v05 >> 25) + v02 += v06 + v14 ^= v02 + v14 = (v14 << 16) | (v14 >> 16) + v10 += v14 + v06 ^= v10 + v06 = (v06 << 12) | (v06 >> 20) + v02 += v06 + v14 ^= v02 + v14 = (v14 << 8) | (v14 >> 24) + v10 += v14 + v06 ^= v10 + v06 = (v06 << 7) | (v06 >> 25) + v03 += v07 + v15 ^= v03 + v15 = (v15 << 16) | (v15 >> 16) + v11 += v15 + v07 ^= v11 + v07 = (v07 << 12) | (v07 >> 20) + v03 += v07 + v15 ^= v03 + v15 = (v15 << 8) | (v15 >> 24) + v11 += v15 + v07 ^= v11 + v07 = (v07 << 7) | (v07 >> 25) + v00 += v05 + v15 ^= v00 + v15 = (v15 << 16) | (v15 >> 16) + v10 += v15 + v05 ^= v10 + v05 = (v05 << 12) | (v05 >> 20) + v00 += v05 + v15 ^= v00 + v15 = (v15 << 8) | (v15 >> 24) + v10 += v15 + v05 ^= v10 + v05 = (v05 << 7) | (v05 >> 25) + v01 += v06 + v12 ^= v01 + v12 = (v12 << 16) | (v12 >> 16) + v11 += v12 + v06 ^= v11 + v06 = (v06 << 12) | (v06 >> 20) + v01 += v06 + v12 ^= v01 + v12 = (v12 << 8) | (v12 >> 24) + v11 += v12 + v06 ^= v11 + v06 = (v06 << 7) | (v06 >> 25) + v02 += v07 + v13 ^= v02 + v13 = (v13 << 16) | (v13 >> 16) + v08 += v13 + v07 ^= v08 + v07 = (v07 << 12) | (v07 >> 20) + v02 += v07 + v13 ^= v02 + v13 = (v13 << 8) | (v13 >> 24) + v08 += v13 + v07 ^= v08 + v07 = (v07 << 7) | (v07 >> 25) + v03 += v04 + v14 ^= v03 + v14 = (v14 << 16) | (v14 >> 16) + v09 += v14 + v04 ^= v09 + v04 = (v04 << 12) | (v04 >> 20) + v03 += v04 + v14 ^= v03 + v14 = (v14 << 8) | (v14 >> 24) + v09 += v14 + v04 ^= v09 + v04 = (v04 << 7) | (v04 >> 25) + } + + v00 += s00 + v01 += s01 + v02 += s02 + v03 += s03 + v04 += s04 + v05 += s05 + v06 += s06 + v07 += s07 + v08 += s08 + v09 += s09 + v10 += s10 + v11 += s11 + v12 += s12 + v13 += s13 + v14 += s14 + v15 += s15 + + s12++ + binary.LittleEndian.PutUint32(state[48:], s12) + if s12 == 0 { // indicates overflow + s13++ + binary.LittleEndian.PutUint32(state[52:], s13) + } + + binary.LittleEndian.PutUint32(dst[0:], v00) + binary.LittleEndian.PutUint32(dst[4:], v01) + binary.LittleEndian.PutUint32(dst[8:], v02) + binary.LittleEndian.PutUint32(dst[12:], v03) + binary.LittleEndian.PutUint32(dst[16:], v04) + binary.LittleEndian.PutUint32(dst[20:], v05) + binary.LittleEndian.PutUint32(dst[24:], v06) + binary.LittleEndian.PutUint32(dst[28:], v07) + binary.LittleEndian.PutUint32(dst[32:], v08) + binary.LittleEndian.PutUint32(dst[36:], v09) + binary.LittleEndian.PutUint32(dst[40:], v10) + binary.LittleEndian.PutUint32(dst[44:], v11) + binary.LittleEndian.PutUint32(dst[48:], v12) + binary.LittleEndian.PutUint32(dst[52:], v13) + binary.LittleEndian.PutUint32(dst[56:], v14) + binary.LittleEndian.PutUint32(dst[60:], v15) +} + +func hChaCha20Generic(out *[32]byte, nonce *[16]byte, key *[32]byte) { + v00 := sigma[0] + v01 := sigma[1] + v02 := sigma[2] + v03 := sigma[3] + v04 := binary.LittleEndian.Uint32(key[0:]) + v05 := binary.LittleEndian.Uint32(key[4:]) + v06 := binary.LittleEndian.Uint32(key[8:]) + v07 := binary.LittleEndian.Uint32(key[12:]) + v08 := binary.LittleEndian.Uint32(key[16:]) + v09 := binary.LittleEndian.Uint32(key[20:]) + v10 := binary.LittleEndian.Uint32(key[24:]) + v11 := binary.LittleEndian.Uint32(key[28:]) + v12 := binary.LittleEndian.Uint32(nonce[0:]) + v13 := binary.LittleEndian.Uint32(nonce[4:]) + v14 := binary.LittleEndian.Uint32(nonce[8:]) + v15 := binary.LittleEndian.Uint32(nonce[12:]) + + for i := 0; i < 20; i += 2 { + v00 += v04 + v12 ^= v00 + v12 = (v12 << 16) | (v12 >> 16) + v08 += v12 + v04 ^= v08 + v04 = (v04 << 12) | (v04 >> 20) + v00 += v04 + v12 ^= v00 + v12 = (v12 << 8) | (v12 >> 24) + v08 += v12 + v04 ^= v08 + v04 = (v04 << 7) | (v04 >> 25) + v01 += v05 + v13 ^= v01 + v13 = (v13 << 16) | (v13 >> 16) + v09 += v13 + v05 ^= v09 + v05 = (v05 << 12) | (v05 >> 20) + v01 += v05 + v13 ^= v01 + v13 = (v13 << 8) | (v13 >> 24) + v09 += v13 + v05 ^= v09 + v05 = (v05 << 7) | (v05 >> 25) + v02 += v06 + v14 ^= v02 + v14 = (v14 << 16) | (v14 >> 16) + v10 += v14 + v06 ^= v10 + v06 = (v06 << 12) | (v06 >> 20) + v02 += v06 + v14 ^= v02 + v14 = (v14 << 8) | (v14 >> 24) + v10 += v14 + v06 ^= v10 + v06 = (v06 << 7) | (v06 >> 25) + v03 += v07 + v15 ^= v03 + v15 = (v15 << 16) | (v15 >> 16) + v11 += v15 + v07 ^= v11 + v07 = (v07 << 12) | (v07 >> 20) + v03 += v07 + v15 ^= v03 + v15 = (v15 << 8) | (v15 >> 24) + v11 += v15 + v07 ^= v11 + v07 = (v07 << 7) | (v07 >> 25) + v00 += v05 + v15 ^= v00 + v15 = (v15 << 16) | (v15 >> 16) + v10 += v15 + v05 ^= v10 + v05 = (v05 << 12) | (v05 >> 20) + v00 += v05 + v15 ^= v00 + v15 = (v15 << 8) | (v15 >> 24) + v10 += v15 + v05 ^= v10 + v05 = (v05 << 7) | (v05 >> 25) + v01 += v06 + v12 ^= v01 + v12 = (v12 << 16) | (v12 >> 16) + v11 += v12 + v06 ^= v11 + v06 = (v06 << 12) | (v06 >> 20) + v01 += v06 + v12 ^= v01 + v12 = (v12 << 8) | (v12 >> 24) + v11 += v12 + v06 ^= v11 + v06 = (v06 << 7) | (v06 >> 25) + v02 += v07 + v13 ^= v02 + v13 = (v13 << 16) | (v13 >> 16) + v08 += v13 + v07 ^= v08 + v07 = (v07 << 12) | (v07 >> 20) + v02 += v07 + v13 ^= v02 + v13 = (v13 << 8) | (v13 >> 24) + v08 += v13 + v07 ^= v08 + v07 = (v07 << 7) | (v07 >> 25) + v03 += v04 + v14 ^= v03 + v14 = (v14 << 16) | (v14 >> 16) + v09 += v14 + v04 ^= v09 + v04 = (v04 << 12) | (v04 >> 20) + v03 += v04 + v14 ^= v03 + v14 = (v14 << 8) | (v14 >> 24) + v09 += v14 + v04 ^= v09 + v04 = (v04 << 7) | (v04 >> 25) + } + + binary.LittleEndian.PutUint32(out[0:], v00) + binary.LittleEndian.PutUint32(out[4:], v01) + binary.LittleEndian.PutUint32(out[8:], v02) + binary.LittleEndian.PutUint32(out[12:], v03) + binary.LittleEndian.PutUint32(out[16:], v12) + binary.LittleEndian.PutUint32(out[20:], v13) + binary.LittleEndian.PutUint32(out[24:], v14) + binary.LittleEndian.PutUint32(out[28:], v15) +} diff --git a/vendor/github.com/aead/chacha20/chacha/chacha_ref.go b/vendor/github.com/aead/chacha20/chacha/chacha_ref.go new file mode 100644 index 0000000..526877c --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/chacha_ref.go @@ -0,0 +1,33 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build !amd64,!386 gccgo appengine nacl + +package chacha + +import "encoding/binary" + +func init() { + useSSE2 = false + useSSSE3 = false + useAVX = false + useAVX2 = false +} + +func initialize(state *[64]byte, key []byte, nonce *[16]byte) { + binary.LittleEndian.PutUint32(state[0:], sigma[0]) + binary.LittleEndian.PutUint32(state[4:], sigma[1]) + binary.LittleEndian.PutUint32(state[8:], sigma[2]) + binary.LittleEndian.PutUint32(state[12:], sigma[3]) + copy(state[16:], key[:]) + copy(state[48:], nonce[:]) +} + +func xorKeyStream(dst, src []byte, block, state *[64]byte, rounds int) int { + return xorKeyStreamGeneric(dst, src, block, state, rounds) +} + +func hChaCha20(out *[32]byte, nonce *[16]byte, key *[32]byte) { + hChaCha20Generic(out, nonce, key) +} diff --git a/vendor/github.com/aead/chacha20/chacha/const.s b/vendor/github.com/aead/chacha20/chacha/const.s new file mode 100644 index 0000000..c7a94a4 --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/const.s @@ -0,0 +1,53 @@ +// Copyright (c) 2018 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build 386,!gccgo,!appengine,!nacl amd64,!gccgo,!appengine,!nacl + +#include "textflag.h" + +DATA ·sigma<>+0x00(SB)/4, $0x61707865 +DATA ·sigma<>+0x04(SB)/4, $0x3320646e +DATA ·sigma<>+0x08(SB)/4, $0x79622d32 +DATA ·sigma<>+0x0C(SB)/4, $0x6b206574 +GLOBL ·sigma<>(SB), (NOPTR+RODATA), $16 // The 4 ChaCha initialization constants + +// SSE2/SSE3/AVX constants + +DATA ·one<>+0x00(SB)/8, $1 +DATA ·one<>+0x08(SB)/8, $0 +GLOBL ·one<>(SB), (NOPTR+RODATA), $16 // The constant 1 as 128 bit value + +DATA ·rol16<>+0x00(SB)/8, $0x0504070601000302 +DATA ·rol16<>+0x08(SB)/8, $0x0D0C0F0E09080B0A +GLOBL ·rol16<>(SB), (NOPTR+RODATA), $16 // The PSHUFB 16 bit left rotate constant + +DATA ·rol8<>+0x00(SB)/8, $0x0605040702010003 +DATA ·rol8<>+0x08(SB)/8, $0x0E0D0C0F0A09080B +GLOBL ·rol8<>(SB), (NOPTR+RODATA), $16 // The PSHUFB 8 bit left rotate constant + +// AVX2 constants + +DATA ·one_AVX2<>+0x00(SB)/8, $0 +DATA ·one_AVX2<>+0x08(SB)/8, $0 +DATA ·one_AVX2<>+0x10(SB)/8, $1 +DATA ·one_AVX2<>+0x18(SB)/8, $0 +GLOBL ·one_AVX2<>(SB), (NOPTR+RODATA), $32 // The constant 1 as 256 bit value + +DATA ·two_AVX2<>+0x00(SB)/8, $2 +DATA ·two_AVX2<>+0x08(SB)/8, $0 +DATA ·two_AVX2<>+0x10(SB)/8, $2 +DATA ·two_AVX2<>+0x18(SB)/8, $0 +GLOBL ·two_AVX2<>(SB), (NOPTR+RODATA), $32 + +DATA ·rol16_AVX2<>+0x00(SB)/8, $0x0504070601000302 +DATA ·rol16_AVX2<>+0x08(SB)/8, $0x0D0C0F0E09080B0A +DATA ·rol16_AVX2<>+0x10(SB)/8, $0x0504070601000302 +DATA ·rol16_AVX2<>+0x18(SB)/8, $0x0D0C0F0E09080B0A +GLOBL ·rol16_AVX2<>(SB), (NOPTR+RODATA), $32 // The VPSHUFB 16 bit left rotate constant + +DATA ·rol8_AVX2<>+0x00(SB)/8, $0x0605040702010003 +DATA ·rol8_AVX2<>+0x08(SB)/8, $0x0E0D0C0F0A09080B +DATA ·rol8_AVX2<>+0x10(SB)/8, $0x0605040702010003 +DATA ·rol8_AVX2<>+0x18(SB)/8, $0x0E0D0C0F0A09080B +GLOBL ·rol8_AVX2<>(SB), (NOPTR+RODATA), $32 // The VPSHUFB 8 bit left rotate constant diff --git a/vendor/github.com/aead/chacha20/chacha/macro.s b/vendor/github.com/aead/chacha20/chacha/macro.s new file mode 100644 index 0000000..780108f --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha/macro.s @@ -0,0 +1,163 @@ +// Copyright (c) 2018 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// +build 386,!gccgo,!appengine,!nacl amd64,!gccgo,!appengine,!nacl + +// ROTL_SSE rotates all 4 32 bit values of the XMM register v +// left by n bits using SSE2 instructions (0 <= n <= 32). +// The XMM register t is used as a temp. register. +#define ROTL_SSE(n, t, v) \ + MOVO v, t; \ + PSLLL $n, t; \ + PSRLL $(32-n), v; \ + PXOR t, v + +// ROTL_AVX rotates all 4/8 32 bit values of the AVX/AVX2 register v +// left by n bits using AVX/AVX2 instructions (0 <= n <= 32). +// The AVX/AVX2 register t is used as a temp. register. +#define ROTL_AVX(n, t, v) \ + VPSLLD $n, v, t; \ + VPSRLD $(32-n), v, v; \ + VPXOR v, t, v + +// CHACHA_QROUND_SSE2 performs a ChaCha quarter-round using the +// 4 XMM registers v0, v1, v2 and v3. It uses only ROTL_SSE2 for +// rotations. The XMM register t is used as a temp. register. +#define CHACHA_QROUND_SSE2(v0, v1, v2, v3, t) \ + PADDL v1, v0; \ + PXOR v0, v3; \ + ROTL_SSE(16, t, v3); \ + PADDL v3, v2; \ + PXOR v2, v1; \ + ROTL_SSE(12, t, v1); \ + PADDL v1, v0; \ + PXOR v0, v3; \ + ROTL_SSE(8, t, v3); \ + PADDL v3, v2; \ + PXOR v2, v1; \ + ROTL_SSE(7, t, v1) + +// CHACHA_QROUND_SSSE3 performs a ChaCha quarter-round using the +// 4 XMM registers v0, v1, v2 and v3. It uses PSHUFB for 8/16 bit +// rotations. The XMM register t is used as a temp. register. +// +// r16 holds the PSHUFB constant for a 16 bit left rotate. +// r8 holds the PSHUFB constant for a 8 bit left rotate. +#define CHACHA_QROUND_SSSE3(v0, v1, v2, v3, t, r16, r8) \ + PADDL v1, v0; \ + PXOR v0, v3; \ + PSHUFB r16, v3; \ + PADDL v3, v2; \ + PXOR v2, v1; \ + ROTL_SSE(12, t, v1); \ + PADDL v1, v0; \ + PXOR v0, v3; \ + PSHUFB r8, v3; \ + PADDL v3, v2; \ + PXOR v2, v1; \ + ROTL_SSE(7, t, v1) + +// CHACHA_QROUND_AVX performs a ChaCha quarter-round using the +// 4 AVX/AVX2 registers v0, v1, v2 and v3. It uses VPSHUFB for 8/16 bit +// rotations. The AVX/AVX2 register t is used as a temp. register. +// +// r16 holds the VPSHUFB constant for a 16 bit left rotate. +// r8 holds the VPSHUFB constant for a 8 bit left rotate. +#define CHACHA_QROUND_AVX(v0, v1, v2, v3, t, r16, r8) \ + VPADDD v0, v1, v0; \ + VPXOR v3, v0, v3; \ + VPSHUFB r16, v3, v3; \ + VPADDD v2, v3, v2; \ + VPXOR v1, v2, v1; \ + ROTL_AVX(12, t, v1); \ + VPADDD v0, v1, v0; \ + VPXOR v3, v0, v3; \ + VPSHUFB r8, v3, v3; \ + VPADDD v2, v3, v2; \ + VPXOR v1, v2, v1; \ + ROTL_AVX(7, t, v1) + +// CHACHA_SHUFFLE_SSE performs a ChaCha shuffle using the +// 3 XMM registers v1, v2 and v3. The inverse shuffle is +// performed by switching v1 and v3: CHACHA_SHUFFLE_SSE(v3, v2, v1). +#define CHACHA_SHUFFLE_SSE(v1, v2, v3) \ + PSHUFL $0x39, v1, v1; \ + PSHUFL $0x4E, v2, v2; \ + PSHUFL $0x93, v3, v3 + +// CHACHA_SHUFFLE_AVX performs a ChaCha shuffle using the +// 3 AVX/AVX2 registers v1, v2 and v3. The inverse shuffle is +// performed by switching v1 and v3: CHACHA_SHUFFLE_AVX(v3, v2, v1). +#define CHACHA_SHUFFLE_AVX(v1, v2, v3) \ + VPSHUFD $0x39, v1, v1; \ + VPSHUFD $0x4E, v2, v2; \ + VPSHUFD $0x93, v3, v3 + +// XOR_SSE extracts 4x16 byte vectors from src at +// off, xors all vectors with the corresponding XMM +// register (v0 - v3) and writes the result to dst +// at off. +// The XMM register t is used as a temp. register. +#define XOR_SSE(dst, src, off, v0, v1, v2, v3, t) \ + MOVOU 0+off(src), t; \ + PXOR v0, t; \ + MOVOU t, 0+off(dst); \ + MOVOU 16+off(src), t; \ + PXOR v1, t; \ + MOVOU t, 16+off(dst); \ + MOVOU 32+off(src), t; \ + PXOR v2, t; \ + MOVOU t, 32+off(dst); \ + MOVOU 48+off(src), t; \ + PXOR v3, t; \ + MOVOU t, 48+off(dst) + +// XOR_AVX extracts 4x16 byte vectors from src at +// off, xors all vectors with the corresponding AVX +// register (v0 - v3) and writes the result to dst +// at off. +// The XMM register t is used as a temp. register. +#define XOR_AVX(dst, src, off, v0, v1, v2, v3, t) \ + VPXOR 0+off(src), v0, t; \ + VMOVDQU t, 0+off(dst); \ + VPXOR 16+off(src), v1, t; \ + VMOVDQU t, 16+off(dst); \ + VPXOR 32+off(src), v2, t; \ + VMOVDQU t, 32+off(dst); \ + VPXOR 48+off(src), v3, t; \ + VMOVDQU t, 48+off(dst) + +#define XOR_AVX2(dst, src, off, v0, v1, v2, v3, t0, t1) \ + VMOVDQU (0+off)(src), t0; \ + VPERM2I128 $32, v1, v0, t1; \ + VPXOR t0, t1, t0; \ + VMOVDQU t0, (0+off)(dst); \ + VMOVDQU (32+off)(src), t0; \ + VPERM2I128 $32, v3, v2, t1; \ + VPXOR t0, t1, t0; \ + VMOVDQU t0, (32+off)(dst); \ + VMOVDQU (64+off)(src), t0; \ + VPERM2I128 $49, v1, v0, t1; \ + VPXOR t0, t1, t0; \ + VMOVDQU t0, (64+off)(dst); \ + VMOVDQU (96+off)(src), t0; \ + VPERM2I128 $49, v3, v2, t1; \ + VPXOR t0, t1, t0; \ + VMOVDQU t0, (96+off)(dst) + +#define XOR_UPPER_AVX2(dst, src, off, v0, v1, v2, v3, t0, t1) \ + VMOVDQU (0+off)(src), t0; \ + VPERM2I128 $32, v1, v0, t1; \ + VPXOR t0, t1, t0; \ + VMOVDQU t0, (0+off)(dst); \ + VMOVDQU (32+off)(src), t0; \ + VPERM2I128 $32, v3, v2, t1; \ + VPXOR t0, t1, t0; \ + VMOVDQU t0, (32+off)(dst); \ + +#define EXTRACT_LOWER(dst, v0, v1, v2, v3, t0) \ + VPERM2I128 $49, v1, v0, t0; \ + VMOVDQU t0, 0(dst); \ + VPERM2I128 $49, v3, v2, t0; \ + VMOVDQU t0, 32(dst) diff --git a/vendor/github.com/aead/chacha20/chacha20.go b/vendor/github.com/aead/chacha20/chacha20.go new file mode 100644 index 0000000..df6ddd2 --- /dev/null +++ b/vendor/github.com/aead/chacha20/chacha20.go @@ -0,0 +1,41 @@ +// Copyright (c) 2016 Andreas Auernhammer. All rights reserved. +// Use of this source code is governed by a license that can be +// found in the LICENSE file. + +// Package chacha20 implements the ChaCha20 / XChaCha20 stream chipher. +// Notice that one specific key-nonce combination must be unique for all time. +// +// There are three versions of ChaCha20: +// - ChaCha20 with a 64 bit nonce (en/decrypt up to 2^64 * 64 bytes for one key-nonce combination) +// - ChaCha20 with a 96 bit nonce (en/decrypt up to 2^32 * 64 bytes (~256 GB) for one key-nonce combination) +// - XChaCha20 with a 192 bit nonce (en/decrypt up to 2^64 * 64 bytes for one key-nonce combination) +package chacha20 // import "github.com/aead/chacha20" + +import ( + "crypto/cipher" + + "github.com/aead/chacha20/chacha" +) + +// XORKeyStream crypts bytes from src to dst using the given nonce and key. +// The length of the nonce determinds the version of ChaCha20: +// - 8 bytes: ChaCha20 with a 64 bit nonce and a 2^64 * 64 byte period. +// - 12 bytes: ChaCha20 as defined in RFC 7539 and a 2^32 * 64 byte period. +// - 24 bytes: XChaCha20 with a 192 bit nonce and a 2^64 * 64 byte period. +// Src and dst may be the same slice but otherwise should not overlap. +// If len(dst) < len(src) this function panics. +// If the nonce is neither 64, 96 nor 192 bits long, this function panics. +func XORKeyStream(dst, src, nonce, key []byte) { + chacha.XORKeyStream(dst, src, nonce, key, 20) +} + +// NewCipher returns a new cipher.Stream implementing a ChaCha20 version. +// The nonce must be unique for one key for all time. +// The length of the nonce determinds the version of ChaCha20: +// - 8 bytes: ChaCha20 with a 64 bit nonce and a 2^64 * 64 byte period. +// - 12 bytes: ChaCha20 as defined in RFC 7539 and a 2^32 * 64 byte period. +// - 24 bytes: XChaCha20 with a 192 bit nonce and a 2^64 * 64 byte period. +// If the nonce is neither 64, 96 nor 192 bits long, a non-nil error is returned. +func NewCipher(nonce, key []byte) (cipher.Stream, error) { + return chacha.NewCipher(nonce, key, 20) +} diff --git a/vendor/github.com/btcsuite/btcd/blockchain/chainio.go b/vendor/github.com/btcsuite/btcd/blockchain/chainio.go index 8d76d3c..c456c00 100644 --- a/vendor/github.com/btcsuite/btcd/blockchain/chainio.go +++ b/vendor/github.com/btcsuite/btcd/blockchain/chainio.go @@ -1149,18 +1149,9 @@ func (b *BlockChain) initChainState() error { blockIndexBucket := dbTx.Metadata().Bucket(blockIndexBucketName) - // Determine how many blocks will be loaded into the index so we can - // allocate the right amount. - var blockCount int32 - cursor := blockIndexBucket.Cursor() - for ok := cursor.First(); ok; ok = cursor.Next() { - blockCount++ - } - blockNodes := make([]blockNode, blockCount) - var i int32 var lastNode *blockNode - cursor = blockIndexBucket.Cursor() + cursor := blockIndexBucket.Cursor() for ok := cursor.First(); ok; ok = cursor.Next() { header, status, err := deserializeBlockRow(cursor.Value()) if err != nil { @@ -1193,7 +1184,7 @@ func (b *BlockChain) initChainState() error { // Initialize the block node for the block, connect it, // and add it to the block index. - node := &blockNodes[i] + node := new(blockNode) initBlockNode(node, header, parent) node.status = status b.index.addNode(node) diff --git a/vendor/github.com/btcsuite/btcd/blockchain/utxoviewpoint.go b/vendor/github.com/btcsuite/btcd/blockchain/utxoviewpoint.go index 08005d2..b857658 100644 --- a/vendor/github.com/btcsuite/btcd/blockchain/utxoviewpoint.go +++ b/vendor/github.com/btcsuite/btcd/blockchain/utxoviewpoint.go @@ -111,6 +111,22 @@ func (entry *UtxoEntry) Clone() *UtxoEntry { } } +// NewUtxoEntry returns a new UtxoEntry built from the arguments. +func NewUtxoEntry( + txOut *wire.TxOut, blockHeight int32, isCoinbase bool) *UtxoEntry { + var cbFlag txoFlags + if isCoinbase { + cbFlag |= tfCoinBase + } + + return &UtxoEntry{ + amount: txOut.Value, + pkScript: txOut.PkScript, + blockHeight: blockHeight, + packedFlags: cbFlag, + } +} + // UtxoViewpoint represents a view into the set of unspent transaction outputs // from a specific point of view in the chain. For example, it could be for // the end of the main chain, some point in the history of the main chain, or diff --git a/vendor/github.com/btcsuite/btcd/btcec/field.go b/vendor/github.com/btcsuite/btcd/btcec/field.go index c2bb84b..98105ed 100644 --- a/vendor/github.com/btcsuite/btcd/btcec/field.go +++ b/vendor/github.com/btcsuite/btcd/btcec/field.go @@ -226,20 +226,24 @@ func (f *fieldVal) SetBytes(b *[32]byte) *fieldVal { return f } -// SetByteSlice packs the passed big-endian value into the internal field value -// representation. Only the first 32-bytes are used. As a result, it is up to -// the caller to ensure numbers of the appropriate size are used or the value -// will be truncated. +// SetByteSlice interprets the provided slice as a 256-bit big-endian unsigned +// integer (meaning it is truncated to the first 32 bytes), packs it into the +// internal field value representation, and returns the updated field value. +// +// Note that since passing a slice with more than 32 bytes is truncated, it is +// possible that the truncated value is less than the field prime. It is up to +// the caller to decide whether it needs to provide numbers of the appropriate +// size or if it is acceptable to use this function with the described +// truncation behavior. // // The field value is returned to support chaining. This enables syntax like: // f := new(fieldVal).SetByteSlice(byteSlice) func (f *fieldVal) SetByteSlice(b []byte) *fieldVal { var b32 [32]byte - for i := 0; i < len(b); i++ { - if i < 32 { - b32[i+(32-len(b))] = b[i] - } + if len(b) > 32 { + b = b[:32] } + copy(b32[32-len(b):], b) return f.SetBytes(&b32) } diff --git a/vendor/github.com/btcsuite/btcd/btcjson/btcdextcmds.go b/vendor/github.com/btcsuite/btcd/btcjson/btcdextcmds.go index 963ccb3..a3ca46b 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/btcdextcmds.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/btcdextcmds.go @@ -59,6 +59,23 @@ func NewDebugLevelCmd(levelSpec string) *DebugLevelCmd { } } +// GenerateToAddressCmd defines the generatetoaddress JSON-RPC command. +type GenerateToAddressCmd struct { + NumBlocks int64 + Address string + MaxTries *int64 `jsonrpcdefault:"1000000"` +} + +// NewGenerateToAddressCmd returns a new instance which can be used to issue a +// generatetoaddress JSON-RPC command. +func NewGenerateToAddressCmd(numBlocks int64, address string, maxTries *int64) *GenerateToAddressCmd { + return &GenerateToAddressCmd{ + NumBlocks: numBlocks, + Address: address, + MaxTries: maxTries, + } +} + // GenerateCmd defines the generate JSON-RPC command. type GenerateCmd struct { NumBlocks uint32 @@ -131,6 +148,7 @@ func init() { MustRegisterCmd("debuglevel", (*DebugLevelCmd)(nil), flags) MustRegisterCmd("node", (*NodeCmd)(nil), flags) MustRegisterCmd("generate", (*GenerateCmd)(nil), flags) + MustRegisterCmd("generatetoaddress", (*GenerateToAddressCmd)(nil), flags) MustRegisterCmd("getbestblock", (*GetBestBlockCmd)(nil), flags) MustRegisterCmd("getcurrentnet", (*GetCurrentNetCmd)(nil), flags) MustRegisterCmd("getheaders", (*GetHeadersCmd)(nil), flags) diff --git a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrcmds.go b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrcmds.go index 406357b..d66478c 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrcmds.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrcmds.go @@ -8,6 +8,7 @@ package btcjson import ( + "encoding/hex" "encoding/json" "fmt" @@ -63,10 +64,15 @@ type CreateRawTransactionCmd struct { // NewCreateRawTransactionCmd returns a new instance which can be used to issue // a createrawtransaction JSON-RPC command. // -// Amounts are in BTC. +// Amounts are in BTC. Passing in nil and the empty slice as inputs is equivalent, +// both gets interpreted as the empty slice. func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[string]float64, lockTime *int64) *CreateRawTransactionCmd { - + // to make sure we're serializing this to the empty list and not null, we + // explicitly initialize the list + if inputs == nil { + inputs = []TransactionInput{} + } return &CreateRawTransactionCmd{ Inputs: inputs, Amounts: amounts, @@ -74,6 +80,37 @@ func NewCreateRawTransactionCmd(inputs []TransactionInput, amounts map[string]fl } } +// FundRawTransactionOpts are the different options that can be passed to rawtransaction +type FundRawTransactionOpts struct { + ChangeAddress *string `json:"changeAddress,omitempty"` + ChangePosition *int `json:"changePosition,omitempty"` + ChangeType *string `json:"change_type,omitempty"` + IncludeWatching *bool `json:"includeWatching,omitempty"` + LockUnspents *bool `json:"lockUnspents,omitempty"` + FeeRate *float64 `json:"feeRate,omitempty"` // BTC/kB + SubtractFeeFromOutputs []int `json:"subtractFeeFromOutputs,omitempty"` + Replaceable *bool `json:"replaceable,omitempty"` + ConfTarget *int `json:"conf_target,omitempty"` + EstimateMode *EstimateSmartFeeMode `json:"estimate_mode,omitempty"` +} + +// FundRawTransactionCmd defines the fundrawtransaction JSON-RPC command +type FundRawTransactionCmd struct { + HexTx string + Options FundRawTransactionOpts + IsWitness *bool +} + +// NewFundRawTransactionCmd returns a new instance which can be used to issue +// a fundrawtransaction JSON-RPC command +func NewFundRawTransactionCmd(serializedTx []byte, opts FundRawTransactionOpts, isWitness *bool) *FundRawTransactionCmd { + return &FundRawTransactionCmd{ + HexTx: hex.EncodeToString(serializedTx), + Options: opts, + IsWitness: isWitness, + } +} + // DecodeRawTransactionCmd defines the decoderawtransaction JSON-RPC command. type DecodeRawTransactionCmd struct { HexTx string @@ -130,8 +167,7 @@ func NewGetBestBlockHashCmd() *GetBestBlockHashCmd { // GetBlockCmd defines the getblock JSON-RPC command. type GetBlockCmd struct { Hash string - Verbose *bool `jsonrpcdefault:"true"` - VerboseTx *bool `jsonrpcdefault:"false"` + Verbosity *int `jsonrpcdefault:"1"` } // NewGetBlockCmd returns a new instance which can be used to issue a getblock @@ -139,11 +175,10 @@ type GetBlockCmd struct { // // 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 { +func NewGetBlockCmd(hash string, verbosity *int) *GetBlockCmd { return &GetBlockCmd{ Hash: hash, - Verbose: verbose, - VerboseTx: verboseTx, + Verbosity: verbosity, } } @@ -193,6 +228,50 @@ func NewGetBlockHeaderCmd(hash string, verbose *bool) *GetBlockHeaderCmd { } } +// HashOrHeight defines a type that can be used as hash_or_height value in JSON-RPC commands. +type HashOrHeight struct { + Value interface{} +} + +// MarshalJSON implements the json.Marshaler interface +func (h HashOrHeight) MarshalJSON() ([]byte, error) { + return json.Marshal(h.Value) +} + +// UnmarshalJSON implements the json.Unmarshaler interface +func (h *HashOrHeight) UnmarshalJSON(data []byte) error { + var unmarshalled interface{} + if err := json.Unmarshal(data, &unmarshalled); err != nil { + return err + } + + switch v := unmarshalled.(type) { + case float64: + h.Value = int(v) + case string: + h.Value = v + default: + return fmt.Errorf("invalid hash_or_height value: %v", unmarshalled) + } + + return nil +} + +// GetBlockStatsCmd defines the getblockstats JSON-RPC command. +type GetBlockStatsCmd struct { + HashOrHeight HashOrHeight + Stats *[]string +} + +// NewGetBlockStatsCmd returns a new instance which can be used to issue a +// getblockstats JSON-RPC command. Either height or hash must be specified. +func NewGetBlockStatsCmd(hashOrHeight HashOrHeight, stats *[]string) *GetBlockStatsCmd { + return &GetBlockStatsCmd{ + HashOrHeight: hashOrHeight, + Stats: stats, + } +} + // 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. @@ -321,6 +400,24 @@ func NewGetChainTipsCmd() *GetChainTipsCmd { return &GetChainTipsCmd{} } +// GetChainTxStatsCmd defines the getchaintxstats JSON-RPC command. +type GetChainTxStatsCmd struct { + NBlocks *int32 + BlockHash *string +} + +// NewGetChainTxStatsCmd returns a new instance which can be used to issue a +// getchaintxstats JSON-RPC command. +// +// The parameters which are pointers indicate they are optional. Passing nil +// for optional parameters will use the default value. +func NewGetChainTxStatsCmd(nBlocks *int32, blockHash *string) *GetChainTxStatsCmd { + return &GetChainTxStatsCmd{ + NBlocks: nBlocks, + BlockHash: blockHash, + } +} + // GetConnectionCountCmd defines the getconnectioncount JSON-RPC command. type GetConnectionCountCmd struct{} @@ -791,6 +888,7 @@ func init() { MustRegisterCmd("addnode", (*AddNodeCmd)(nil), flags) MustRegisterCmd("createrawtransaction", (*CreateRawTransactionCmd)(nil), flags) + MustRegisterCmd("fundrawtransaction", (*FundRawTransactionCmd)(nil), flags) MustRegisterCmd("decoderawtransaction", (*DecodeRawTransactionCmd)(nil), flags) MustRegisterCmd("decodescript", (*DecodeScriptCmd)(nil), flags) MustRegisterCmd("getaddednodeinfo", (*GetAddedNodeInfoCmd)(nil), flags) @@ -800,10 +898,12 @@ func init() { MustRegisterCmd("getblockcount", (*GetBlockCountCmd)(nil), flags) MustRegisterCmd("getblockhash", (*GetBlockHashCmd)(nil), flags) MustRegisterCmd("getblockheader", (*GetBlockHeaderCmd)(nil), flags) + MustRegisterCmd("getblockstats", (*GetBlockStatsCmd)(nil), flags) MustRegisterCmd("getblocktemplate", (*GetBlockTemplateCmd)(nil), flags) MustRegisterCmd("getcfilter", (*GetCFilterCmd)(nil), flags) MustRegisterCmd("getcfilterheader", (*GetCFilterHeaderCmd)(nil), flags) MustRegisterCmd("getchaintips", (*GetChainTipsCmd)(nil), flags) + MustRegisterCmd("getchaintxstats", (*GetChainTxStatsCmd)(nil), flags) MustRegisterCmd("getconnectioncount", (*GetConnectionCountCmd)(nil), flags) MustRegisterCmd("getdifficulty", (*GetDifficultyCmd)(nil), flags) MustRegisterCmd("getgenerate", (*GetGenerateCmd)(nil), flags) diff --git a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrresults.go b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrresults.go index 7e6c710..a96319b 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrresults.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrresults.go @@ -4,7 +4,14 @@ package btcjson -import "encoding/json" +import ( + "bytes" + "encoding/hex" + "encoding/json" + + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" +) // GetBlockHeaderVerboseResult models the data from the getblockheader command when // the verbose flag is set. When the verbose flag is not set, getblockheader @@ -24,9 +31,44 @@ type GetBlockHeaderVerboseResult struct { NextHash string `json:"nextblockhash,omitempty"` } +// GetBlockStatsResult models the data from the getblockstats command. +type GetBlockStatsResult struct { + AverageFee int64 `json:"avgfee"` + AverageFeeRate int64 `json:"avgfeerate"` + AverageTxSize int64 `json:"avgtxsize"` + FeeratePercentiles []int64 `json:"feerate_percentiles"` + Hash string `json:"blockhash"` + Height int64 `json:"height"` + Ins int64 `json:"ins"` + MaxFee int64 `json:"maxfee"` + MaxFeeRate int64 `json:"maxfeerate"` + MaxTxSize int64 `json:"maxtxsize"` + MedianFee int64 `json:"medianfee"` + MedianTime int64 `json:"mediantime"` + MedianTxSize int64 `json:"mediantxsize"` + MinFee int64 `json:"minfee"` + MinFeeRate int64 `json:"minfeerate"` + MinTxSize int64 `json:"mintxsize"` + Outs int64 `json:"outs"` + SegWitTotalSize int64 `json:"swtotal_size"` + SegWitTotalWeight int64 `json:"swtotal_weight"` + SegWitTxs int64 `json:"swtxs"` + Subsidy int64 `json:"subsidy"` + Time int64 `json:"time"` + TotalOut int64 `json:"total_out"` + TotalSize int64 `json:"total_size"` + TotalWeight int64 `json:"total_weight"` + Txs int64 `json:"txs"` + UTXOIncrease int64 `json:"utxo_increase"` + UTXOSizeIncrease int64 `json:"utxo_size_inc"` +} + // 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. +// verbose flag is set to 1. When the verbose flag is set to 0, getblock returns a +// hex-encoded string. When the verbose flag is set to 1, getblock returns an object +// whose tx field is an array of transaction hashes. When the verbose flag is set to 2, +// getblock returns an object whose tx field is an array of raw transactions. +// Use GetBlockVerboseTxResult to unmarshal data received from passing verbose=2 to getblock. type GetBlockVerboseResult struct { Hash string `json:"hash"` Confirmations int64 `json:"confirmations"` @@ -38,7 +80,7 @@ type GetBlockVerboseResult struct { VersionHex string `json:"versionHex"` MerkleRoot string `json:"merkleroot"` Tx []string `json:"tx,omitempty"` - RawTx []TxRawResult `json:"rawtx,omitempty"` + RawTx []TxRawResult `json:"rawtx,omitempty"` // Note: this field is always empty when verbose != 2. Time int64 `json:"time"` Nonce uint32 `json:"nonce"` Bits string `json:"bits"` @@ -47,6 +89,43 @@ type GetBlockVerboseResult struct { NextHash string `json:"nextblockhash,omitempty"` } +// GetBlockVerboseTxResult models the data from the getblock command when the +// verbose flag is set to 2. When the verbose flag is set to 0, getblock returns a +// hex-encoded string. When the verbose flag is set to 1, getblock returns an object +// whose tx field is an array of transaction hashes. When the verbose flag is set to 2, +// getblock returns an object whose tx field is an array of raw transactions. +// Use GetBlockVerboseResult to unmarshal data received from passing verbose=1 to getblock. +type GetBlockVerboseTxResult 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 []TxRawResult `json:"tx,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"` +} + +// GetChainTxStatsResult models the data from the getchaintxstats command. +type GetChainTxStatsResult struct { + Time int64 `json:"time"` + TxCount int64 `json:"txcount"` + WindowFinalBlockHash string `json:"window_final_block_hash"` + WindowFinalBlockHeight int32 `json:"window_final_block_height"` + WindowBlockCount int32 `json:"window_block_count"` + WindowTxCount int32 `json:"window_tx_count"` + WindowInterval int32 `json:"window_interval"` + TxRate float64 `json:"txrate"` +} + // CreateMultiSigResult models the data returned from the createmultisig // command. type CreateMultiSigResult struct { @@ -206,23 +285,35 @@ type GetBlockTemplateResult struct { RejectReasion string `json:"reject-reason,omitempty"` } +// GetMempoolEntryResult models the data returned from the getmempoolentry's +// fee field + +type MempoolFees struct { + Base float64 `json:"base"` + Modified float64 `json:"modified"` + Ancestor float64 `json:"ancestor"` + Descendant float64 `json:"descendant"` +} + // 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"` + VSize int32 `json:"vsize"` + Size int32 `json:"size"` + Weight int64 `json:"weight"` + Fee float64 `json:"fee"` + ModifiedFee float64 `json:"modifiedfee"` + Time int64 `json:"time"` + Height int64 `json:"height"` + DescendantCount int64 `json:"descendantcount"` + DescendantSize int64 `json:"descendantsize"` + DescendantFees float64 `json:"descendantfees"` + AncestorCount int64 `json:"ancestorcount"` + AncestorSize int64 `json:"ancestorsize"` + AncestorFees float64 `json:"ancestorfees"` + WTxId string `json:"wtxid"` + Fees MempoolFees `json:"fees"` + Depends []string `json:"depends"` } // GetMempoolInfoResult models the data returned from the getmempoolinfo @@ -584,3 +675,58 @@ type ValidateAddressChainResult struct { IsValid bool `json:"isvalid"` Address string `json:"address,omitempty"` } + +// EstimateSmartFeeResult models the data returned buy the chain server +// estimatesmartfee command +type EstimateSmartFeeResult struct { + FeeRate *float64 `json:"feerate,omitempty"` + Errors []string `json:"errors,omitempty"` + Blocks int64 `json:"blocks"` +} + +var _ json.Unmarshaler = &FundRawTransactionResult{} + +type rawFundRawTransactionResult struct { + Transaction string `json:"hex"` + Fee float64 `json:"fee"` + ChangePosition int `json:"changepos"` +} + +// FundRawTransactionResult is the result of the fundrawtransaction JSON-RPC call +type FundRawTransactionResult struct { + Transaction *wire.MsgTx + Fee btcutil.Amount + ChangePosition int // the position of the added change output, or -1 +} + +// UnmarshalJSON unmarshals the result of the fundrawtransaction JSON-RPC call +func (f *FundRawTransactionResult) UnmarshalJSON(data []byte) error { + var rawRes rawFundRawTransactionResult + if err := json.Unmarshal(data, &rawRes); err != nil { + return err + } + + txBytes, err := hex.DecodeString(rawRes.Transaction) + if err != nil { + return err + } + + var msgTx wire.MsgTx + witnessErr := msgTx.Deserialize(bytes.NewReader(txBytes)) + if witnessErr != nil { + legacyErr := msgTx.DeserializeNoWitness(bytes.NewReader(txBytes)) + if legacyErr != nil { + return legacyErr + } + } + + fee, err := btcutil.NewAmount(rawRes.Fee) + if err != nil { + return err + } + + f.Transaction = &msgTx + f.Fee = fee + f.ChangePosition = rawRes.ChangePosition + return nil +} diff --git a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwscmds.go b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwscmds.go index bf973e2..dfe499e 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwscmds.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwscmds.go @@ -80,7 +80,7 @@ func NewStopNotifyNewTransactionsCmd() *StopNotifyNewTransactionsCmd { // NotifyReceivedCmd defines the notifyreceived JSON-RPC command. // -// NOTE: Deprecated. Use LoadTxFilterCmd instead. +// Deprecated: Use LoadTxFilterCmd instead. type NotifyReceivedCmd struct { Addresses []string } @@ -88,7 +88,7 @@ type NotifyReceivedCmd struct { // NewNotifyReceivedCmd returns a new instance which can be used to issue a // notifyreceived JSON-RPC command. // -// NOTE: Deprecated. Use NewLoadTxFilterCmd instead. +// Deprecated: Use NewLoadTxFilterCmd instead. func NewNotifyReceivedCmd(addresses []string) *NotifyReceivedCmd { return &NotifyReceivedCmd{ Addresses: addresses, @@ -128,7 +128,7 @@ func NewLoadTxFilterCmd(reload bool, addresses []string, outPoints []OutPoint) * // NotifySpentCmd defines the notifyspent JSON-RPC command. // -// NOTE: Deprecated. Use LoadTxFilterCmd instead. +// Deprecated: Use LoadTxFilterCmd instead. type NotifySpentCmd struct { OutPoints []OutPoint } @@ -136,7 +136,7 @@ type NotifySpentCmd struct { // NewNotifySpentCmd returns a new instance which can be used to issue a // notifyspent JSON-RPC command. // -// NOTE: Deprecated. Use NewLoadTxFilterCmd instead. +// Deprecated: Use NewLoadTxFilterCmd instead. func NewNotifySpentCmd(outPoints []OutPoint) *NotifySpentCmd { return &NotifySpentCmd{ OutPoints: outPoints, @@ -145,7 +145,7 @@ func NewNotifySpentCmd(outPoints []OutPoint) *NotifySpentCmd { // StopNotifyReceivedCmd defines the stopnotifyreceived JSON-RPC command. // -// NOTE: Deprecated. Use LoadTxFilterCmd instead. +// Deprecated: Use LoadTxFilterCmd instead. type StopNotifyReceivedCmd struct { Addresses []string } @@ -153,7 +153,7 @@ type StopNotifyReceivedCmd struct { // NewStopNotifyReceivedCmd returns a new instance which can be used to issue a // stopnotifyreceived JSON-RPC command. // -// NOTE: Deprecated. Use NewLoadTxFilterCmd instead. +// Deprecated: Use NewLoadTxFilterCmd instead. func NewStopNotifyReceivedCmd(addresses []string) *StopNotifyReceivedCmd { return &StopNotifyReceivedCmd{ Addresses: addresses, @@ -162,7 +162,7 @@ func NewStopNotifyReceivedCmd(addresses []string) *StopNotifyReceivedCmd { // StopNotifySpentCmd defines the stopnotifyspent JSON-RPC command. // -// NOTE: Deprecated. Use LoadTxFilterCmd instead. +// Deprecated: Use LoadTxFilterCmd instead. type StopNotifySpentCmd struct { OutPoints []OutPoint } @@ -170,7 +170,7 @@ type StopNotifySpentCmd struct { // NewStopNotifySpentCmd returns a new instance which can be used to issue a // stopnotifyspent JSON-RPC command. // -// NOTE: Deprecated. Use NewLoadTxFilterCmd instead. +// Deprecated: Use NewLoadTxFilterCmd instead. func NewStopNotifySpentCmd(outPoints []OutPoint) *StopNotifySpentCmd { return &StopNotifySpentCmd{ OutPoints: outPoints, @@ -179,7 +179,7 @@ func NewStopNotifySpentCmd(outPoints []OutPoint) *StopNotifySpentCmd { // RescanCmd defines the rescan JSON-RPC command. // -// NOTE: Deprecated. Use RescanBlocksCmd instead. +// Deprecated: Use RescanBlocksCmd instead. type RescanCmd struct { BeginBlock string Addresses []string @@ -193,7 +193,7 @@ type RescanCmd struct { // The parameters which are pointers indicate they are optional. Passing nil // for optional parameters will use the default value. // -// NOTE: Deprecated. Use NewRescanBlocksCmd instead. +// Deprecated: Use NewRescanBlocksCmd instead. func NewRescanCmd(beginBlock string, addresses []string, outPoints []OutPoint, endBlock *string) *RescanCmd { return &RescanCmd{ BeginBlock: beginBlock, diff --git a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsntfns.go b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsntfns.go index 1f15623..58b7a54 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsntfns.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/chainsvrwsntfns.go @@ -12,14 +12,14 @@ 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. + // 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. + // Deprecated: Use FilteredBlockDisconnectedNtfnMethod instead. BlockDisconnectedNtfnMethod = "blockdisconnected" // FilteredBlockConnectedNtfnMethod is the new method used for @@ -35,7 +35,7 @@ const ( // notifications from the chain server that a transaction which pays to // a registered address has been processed. // - // NOTE: Deprecated. Use RelevantTxAcceptedNtfnMethod and + // Deprecated: Use RelevantTxAcceptedNtfnMethod and // FilteredBlockConnectedNtfnMethod instead. RecvTxNtfnMethod = "recvtx" @@ -43,7 +43,7 @@ const ( // notifications from the chain server that a transaction which spends a // registered outpoint has been processed. // - // NOTE: Deprecated. Use RelevantTxAcceptedNtfnMethod and + // Deprecated: Use RelevantTxAcceptedNtfnMethod and // FilteredBlockConnectedNtfnMethod instead. RedeemingTxNtfnMethod = "redeemingtx" @@ -51,14 +51,14 @@ const ( // notifications from the chain server that a legacy, deprecated rescan // operation has finished. // - // NOTE: Deprecated. Not used with rescanblocks command. + // 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. + // Deprecated: Not used with rescanblocks command. RescanProgressNtfnMethod = "rescanprogress" // TxAcceptedNtfnMethod is the method used for notifications from the @@ -79,7 +79,7 @@ const ( // BlockConnectedNtfn defines the blockconnected JSON-RPC notification. // -// NOTE: Deprecated. Use FilteredBlockConnectedNtfn instead. +// Deprecated: Use FilteredBlockConnectedNtfn instead. type BlockConnectedNtfn struct { Hash string Height int32 @@ -89,7 +89,7 @@ type BlockConnectedNtfn struct { // NewBlockConnectedNtfn returns a new instance which can be used to issue a // blockconnected JSON-RPC notification. // -// NOTE: Deprecated. Use NewFilteredBlockConnectedNtfn instead. +// Deprecated: Use NewFilteredBlockConnectedNtfn instead. func NewBlockConnectedNtfn(hash string, height int32, time int64) *BlockConnectedNtfn { return &BlockConnectedNtfn{ Hash: hash, @@ -100,7 +100,7 @@ func NewBlockConnectedNtfn(hash string, height int32, time int64) *BlockConnecte // BlockDisconnectedNtfn defines the blockdisconnected JSON-RPC notification. // -// NOTE: Deprecated. Use FilteredBlockDisconnectedNtfn instead. +// Deprecated: Use FilteredBlockDisconnectedNtfn instead. type BlockDisconnectedNtfn struct { Hash string Height int32 @@ -110,7 +110,7 @@ type BlockDisconnectedNtfn struct { // NewBlockDisconnectedNtfn returns a new instance which can be used to issue a // blockdisconnected JSON-RPC notification. // -// NOTE: Deprecated. Use NewFilteredBlockDisconnectedNtfn instead. +// Deprecated: Use NewFilteredBlockDisconnectedNtfn instead. func NewBlockDisconnectedNtfn(hash string, height int32, time int64) *BlockDisconnectedNtfn { return &BlockDisconnectedNtfn{ Hash: hash, @@ -163,7 +163,7 @@ type BlockDetails struct { // RecvTxNtfn defines the recvtx JSON-RPC notification. // -// NOTE: Deprecated. Use RelevantTxAcceptedNtfn and FilteredBlockConnectedNtfn +// Deprecated: Use RelevantTxAcceptedNtfn and FilteredBlockConnectedNtfn // instead. type RecvTxNtfn struct { HexTx string @@ -173,7 +173,7 @@ type RecvTxNtfn struct { // NewRecvTxNtfn returns a new instance which can be used to issue a recvtx // JSON-RPC notification. // -// NOTE: Deprecated. Use NewRelevantTxAcceptedNtfn and +// Deprecated: Use NewRelevantTxAcceptedNtfn and // NewFilteredBlockConnectedNtfn instead. func NewRecvTxNtfn(hexTx string, block *BlockDetails) *RecvTxNtfn { return &RecvTxNtfn{ @@ -184,7 +184,7 @@ func NewRecvTxNtfn(hexTx string, block *BlockDetails) *RecvTxNtfn { // RedeemingTxNtfn defines the redeemingtx JSON-RPC notification. // -// NOTE: Deprecated. Use RelevantTxAcceptedNtfn and FilteredBlockConnectedNtfn +// Deprecated: Use RelevantTxAcceptedNtfn and FilteredBlockConnectedNtfn // instead. type RedeemingTxNtfn struct { HexTx string @@ -194,7 +194,7 @@ type RedeemingTxNtfn struct { // NewRedeemingTxNtfn returns a new instance which can be used to issue a // redeemingtx JSON-RPC notification. // -// NOTE: Deprecated. Use NewRelevantTxAcceptedNtfn and +// Deprecated: Use NewRelevantTxAcceptedNtfn and // NewFilteredBlockConnectedNtfn instead. func NewRedeemingTxNtfn(hexTx string, block *BlockDetails) *RedeemingTxNtfn { return &RedeemingTxNtfn{ @@ -205,7 +205,7 @@ func NewRedeemingTxNtfn(hexTx string, block *BlockDetails) *RedeemingTxNtfn { // RescanFinishedNtfn defines the rescanfinished JSON-RPC notification. // -// NOTE: Deprecated. Not used with rescanblocks command. +// Deprecated: Not used with rescanblocks command. type RescanFinishedNtfn struct { Hash string Height int32 @@ -215,7 +215,7 @@ type RescanFinishedNtfn struct { // NewRescanFinishedNtfn returns a new instance which can be used to issue a // rescanfinished JSON-RPC notification. // -// NOTE: Deprecated. Not used with rescanblocks command. +// Deprecated: Not used with rescanblocks command. func NewRescanFinishedNtfn(hash string, height int32, time int64) *RescanFinishedNtfn { return &RescanFinishedNtfn{ Hash: hash, @@ -226,7 +226,7 @@ func NewRescanFinishedNtfn(hash string, height int32, time int64) *RescanFinishe // RescanProgressNtfn defines the rescanprogress JSON-RPC notification. // -// NOTE: Deprecated. Not used with rescanblocks command. +// Deprecated: Not used with rescanblocks command. type RescanProgressNtfn struct { Hash string Height int32 @@ -236,7 +236,7 @@ type RescanProgressNtfn struct { // NewRescanProgressNtfn returns a new instance which can be used to issue a // rescanprogress JSON-RPC notification. // -// NOTE: Deprecated. Not used with rescanblocks command. +// Deprecated: Not used with rescanblocks command. func NewRescanProgressNtfn(hash string, height int32, time int64) *RescanProgressNtfn { return &RescanProgressNtfn{ Hash: hash, diff --git a/vendor/github.com/btcsuite/btcd/btcjson/jsonrpc.go b/vendor/github.com/btcsuite/btcd/btcjson/jsonrpc.go index e99d9f4..0ead85e 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/jsonrpc.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/jsonrpc.go @@ -22,10 +22,10 @@ type RPCError struct { Message string `json:"message,omitempty"` } -// Guarantee RPCError satisifies the builtin error interface. +// Guarantee RPCError satisfies the builtin error interface. var _, _ error = RPCError{}, (*RPCError)(nil) -// Error returns a string describing the RPC error. This satisifies the +// Error returns a string describing the RPC error. This satisfies the // builtin error interface. func (e RPCError) Error() string { return fmt.Sprintf("%d: %s", e.Code, e.Message) diff --git a/vendor/github.com/btcsuite/btcd/btcjson/jsonrpcerr.go b/vendor/github.com/btcsuite/btcd/btcjson/jsonrpcerr.go index 8996c47..ea62fb5 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/jsonrpcerr.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/jsonrpcerr.go @@ -39,6 +39,7 @@ const ( ErrRPCDatabase RPCErrorCode = -20 ErrRPCDeserialization RPCErrorCode = -22 ErrRPCVerify RPCErrorCode = -25 + ErrRPCInWarmup RPCErrorCode = -28 ) // Peer-to-peer client errors. diff --git a/vendor/github.com/btcsuite/btcd/btcjson/register.go b/vendor/github.com/btcsuite/btcd/btcjson/register.go index 5de001c..10cd0f9 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/register.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/register.go @@ -287,6 +287,6 @@ func RegisteredCmdMethods() []string { methods = append(methods, k) } - sort.Sort(sort.StringSlice(methods)) + sort.Strings(methods) return methods } diff --git a/vendor/github.com/btcsuite/btcd/btcjson/walletsvrcmds.go b/vendor/github.com/btcsuite/btcd/btcjson/walletsvrcmds.go index 6697555..be1a67f 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/walletsvrcmds.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/walletsvrcmds.go @@ -81,6 +81,30 @@ func NewEncryptWalletCmd(passphrase string) *EncryptWalletCmd { } } +// EstimateSmartFeeMode defines the different fee estimation modes available +// for the estimatesmartfee JSON-RPC command. +type EstimateSmartFeeMode string + +var ( + EstimateModeUnset EstimateSmartFeeMode = "UNSET" + EstimateModeEconomical EstimateSmartFeeMode = "ECONOMICAL" + EstimateModeConservative EstimateSmartFeeMode = "CONSERVATIVE" +) + +// EstimateSmartFeeCmd defines the estimatesmartfee JSON-RPC command. +type EstimateSmartFeeCmd struct { + ConfTarget int64 + EstimateMode *EstimateSmartFeeMode `jsonrpcdefault:"\"CONSERVATIVE\""` +} + +// NewEstimateSmartFeeCmd returns a new instance which can be used to issue a +// estimatesmartfee JSON-RPC command. +func NewEstimateSmartFeeCmd(confTarget int64, mode *EstimateSmartFeeMode) *EstimateSmartFeeCmd { + return &EstimateSmartFeeCmd{ + ConfTarget: confTarget, EstimateMode: mode, + } +} + // EstimateFeeCmd defines the estimatefee JSON-RPC command. type EstimateFeeCmd struct { NumBlocks int64 @@ -164,6 +188,15 @@ func NewGetBalanceCmd(account *string, minConf *int) *GetBalanceCmd { } } +// GetBalancesCmd defines the getbalances JSON-RPC command. +type GetBalancesCmd struct{} + +// NewGetBalancesCmd returns a new instance which can be used to issue a +// getbalances JSON-RPC command. +func NewGetBalancesCmd() *GetBalancesCmd { + return &GetBalancesCmd{} +} + // GetNewAddressCmd defines the getnewaddress JSON-RPC command. type GetNewAddressCmd struct { Account *string @@ -662,12 +695,14 @@ func init() { MustRegisterCmd("createmultisig", (*CreateMultisigCmd)(nil), flags) MustRegisterCmd("dumpprivkey", (*DumpPrivKeyCmd)(nil), flags) MustRegisterCmd("encryptwallet", (*EncryptWalletCmd)(nil), flags) + MustRegisterCmd("estimatesmartfee", (*EstimateSmartFeeCmd)(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("getbalances", (*GetBalancesCmd)(nil), flags) MustRegisterCmd("getnewaddress", (*GetNewAddressCmd)(nil), flags) MustRegisterCmd("getrawchangeaddress", (*GetRawChangeAddressCmd)(nil), flags) MustRegisterCmd("getreceivedbyaccount", (*GetReceivedByAccountCmd)(nil), flags) diff --git a/vendor/github.com/btcsuite/btcd/btcjson/walletsvrresults.go b/vendor/github.com/btcsuite/btcd/btcjson/walletsvrresults.go index 9246d13..6e69ed9 100644 --- a/vendor/github.com/btcsuite/btcd/btcjson/walletsvrresults.go +++ b/vendor/github.com/btcsuite/btcd/btcjson/walletsvrresults.go @@ -159,3 +159,17 @@ type GetBestBlockResult struct { Hash string `json:"hash"` Height int32 `json:"height"` } + +// BalanceDetailsResult models the details data from the `getbalances` command. +type BalanceDetailsResult struct { + Trusted float64 `json:"trusted"` + UntrustedPending float64 `json:"untrusted_pending"` + Immature float64 `json:"immature"` + Used *float64 `json:"used"` +} + +// GetBalancesResult models the data returned from the getbalances command. +type GetBalancesResult struct { + Mine BalanceDetailsResult `json:"mine"` + WatchOnly *BalanceDetailsResult `json:"watchonly"` +} diff --git a/vendor/github.com/btcsuite/btcd/connmgr/dynamicbanscore.go b/vendor/github.com/btcsuite/btcd/connmgr/dynamicbanscore.go index bc3c2a4..38180ba 100644 --- a/vendor/github.com/btcsuite/btcd/connmgr/dynamicbanscore.go +++ b/vendor/github.com/btcsuite/btcd/connmgr/dynamicbanscore.go @@ -71,7 +71,7 @@ type DynamicBanScore struct { func (s *DynamicBanScore) String() string { s.mtx.Lock() r := fmt.Sprintf("persistent %v + transient %v at %v = %v as of now", - s.persistent, s.transient, s.lastUnix, s.Int()) + s.persistent, s.transient, s.lastUnix, s.int(time.Now())) s.mtx.Unlock() return r } diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/README.md b/vendor/github.com/btcsuite/btcd/integration/rpctest/README.md new file mode 100644 index 0000000..fceeed2 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/README.md @@ -0,0 +1,30 @@ +rpctest +======= + +[![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/integration/rpctest) + +Package rpctest provides a btcd-specific RPC testing harness crafting and +executing integration tests by driving a `btcd` instance via the `RPC` +interface. Each instance of an active harness comes equipped with a simple +in-memory HD wallet capable of properly syncing to the generated chain, +creating new addresses, and crafting fully signed transactions paying to an +arbitrary set of outputs. + +This package was designed specifically to act as an RPC testing harness for +`btcd`. However, the constructs presented are general enough to be adapted to +any project wishing to programmatically drive a `btcd` instance of its +systems/integration tests. + +## Installation and Updating + +```bash +$ go get -u github.com/btcsuite/btcd/integration/rpctest +``` + +## License + +Package rpctest is licensed under the [copyfree](http://copyfree.org) ISC +License. + diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/blockgen.go b/vendor/github.com/btcsuite/btcd/integration/rpctest/blockgen.go new file mode 100644 index 0000000..de5821b --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/blockgen.go @@ -0,0 +1,207 @@ +// 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 rpctest + +import ( + "errors" + "math" + "math/big" + "runtime" + "time" + + "github.com/btcsuite/btcd/blockchain" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" +) + +// solveBlock attempts to find a nonce which makes the passed block header hash +// to a value less than the target difficulty. When a successful solution is +// found true is returned and the nonce field of the passed header is updated +// with the solution. False is returned if no solution exists. +func solveBlock(header *wire.BlockHeader, targetDifficulty *big.Int) bool { + // sbResult is used by the solver goroutines to send results. + type sbResult struct { + found bool + nonce uint32 + } + + // solver accepts a block header and a nonce range to test. It is + // intended to be run as a goroutine. + quit := make(chan bool) + results := make(chan sbResult) + solver := func(hdr wire.BlockHeader, startNonce, stopNonce uint32) { + // We need to modify the nonce field of the header, so make sure + // we work with a copy of the original header. + for i := startNonce; i >= startNonce && i <= stopNonce; i++ { + select { + case <-quit: + return + default: + hdr.Nonce = i + hash := hdr.BlockHash() + if blockchain.HashToBig(&hash).Cmp(targetDifficulty) <= 0 { + select { + case results <- sbResult{true, i}: + return + case <-quit: + return + } + } + } + } + select { + case results <- sbResult{false, 0}: + case <-quit: + return + } + } + + startNonce := uint32(0) + stopNonce := uint32(math.MaxUint32) + numCores := uint32(runtime.NumCPU()) + noncesPerCore := (stopNonce - startNonce) / numCores + for i := uint32(0); i < numCores; i++ { + rangeStart := startNonce + (noncesPerCore * i) + rangeStop := startNonce + (noncesPerCore * (i + 1)) - 1 + if i == numCores-1 { + rangeStop = stopNonce + } + go solver(*header, rangeStart, rangeStop) + } + for i := uint32(0); i < numCores; i++ { + result := <-results + if result.found { + close(quit) + header.Nonce = result.nonce + return true + } + } + + return false +} + +// standardCoinbaseScript returns a standard script suitable for use as the +// signature script of the coinbase transaction of a new block. In particular, +// it starts with the block height that is required by version 2 blocks. +func standardCoinbaseScript(nextBlockHeight int32, extraNonce uint64) ([]byte, error) { + return txscript.NewScriptBuilder().AddInt64(int64(nextBlockHeight)). + AddInt64(int64(extraNonce)).Script() +} + +// createCoinbaseTx returns a coinbase transaction paying an appropriate +// subsidy based on the passed block height to the provided address. +func createCoinbaseTx(coinbaseScript []byte, nextBlockHeight int32, + addr btcutil.Address, mineTo []wire.TxOut, + net *chaincfg.Params) (*btcutil.Tx, error) { + + // Create the script to pay to the provided payment address. + pkScript, err := txscript.PayToAddrScript(addr) + if err != nil { + return nil, err + } + + tx := wire.NewMsgTx(wire.TxVersion) + tx.AddTxIn(&wire.TxIn{ + // Coinbase transactions have no inputs, so previous outpoint is + // zero hash and max index. + PreviousOutPoint: *wire.NewOutPoint(&chainhash.Hash{}, + wire.MaxPrevOutIndex), + SignatureScript: coinbaseScript, + Sequence: wire.MaxTxInSequenceNum, + }) + if len(mineTo) == 0 { + tx.AddTxOut(&wire.TxOut{ + Value: blockchain.CalcBlockSubsidy(nextBlockHeight, net), + PkScript: pkScript, + }) + } else { + for i := range mineTo { + tx.AddTxOut(&mineTo[i]) + } + } + return btcutil.NewTx(tx), nil +} + +// CreateBlock creates a new block building from the previous block with a +// specified blockversion and timestamp. If the timestamp passed is zero (not +// initialized), then the timestamp of the previous block will be used plus 1 +// second is used. Passing nil for the previous block results in a block that +// builds off of the genesis block for the specified chain. +func CreateBlock(prevBlock *btcutil.Block, inclusionTxs []*btcutil.Tx, + blockVersion int32, blockTime time.Time, miningAddr btcutil.Address, + mineTo []wire.TxOut, net *chaincfg.Params) (*btcutil.Block, error) { + + var ( + prevHash *chainhash.Hash + blockHeight int32 + prevBlockTime time.Time + ) + + // If the previous block isn't specified, then we'll construct a block + // that builds off of the genesis block for the chain. + if prevBlock == nil { + prevHash = net.GenesisHash + blockHeight = 1 + prevBlockTime = net.GenesisBlock.Header.Timestamp.Add(time.Minute) + } else { + prevHash = prevBlock.Hash() + blockHeight = prevBlock.Height() + 1 + prevBlockTime = prevBlock.MsgBlock().Header.Timestamp + } + + // If a target block time was specified, then use that as the header's + // timestamp. Otherwise, add one second to the previous block unless + // it's the genesis block in which case use the current time. + var ts time.Time + switch { + case !blockTime.IsZero(): + ts = blockTime + default: + ts = prevBlockTime.Add(time.Second) + } + + extraNonce := uint64(0) + coinbaseScript, err := standardCoinbaseScript(blockHeight, extraNonce) + if err != nil { + return nil, err + } + coinbaseTx, err := createCoinbaseTx(coinbaseScript, blockHeight, + miningAddr, mineTo, net) + if err != nil { + return nil, err + } + + // Create a new block ready to be solved. + blockTxns := []*btcutil.Tx{coinbaseTx} + if inclusionTxs != nil { + blockTxns = append(blockTxns, inclusionTxs...) + } + merkles := blockchain.BuildMerkleTreeStore(blockTxns, false) + var block wire.MsgBlock + block.Header = wire.BlockHeader{ + Version: blockVersion, + PrevBlock: *prevHash, + MerkleRoot: *merkles[len(merkles)-1], + Timestamp: ts, + Bits: net.PowLimitBits, + } + for _, tx := range blockTxns { + if err := block.AddTransaction(tx.MsgTx()); err != nil { + return nil, err + } + } + + found := solveBlock(&block.Header, net.PowLimit) + if !found { + return nil, errors.New("Unable to solve block") + } + + utilBlock := btcutil.NewBlock(&block) + utilBlock.SetHeight(blockHeight) + return utilBlock, nil +} diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/btcd.go b/vendor/github.com/btcsuite/btcd/integration/rpctest/btcd.go new file mode 100644 index 0000000..29642c8 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/btcd.go @@ -0,0 +1,62 @@ +// 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 rpctest + +import ( + "fmt" + "os/exec" + "path/filepath" + "runtime" + "sync" +) + +var ( + // compileMtx guards access to the executable path so that the project is + // only compiled once. + compileMtx sync.Mutex + + // executablePath is the path to the compiled executable. This is the empty + // string until btcd is compiled. This should not be accessed directly; + // instead use the function btcdExecutablePath(). + executablePath string +) + +// btcdExecutablePath returns a path to the btcd executable to be used by +// rpctests. To ensure the code tests against the most up-to-date version of +// btcd, this method compiles btcd the first time it is called. After that, the +// generated binary is used for subsequent test harnesses. The executable file +// is not cleaned up, but since it lives at a static path in a temp directory, +// it is not a big deal. +func btcdExecutablePath() (string, error) { + compileMtx.Lock() + defer compileMtx.Unlock() + + // If btcd has already been compiled, just use that. + if len(executablePath) != 0 { + return executablePath, nil + } + + testDir, err := baseDir() + if err != nil { + return "", err + } + + // Build btcd and output an executable in a static temp path. + outputPath := filepath.Join(testDir, "btcd") + if runtime.GOOS == "windows" { + outputPath += ".exe" + } + cmd := exec.Command( + "go", "build", "-o", outputPath, "github.com/btcsuite/btcd", + ) + err = cmd.Run() + if err != nil { + return "", fmt.Errorf("Failed to build btcd: %v", err) + } + + // Save executable path so future calls do not recompile. + executablePath = outputPath + return executablePath, nil +} diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/doc.go b/vendor/github.com/btcsuite/btcd/integration/rpctest/doc.go new file mode 100644 index 0000000..3601b55 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/doc.go @@ -0,0 +1,12 @@ +// Package rpctest provides a btcd-specific RPC testing harness crafting and +// executing integration tests by driving a `btcd` instance via the `RPC` +// interface. Each instance of an active harness comes equipped with a simple +// in-memory HD wallet capable of properly syncing to the generated chain, +// creating new addresses, and crafting fully signed transactions paying to an +// arbitrary set of outputs. +// +// This package was designed specifically to act as an RPC testing harness for +// `btcd`. However, the constructs presented are general enough to be adapted to +// any project wishing to programmatically drive a `btcd` instance of its +// systems/integration tests. +package rpctest diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/memwallet.go b/vendor/github.com/btcsuite/btcd/integration/rpctest/memwallet.go new file mode 100644 index 0000000..f161307 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/memwallet.go @@ -0,0 +1,591 @@ +// 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 rpctest + +import ( + "bytes" + "encoding/binary" + "fmt" + "sync" + + "github.com/btcsuite/btcd/blockchain" + "github.com/btcsuite/btcd/btcec" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcutil/hdkeychain" +) + +var ( + // hdSeed is the BIP 32 seed used by the memWallet to initialize it's + // HD root key. This value is hard coded in order to ensure + // deterministic behavior across test runs. + hdSeed = [chainhash.HashSize]byte{ + 0x79, 0xa6, 0x1a, 0xdb, 0xc6, 0xe5, 0xa2, 0xe1, + 0x39, 0xd2, 0x71, 0x3a, 0x54, 0x6e, 0xc7, 0xc8, + 0x75, 0x63, 0x2e, 0x75, 0xf1, 0xdf, 0x9c, 0x3f, + 0xa6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + } +) + +// utxo represents an unspent output spendable by the memWallet. The maturity +// height of the transaction is recorded in order to properly observe the +// maturity period of direct coinbase outputs. +type utxo struct { + pkScript []byte + value btcutil.Amount + keyIndex uint32 + maturityHeight int32 + isLocked bool +} + +// isMature returns true if the target utxo is considered "mature" at the +// passed block height. Otherwise, false is returned. +func (u *utxo) isMature(height int32) bool { + return height >= u.maturityHeight +} + +// chainUpdate encapsulates an update to the current main chain. This struct is +// used to sync up the memWallet each time a new block is connected to the main +// chain. +type chainUpdate struct { + blockHeight int32 + filteredTxns []*btcutil.Tx + isConnect bool // True if connect, false if disconnect +} + +// undoEntry is functionally the opposite of a chainUpdate. An undoEntry is +// created for each new block received, then stored in a log in order to +// properly handle block re-orgs. +type undoEntry struct { + utxosDestroyed map[wire.OutPoint]*utxo + utxosCreated []wire.OutPoint +} + +// memWallet is a simple in-memory wallet whose purpose is to provide basic +// wallet functionality to the harness. The wallet uses a hard-coded HD key +// hierarchy which promotes reproducibility between harness test runs. +type memWallet struct { + coinbaseKey *btcec.PrivateKey + coinbaseAddr btcutil.Address + + // hdRoot is the root master private key for the wallet. + hdRoot *hdkeychain.ExtendedKey + + // hdIndex is the next available key index offset from the hdRoot. + hdIndex uint32 + + // currentHeight is the latest height the wallet is known to be synced + // to. + currentHeight int32 + + // addrs tracks all addresses belonging to the wallet. The addresses + // are indexed by their keypath from the hdRoot. + addrs map[uint32]btcutil.Address + + // utxos is the set of utxos spendable by the wallet. + utxos map[wire.OutPoint]*utxo + + // reorgJournal is a map storing an undo entry for each new block + // received. Once a block is disconnected, the undo entry for the + // particular height is evaluated, thereby rewinding the effect of the + // disconnected block on the wallet's set of spendable utxos. + reorgJournal map[int32]*undoEntry + + chainUpdates []*chainUpdate + chainUpdateSignal chan struct{} + chainMtx sync.Mutex + + net *chaincfg.Params + + rpc *rpcclient.Client + + sync.RWMutex +} + +// newMemWallet creates and returns a fully initialized instance of the +// memWallet given a particular blockchain's parameters. +func newMemWallet(net *chaincfg.Params, harnessID uint32) (*memWallet, error) { + // The wallet's final HD seed is: hdSeed || harnessID. This method + // ensures that each harness instance uses a deterministic root seed + // based on its harness ID. + var harnessHDSeed [chainhash.HashSize + 4]byte + copy(harnessHDSeed[:], hdSeed[:]) + binary.BigEndian.PutUint32(harnessHDSeed[:chainhash.HashSize], harnessID) + + hdRoot, err := hdkeychain.NewMaster(harnessHDSeed[:], net) + if err != nil { + return nil, nil + } + + // The first child key from the hd root is reserved as the coinbase + // generation address. + coinbaseChild, err := hdRoot.Child(0) + if err != nil { + return nil, err + } + coinbaseKey, err := coinbaseChild.ECPrivKey() + if err != nil { + return nil, err + } + coinbaseAddr, err := keyToAddr(coinbaseKey, net) + if err != nil { + return nil, err + } + + // Track the coinbase generation address to ensure we properly track + // newly generated bitcoin we can spend. + addrs := make(map[uint32]btcutil.Address) + addrs[0] = coinbaseAddr + + return &memWallet{ + net: net, + coinbaseKey: coinbaseKey, + coinbaseAddr: coinbaseAddr, + hdIndex: 1, + hdRoot: hdRoot, + addrs: addrs, + utxos: make(map[wire.OutPoint]*utxo), + chainUpdateSignal: make(chan struct{}), + reorgJournal: make(map[int32]*undoEntry), + }, nil +} + +// Start launches all goroutines required for the wallet to function properly. +func (m *memWallet) Start() { + go m.chainSyncer() +} + +// SyncedHeight returns the height the wallet is known to be synced to. +// +// This function is safe for concurrent access. +func (m *memWallet) SyncedHeight() int32 { + m.RLock() + defer m.RUnlock() + return m.currentHeight +} + +// SetRPCClient saves the passed rpc connection to btcd as the wallet's +// personal rpc connection. +func (m *memWallet) SetRPCClient(rpcClient *rpcclient.Client) { + m.rpc = rpcClient +} + +// IngestBlock is a call-back which is to be triggered each time a new block is +// connected to the main chain. It queues the update for the chain syncer, +// calling the private version in sequential order. +func (m *memWallet) IngestBlock(height int32, header *wire.BlockHeader, filteredTxns []*btcutil.Tx) { + // Append this new chain update to the end of the queue of new chain + // updates. + m.chainMtx.Lock() + m.chainUpdates = append(m.chainUpdates, &chainUpdate{height, + filteredTxns, true}) + m.chainMtx.Unlock() + + // Launch a goroutine to signal the chainSyncer that a new update is + // available. We do this in a new goroutine in order to avoid blocking + // the main loop of the rpc client. + go func() { + m.chainUpdateSignal <- struct{}{} + }() +} + +// ingestBlock updates the wallet's internal utxo state based on the outputs +// created and destroyed within each block. +func (m *memWallet) ingestBlock(update *chainUpdate) { + // Update the latest synced height, then process each filtered + // transaction in the block creating and destroying utxos within + // the wallet as a result. + m.currentHeight = update.blockHeight + undo := &undoEntry{ + utxosDestroyed: make(map[wire.OutPoint]*utxo), + } + for _, tx := range update.filteredTxns { + mtx := tx.MsgTx() + isCoinbase := blockchain.IsCoinBaseTx(mtx) + txHash := mtx.TxHash() + m.evalOutputs(mtx.TxOut, &txHash, isCoinbase, undo) + m.evalInputs(mtx.TxIn, undo) + } + + // Finally, record the undo entry for this block so we can + // properly update our internal state in response to the block + // being re-org'd from the main chain. + m.reorgJournal[update.blockHeight] = undo +} + +// chainSyncer is a goroutine dedicated to processing new blocks in order to +// keep the wallet's utxo state up to date. +// +// NOTE: This MUST be run as a goroutine. +func (m *memWallet) chainSyncer() { + var update *chainUpdate + + for range m.chainUpdateSignal { + // A new update is available, so pop the new chain update from + // the front of the update queue. + m.chainMtx.Lock() + update = m.chainUpdates[0] + m.chainUpdates[0] = nil // Set to nil to prevent GC leak. + m.chainUpdates = m.chainUpdates[1:] + m.chainMtx.Unlock() + + m.Lock() + if update.isConnect { + m.ingestBlock(update) + } else { + m.unwindBlock(update) + } + m.Unlock() + } +} + +// evalOutputs evaluates each of the passed outputs, creating a new matching +// utxo within the wallet if we're able to spend the output. +func (m *memWallet) evalOutputs(outputs []*wire.TxOut, txHash *chainhash.Hash, + isCoinbase bool, undo *undoEntry) { + + for i, output := range outputs { + pkScript := output.PkScript + + // Scan all the addresses we currently control to see if the + // output is paying to us. + for keyIndex, addr := range m.addrs { + pkHash := addr.ScriptAddress() + if !bytes.Contains(pkScript, pkHash) { + continue + } + + // If this is a coinbase output, then we mark the + // maturity height at the proper block height in the + // future. + var maturityHeight int32 + if isCoinbase { + maturityHeight = m.currentHeight + int32(m.net.CoinbaseMaturity) + } + + op := wire.OutPoint{Hash: *txHash, Index: uint32(i)} + m.utxos[op] = &utxo{ + value: btcutil.Amount(output.Value), + keyIndex: keyIndex, + maturityHeight: maturityHeight, + pkScript: pkScript, + } + undo.utxosCreated = append(undo.utxosCreated, op) + } + } +} + +// evalInputs scans all the passed inputs, destroying any utxos within the +// wallet which are spent by an input. +func (m *memWallet) evalInputs(inputs []*wire.TxIn, undo *undoEntry) { + for _, txIn := range inputs { + op := txIn.PreviousOutPoint + oldUtxo, ok := m.utxos[op] + if !ok { + continue + } + + undo.utxosDestroyed[op] = oldUtxo + delete(m.utxos, op) + } +} + +// UnwindBlock is a call-back which is to be executed each time a block is +// disconnected from the main chain. It queues the update for the chain syncer, +// calling the private version in sequential order. +func (m *memWallet) UnwindBlock(height int32, header *wire.BlockHeader) { + // Append this new chain update to the end of the queue of new chain + // updates. + m.chainMtx.Lock() + m.chainUpdates = append(m.chainUpdates, &chainUpdate{height, + nil, false}) + m.chainMtx.Unlock() + + // Launch a goroutine to signal the chainSyncer that a new update is + // available. We do this in a new goroutine in order to avoid blocking + // the main loop of the rpc client. + go func() { + m.chainUpdateSignal <- struct{}{} + }() +} + +// unwindBlock undoes the effect that a particular block had on the wallet's +// internal utxo state. +func (m *memWallet) unwindBlock(update *chainUpdate) { + undo := m.reorgJournal[update.blockHeight] + + for _, utxo := range undo.utxosCreated { + delete(m.utxos, utxo) + } + + for outPoint, utxo := range undo.utxosDestroyed { + m.utxos[outPoint] = utxo + } + + delete(m.reorgJournal, update.blockHeight) +} + +// newAddress returns a new address from the wallet's hd key chain. It also +// loads the address into the RPC client's transaction filter to ensure any +// transactions that involve it are delivered via the notifications. +func (m *memWallet) newAddress() (btcutil.Address, error) { + index := m.hdIndex + + childKey, err := m.hdRoot.Child(index) + if err != nil { + return nil, err + } + privKey, err := childKey.ECPrivKey() + if err != nil { + return nil, err + } + + addr, err := keyToAddr(privKey, m.net) + if err != nil { + return nil, err + } + + err = m.rpc.LoadTxFilter(false, []btcutil.Address{addr}, nil) + if err != nil { + return nil, err + } + + m.addrs[index] = addr + + m.hdIndex++ + + return addr, nil +} + +// NewAddress returns a fresh address spendable by the wallet. +// +// This function is safe for concurrent access. +func (m *memWallet) NewAddress() (btcutil.Address, error) { + m.Lock() + defer m.Unlock() + + return m.newAddress() +} + +// fundTx attempts to fund a transaction sending amt bitcoin. The coins are +// selected such that the final amount spent pays enough fees as dictated by the +// passed fee rate. The passed fee rate should be expressed in +// satoshis-per-byte. The transaction being funded can optionally include a +// change output indicated by the change boolean. +// +// NOTE: The memWallet's mutex must be held when this function is called. +func (m *memWallet) fundTx(tx *wire.MsgTx, amt btcutil.Amount, + feeRate btcutil.Amount, change bool) error { + + const ( + // spendSize is the largest number of bytes of a sigScript + // which spends a p2pkh output: OP_DATA_73 OP_DATA_33 + spendSize = 1 + 73 + 1 + 33 + ) + + var ( + amtSelected btcutil.Amount + txSize int + ) + + for outPoint, utxo := range m.utxos { + // Skip any outputs that are still currently immature or are + // currently locked. + if !utxo.isMature(m.currentHeight) || utxo.isLocked { + continue + } + + amtSelected += utxo.value + + // Add the selected output to the transaction, updating the + // current tx size while accounting for the size of the future + // sigScript. + tx.AddTxIn(wire.NewTxIn(&outPoint, nil, nil)) + txSize = tx.SerializeSize() + spendSize*len(tx.TxIn) + + // Calculate the fee required for the txn at this point + // observing the specified fee rate. If we don't have enough + // coins from he current amount selected to pay the fee, then + // continue to grab more coins. + reqFee := btcutil.Amount(txSize * int(feeRate)) + if amtSelected-reqFee < amt { + continue + } + + // If we have any change left over and we should create a change + // output, then add an additional output to the transaction + // reserved for it. + changeVal := amtSelected - amt - reqFee + if changeVal > 0 && change { + addr, err := m.newAddress() + if err != nil { + return err + } + pkScript, err := txscript.PayToAddrScript(addr) + if err != nil { + return err + } + changeOutput := &wire.TxOut{ + Value: int64(changeVal), + PkScript: pkScript, + } + tx.AddTxOut(changeOutput) + } + + return nil + } + + // If we've reached this point, then coin selection failed due to an + // insufficient amount of coins. + return fmt.Errorf("not enough funds for coin selection") +} + +// SendOutputs creates, then sends a transaction paying to the specified output +// while observing the passed fee rate. The passed fee rate should be expressed +// in satoshis-per-byte. +func (m *memWallet) SendOutputs(outputs []*wire.TxOut, + feeRate btcutil.Amount) (*chainhash.Hash, error) { + + tx, err := m.CreateTransaction(outputs, feeRate, true) + if err != nil { + return nil, err + } + + return m.rpc.SendRawTransaction(tx, true) +} + +// SendOutputsWithoutChange creates and sends a transaction that pays to the +// specified outputs while observing the passed fee rate and ignoring a change +// output. The passed fee rate should be expressed in sat/b. +func (m *memWallet) SendOutputsWithoutChange(outputs []*wire.TxOut, + feeRate btcutil.Amount) (*chainhash.Hash, error) { + + tx, err := m.CreateTransaction(outputs, feeRate, false) + if err != nil { + return nil, err + } + + return m.rpc.SendRawTransaction(tx, true) +} + +// CreateTransaction returns a fully signed transaction paying to the specified +// outputs while observing the desired fee rate. The passed fee rate should be +// expressed in satoshis-per-byte. The transaction being created can optionally +// include a change output indicated by the change boolean. +// +// This function is safe for concurrent access. +func (m *memWallet) CreateTransaction(outputs []*wire.TxOut, + feeRate btcutil.Amount, change bool) (*wire.MsgTx, error) { + + m.Lock() + defer m.Unlock() + + tx := wire.NewMsgTx(wire.TxVersion) + + // Tally up the total amount to be sent in order to perform coin + // selection shortly below. + var outputAmt btcutil.Amount + for _, output := range outputs { + outputAmt += btcutil.Amount(output.Value) + tx.AddTxOut(output) + } + + // Attempt to fund the transaction with spendable utxos. + if err := m.fundTx(tx, outputAmt, feeRate, change); err != nil { + return nil, err + } + + // Populate all the selected inputs with valid sigScript for spending. + // Along the way record all outputs being spent in order to avoid a + // potential double spend. + spentOutputs := make([]*utxo, 0, len(tx.TxIn)) + for i, txIn := range tx.TxIn { + outPoint := txIn.PreviousOutPoint + utxo := m.utxos[outPoint] + + extendedKey, err := m.hdRoot.Child(utxo.keyIndex) + if err != nil { + return nil, err + } + + privKey, err := extendedKey.ECPrivKey() + if err != nil { + return nil, err + } + + sigScript, err := txscript.SignatureScript(tx, i, utxo.pkScript, + txscript.SigHashAll, privKey, true) + if err != nil { + return nil, err + } + + txIn.SignatureScript = sigScript + + spentOutputs = append(spentOutputs, utxo) + } + + // As these outputs are now being spent by this newly created + // transaction, mark the outputs are "locked". This action ensures + // these outputs won't be double spent by any subsequent transactions. + // These locked outputs can be freed via a call to UnlockOutputs. + for _, utxo := range spentOutputs { + utxo.isLocked = true + } + + return tx, nil +} + +// UnlockOutputs unlocks any outputs which were previously locked due to +// being selected to fund a transaction via the CreateTransaction method. +// +// This function is safe for concurrent access. +func (m *memWallet) UnlockOutputs(inputs []*wire.TxIn) { + m.Lock() + defer m.Unlock() + + for _, input := range inputs { + utxo, ok := m.utxos[input.PreviousOutPoint] + if !ok { + continue + } + + utxo.isLocked = false + } +} + +// ConfirmedBalance returns the confirmed balance of the wallet. +// +// This function is safe for concurrent access. +func (m *memWallet) ConfirmedBalance() btcutil.Amount { + m.RLock() + defer m.RUnlock() + + var balance btcutil.Amount + for _, utxo := range m.utxos { + // Prevent any immature or locked outputs from contributing to + // the wallet's total confirmed balance. + if !utxo.isMature(m.currentHeight) || utxo.isLocked { + continue + } + + balance += utxo.value + } + + return balance +} + +// keyToAddr maps the passed private to corresponding p2pkh address. +func keyToAddr(key *btcec.PrivateKey, net *chaincfg.Params) (btcutil.Address, error) { + serializedKey := key.PubKey().SerializeCompressed() + pubKeyAddr, err := btcutil.NewAddressPubKey(serializedKey, net) + if err != nil { + return nil, err + } + return pubKeyAddr.AddressPubKeyHash(), nil +} diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/node.go b/vendor/github.com/btcsuite/btcd/integration/rpctest/node.go new file mode 100644 index 0000000..6aec2b1 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/node.go @@ -0,0 +1,287 @@ +// 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 rpctest + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "time" + + rpc "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcutil" +) + +// nodeConfig contains all the args, and data required to launch a btcd process +// and connect the rpc client to it. +type nodeConfig struct { + rpcUser string + rpcPass string + listen string + rpcListen string + rpcConnect string + dataDir string + logDir string + profile string + debugLevel string + extra []string + prefix string + + exe string + endpoint string + certFile string + keyFile string + certificates []byte +} + +// newConfig returns a newConfig with all default values. +func newConfig(prefix, certFile, keyFile string, extra []string) (*nodeConfig, error) { + btcdPath, err := btcdExecutablePath() + if err != nil { + btcdPath = "btcd" + } + + a := &nodeConfig{ + listen: "127.0.0.1:18555", + rpcListen: "127.0.0.1:18556", + rpcUser: "user", + rpcPass: "pass", + extra: extra, + prefix: prefix, + exe: btcdPath, + endpoint: "ws", + certFile: certFile, + keyFile: keyFile, + } + if err := a.setDefaults(); err != nil { + return nil, err + } + return a, nil +} + +// setDefaults sets the default values of the config. It also creates the +// temporary data, and log directories which must be cleaned up with a call to +// cleanup(). +func (n *nodeConfig) setDefaults() error { + datadir, err := ioutil.TempDir("", n.prefix+"-data") + if err != nil { + return err + } + n.dataDir = datadir + logdir, err := ioutil.TempDir("", n.prefix+"-logs") + if err != nil { + return err + } + n.logDir = logdir + cert, err := ioutil.ReadFile(n.certFile) + if err != nil { + return err + } + n.certificates = cert + return nil +} + +// arguments returns an array of arguments that be used to launch the btcd +// process. +func (n *nodeConfig) arguments() []string { + args := []string{} + if n.rpcUser != "" { + // --rpcuser + args = append(args, fmt.Sprintf("--rpcuser=%s", n.rpcUser)) + } + if n.rpcPass != "" { + // --rpcpass + args = append(args, fmt.Sprintf("--rpcpass=%s", n.rpcPass)) + } + if n.listen != "" { + // --listen + args = append(args, fmt.Sprintf("--listen=%s", n.listen)) + } + if n.rpcListen != "" { + // --rpclisten + args = append(args, fmt.Sprintf("--rpclisten=%s", n.rpcListen)) + } + if n.rpcConnect != "" { + // --rpcconnect + args = append(args, fmt.Sprintf("--rpcconnect=%s", n.rpcConnect)) + } + // --rpccert + args = append(args, fmt.Sprintf("--rpccert=%s", n.certFile)) + // --rpckey + args = append(args, fmt.Sprintf("--rpckey=%s", n.keyFile)) + if n.dataDir != "" { + // --datadir + args = append(args, fmt.Sprintf("--datadir=%s", n.dataDir)) + } + if n.logDir != "" { + // --logdir + args = append(args, fmt.Sprintf("--logdir=%s", n.logDir)) + } + if n.profile != "" { + // --profile + args = append(args, fmt.Sprintf("--profile=%s", n.profile)) + } + if n.debugLevel != "" { + // --debuglevel + args = append(args, fmt.Sprintf("--debuglevel=%s", n.debugLevel)) + } + args = append(args, n.extra...) + return args +} + +// command returns the exec.Cmd which will be used to start the btcd process. +func (n *nodeConfig) command() *exec.Cmd { + return exec.Command(n.exe, n.arguments()...) +} + +// rpcConnConfig returns the rpc connection config that can be used to connect +// to the btcd process that is launched via Start(). +func (n *nodeConfig) rpcConnConfig() rpc.ConnConfig { + return rpc.ConnConfig{ + Host: n.rpcListen, + Endpoint: n.endpoint, + User: n.rpcUser, + Pass: n.rpcPass, + Certificates: n.certificates, + DisableAutoReconnect: true, + } +} + +// String returns the string representation of this nodeConfig. +func (n *nodeConfig) String() string { + return n.prefix +} + +// cleanup removes the tmp data and log directories. +func (n *nodeConfig) cleanup() error { + dirs := []string{ + n.logDir, + n.dataDir, + } + var err error + for _, dir := range dirs { + if err = os.RemoveAll(dir); err != nil { + log.Printf("Cannot remove dir %s: %v", dir, err) + } + } + return err +} + +// node houses the necessary state required to configure, launch, and manage a +// btcd process. +type node struct { + config *nodeConfig + + cmd *exec.Cmd + pidFile string + + dataDir string +} + +// newNode creates a new node instance according to the passed config. dataDir +// will be used to hold a file recording the pid of the launched process, and +// as the base for the log and data directories for btcd. +func newNode(config *nodeConfig, dataDir string) (*node, error) { + return &node{ + config: config, + dataDir: dataDir, + cmd: config.command(), + }, nil +} + +// start creates a new btcd process, and writes its pid in a file reserved for +// recording the pid of the launched process. This file can be used to +// terminate the process in case of a hang, or panic. In the case of a failing +// test case, or panic, it is important that the process be stopped via stop(), +// otherwise, it will persist unless explicitly killed. +func (n *node) start() error { + if err := n.cmd.Start(); err != nil { + return err + } + + pid, err := os.Create(filepath.Join(n.dataDir, + fmt.Sprintf("%s.pid", n.config))) + if err != nil { + return err + } + + n.pidFile = pid.Name() + if _, err = fmt.Fprintf(pid, "%d\n", n.cmd.Process.Pid); err != nil { + return err + } + + if err := pid.Close(); err != nil { + return err + } + + return nil +} + +// stop interrupts the running btcd process process, and waits until it exits +// properly. On windows, interrupt is not supported, so a kill signal is used +// instead +func (n *node) stop() error { + if n.cmd == nil || n.cmd.Process == nil { + // return if not properly initialized + // or error starting the process + return nil + } + defer n.cmd.Wait() + if runtime.GOOS == "windows" { + return n.cmd.Process.Signal(os.Kill) + } + return n.cmd.Process.Signal(os.Interrupt) +} + +// cleanup cleanups process and args files. The file housing the pid of the +// created process will be deleted, as well as any directories created by the +// process. +func (n *node) cleanup() error { + if n.pidFile != "" { + if err := os.Remove(n.pidFile); err != nil { + log.Printf("unable to remove file %s: %v", n.pidFile, + err) + } + } + + return n.config.cleanup() +} + +// shutdown terminates the running btcd process, and cleans up all +// file/directories created by node. +func (n *node) shutdown() error { + if err := n.stop(); err != nil { + return err + } + if err := n.cleanup(); err != nil { + return err + } + return nil +} + +// genCertPair generates a key/cert pair to the paths provided. +func genCertPair(certFile, keyFile string) error { + org := "rpctest autogenerated cert" + validUntil := time.Now().Add(10 * 365 * 24 * time.Hour) + cert, key, err := btcutil.NewTLSCertPair(org, validUntil, nil) + if err != nil { + return err + } + + // Write cert and key files. + if err = ioutil.WriteFile(certFile, cert, 0666); err != nil { + return err + } + if err = ioutil.WriteFile(keyFile, key, 0600); err != nil { + os.Remove(certFile) + return err + } + + return nil +} diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/rpc_harness.go b/vendor/github.com/btcsuite/btcd/integration/rpctest/rpc_harness.go new file mode 100644 index 0000000..1c2612e --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/rpc_harness.go @@ -0,0 +1,500 @@ +// 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 rpctest + +import ( + "fmt" + "io/ioutil" + "net" + "os" + "path/filepath" + "strconv" + "sync" + "testing" + "time" + + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/rpcclient" + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" +) + +const ( + // These constants define the minimum and maximum p2p and rpc port + // numbers used by a test harness. The min port is inclusive while the + // max port is exclusive. + minPeerPort = 10000 + maxPeerPort = 35000 + minRPCPort = maxPeerPort + maxRPCPort = 60000 + + // BlockVersion is the default block version used when generating + // blocks. + BlockVersion = 4 +) + +var ( + // current number of active test nodes. + numTestInstances = 0 + + // processID is the process ID of the current running process. It is + // used to calculate ports based upon it when launching an rpc + // harnesses. The intent is to allow multiple process to run in + // parallel without port collisions. + // + // It should be noted however that there is still some small probability + // that there will be port collisions either due to other processes + // running or simply due to the stars aligning on the process IDs. + processID = os.Getpid() + + // testInstances is a private package-level slice used to keep track of + // all active test harnesses. This global can be used to perform + // various "joins", shutdown several active harnesses after a test, + // etc. + testInstances = make(map[string]*Harness) + + // Used to protest concurrent access to above declared variables. + harnessStateMtx sync.RWMutex +) + +// HarnessTestCase represents a test-case which utilizes an instance of the +// Harness to exercise functionality. +type HarnessTestCase func(r *Harness, t *testing.T) + +// Harness fully encapsulates an active btcd process to provide a unified +// platform for creating rpc driven integration tests involving btcd. The +// active btcd node will typically be run in simnet mode in order to allow for +// easy generation of test blockchains. The active btcd process is fully +// managed by Harness, which handles the necessary initialization, and teardown +// of the process along with any temporary directories created as a result. +// Multiple Harness instances may be run concurrently, in order to allow for +// testing complex scenarios involving multiple nodes. The harness also +// includes an in-memory wallet to streamline various classes of tests. +type Harness struct { + // ActiveNet is the parameters of the blockchain the Harness belongs + // to. + ActiveNet *chaincfg.Params + + Node *rpcclient.Client + node *node + handlers *rpcclient.NotificationHandlers + + wallet *memWallet + + testNodeDir string + maxConnRetries int + nodeNum int + + sync.Mutex +} + +// New creates and initializes new instance of the rpc test harness. +// Optionally, websocket handlers and a specified configuration may be passed. +// In the case that a nil config is passed, a default configuration will be +// used. +// +// NOTE: This function is safe for concurrent access. +func New(activeNet *chaincfg.Params, handlers *rpcclient.NotificationHandlers, + extraArgs []string) (*Harness, error) { + + harnessStateMtx.Lock() + defer harnessStateMtx.Unlock() + + // Add a flag for the appropriate network type based on the provided + // chain params. + switch activeNet.Net { + case wire.MainNet: + // No extra flags since mainnet is the default + case wire.TestNet3: + extraArgs = append(extraArgs, "--testnet") + case wire.TestNet: + extraArgs = append(extraArgs, "--regtest") + case wire.SimNet: + extraArgs = append(extraArgs, "--simnet") + default: + return nil, fmt.Errorf("rpctest.New must be called with one " + + "of the supported chain networks") + } + + testDir, err := baseDir() + if err != nil { + return nil, err + } + + harnessID := strconv.Itoa(numTestInstances) + nodeTestData, err := ioutil.TempDir(testDir, "harness-"+harnessID) + if err != nil { + return nil, err + } + + certFile := filepath.Join(nodeTestData, "rpc.cert") + keyFile := filepath.Join(nodeTestData, "rpc.key") + if err := genCertPair(certFile, keyFile); err != nil { + return nil, err + } + + wallet, err := newMemWallet(activeNet, uint32(numTestInstances)) + if err != nil { + return nil, err + } + + miningAddr := fmt.Sprintf("--miningaddr=%s", wallet.coinbaseAddr) + extraArgs = append(extraArgs, miningAddr) + + config, err := newConfig("rpctest", certFile, keyFile, extraArgs) + if err != nil { + return nil, err + } + + // Generate p2p+rpc listening addresses. + config.listen, config.rpcListen = generateListeningAddresses() + + // Create the testing node bounded to the simnet. + node, err := newNode(config, nodeTestData) + if err != nil { + return nil, err + } + + nodeNum := numTestInstances + numTestInstances++ + + if handlers == nil { + handlers = &rpcclient.NotificationHandlers{} + } + + // If a handler for the OnFilteredBlock{Connected,Disconnected} callback + // callback has already been set, then create a wrapper callback which + // executes both the currently registered callback and the mem wallet's + // callback. + if handlers.OnFilteredBlockConnected != nil { + obc := handlers.OnFilteredBlockConnected + handlers.OnFilteredBlockConnected = func(height int32, header *wire.BlockHeader, filteredTxns []*btcutil.Tx) { + wallet.IngestBlock(height, header, filteredTxns) + obc(height, header, filteredTxns) + } + } else { + // Otherwise, we can claim the callback ourselves. + handlers.OnFilteredBlockConnected = wallet.IngestBlock + } + if handlers.OnFilteredBlockDisconnected != nil { + obd := handlers.OnFilteredBlockDisconnected + handlers.OnFilteredBlockDisconnected = func(height int32, header *wire.BlockHeader) { + wallet.UnwindBlock(height, header) + obd(height, header) + } + } else { + handlers.OnFilteredBlockDisconnected = wallet.UnwindBlock + } + + h := &Harness{ + handlers: handlers, + node: node, + maxConnRetries: 20, + testNodeDir: nodeTestData, + ActiveNet: activeNet, + nodeNum: nodeNum, + wallet: wallet, + } + + // Track this newly created test instance within the package level + // global map of all active test instances. + testInstances[h.testNodeDir] = h + + return h, nil +} + +// SetUp initializes the rpc test state. Initialization includes: starting up a +// simnet node, creating a websockets client and connecting to the started +// node, and finally: optionally generating and submitting a testchain with a +// configurable number of mature coinbase outputs coinbase outputs. +// +// NOTE: This method and TearDown should always be called from the same +// goroutine as they are not concurrent safe. +func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error { + // Start the btcd node itself. This spawns a new process which will be + // managed + if err := h.node.start(); err != nil { + return err + } + if err := h.connectRPCClient(); err != nil { + return err + } + + h.wallet.Start() + + // Filter transactions that pay to the coinbase associated with the + // wallet. + filterAddrs := []btcutil.Address{h.wallet.coinbaseAddr} + if err := h.Node.LoadTxFilter(true, filterAddrs, nil); err != nil { + return err + } + + // Ensure btcd properly dispatches our registered call-back for each new + // block. Otherwise, the memWallet won't function properly. + if err := h.Node.NotifyBlocks(); err != nil { + return err + } + + // Create a test chain with the desired number of mature coinbase + // outputs. + if createTestChain && numMatureOutputs != 0 { + numToGenerate := (uint32(h.ActiveNet.CoinbaseMaturity) + + numMatureOutputs) + _, err := h.Node.Generate(numToGenerate) + if err != nil { + return err + } + } + + // Block until the wallet has fully synced up to the tip of the main + // chain. + _, height, err := h.Node.GetBestBlock() + if err != nil { + return err + } + ticker := time.NewTicker(time.Millisecond * 100) + for range ticker.C { + walletHeight := h.wallet.SyncedHeight() + if walletHeight == height { + break + } + } + ticker.Stop() + + return nil +} + +// tearDown stops the running rpc test instance. All created processes are +// killed, and temporary directories removed. +// +// This function MUST be called with the harness state mutex held (for writes). +func (h *Harness) tearDown() error { + if h.Node != nil { + h.Node.Shutdown() + } + + if err := h.node.shutdown(); err != nil { + return err + } + + if err := os.RemoveAll(h.testNodeDir); err != nil { + return err + } + + delete(testInstances, h.testNodeDir) + + return nil +} + +// TearDown stops the running rpc test instance. All created processes are +// killed, and temporary directories removed. +// +// NOTE: This method and SetUp should always be called from the same goroutine +// as they are not concurrent safe. +func (h *Harness) TearDown() error { + harnessStateMtx.Lock() + defer harnessStateMtx.Unlock() + + return h.tearDown() +} + +// connectRPCClient attempts to establish an RPC connection to the created btcd +// process belonging to this Harness instance. If the initial connection +// attempt fails, this function will retry h.maxConnRetries times, backing off +// the time between subsequent attempts. If after h.maxConnRetries attempts, +// we're not able to establish a connection, this function returns with an +// error. +func (h *Harness) connectRPCClient() error { + var client *rpcclient.Client + var err error + + rpcConf := h.node.config.rpcConnConfig() + for i := 0; i < h.maxConnRetries; i++ { + if client, err = rpcclient.New(&rpcConf, h.handlers); err != nil { + time.Sleep(time.Duration(i) * 50 * time.Millisecond) + continue + } + break + } + + if client == nil { + return fmt.Errorf("connection timeout") + } + + h.Node = client + h.wallet.SetRPCClient(client) + return nil +} + +// NewAddress returns a fresh address spendable by the Harness' internal +// wallet. +// +// This function is safe for concurrent access. +func (h *Harness) NewAddress() (btcutil.Address, error) { + return h.wallet.NewAddress() +} + +// ConfirmedBalance returns the confirmed balance of the Harness' internal +// wallet. +// +// This function is safe for concurrent access. +func (h *Harness) ConfirmedBalance() btcutil.Amount { + return h.wallet.ConfirmedBalance() +} + +// SendOutputs creates, signs, and finally broadcasts a transaction spending +// the harness' available mature coinbase outputs creating new outputs +// according to targetOutputs. +// +// This function is safe for concurrent access. +func (h *Harness) SendOutputs(targetOutputs []*wire.TxOut, + feeRate btcutil.Amount) (*chainhash.Hash, error) { + + return h.wallet.SendOutputs(targetOutputs, feeRate) +} + +// SendOutputsWithoutChange creates and sends a transaction that pays to the +// specified outputs while observing the passed fee rate and ignoring a change +// output. The passed fee rate should be expressed in sat/b. +// +// This function is safe for concurrent access. +func (h *Harness) SendOutputsWithoutChange(targetOutputs []*wire.TxOut, + feeRate btcutil.Amount) (*chainhash.Hash, error) { + + return h.wallet.SendOutputsWithoutChange(targetOutputs, feeRate) +} + +// CreateTransaction returns a fully signed transaction paying to the specified +// outputs while observing the desired fee rate. The passed fee rate should be +// expressed in satoshis-per-byte. The transaction being created can optionally +// include a change output indicated by the change boolean. Any unspent outputs +// selected as inputs for the crafted transaction are marked as unspendable in +// order to avoid potential double-spends by future calls to this method. If the +// created transaction is cancelled for any reason then the selected inputs MUST +// be freed via a call to UnlockOutputs. Otherwise, the locked inputs won't be +// returned to the pool of spendable outputs. +// +// This function is safe for concurrent access. +func (h *Harness) CreateTransaction(targetOutputs []*wire.TxOut, + feeRate btcutil.Amount, change bool) (*wire.MsgTx, error) { + + return h.wallet.CreateTransaction(targetOutputs, feeRate, change) +} + +// UnlockOutputs unlocks any outputs which were previously marked as +// unspendabe due to being selected to fund a transaction via the +// CreateTransaction method. +// +// This function is safe for concurrent access. +func (h *Harness) UnlockOutputs(inputs []*wire.TxIn) { + h.wallet.UnlockOutputs(inputs) +} + +// RPCConfig returns the harnesses current rpc configuration. This allows other +// potential RPC clients created within tests to connect to a given test +// harness instance. +func (h *Harness) RPCConfig() rpcclient.ConnConfig { + return h.node.config.rpcConnConfig() +} + +// P2PAddress returns the harness' P2P listening address. This allows potential +// peers (such as SPV peers) created within tests to connect to a given test +// harness instance. +func (h *Harness) P2PAddress() string { + return h.node.config.listen +} + +// GenerateAndSubmitBlock creates a block whose contents include the passed +// transactions and submits it to the running simnet node. For generating +// blocks with only a coinbase tx, callers can simply pass nil instead of +// transactions to be mined. Additionally, a custom block version can be set by +// the caller. A blockVersion of -1 indicates that the current default block +// version should be used. An uninitialized time.Time should be used for the +// blockTime parameter if one doesn't wish to set a custom time. +// +// This function is safe for concurrent access. +func (h *Harness) GenerateAndSubmitBlock(txns []*btcutil.Tx, blockVersion int32, + blockTime time.Time) (*btcutil.Block, error) { + return h.GenerateAndSubmitBlockWithCustomCoinbaseOutputs(txns, + blockVersion, blockTime, []wire.TxOut{}) +} + +// GenerateAndSubmitBlockWithCustomCoinbaseOutputs creates a block whose +// contents include the passed coinbase outputs and transactions and submits +// it to the running simnet node. For generating blocks with only a coinbase tx, +// callers can simply pass nil instead of transactions to be mined. +// Additionally, a custom block version can be set by the caller. A blockVersion +// of -1 indicates that the current default block version should be used. An +// uninitialized time.Time should be used for the blockTime parameter if one +// doesn't wish to set a custom time. The mineTo list of outputs will be added +// to the coinbase; this is not checked for correctness until the block is +// submitted; thus, it is the caller's responsibility to ensure that the outputs +// are correct. If the list is empty, the coinbase reward goes to the wallet +// managed by the Harness. +// +// This function is safe for concurrent access. +func (h *Harness) GenerateAndSubmitBlockWithCustomCoinbaseOutputs( + txns []*btcutil.Tx, blockVersion int32, blockTime time.Time, + mineTo []wire.TxOut) (*btcutil.Block, error) { + + h.Lock() + defer h.Unlock() + + if blockVersion == -1 { + blockVersion = BlockVersion + } + + prevBlockHash, prevBlockHeight, err := h.Node.GetBestBlock() + if err != nil { + return nil, err + } + mBlock, err := h.Node.GetBlock(prevBlockHash) + if err != nil { + return nil, err + } + prevBlock := btcutil.NewBlock(mBlock) + prevBlock.SetHeight(prevBlockHeight) + + // Create a new block including the specified transactions + newBlock, err := CreateBlock(prevBlock, txns, blockVersion, + blockTime, h.wallet.coinbaseAddr, mineTo, h.ActiveNet) + if err != nil { + return nil, err + } + + // Submit the block to the simnet node. + if err := h.Node.SubmitBlock(newBlock, nil); err != nil { + return nil, err + } + + return newBlock, nil +} + +// generateListeningAddresses returns two strings representing listening +// addresses designated for the current rpc test. If there haven't been any +// test instances created, the default ports are used. Otherwise, in order to +// support multiple test nodes running at once, the p2p and rpc port are +// incremented after each initialization. +func generateListeningAddresses() (string, string) { + localhost := "127.0.0.1" + + portString := func(minPort, maxPort int) string { + port := minPort + numTestInstances + ((20 * processID) % + (maxPort - minPort)) + return strconv.Itoa(port) + } + + p2p := net.JoinHostPort(localhost, portString(minPeerPort, maxPeerPort)) + rpc := net.JoinHostPort(localhost, portString(minRPCPort, maxRPCPort)) + return p2p, rpc +} + +// baseDir is the directory path of the temp directory for all rpctest files. +func baseDir() (string, error) { + dirPath := filepath.Join(os.TempDir(), "btcd", "rpctest") + err := os.MkdirAll(dirPath, 0755) + return dirPath, err +} diff --git a/vendor/github.com/btcsuite/btcd/integration/rpctest/utils.go b/vendor/github.com/btcsuite/btcd/integration/rpctest/utils.go new file mode 100644 index 0000000..fc7d938 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/integration/rpctest/utils.go @@ -0,0 +1,164 @@ +// 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 rpctest + +import ( + "reflect" + "time" + + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/rpcclient" +) + +// JoinType is an enum representing a particular type of "node join". A node +// join is a synchronization tool used to wait until a subset of nodes have a +// consistent state with respect to an attribute. +type JoinType uint8 + +const ( + // Blocks is a JoinType which waits until all nodes share the same + // block height. + Blocks JoinType = iota + + // Mempools is a JoinType which blocks until all nodes have identical + // mempool. + Mempools +) + +// JoinNodes is a synchronization tool used to block until all passed nodes are +// fully synced with respect to an attribute. This function will block for a +// period of time, finally returning once all nodes are synced according to the +// passed JoinType. This function be used to to ensure all active test +// harnesses are at a consistent state before proceeding to an assertion or +// check within rpc tests. +func JoinNodes(nodes []*Harness, joinType JoinType) error { + switch joinType { + case Blocks: + return syncBlocks(nodes) + case Mempools: + return syncMempools(nodes) + } + return nil +} + +// syncMempools blocks until all nodes have identical mempools. +func syncMempools(nodes []*Harness) error { + poolsMatch := false + +retry: + for !poolsMatch { + firstPool, err := nodes[0].Node.GetRawMempool() + if err != nil { + return err + } + + // If all nodes have an identical mempool with respect to the + // first node, then we're done. Otherwise, drop back to the top + // of the loop and retry after a short wait period. + for _, node := range nodes[1:] { + nodePool, err := node.Node.GetRawMempool() + if err != nil { + return err + } + + if !reflect.DeepEqual(firstPool, nodePool) { + time.Sleep(time.Millisecond * 100) + continue retry + } + } + + poolsMatch = true + } + + return nil +} + +// syncBlocks blocks until all nodes report the same best chain. +func syncBlocks(nodes []*Harness) error { + blocksMatch := false + +retry: + for !blocksMatch { + var prevHash *chainhash.Hash + var prevHeight int32 + for _, node := range nodes { + blockHash, blockHeight, err := node.Node.GetBestBlock() + if err != nil { + return err + } + if prevHash != nil && (*blockHash != *prevHash || + blockHeight != prevHeight) { + + time.Sleep(time.Millisecond * 100) + continue retry + } + prevHash, prevHeight = blockHash, blockHeight + } + + blocksMatch = true + } + + return nil +} + +// ConnectNode establishes a new peer-to-peer connection between the "from" +// harness and the "to" harness. The connection made is flagged as persistent, +// therefore in the case of disconnects, "from" will attempt to reestablish a +// connection to the "to" harness. +func ConnectNode(from *Harness, to *Harness) error { + peerInfo, err := from.Node.GetPeerInfo() + if err != nil { + return err + } + numPeers := len(peerInfo) + + targetAddr := to.node.config.listen + if err := from.Node.AddNode(targetAddr, rpcclient.ANAdd); err != nil { + return err + } + + // Block until a new connection has been established. + peerInfo, err = from.Node.GetPeerInfo() + if err != nil { + return err + } + for len(peerInfo) <= numPeers { + peerInfo, err = from.Node.GetPeerInfo() + if err != nil { + return err + } + } + + return nil +} + +// TearDownAll tears down all active test harnesses. +func TearDownAll() error { + harnessStateMtx.Lock() + defer harnessStateMtx.Unlock() + + for _, harness := range testInstances { + if err := harness.tearDown(); err != nil { + return err + } + } + + return nil +} + +// ActiveHarnesses returns a slice of all currently active test harnesses. A +// test harness if considered "active" if it has been created, but not yet torn +// down. +func ActiveHarnesses() []*Harness { + harnessStateMtx.RLock() + defer harnessStateMtx.RUnlock() + + activeNodes := make([]*Harness, 0, len(testInstances)) + for _, harness := range testInstances { + activeNodes = append(activeNodes, harness) + } + + return activeNodes +} diff --git a/vendor/github.com/btcsuite/btcd/peer/mruinvmap.go b/vendor/github.com/btcsuite/btcd/peer/mruinvmap.go deleted file mode 100644 index 0bf1b2b..0000000 --- a/vendor/github.com/btcsuite/btcd/peer/mruinvmap.go +++ /dev/null @@ -1,127 +0,0 @@ -// 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 peer - -import ( - "bytes" - "container/list" - "fmt" - "sync" - - "github.com/btcsuite/btcd/wire" -) - -// mruInventoryMap provides a concurrency safe map that is limited to a maximum -// number of items with eviction for the oldest entry when the limit is -// exceeded. -type mruInventoryMap struct { - invMtx sync.Mutex - invMap map[wire.InvVect]*list.Element // nearly O(1) lookups - invList *list.List // O(1) insert, update, delete - limit uint -} - -// String returns the map as a human-readable string. -// -// This function is safe for concurrent access. -func (m *mruInventoryMap) String() string { - m.invMtx.Lock() - defer m.invMtx.Unlock() - - lastEntryNum := len(m.invMap) - 1 - curEntry := 0 - buf := bytes.NewBufferString("[") - for iv := range m.invMap { - buf.WriteString(fmt.Sprintf("%v", iv)) - if curEntry < lastEntryNum { - buf.WriteString(", ") - } - curEntry++ - } - buf.WriteString("]") - - return fmt.Sprintf("<%d>%s", m.limit, buf.String()) -} - -// Exists returns whether or not the passed inventory item is in the map. -// -// This function is safe for concurrent access. -func (m *mruInventoryMap) Exists(iv *wire.InvVect) bool { - m.invMtx.Lock() - _, exists := m.invMap[*iv] - m.invMtx.Unlock() - - return exists -} - -// Add adds the passed inventory to the map and handles eviction of the oldest -// item if adding the new item would exceed the max limit. Adding an existing -// item makes it the most recently used item. -// -// This function is safe for concurrent access. -func (m *mruInventoryMap) Add(iv *wire.InvVect) { - m.invMtx.Lock() - defer m.invMtx.Unlock() - - // When the limit is zero, nothing can be added to the map, so just - // return. - if m.limit == 0 { - return - } - - // When the entry already exists move it to the front of the list - // thereby marking it most recently used. - if node, exists := m.invMap[*iv]; exists { - m.invList.MoveToFront(node) - return - } - - // Evict the least recently used entry (back of the list) if the the new - // entry would exceed the size limit for the map. Also reuse the list - // node so a new one doesn't have to be allocated. - if uint(len(m.invMap))+1 > m.limit { - node := m.invList.Back() - lru := node.Value.(*wire.InvVect) - - // Evict least recently used item. - delete(m.invMap, *lru) - - // Reuse the list node of the item that was just evicted for the - // new item. - node.Value = iv - m.invList.MoveToFront(node) - m.invMap[*iv] = node - return - } - - // The limit hasn't been reached yet, so just add the new item. - node := m.invList.PushFront(iv) - m.invMap[*iv] = node -} - -// Delete deletes the passed inventory item from the map (if it exists). -// -// This function is safe for concurrent access. -func (m *mruInventoryMap) Delete(iv *wire.InvVect) { - m.invMtx.Lock() - if node, exists := m.invMap[*iv]; exists { - m.invList.Remove(node) - delete(m.invMap, *iv) - } - m.invMtx.Unlock() -} - -// newMruInventoryMap returns a new inventory map that is limited to the number -// of entries specified by limit. When the number of entries exceeds the limit, -// the oldest (least recently used) entry will be removed to make room for the -// new entry. -func newMruInventoryMap(limit uint) *mruInventoryMap { - m := mruInventoryMap{ - invMap: make(map[wire.InvVect]*list.Element), - invList: list.New(), - limit: limit, - } - return &m -} diff --git a/vendor/github.com/btcsuite/btcd/peer/mrunoncemap.go b/vendor/github.com/btcsuite/btcd/peer/mrunoncemap.go deleted file mode 100644 index 5f7c798..0000000 --- a/vendor/github.com/btcsuite/btcd/peer/mrunoncemap.go +++ /dev/null @@ -1,125 +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. - -package peer - -import ( - "bytes" - "container/list" - "fmt" - "sync" -) - -// mruNonceMap provides a concurrency safe map that is limited to a maximum -// number of items with eviction for the oldest entry when the limit is -// exceeded. -type mruNonceMap struct { - mtx sync.Mutex - nonceMap map[uint64]*list.Element // nearly O(1) lookups - nonceList *list.List // O(1) insert, update, delete - limit uint -} - -// String returns the map as a human-readable string. -// -// This function is safe for concurrent access. -func (m *mruNonceMap) String() string { - m.mtx.Lock() - defer m.mtx.Unlock() - - lastEntryNum := len(m.nonceMap) - 1 - curEntry := 0 - buf := bytes.NewBufferString("[") - for nonce := range m.nonceMap { - buf.WriteString(fmt.Sprintf("%d", nonce)) - if curEntry < lastEntryNum { - buf.WriteString(", ") - } - curEntry++ - } - buf.WriteString("]") - - return fmt.Sprintf("<%d>%s", m.limit, buf.String()) -} - -// Exists returns whether or not the passed nonce is in the map. -// -// This function is safe for concurrent access. -func (m *mruNonceMap) Exists(nonce uint64) bool { - m.mtx.Lock() - _, exists := m.nonceMap[nonce] - m.mtx.Unlock() - - return exists -} - -// Add adds the passed nonce to the map and handles eviction of the oldest item -// if adding the new item would exceed the max limit. Adding an existing item -// makes it the most recently used item. -// -// This function is safe for concurrent access. -func (m *mruNonceMap) Add(nonce uint64) { - m.mtx.Lock() - defer m.mtx.Unlock() - - // When the limit is zero, nothing can be added to the map, so just - // return. - if m.limit == 0 { - return - } - - // When the entry already exists move it to the front of the list - // thereby marking it most recently used. - if node, exists := m.nonceMap[nonce]; exists { - m.nonceList.MoveToFront(node) - return - } - - // Evict the least recently used entry (back of the list) if the the new - // entry would exceed the size limit for the map. Also reuse the list - // node so a new one doesn't have to be allocated. - if uint(len(m.nonceMap))+1 > m.limit { - node := m.nonceList.Back() - lru := node.Value.(uint64) - - // Evict least recently used item. - delete(m.nonceMap, lru) - - // Reuse the list node of the item that was just evicted for the - // new item. - node.Value = nonce - m.nonceList.MoveToFront(node) - m.nonceMap[nonce] = node - return - } - - // The limit hasn't been reached yet, so just add the new item. - node := m.nonceList.PushFront(nonce) - m.nonceMap[nonce] = node -} - -// Delete deletes the passed nonce from the map (if it exists). -// -// This function is safe for concurrent access. -func (m *mruNonceMap) Delete(nonce uint64) { - m.mtx.Lock() - if node, exists := m.nonceMap[nonce]; exists { - m.nonceList.Remove(node) - delete(m.nonceMap, nonce) - } - m.mtx.Unlock() -} - -// newMruNonceMap returns a new nonce map that is limited to the number of -// entries specified by limit. When the number of entries exceeds the limit, -// the oldest (least recently used) entry will be removed to make room for the -// new entry. -func newMruNonceMap(limit uint) *mruNonceMap { - m := mruNonceMap{ - nonceMap: make(map[uint64]*list.Element), - nonceList: list.New(), - limit: limit, - } - return &m -} diff --git a/vendor/github.com/btcsuite/btcd/peer/peer.go b/vendor/github.com/btcsuite/btcd/peer/peer.go index 11306ac..82010f3 100644 --- a/vendor/github.com/btcsuite/btcd/peer/peer.go +++ b/vendor/github.com/btcsuite/btcd/peer/peer.go @@ -24,6 +24,7 @@ import ( "github.com/btcsuite/btcd/wire" "github.com/btcsuite/go-socks/socks" "github.com/davecgh/go-spew/spew" + "github.com/decred/dcrd/lru" ) const ( @@ -82,7 +83,7 @@ var ( // sentNonces houses the unique nonces that are generated when pushing // version messages that are used to detect self connections. - sentNonces = newMruNonceMap(50) + sentNonces = lru.NewCache(50) // allowSelfConns is only used to allow the tests to bypass the self // connection detecting and disconnect logic since they intentionally @@ -450,7 +451,7 @@ type Peer struct { wireEncoding wire.MessageEncoding - knownInventory *mruInventoryMap + knownInventory lru.Cache prevGetBlocksMtx sync.Mutex prevGetBlocksBegin *chainhash.Hash prevGetBlocksStop *chainhash.Hash @@ -1626,7 +1627,7 @@ out: // Don't send inventory that became known after // the initial check. - if p.knownInventory.Exists(iv) { + if p.knownInventory.Contains(iv) { continue } @@ -1832,7 +1833,7 @@ func (p *Peer) QueueMessageWithEncoding(msg wire.Message, doneChan chan<- struct func (p *Peer) QueueInventory(invVect *wire.InvVect) { // Don't add the inventory to the send queue if the peer is already // known to have it. - if p.knownInventory.Exists(invVect) { + if p.knownInventory.Contains(invVect) { return } @@ -1891,7 +1892,7 @@ func (p *Peer) readRemoteVersionMsg() error { } // Detect self connections. - if !allowSelfConns && sentNonces.Exists(msg.Nonce) { + if !allowSelfConns && sentNonces.Contains(msg.Nonce) { return errors.New("disconnecting peer connected to self") } @@ -2097,7 +2098,7 @@ func (p *Peer) negotiateInboundProtocol() error { return p.readRemoteVerAckMsg() } -// negotiateOutoundProtocol performs the negotiation protocol for an outbound +// negotiateOutboundProtocol performs the negotiation protocol for an outbound // peer. The events should occur in the following order, otherwise an error is // returned: // @@ -2224,7 +2225,7 @@ func newPeerBase(origCfg *Config, inbound bool) *Peer { p := Peer{ inbound: inbound, wireEncoding: wire.BaseEncoding, - knownInventory: newMruInventoryMap(maxKnownInventory), + knownInventory: lru.NewCache(maxKnownInventory), stallControl: make(chan stallControlMsg, 1), // nonblocking sync outputQueue: make(chan outMsg, outputBufferSize), sendQueue: make(chan outMsg, 1), // nonblocking sync diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/chain.go b/vendor/github.com/btcsuite/btcd/rpcclient/chain.go index 996d804..9f0c6c6 100644 --- a/vendor/github.com/btcsuite/btcd/rpcclient/chain.go +++ b/vendor/github.com/btcsuite/btcd/rpcclient/chain.go @@ -52,14 +52,61 @@ func (c *Client) GetBestBlockHash() (*chainhash.Hash, error) { return c.GetBestBlockHashAsync().Receive() } +// legacyGetBlockRequest constructs and sends a legacy getblock request which +// contains two separate bools to denote verbosity, in contract to a single int +// parameter. +func (c *Client) legacyGetBlockRequest(hash string, verbose, + verboseTx bool) ([]byte, error) { + + hashJSON, err := json.Marshal(hash) + if err != nil { + return nil, err + } + verboseJSON, err := json.Marshal(btcjson.Bool(verbose)) + if err != nil { + return nil, err + } + verboseTxJSON, err := json.Marshal(btcjson.Bool(verboseTx)) + if err != nil { + return nil, err + } + return c.RawRequest("getblock", []json.RawMessage{ + hashJSON, verboseJSON, verboseTxJSON, + }) +} + +// waitForGetBlockRes waits for the response of a getblock request. If the +// response indicates an invalid parameter was provided, a legacy style of the +// request is resent and its response is returned instead. +func (c *Client) waitForGetBlockRes(respChan chan *response, hash string, + verbose, verboseTx bool) ([]byte, error) { + + res, err := receiveFuture(respChan) + + // If we receive an invalid parameter error, then we may be + // communicating with a btcd node which only understands the legacy + // request, so we'll try that. + if err, ok := err.(*btcjson.RPCError); ok && + err.Code == btcjson.ErrRPCInvalidParams.Code { + return c.legacyGetBlockRequest(hash, verbose, verboseTx) + } + + // Otherwise, we can return the response as is. + return res, err +} + // FutureGetBlockResult is a future promise to deliver the result of a // GetBlockAsync RPC invocation (or an applicable error). -type FutureGetBlockResult chan *response +type FutureGetBlockResult struct { + client *Client + hash string + Response 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) + res, err := r.client.waitForGetBlockRes(r.Response, r.hash, false, false) if err != nil { return nil, err } @@ -97,8 +144,12 @@ func (c *Client) GetBlockAsync(blockHash *chainhash.Hash) FutureGetBlockResult { hash = blockHash.String() } - cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(false), nil) - return c.sendCmd(cmd) + cmd := btcjson.NewGetBlockCmd(hash, btcjson.Int(0)) + return FutureGetBlockResult{ + client: c, + hash: hash, + Response: c.sendCmd(cmd), + } } // GetBlock returns a raw block from the server given its hash. @@ -111,12 +162,16 @@ func (c *Client) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) { // FutureGetBlockVerboseResult is a future promise to deliver the result of a // GetBlockVerboseAsync RPC invocation (or an applicable error). -type FutureGetBlockVerboseResult chan *response +type FutureGetBlockVerboseResult struct { + client *Client + hash string + Response 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) + res, err := r.client.waitForGetBlockRes(r.Response, r.hash, true, false) if err != nil { return nil, err } @@ -140,9 +195,14 @@ func (c *Client) GetBlockVerboseAsync(blockHash *chainhash.Hash) FutureGetBlockV if blockHash != nil { hash = blockHash.String() } - - cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), nil) - return c.sendCmd(cmd) + // From the bitcoin-cli getblock documentation: + // "If verbosity is 1, returns an Object with information about block ." + cmd := btcjson.NewGetBlockCmd(hash, btcjson.Int(1)) + return FutureGetBlockVerboseResult{ + client: c, + hash: hash, + Response: c.sendCmd(cmd), + } } // GetBlockVerbose returns a data structure from the server with information @@ -154,19 +214,52 @@ func (c *Client) GetBlockVerbose(blockHash *chainhash.Hash) (*btcjson.GetBlockVe return c.GetBlockVerboseAsync(blockHash).Receive() } +// FutureGetBlockVerboseTxResult is a future promise to deliver the result of a +// GetBlockVerboseTxResult RPC invocation (or an applicable error). +type FutureGetBlockVerboseTxResult struct { + client *Client + hash string + Response chan *response +} + +// Receive waits for the response promised by the future and returns a verbose +// version of the block including detailed information about its transactions. +func (r FutureGetBlockVerboseTxResult) Receive() (*btcjson.GetBlockVerboseTxResult, error) { + res, err := r.client.waitForGetBlockRes(r.Response, r.hash, true, true) + if err != nil { + return nil, err + } + + var blockResult btcjson.GetBlockVerboseTxResult + err = json.Unmarshal(res, &blockResult) + if err != nil { + return nil, err + } + + return &blockResult, nil +} + // 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 { +func (c *Client) GetBlockVerboseTxAsync(blockHash *chainhash.Hash) FutureGetBlockVerboseTxResult { hash := "" if blockHash != nil { hash = blockHash.String() } - cmd := btcjson.NewGetBlockCmd(hash, btcjson.Bool(true), btcjson.Bool(true)) - return c.sendCmd(cmd) + // From the bitcoin-cli getblock documentation: + // + // If verbosity is 2, returns an Object with information about block + // and information about each transaction. + cmd := btcjson.NewGetBlockCmd(hash, btcjson.Int(2)) + return FutureGetBlockVerboseTxResult{ + client: c, + hash: hash, + Response: c.sendCmd(cmd), + } } // GetBlockVerboseTx returns a data structure from the server with information @@ -174,7 +267,7 @@ func (c *Client) GetBlockVerboseTxAsync(blockHash *chainhash.Hash) FutureGetBloc // // 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) { +func (c *Client) GetBlockVerboseTx(blockHash *chainhash.Hash) (*btcjson.GetBlockVerboseTxResult, error) { return c.GetBlockVerboseTxAsync(blockHash).Receive() } @@ -214,6 +307,79 @@ func (c *Client) GetBlockCount() (int64, error) { return c.GetBlockCountAsync().Receive() } +// FutureGetChainTxStatsResult is a future promise to deliver the result of a +// GetChainTxStatsAsync RPC invocation (or an applicable error). +type FutureGetChainTxStatsResult chan *response + +// Receive waits for the response promised by the future and returns transaction statistics +func (r FutureGetChainTxStatsResult) Receive() (*btcjson.GetChainTxStatsResult, error) { + res, err := receiveFuture(r) + if err != nil { + return nil, err + } + + var chainTxStats btcjson.GetChainTxStatsResult + err = json.Unmarshal(res, &chainTxStats) + if err != nil { + return nil, err + } + + return &chainTxStats, nil +} + +// GetChainTxStatsAsync 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 GetChainTxStats for the blocking version and more details. +func (c *Client) GetChainTxStatsAsync() FutureGetChainTxStatsResult { + cmd := btcjson.NewGetChainTxStatsCmd(nil, nil) + return c.sendCmd(cmd) +} + +// GetChainTxStatsNBlocksAsync 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 GetChainTxStatsNBlocks for the blocking version and more details. +func (c *Client) GetChainTxStatsNBlocksAsync(nBlocks int32) FutureGetChainTxStatsResult { + cmd := btcjson.NewGetChainTxStatsCmd(&nBlocks, nil) + return c.sendCmd(cmd) +} + +// GetChainTxStatsNBlocksBlockHashAsync 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 GetChainTxStatsNBlocksBlockHash for the blocking version and more details. +func (c *Client) GetChainTxStatsNBlocksBlockHashAsync(nBlocks int32, blockHash chainhash.Hash) FutureGetChainTxStatsResult { + hash := blockHash.String() + cmd := btcjson.NewGetChainTxStatsCmd(&nBlocks, &hash) + return c.sendCmd(cmd) +} + +// GetChainTxStats returns statistics about the total number and rate of transactions in the chain. +// +// Size of the window is one month and it ends at chain tip. +func (c *Client) GetChainTxStats() (*btcjson.GetChainTxStatsResult, error) { + return c.GetChainTxStatsAsync().Receive() +} + +// GetChainTxStatsNBlocks returns statistics about the total number and rate of transactions in the chain. +// +// The argument specifies size of the window in number of blocks. The window ends at chain tip. +func (c *Client) GetChainTxStatsNBlocks(nBlocks int32) (*btcjson.GetChainTxStatsResult, error) { + return c.GetChainTxStatsNBlocksAsync(nBlocks).Receive() +} + +// GetChainTxStatsNBlocksBlockHash returns statistics about the total number and rate of transactions in the chain. +// +// First argument specifies size of the window in number of blocks. +// Second argument is the hash of the block that ends the window. +func (c *Client) GetChainTxStatsNBlocksBlockHash(nBlocks int32, blockHash chainhash.Hash) (*btcjson.GetChainTxStatsResult, error) { + return c.GetChainTxStatsNBlocksBlockHashAsync(nBlocks, blockHash).Receive() +} + // FutureGetDifficultyResult is a future promise to deliver the result of a // GetDifficultyAsync RPC invocation (or an applicable error). type FutureGetDifficultyResult chan *response @@ -649,6 +815,41 @@ func (c *Client) EstimateFee(numBlocks int64) (float64, error) { return c.EstimateFeeAsync(numBlocks).Receive() } +// FutureEstimateFeeResult is a future promise to deliver the result of a +// EstimateSmartFeeAsync RPC invocation (or an applicable error). +type FutureEstimateSmartFeeResult chan *response + +// Receive waits for the response promised by the future and returns the +// estimated fee. +func (r FutureEstimateSmartFeeResult) Receive() (*btcjson.EstimateSmartFeeResult, error) { + res, err := receiveFuture(r) + if err != nil { + return nil, err + } + + var verified btcjson.EstimateSmartFeeResult + err = json.Unmarshal(res, &verified) + if err != nil { + return nil, err + } + return &verified, nil +} + +// EstimateSmartFeeAsync 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 EstimateSmartFee for the blocking version and more details. +func (c *Client) EstimateSmartFeeAsync(confTarget int64, mode *btcjson.EstimateSmartFeeMode) FutureEstimateSmartFeeResult { + cmd := btcjson.NewEstimateSmartFeeCmd(confTarget, mode) + return c.sendCmd(cmd) +} + +// EstimateSmartFee requests the server to estimate a fee level based on the given parameters. +func (c *Client) EstimateSmartFee(confTarget int64, mode *btcjson.EstimateSmartFeeMode) (*btcjson.EstimateSmartFeeResult, error) { + return c.EstimateSmartFeeAsync(confTarget, mode).Receive() +} + // FutureVerifyChainResult is a future promise to deliver the result of a // VerifyChainAsync, VerifyChainLevelAsyncRPC, or VerifyChainBlocksAsync // invocation (or an applicable error). @@ -982,3 +1183,44 @@ func (c *Client) GetCFilterHeader(blockHash *chainhash.Hash, filterType wire.FilterType) (*wire.MsgCFHeaders, error) { return c.GetCFilterHeaderAsync(blockHash, filterType).Receive() } + +// FutureGetBlockStatsResult is a future promise to deliver the result of a +// GetBlockStatsAsync RPC invocation (or an applicable error). +type FutureGetBlockStatsResult chan *response + +// Receive waits for the response promised by the future and returns statistics +// of a block at a certain height. +func (r FutureGetBlockStatsResult) Receive() (*btcjson.GetBlockStatsResult, error) { + res, err := receiveFuture(r) + if err != nil { + return nil, err + } + + var blockStats btcjson.GetBlockStatsResult + err = json.Unmarshal(res, &blockStats) + if err != nil { + return nil, err + } + + return &blockStats, nil +} + +// GetBlockStatsAsync 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 GetBlockStats or the blocking version and more details. +func (c *Client) GetBlockStatsAsync(hashOrHeight interface{}, stats *[]string) FutureGetBlockStatsResult { + if hash, ok := hashOrHeight.(*chainhash.Hash); ok { + hashOrHeight = hash.String() + } + + cmd := btcjson.NewGetBlockStatsCmd(btcjson.HashOrHeight{Value: hashOrHeight}, stats) + return c.sendCmd(cmd) +} + +// GetBlockStats returns block statistics. First argument specifies height or hash of the target block. +// Second argument allows to select certain stats to return. +func (c *Client) GetBlockStats(hashOrHeight interface{}, stats *[]string) (*btcjson.GetBlockStatsResult, error) { + return c.GetBlockStatsAsync(hashOrHeight, stats).Receive() +} diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/cookiefile.go b/vendor/github.com/btcsuite/btcd/rpcclient/cookiefile.go new file mode 100644 index 0000000..c3f7068 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/rpcclient/cookiefile.go @@ -0,0 +1,38 @@ +// Copyright (c) 2017 The Namecoin developers +// Copyright (c) 2019 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 ( + "bufio" + "fmt" + "os" + "strings" +) + +func readCookieFile(path string) (username, password string, err error) { + f, err := os.Open(path) + if err != nil { + return + } + defer f.Close() + + scanner := bufio.NewScanner(f) + scanner.Scan() + err = scanner.Err() + if err != nil { + return + } + s := scanner.Text() + + parts := strings.SplitN(s, ":", 2) + if len(parts) != 2 { + err = fmt.Errorf("malformed cookie file") + return + } + + username, password = parts[0], parts[1] + return +} diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/doc.go b/vendor/github.com/btcsuite/btcd/rpcclient/doc.go index d4bbb64..b682ba1 100644 --- a/vendor/github.com/btcsuite/btcd/rpcclient/doc.go +++ b/vendor/github.com/btcsuite/btcd/rpcclient/doc.go @@ -106,7 +106,7 @@ 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 +from the server. An effort has been made to call out which commands are extensions in their documentation. Also, it is important to realize that btcd intentionally separates the wallet diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/infrastructure.go b/vendor/github.com/btcsuite/btcd/rpcclient/infrastructure.go index 7a8f188..8609e7c 100644 --- a/vendor/github.com/btcsuite/btcd/rpcclient/infrastructure.go +++ b/vendor/github.com/btcsuite/btcd/rpcclient/infrastructure.go @@ -19,12 +19,14 @@ import ( "net" "net/http" "net/url" + "os" "strings" "sync" "sync/atomic" "time" "github.com/btcsuite/btcd/btcjson" + "github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/go-socks/socks" "github.com/btcsuite/websocket" ) @@ -138,6 +140,10 @@ type Client struct { // config holds the connection configuration assoiated with this client. config *ConnConfig + // chainParams holds the params for the chain that this client is using, + // and is used for many wallet methods. + chainParams *chaincfg.Params + // wsConn is the underlying websocket connection when not in HTTP POST // mode. wsConn *websocket.Conn @@ -283,31 +289,29 @@ func (c *Client) trackRegisteredNtfns(cmd interface{}) { } } -type ( - // inMessage is the first type that an incoming message is unmarshaled - // into. It supports both requests (for notification support) and - // responses. The partially-unmarshaled message is a notification if - // the embedded ID (from the response) is nil. Otherwise, it is a - // response. - inMessage struct { - ID *float64 `json:"id"` - *rawNotification - *rawResponse - } +// inMessage is the first type that an incoming message is unmarshaled +// into. It supports both requests (for notification support) and +// responses. The partially-unmarshaled message is a notification if +// the embedded ID (from the response) is nil. Otherwise, it is a +// response. +type inMessage struct { + ID *float64 `json:"id"` + *rawNotification + *rawResponse +} - // rawNotification is a partially-unmarshaled JSON-RPC notification. - rawNotification struct { - Method string `json:"method"` - Params []json.RawMessage `json:"params"` - } +// rawNotification is a partially-unmarshaled JSON-RPC notification. +type rawNotification struct { + Method string `json:"method"` + Params []json.RawMessage `json:"params"` +} - // rawResponse is a partially-unmarshaled JSON-RPC response. For this - // to be valid (according to JSON-RPC 1.0 spec), ID may not be nil. - rawResponse struct { - Result json.RawMessage `json:"result"` - Error *btcjson.RPCError `json:"error"` - } -) +// rawResponse is a partially-unmarshaled JSON-RPC response. For this +// to be valid (according to JSON-RPC 1.0 spec), ID may not be nil. +type rawResponse struct { + Result json.RawMessage `json:"result"` + Error *btcjson.RPCError `json:"error"` +} // response is the raw bytes of a JSON-RPC result, or the error if the response // error object was non-null. @@ -848,7 +852,12 @@ func (c *Client) sendPost(jReq *jsonRequest) { httpReq.Header.Set("Content-Type", "application/json") // Configure basic access authorization. - httpReq.SetBasicAuth(c.config.User, c.config.Pass) + user, pass, err := c.config.getAuth() + if err != nil { + jReq.responseChan <- &response{result: nil, err: err} + return + } + httpReq.SetBasicAuth(user, pass) log.Tracef("Sending command [%s] with id %d", jReq.method, jReq.id) c.sendPostRequest(httpReq, jReq) @@ -1093,6 +1102,22 @@ type ConnConfig struct { // Pass is the passphrase to use to authenticate to the RPC server. Pass string + // CookiePath is the path to a cookie file containing the username and + // passphrase to use to authenticate to the RPC server. It is used + // instead of User and Pass if non-empty. + CookiePath string + + cookieLastCheckTime time.Time + cookieLastModTime time.Time + cookieLastUser string + cookieLastPass string + cookieLastErr error + + // Params is the string representing the network that the server + // is running. If there is no parameter set in the config, then + // mainnet will be used by default. + Params string + // DisableTLS specifies whether transport layer security should be // disabled. It is recommended to always use TLS if the RPC server // supports it as otherwise your username and password is sent across @@ -1141,6 +1166,43 @@ type ConnConfig struct { EnableBCInfoHacks bool } +// getAuth returns the username and passphrase that will actually be used for +// this connection. This will be the result of checking the cookie if a cookie +// path is configured; if not, it will be the user-configured username and +// passphrase. +func (config *ConnConfig) getAuth() (username, passphrase string, err error) { + // Try username+passphrase auth first. + if config.Pass != "" { + return config.User, config.Pass, nil + } + + // If no username or passphrase is set, try cookie auth. + return config.retrieveCookie() +} + +// retrieveCookie returns the cookie username and passphrase. +func (config *ConnConfig) retrieveCookie() (username, passphrase string, err error) { + if !config.cookieLastCheckTime.IsZero() && time.Now().Before(config.cookieLastCheckTime.Add(30*time.Second)) { + return config.cookieLastUser, config.cookieLastPass, config.cookieLastErr + } + + config.cookieLastCheckTime = time.Now() + + st, err := os.Stat(config.CookiePath) + if err != nil { + config.cookieLastErr = err + return config.cookieLastUser, config.cookieLastPass, config.cookieLastErr + } + + modTime := st.ModTime() + if !modTime.Equal(config.cookieLastModTime) { + config.cookieLastModTime = modTime + config.cookieLastUser, config.cookieLastPass, config.cookieLastErr = readCookieFile(config.CookiePath) + } + + return config.cookieLastUser, config.cookieLastPass, config.cookieLastErr +} + // newHTTPClient returns a new http client that is configured according to the // proxy and TLS settings in the associated connection configuration. func newHTTPClient(config *ConnConfig) (*http.Client, error) { @@ -1210,7 +1272,11 @@ func dial(config *ConnConfig) (*websocket.Conn, error) { // The RPC server requires basic authorization, so create a custom // request header with the Authorization header set. - login := config.User + ":" + config.Pass + user, pass, err := config.getAuth() + if err != nil { + return nil, err + } + login := user + ":" + pass auth := "Basic " + base64.StdEncoding.EncodeToString([]byte(login)) requestHeader := make(http.Header) requestHeader.Add("Authorization", auth) @@ -1290,6 +1356,23 @@ func New(config *ConnConfig, ntfnHandlers *NotificationHandlers) (*Client, error shutdown: make(chan struct{}), } + // Default network is mainnet, no parameters are necessary but if mainnet + // is specified it will be the param + switch config.Params { + case "": + fallthrough + case chaincfg.MainNetParams.Name: + client.chainParams = &chaincfg.MainNetParams + case chaincfg.TestNet3Params.Name: + client.chainParams = &chaincfg.TestNet3Params + case chaincfg.RegressionNetParams.Name: + client.chainParams = &chaincfg.RegressionNetParams + case chaincfg.SimNetParams.Name: + client.chainParams = &chaincfg.SimNetParams + default: + return nil, fmt.Errorf("rpcclient.New: Unknown chain %s", config.Params) + } + if start { log.Infof("Established connection to RPC server %s", config.Host) diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/mining.go b/vendor/github.com/btcsuite/btcd/rpcclient/mining.go index 76a9d30..8717d32 100644 --- a/vendor/github.com/btcsuite/btcd/rpcclient/mining.go +++ b/vendor/github.com/btcsuite/btcd/rpcclient/mining.go @@ -61,6 +61,53 @@ func (c *Client) Generate(numBlocks uint32) ([]*chainhash.Hash, error) { return c.GenerateAsync(numBlocks).Receive() } +// FutureGenerateToAddressResult is a future promise to deliver the result of a +// GenerateToAddressResult RPC invocation (or an applicable error). +type FutureGenerateToAddressResult chan *response + +// Receive waits for the response promised by the future and returns the hashes of +// of the generated blocks. +func (f FutureGenerateToAddressResult) Receive() ([]*chainhash.Hash, error) { + res, err := receiveFuture(f) + 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 +} + +// GenerateToAddressAsync 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 GenerateToAddress for the blocking version and more details. +func (c *Client) GenerateToAddressAsync(numBlocks int64, address btcutil.Address, maxTries *int64) FutureGenerateToAddressResult { + cmd := btcjson.NewGenerateToAddressCmd(numBlocks, address.EncodeAddress(), maxTries) + return c.sendCmd(cmd) +} + +// GenerateToAddress generates numBlocks blocks to the given address and returns their hashes. +func (c *Client) GenerateToAddress(numBlocks int64, address btcutil.Address, maxTries *int64) ([]*chainhash.Hash, error) { + return c.GenerateToAddressAsync(numBlocks, address, maxTries).Receive() +} + // FutureGetGenerateResult is a future promise to deliver the result of a // GetGenerateAsync RPC invocation (or an applicable error). type FutureGetGenerateResult chan *response diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/notify.go b/vendor/github.com/btcsuite/btcd/rpcclient/notify.go index 2454a94..1feb755 100644 --- a/vendor/github.com/btcsuite/btcd/rpcclient/notify.go +++ b/vendor/github.com/btcsuite/btcd/rpcclient/notify.go @@ -95,7 +95,7 @@ type NotificationHandlers struct { // NotifyBlocks has been made to register for the notification and the // function is non-nil. // - // NOTE: Deprecated. Use OnFilteredBlockConnected instead. + // Deprecated: Use OnFilteredBlockConnected instead. OnBlockConnected func(hash *chainhash.Hash, height int32, t time.Time) // OnFilteredBlockConnected is invoked when a block is connected to the @@ -111,7 +111,7 @@ type NotificationHandlers struct { // NotifyBlocks has been made to register for the notification and the // function is non-nil. // - // NOTE: Deprecated. Use OnFilteredBlockDisconnected instead. + // Deprecated: Use OnFilteredBlockDisconnected instead. OnBlockDisconnected func(hash *chainhash.Hash, height int32, t time.Time) // OnFilteredBlockDisconnected is invoked when a block is disconnected @@ -127,7 +127,7 @@ type NotificationHandlers struct { // preceding call to NotifyReceived, Rescan, or RescanEndHeight has been // made to register for the notification and the function is non-nil. // - // NOTE: Deprecated. Use OnRelevantTxAccepted instead. + // Deprecated: Use OnRelevantTxAccepted instead. OnRecvTx func(transaction *btcutil.Tx, details *btcjson.BlockDetails) // OnRedeemingTx is invoked when a transaction that spends a registered @@ -141,7 +141,7 @@ type NotificationHandlers struct { // funds to the registered addresses. This means it is possible for // this to invoked indirectly as the result of a NotifyReceived call. // - // NOTE: Deprecated. Use OnRelevantTxAccepted instead. + // Deprecated: Use OnRelevantTxAccepted instead. OnRedeemingTx func(transaction *btcutil.Tx, details *btcjson.BlockDetails) // OnRelevantTxAccepted is invoked when an unmined transaction passes @@ -157,14 +157,14 @@ type NotificationHandlers struct { // result of a rescan request, due to how btcd may send various rescan // notifications after the rescan request has already returned. // - // NOTE: Deprecated. Not used with RescanBlocks. + // Deprecated: Not used with RescanBlocks. OnRescanFinished func(hash *chainhash.Hash, height int32, blkTime time.Time) // OnRescanProgress is invoked periodically when a rescan is underway. // It will only be invoked if a preceding call to Rescan or // RescanEndHeight has been made and the function is non-nil. // - // NOTE: Deprecated. Not used with RescanBlocks. + // Deprecated: Not used with RescanBlocks. OnRescanProgress func(hash *chainhash.Hash, height int32, blkTime time.Time) // OnTxAccepted is invoked when a transaction is accepted into the @@ -905,7 +905,7 @@ func (c *Client) NotifyBlocks() error { // FutureNotifySpentResult is a future promise to deliver the result of a // NotifySpentAsync RPC invocation (or an applicable error). // -// NOTE: Deprecated. Use FutureLoadTxFilterResult instead. +// Deprecated: Use FutureLoadTxFilterResult instead. type FutureNotifySpentResult chan *response // Receive waits for the response promised by the future and returns an error @@ -951,7 +951,7 @@ func newOutPointFromWire(op *wire.OutPoint) btcjson.OutPoint { // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use LoadTxFilterAsync instead. +// Deprecated: Use LoadTxFilterAsync instead. func (c *Client) NotifySpentAsync(outpoints []*wire.OutPoint) FutureNotifySpentResult { // Not supported in HTTP POST mode. if c.config.HTTPPostMode { @@ -983,7 +983,7 @@ func (c *Client) NotifySpentAsync(outpoints []*wire.OutPoint) FutureNotifySpentR // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use LoadTxFilter instead. +// Deprecated: Use LoadTxFilter instead. func (c *Client) NotifySpent(outpoints []*wire.OutPoint) error { return c.NotifySpentAsync(outpoints).Receive() } @@ -1040,7 +1040,7 @@ func (c *Client) NotifyNewTransactions(verbose bool) error { // FutureNotifyReceivedResult is a future promise to deliver the result of a // NotifyReceivedAsync RPC invocation (or an applicable error). // -// NOTE: Deprecated. Use FutureLoadTxFilterResult instead. +// Deprecated: Use FutureLoadTxFilterResult instead. type FutureNotifyReceivedResult chan *response // Receive waits for the response promised by the future and returns an error @@ -1078,7 +1078,7 @@ func (c *Client) notifyReceivedInternal(addresses []string) FutureNotifyReceived // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use LoadTxFilterAsync instead. +// Deprecated: Use LoadTxFilterAsync instead. func (c *Client) NotifyReceivedAsync(addresses []btcutil.Address) FutureNotifyReceivedResult { // Not supported in HTTP POST mode. if c.config.HTTPPostMode { @@ -1118,7 +1118,7 @@ func (c *Client) NotifyReceivedAsync(addresses []btcutil.Address) FutureNotifyRe // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use LoadTxFilter instead. +// Deprecated: Use LoadTxFilter instead. func (c *Client) NotifyReceived(addresses []btcutil.Address) error { return c.NotifyReceivedAsync(addresses).Receive() } @@ -1126,7 +1126,7 @@ func (c *Client) NotifyReceived(addresses []btcutil.Address) error { // FutureRescanResult is a future promise to deliver the result of a RescanAsync // or RescanEndHeightAsync RPC invocation (or an applicable error). // -// NOTE: Deprecated. Use FutureRescanBlocksResult instead. +// Deprecated: Use FutureRescanBlocksResult instead. type FutureRescanResult chan *response // Receive waits for the response promised by the future and returns an error @@ -1150,7 +1150,7 @@ func (r FutureRescanResult) Receive() error { // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use RescanBlocksAsync instead. +// Deprecated: Use RescanBlocksAsync instead. func (c *Client) RescanAsync(startBlock *chainhash.Hash, addresses []btcutil.Address, outpoints []*wire.OutPoint) FutureRescanResult { @@ -1215,7 +1215,7 @@ func (c *Client) RescanAsync(startBlock *chainhash.Hash, // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use RescanBlocks instead. +// Deprecated: Use RescanBlocks instead. func (c *Client) Rescan(startBlock *chainhash.Hash, addresses []btcutil.Address, outpoints []*wire.OutPoint) error { @@ -1231,7 +1231,7 @@ func (c *Client) Rescan(startBlock *chainhash.Hash, // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use RescanBlocksAsync instead. +// Deprecated: Use RescanBlocksAsync instead. func (c *Client) RescanEndBlockAsync(startBlock *chainhash.Hash, addresses []btcutil.Address, outpoints []*wire.OutPoint, endBlock *chainhash.Hash) FutureRescanResult { @@ -1293,7 +1293,7 @@ func (c *Client) RescanEndBlockAsync(startBlock *chainhash.Hash, // // NOTE: This is a btcd extension and requires a websocket connection. // -// NOTE: Deprecated. Use RescanBlocks instead. +// Deprecated: Use RescanBlocks instead. func (c *Client) RescanEndHeight(startBlock *chainhash.Hash, addresses []btcutil.Address, outpoints []*wire.OutPoint, endBlock *chainhash.Hash) error { diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/rawtransactions.go b/vendor/github.com/btcsuite/btcd/rpcclient/rawtransactions.go index 4bf4ee5..4e8d4e4 100644 --- a/vendor/github.com/btcsuite/btcd/rpcclient/rawtransactions.go +++ b/vendor/github.com/btcsuite/btcd/rpcclient/rawtransactions.go @@ -205,6 +205,47 @@ func (c *Client) DecodeRawTransaction(serializedTx []byte) (*btcjson.TxRawResult return c.DecodeRawTransactionAsync(serializedTx).Receive() } +// FutureFundRawTransactionResult is a future promise to deliver the result +// of a FutureFundRawTransactionAsync RPC invocation (or an applicable error). +type FutureFundRawTransactionResult chan *response + +// Receive waits for the response promised by the future and returns information +// about a funding attempt +func (r FutureFundRawTransactionResult) Receive() (*btcjson.FundRawTransactionResult, error) { + res, err := receiveFuture(r) + if err != nil { + return nil, err + } + + var marshalled btcjson.FundRawTransactionResult + if err := json.Unmarshal(res, &marshalled); err != nil { + return nil, err + } + + return &marshalled, nil +} + +// FundRawTransactionAsync 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 FundRawTransaction for the blocking version and more details. +func (c *Client) FundRawTransactionAsync(tx *wire.MsgTx, opts btcjson.FundRawTransactionOpts, isWitness *bool) FutureFundRawTransactionResult { + var txBuf bytes.Buffer + if err := tx.Serialize(&txBuf); err != nil { + return newFutureError(err) + } + + cmd := btcjson.NewFundRawTransactionCmd(txBuf.Bytes(), opts, isWitness) + return c.sendCmd(cmd) +} + +// FundRawTransaction returns the result of trying to fund the given transaction with +// funds from the node wallet +func (c *Client) FundRawTransaction(tx *wire.MsgTx, opts btcjson.FundRawTransactionOpts, isWitness *bool) (*btcjson.FundRawTransactionResult, error) { + return c.FundRawTransactionAsync(tx, opts, isWitness).Receive() +} + // FutureCreateRawTransactionResult is a future promise to deliver the result // of a CreateRawTransactionAsync RPC invocation (or an applicable error). type FutureCreateRawTransactionResult chan *response @@ -233,8 +274,13 @@ func (r FutureCreateRawTransactionResult) Receive() (*wire.MsgTx, error) { // Deserialize the transaction and return it. var msgTx wire.MsgTx - if err := msgTx.Deserialize(bytes.NewReader(serializedTx)); err != nil { - return nil, err + // we try both the new and old encoding format + witnessErr := msgTx.Deserialize(bytes.NewReader(serializedTx)) + if witnessErr != nil { + legacyErr := msgTx.DeserializeNoWitness(bytes.NewReader(serializedTx)) + if legacyErr != nil { + return nil, legacyErr + } } return &msgTx, nil } @@ -256,7 +302,8 @@ func (c *Client) CreateRawTransactionAsync(inputs []btcjson.TransactionInput, } // CreateRawTransaction returns a new transaction spending the provided inputs -// and sending to the provided addresses. +// and sending to the provided addresses. If the inputs are either nil or an +// empty slice, it is interpreted as an empty slice. func (c *Client) CreateRawTransaction(inputs []btcjson.TransactionInput, amounts map[btcutil.Address]btcutil.Amount, lockTime *int64) (*wire.MsgTx, error) { diff --git a/vendor/github.com/btcsuite/btcd/rpcclient/wallet.go b/vendor/github.com/btcsuite/btcd/rpcclient/wallet.go index 27546f5..37bf947 100644 --- a/vendor/github.com/btcsuite/btcd/rpcclient/wallet.go +++ b/vendor/github.com/btcsuite/btcd/rpcclient/wallet.go @@ -20,7 +20,8 @@ import ( // ***************************** // FutureGetTransactionResult is a future promise to deliver the result -// of a GetTransactionAsync RPC invocation (or an applicable error). +// of a GetTransactionAsync or GetTransactionWatchOnlyAsync RPC invocation +// (or an applicable error). type FutureGetTransactionResult chan *response // Receive waits for the response promised by the future and returns detailed @@ -63,6 +64,28 @@ func (c *Client) GetTransaction(txHash *chainhash.Hash) (*btcjson.GetTransaction return c.GetTransactionAsync(txHash).Receive() } +// GetTransactionWatchOnlyAsync 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 GetTransactionWatchOnly for the blocking version and more details. +func (c *Client) GetTransactionWatchOnlyAsync(txHash *chainhash.Hash, watchOnly bool) FutureGetTransactionResult { + hash := "" + if txHash != nil { + hash = txHash.String() + } + + cmd := btcjson.NewGetTransactionCmd(hash, &watchOnly) + return c.sendCmd(cmd) +} + +// GetTransactionWatchOnly returns detailed information about a wallet +// transaction, and allow including watch-only addresses in balance +// calculation and details. +func (c *Client) GetTransactionWatchOnly(txHash *chainhash.Hash, watchOnly bool) (*btcjson.GetTransactionResult, error) { + return c.GetTransactionWatchOnlyAsync(txHash, watchOnly).Receive() +} + // FutureListTransactionsResult is a future promise to deliver the result of a // ListTransactionsAsync, ListTransactionsCountAsync, or // ListTransactionsCountFromAsync RPC invocation (or an applicable error). @@ -753,13 +776,16 @@ func (c *Client) SendManyComment(fromAccount string, // FutureAddMultisigAddressResult is a future promise to deliver the result of a // AddMultisigAddressAsync RPC invocation (or an applicable error). -type FutureAddMultisigAddressResult chan *response +type FutureAddMultisigAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the // multisignature address that requires the specified number of signatures for // the provided addresses. func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -771,7 +797,7 @@ func (r FutureAddMultisigAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // AddMultisigAddressAsync returns an instance of a type that can be used to get @@ -786,14 +812,17 @@ func (c *Client) AddMultisigAddressAsync(requiredSigs int, addresses []btcutil.A } cmd := btcjson.NewAddMultisigAddressCmd(requiredSigs, addrs, &account) - return c.sendCmd(cmd) + result := FutureAddMultisigAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // AddMultisigAddress adds a multisignature address that requires the specified // number of signatures for the provided addresses to the wallet. func (c *Client) AddMultisigAddress(requiredSigs int, addresses []btcutil.Address, account string) (btcutil.Address, error) { - return c.AddMultisigAddressAsync(requiredSigs, addresses, - account).Receive() + return c.AddMultisigAddressAsync(requiredSigs, addresses, account).Receive() } // FutureCreateMultisigResult is a future promise to deliver the result of a @@ -868,12 +897,15 @@ func (c *Client) CreateNewAccount(account string) error { // FutureGetNewAddressResult is a future promise to deliver the result of a // GetNewAddressAsync RPC invocation (or an applicable error). -type FutureGetNewAddressResult chan *response +type FutureGetNewAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns a new // address. func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -885,7 +917,7 @@ func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // GetNewAddressAsync returns an instance of a type that can be used to get the @@ -895,23 +927,31 @@ func (r FutureGetNewAddressResult) Receive() (btcutil.Address, error) { // See GetNewAddress for the blocking version and more details. func (c *Client) GetNewAddressAsync(account string) FutureGetNewAddressResult { cmd := btcjson.NewGetNewAddressCmd(&account) - return c.sendCmd(cmd) + result := FutureGetNewAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } -// GetNewAddress returns a new address. +// GetNewAddress returns a new address, and decodes based on the client's +// chain params. func (c *Client) GetNewAddress(account string) (btcutil.Address, error) { return c.GetNewAddressAsync(account).Receive() } // FutureGetRawChangeAddressResult is a future promise to deliver the result of // a GetRawChangeAddressAsync RPC invocation (or an applicable error). -type FutureGetRawChangeAddressResult chan *response +type FutureGetRawChangeAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns a new // address for receiving change that will be associated with the provided // account. Note that this is only for raw transactions and NOT for normal use. func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -923,7 +963,7 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // GetRawChangeAddressAsync returns an instance of a type that can be used to @@ -933,7 +973,11 @@ func (r FutureGetRawChangeAddressResult) Receive() (btcutil.Address, error) { // See GetRawChangeAddress for the blocking version and more details. func (c *Client) GetRawChangeAddressAsync(account string) FutureGetRawChangeAddressResult { cmd := btcjson.NewGetRawChangeAddressCmd(&account) - return c.sendCmd(cmd) + result := FutureGetRawChangeAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // GetRawChangeAddress returns a new address for receiving change that will be @@ -945,12 +989,15 @@ func (c *Client) GetRawChangeAddress(account string) (btcutil.Address, error) { // FutureAddWitnessAddressResult is a future promise to deliver the result of // a AddWitnessAddressAsync RPC invocation (or an applicable error). -type FutureAddWitnessAddressResult chan *response +type FutureAddWitnessAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the new // address. func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -962,7 +1009,7 @@ func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // AddWitnessAddressAsync returns an instance of a type that can be used to get @@ -972,7 +1019,11 @@ func (r FutureAddWitnessAddressResult) Receive() (btcutil.Address, error) { // See AddWitnessAddress for the blocking version and more details. func (c *Client) AddWitnessAddressAsync(address string) FutureAddWitnessAddressResult { cmd := btcjson.NewAddWitnessAddressCmd(address) - return c.sendCmd(cmd) + response := FutureAddWitnessAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return response } // AddWitnessAddress adds a witness address for a script and returns the new @@ -983,12 +1034,15 @@ func (c *Client) AddWitnessAddress(address string) (btcutil.Address, error) { // FutureGetAccountAddressResult is a future promise to deliver the result of a // GetAccountAddressAsync RPC invocation (or an applicable error). -type FutureGetAccountAddressResult chan *response +type FutureGetAccountAddressResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the current // Bitcoin address for receiving payments to the specified account. func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -1000,7 +1054,7 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { return nil, err } - return btcutil.DecodeAddress(addr, &chaincfg.MainNetParams) + return btcutil.DecodeAddress(addr, r.network) } // GetAccountAddressAsync returns an instance of a type that can be used to get @@ -1010,7 +1064,11 @@ func (r FutureGetAccountAddressResult) Receive() (btcutil.Address, error) { // See GetAccountAddress for the blocking version and more details. func (c *Client) GetAccountAddressAsync(account string) FutureGetAccountAddressResult { cmd := btcjson.NewGetAccountAddressCmd(account) - return c.sendCmd(cmd) + result := FutureGetAccountAddressResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // GetAccountAddress returns the current Bitcoin address for receiving payments @@ -1086,12 +1144,15 @@ func (c *Client) SetAccount(address btcutil.Address, account string) error { // FutureGetAddressesByAccountResult is a future promise to deliver the result // of a GetAddressesByAccountAsync RPC invocation (or an applicable error). -type FutureGetAddressesByAccountResult chan *response +type FutureGetAddressesByAccountResult struct { + responseChannel chan *response + network *chaincfg.Params +} // Receive waits for the response promised by the future and returns the list of // addresses associated with the passed account. func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) { - res, err := receiveFuture(r) + res, err := receiveFuture(r.responseChannel) if err != nil { return nil, err } @@ -1103,17 +1164,15 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) return nil, err } - addrs := make([]btcutil.Address, 0, len(addrStrings)) - for _, addrStr := range addrStrings { - addr, err := btcutil.DecodeAddress(addrStr, - &chaincfg.MainNetParams) + addresses := make([]btcutil.Address, len(addrStrings)) + for i, addrString := range addrStrings { + addresses[i], err = btcutil.DecodeAddress(addrString, r.network) if err != nil { return nil, err } - addrs = append(addrs, addr) } - return addrs, nil + return addresses, nil } // GetAddressesByAccountAsync returns an instance of a type that can be used to @@ -1123,7 +1182,11 @@ func (r FutureGetAddressesByAccountResult) Receive() ([]btcutil.Address, error) // See GetAddressesByAccount for the blocking version and more details. func (c *Client) GetAddressesByAccountAsync(account string) FutureGetAddressesByAccountResult { cmd := btcjson.NewGetAddressesByAccountCmd(account) - return c.sendCmd(cmd) + result := FutureGetAddressesByAccountResult{ + network: c.chainParams, + responseChannel: c.sendCmd(cmd), + } + return result } // GetAddressesByAccount returns the list of addresses associated with the @@ -1507,6 +1570,43 @@ func (c *Client) GetBalanceMinConf(account string, minConfirms int) (btcutil.Amo return c.GetBalanceMinConfAsync(account, minConfirms).Receive() } +// FutureGetBalancesResult is a future promise to deliver the result of a +// GetBalancesAsync RPC invocation (or an applicable error). +type FutureGetBalancesResult chan *response + +// Receive waits for the response promised by the future and returns the +// available balances from the server. +func (r FutureGetBalancesResult) Receive() (*btcjson.GetBalancesResult, error) { + res, err := receiveFuture(r) + if err != nil { + return nil, err + } + + // Unmarshal result as a floating point number. + var balances btcjson.GetBalancesResult + err = json.Unmarshal(res, &balances) + if err != nil { + return nil, err + } + + return &balances, nil +} + +// GetBalancesAsync 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 GetBalances for the blocking version and more details. +func (c *Client) GetBalancesAsync() FutureGetBalancesResult { + cmd := btcjson.NewGetBalancesCmd() + return c.sendCmd(cmd) +} + +// GetBalances returns the available balances from the server. +func (c *Client) GetBalances() (*btcjson.GetBalancesResult, error) { + return c.GetBalancesAsync().Receive() +} + // FutureGetReceivedByAccountResult is a future promise to deliver the result of // a GetReceivedByAccountAsync or GetReceivedByAccountMinConfAsync RPC // invocation (or an applicable error). diff --git a/vendor/github.com/btcsuite/btcd/txscript/engine.go b/vendor/github.com/btcsuite/btcd/txscript/engine.go index db66186..f2d7b30 100644 --- a/vendor/github.com/btcsuite/btcd/txscript/engine.go +++ b/vendor/github.com/btcsuite/btcd/txscript/engine.go @@ -586,7 +586,7 @@ func (vm *Engine) checkPubKeyEncoding(pubKey []byte) error { if vm.hasFlag(ScriptVerifyWitnessPubKeyType) && vm.isWitnessVersionActive(0) && !btcec.IsCompressedPubKey(pubKey) { - str := "only uncompressed keys are accepted post-segwit" + str := "only compressed keys are accepted post-segwit" return scriptError(ErrWitnessPubKeyType, str) } diff --git a/vendor/github.com/btcsuite/btcutil/go.mod b/vendor/github.com/btcsuite/btcutil/go.mod new file mode 100644 index 0000000..d455377 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/go.mod @@ -0,0 +1,11 @@ +module github.com/btcsuite/btcutil + +go 1.13 + +require ( + github.com/aead/siphash v1.0.1 + github.com/btcsuite/btcd v0.20.1-beta + github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 + github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 + golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d +) diff --git a/vendor/github.com/btcsuite/btcutil/go.sum b/vendor/github.com/btcsuite/btcutil/go.sum new file mode 100644 index 0000000..088c1a3 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/go.sum @@ -0,0 +1,54 @@ +github.com/aead/siphash v1.0.1 h1:FwHfE/T45KPKYuuSAKyyvE+oPWcaQ+CUmFW0bPlM+kg= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +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= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723 h1:ZA/jbKoGcVAnER6pCHPEkGdZOV7U1oLUedErBHCUMs0= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495 h1:6IyqGr3fnd0tM3YxipK27TUskaOVUjU2nG45yzwcQKY= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +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/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d h1:2+ZP7EfsZV7Vvmx3TIqSlSzATMkTAKqM14YGFPoSKjI= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/btcsuite/btcutil/psbt/LICENSE b/vendor/github.com/btcsuite/btcutil/psbt/LICENSE new file mode 100644 index 0000000..3e7b167 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2013-2017 The btcsuite developers +Copyright (c) 2016-2017 The Lightning Network 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. diff --git a/vendor/github.com/btcsuite/btcutil/psbt/bip32.go b/vendor/github.com/btcsuite/btcutil/psbt/bip32.go new file mode 100644 index 0000000..9fbfc73 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/bip32.go @@ -0,0 +1,77 @@ +package psbt + +import ( + "bytes" + "encoding/binary" +) + +// Bip32Derivation encapsulates the data for the input and output +// Bip32Derivation key-value fields. +// +// TODO(roasbeef): use hdkeychain here instead? +type Bip32Derivation struct { + // PubKey is the raw pubkey serialized in compressed format. + PubKey []byte + + // MasterKeyFingerprint is the finger print of the master pubkey. + MasterKeyFingerprint uint32 + + // Bip32Path is the BIP 32 path with child index as a distinct integer. + Bip32Path []uint32 +} + +// checkValid ensures that the PubKey in the Bip32Derivation struct is valid. +func (pb *Bip32Derivation) checkValid() bool { + return validatePubkey(pb.PubKey) +} + +// Bip32Sorter implements sort.Interface for the Bip32Derivation struct. +type Bip32Sorter []*Bip32Derivation + +func (s Bip32Sorter) Len() int { return len(s) } + +func (s Bip32Sorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func (s Bip32Sorter) Less(i, j int) bool { + return bytes.Compare(s[i].PubKey, s[j].PubKey) < 0 +} + +// readBip32Derivation deserializes a byte slice containing chunks of 4 byte +// little endian encodings of uint32 values, the first of which is the +// masterkeyfingerprint and the remainder of which are the derivation path. +func readBip32Derivation(path []byte) (uint32, []uint32, error) { + + if len(path)%4 != 0 || len(path)/4-1 < 1 { + return 0, nil, ErrInvalidPsbtFormat + } + + masterKeyInt := binary.LittleEndian.Uint32(path[:4]) + + var paths []uint32 + for i := 4; i < len(path); i += 4 { + paths = append(paths, binary.LittleEndian.Uint32(path[i:i+4])) + } + + return masterKeyInt, paths, nil +} + +// SerializeBIP32Derivation takes a master key fingerprint as defined in BIP32, +// along with a path specified as a list of uint32 values, and returns a +// bytestring specifying the derivation in the format required by BIP174: // +// master key fingerprint (4) || child index (4) || child index (4) || .... +func SerializeBIP32Derivation(masterKeyFingerprint uint32, + bip32Path []uint32) []byte { + + var masterKeyBytes [4]byte + binary.LittleEndian.PutUint32(masterKeyBytes[:], masterKeyFingerprint) + + derivationPath := make([]byte, 0, 4+4*len(bip32Path)) + derivationPath = append(derivationPath, masterKeyBytes[:]...) + for _, path := range bip32Path { + var pathbytes [4]byte + binary.LittleEndian.PutUint32(pathbytes[:], path) + derivationPath = append(derivationPath, pathbytes[:]...) + } + + return derivationPath +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/creator.go b/vendor/github.com/btcsuite/btcutil/psbt/creator.go new file mode 100644 index 0000000..a5f832e --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/creator.go @@ -0,0 +1,63 @@ +// 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 psbt + +import ( + "github.com/btcsuite/btcd/wire" +) + +// MinTxVersion is the lowest transaction version that we'll permit. +const MinTxVersion = 1 + +// New on provision of an input and output 'skeleton' for the transaction, a +// new partially populated PBST packet. The populated packet will include the +// unsigned transaction, and the set of known inputs and outputs contained +// within the unsigned transaction. The values of nLockTime, nSequence (per +// input) and transaction version (must be 1 of 2) must be specified here. Note +// that the default nSequence value is wire.MaxTxInSequenceNum. Referencing +// the PSBT BIP, this function serves the roles of teh Creator. +func New(inputs []*wire.OutPoint, + outputs []*wire.TxOut, version int32, nLockTime uint32, + nSequences []uint32) (*Packet, error) { + + // Create the new struct; the input and output lists will be empty, the + // unsignedTx object must be constructed and serialized, and that + // serialization should be entered as the only entry for the + // globalKVPairs list. + // + // Ensure that the version of the transaction is greater then our + // minimum allowed transaction version. There must be one sequence + // number per input. + if version < MinTxVersion || len(nSequences) != len(inputs) { + return nil, ErrInvalidPsbtFormat + } + + unsignedTx := wire.NewMsgTx(version) + unsignedTx.LockTime = nLockTime + for i, in := range inputs { + unsignedTx.AddTxIn(&wire.TxIn{ + PreviousOutPoint: *in, + Sequence: nSequences[i], + }) + } + for _, out := range outputs { + unsignedTx.AddTxOut(out) + } + + // The input and output lists are empty, but there is a list of those + // two lists, and each one must be of length matching the unsigned + // transaction; the unknown list can be nil. + pInputs := make([]PInput, len(unsignedTx.TxIn)) + pOutputs := make([]POutput, len(unsignedTx.TxOut)) + + // This new Psbt is "raw" and contains no key-value fields, so sanity + // checking with c.Cpsbt.SanityCheck() is not required. + return &Packet{ + UnsignedTx: unsignedTx, + Inputs: pInputs, + Outputs: pOutputs, + Unknowns: nil, + }, nil +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/extractor.go b/vendor/github.com/btcsuite/btcutil/psbt/extractor.go new file mode 100644 index 0000000..dc7f10f --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/extractor.go @@ -0,0 +1,81 @@ +// 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 psbt + +// The Extractor requires provision of a single PSBT +// in which all necessary signatures are encoded, and +// uses it to construct a fully valid network serialized +// transaction. + +import ( + "bytes" + + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" +) + +// Extract takes a finalized psbt.Packet and outputs a finalized transaction +// instance. Note that if the PSBT is in-complete, then an error +// ErrIncompletePSBT will be returned. As the extracted transaction has been +// fully finalized, it will be ready for network broadcast once returned. +func Extract(p *Packet) (*wire.MsgTx, error) { + // If the packet isn't complete, then we'll return an error as it + // doesn't have all the required witness data. + if !p.IsComplete() { + return nil, ErrIncompletePSBT + } + + // First, we'll make a copy of the underlying unsigned transaction (the + // initial template) so we don't mutate it during our activates below. + finalTx := p.UnsignedTx.Copy() + + // For each input, we'll now populate any relevant witness and + // sigScript data. + for i, tin := range finalTx.TxIn { + // We'll grab the corresponding internal packet input which + // matches this materialized transaction input and emplace that + // final sigScript (if present). + pInput := p.Inputs[i] + if pInput.FinalScriptSig != nil { + tin.SignatureScript = pInput.FinalScriptSig + } + + // Similarly, if there's a final witness, then we'll also need + // to extract that as well, parsing the lower-level transaction + // encoding. + if pInput.FinalScriptWitness != nil { + // In order to set the witness, need to re-deserialize + // the field as encoded within the PSBT packet. For + // each input, the witness is encoded as a stack with + // one or more items. + witnessReader := bytes.NewReader( + pInput.FinalScriptWitness, + ) + + // First we extract the number of witness elements + // encoded in the above witnessReader. + witCount, err := wire.ReadVarInt(witnessReader, 0) + if err != nil { + return nil, err + } + + // Now that we know how may inputs we'll need, we'll + // construct a packing slice, then read out each input + // (with a varint prefix) from the witnessReader. + tin.Witness = make(wire.TxWitness, witCount) + for j := uint64(0); j < witCount; j++ { + wit, err := wire.ReadVarBytes( + witnessReader, 0, txscript.MaxScriptSize, "witness", + ) + if err != nil { + return nil, err + } + tin.Witness[j] = wit + } + } + } + + return finalTx, nil +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/finalizer.go b/vendor/github.com/btcsuite/btcutil/psbt/finalizer.go new file mode 100644 index 0000000..0bf9dbb --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/finalizer.go @@ -0,0 +1,462 @@ +// 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 psbt + +// The Finalizer requires provision of a single PSBT input +// in which all necessary signatures are encoded, and +// uses it to construct valid final sigScript and scriptWitness +// fields. +// NOTE that p2sh (legacy) and p2wsh currently support only +// multisig and no other custom script. + +import ( + "github.com/btcsuite/btcd/txscript" +) + +// isFinalized considers this input finalized if it contains at least one of +// the FinalScriptSig or FinalScriptWitness are filled (which only occurs in a +// successful call to Finalize*). +func isFinalized(p *Packet, inIndex int) bool { + input := p.Inputs[inIndex] + return input.FinalScriptSig != nil || input.FinalScriptWitness != nil +} + +// isFinalizableWitnessInput returns true if the target input is a witness UTXO +// that can be finalized. +func isFinalizableWitnessInput(pInput *PInput) bool { + pkScript := pInput.WitnessUtxo.PkScript + + switch { + // If this is a native witness output, then we require both + // the witness script, but not a redeem script. + case txscript.IsWitnessProgram(pkScript): + if txscript.IsPayToWitnessScriptHash(pkScript) { + if pInput.WitnessScript == nil || + pInput.RedeemScript != nil { + return false + } + } else { + // A P2WKH output on the other hand doesn't need + // neither a witnessScript or redeemScript. + if pInput.WitnessScript != nil || + pInput.RedeemScript != nil { + return false + } + } + + // For nested P2SH inputs, we verify that a witness script is known. + case txscript.IsPayToScriptHash(pkScript): + if pInput.RedeemScript == nil { + return false + } + + // If this is a nested P2SH input, then it must also have a + // witness script, while we don't need one for P2WKH. + if txscript.IsPayToWitnessScriptHash(pInput.RedeemScript) { + if pInput.WitnessScript == nil { + return false + } + } else if txscript.IsPayToWitnessPubKeyHash(pInput.RedeemScript) { + if pInput.WitnessScript != nil { + return false + } + } else { + // unrecognized type + return false + } + + // If this isn't a nested nested P2SH output or a native witness + // output, then we can't finalize this input as we don't understand it. + default: + return false + } + + return true +} + +// isFinalizableLegacyInput returns true of the passed input a legacy input +// (non-witness) that can be finalized. +func isFinalizableLegacyInput(p *Packet, pInput *PInput, inIndex int) bool { + // If the input has a witness, then it's invalid. + if pInput.WitnessScript != nil { + return false + } + + // Otherwise, we'll verify that we only have a RedeemScript if the prev + // output script is P2SH. + outIndex := p.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index + if txscript.IsPayToScriptHash(pInput.NonWitnessUtxo.TxOut[outIndex].PkScript) { + if pInput.RedeemScript == nil { + return false + } + } else { + if pInput.RedeemScript != nil { + return false + } + } + + return true +} + +// isFinalizable checks whether the structure of the entry for the input of the +// psbt.Packet at index inIndex contains sufficient information to finalize +// this input. +func isFinalizable(p *Packet, inIndex int) bool { + pInput := p.Inputs[inIndex] + + // The input cannot be finalized without any signatures + if pInput.PartialSigs == nil { + return false + } + + // For an input to be finalized, we'll one of two possible top-level + // UTXOs present. Each UTXO type has a distinct set of requirements to + // be considered finalized. + switch { + + // A witness input must be either native P2WSH or nested P2SH with all + // relevant sigScript or witness data populated. + case pInput.WitnessUtxo != nil: + if !isFinalizableWitnessInput(&pInput) { + return false + } + + case pInput.NonWitnessUtxo != nil: + if !isFinalizableLegacyInput(p, &pInput, inIndex) { + return false + } + + // If neither a known UTXO type isn't present at all, then we'll + // return false as we need one of them. + default: + return false + } + + return true +} + +// MaybeFinalize attempts to finalize the input at index inIndex in the PSBT p, +// returning true with no error if it succeeds, OR if the input has already +// been finalized. +func MaybeFinalize(p *Packet, inIndex int) (bool, error) { + if isFinalized(p, inIndex) { + return true, nil + } + + if !isFinalizable(p, inIndex) { + return false, ErrNotFinalizable + } + + if err := Finalize(p, inIndex); err != nil { + return false, err + } + + return true, nil +} + +// MaybeFinalizeAll attempts to finalize all inputs of the psbt.Packet that are +// not already finalized, and returns an error if it fails to do so. +func MaybeFinalizeAll(p *Packet) error { + + for i := range p.UnsignedTx.TxIn { + success, err := MaybeFinalize(p, i) + if err != nil || !success { + return err + } + } + + return nil +} + +// Finalize assumes that the provided psbt.Packet struct has all partial +// signatures and redeem scripts/witness scripts already prepared for the +// specified input, and so removes all temporary data and replaces them with +// completed sigScript and witness fields, which are stored in key-types 07 and +// 08. The witness/non-witness utxo fields in the inputs (key-types 00 and 01) +// are left intact as they may be needed for validation (?). If there is any +// invalid or incomplete data, an error is returned. +func Finalize(p *Packet, inIndex int) error { + pInput := p.Inputs[inIndex] + + // Depending on the UTXO type, we either attempt to finalize it as a + // witness or legacy UTXO. + switch { + case pInput.WitnessUtxo != nil: + if err := finalizeWitnessInput(p, inIndex); err != nil { + return err + } + + case pInput.NonWitnessUtxo != nil: + if err := finalizeNonWitnessInput(p, inIndex); err != nil { + return err + } + + default: + return ErrInvalidPsbtFormat + } + + // Before returning we sanity check the PSBT to ensure we don't extract + // an invalid transaction or produce an invalid intermediate state. + if err := p.SanityCheck(); err != nil { + return err + } + + return nil +} + +// checkFinalScriptSigWitness checks whether a given input in the psbt.Packet +// struct already has the fields 07 (FinalInScriptSig) or 08 (FinalInWitness). +// If so, it returns true. It does not modify the Psbt. +func checkFinalScriptSigWitness(p *Packet, inIndex int) bool { + pInput := p.Inputs[inIndex] + + if pInput.FinalScriptSig != nil { + return true + } + + if pInput.FinalScriptWitness != nil { + return true + } + + return false +} + +// finalizeNonWitnessInput attempts to create a PsbtInFinalScriptSig field for +// the input at index inIndex, and removes all other fields except for the UTXO +// field, for an input of type non-witness, or returns an error. +func finalizeNonWitnessInput(p *Packet, inIndex int) error { + // If this input has already been finalized, then we'll return an error + // as we can't proceed. + if checkFinalScriptSigWitness(p, inIndex) { + return ErrInputAlreadyFinalized + } + + // Our goal here is to construct a sigScript given the pubkey, + // signature (keytype 02), of which there might be multiple, and the + // redeem script field (keytype 04) if present (note, it is not present + // for p2pkh type inputs). + var sigScript []byte + + pInput := p.Inputs[inIndex] + containsRedeemScript := pInput.RedeemScript != nil + + var ( + pubKeys [][]byte + sigs [][]byte + ) + for _, ps := range pInput.PartialSigs { + pubKeys = append(pubKeys, ps.PubKey) + + sigOK := checkSigHashFlags(ps.Signature, &pInput) + if !sigOK { + return ErrInvalidSigHashFlags + } + + sigs = append(sigs, ps.Signature) + } + + // We have failed to identify at least 1 (sig, pub) pair in the PSBT, + // which indicates it was not ready to be finalized. As a result, we + // can't proceed. + if len(sigs) < 1 || len(pubKeys) < 1 { + return ErrNotFinalizable + } + + // If this input doesn't need a redeem script (P2PKH), then we'll + // construct a simple sigScript that's just the signature then the + // pubkey (OP_CHECKSIG). + var err error + if !containsRedeemScript { + // At this point, we should only have a single signature and + // pubkey. + if len(sigs) != 1 || len(pubKeys) != 1 { + return ErrNotFinalizable + } + + // In this case, our sigScript is just: . + builder := txscript.NewScriptBuilder() + builder.AddData(sigs[0]).AddData(pubKeys[0]) + sigScript, err = builder.Script() + if err != nil { + return err + } + } else { + // This is assumed p2sh multisig Given redeemScript and pubKeys + // we can decide in what order signatures must be appended. + orderedSigs, err := extractKeyOrderFromScript( + pInput.RedeemScript, pubKeys, sigs, + ) + if err != nil { + return err + } + + // At this point, we assume that this is a mult-sig input, so + // we construct our sigScript which looks something like this + // (mind the extra element for the extra multi-sig pop): + // * + // + // TODO(waxwing): the below is specific to the multisig case. + builder := txscript.NewScriptBuilder() + builder.AddOp(txscript.OP_FALSE) + for _, os := range orderedSigs { + builder.AddData(os) + } + builder.AddData(pInput.RedeemScript) + sigScript, err = builder.Script() + if err != nil { + return err + } + } + + // At this point, a sigScript has been constructed. Remove all fields + // other than non-witness utxo (00) and finaliscriptsig (07) + newInput := NewPsbtInput(pInput.NonWitnessUtxo, nil) + newInput.FinalScriptSig = sigScript + + // Overwrite the entry in the input list at the correct index. Note + // that this removes all the other entries in the list for this input + // index. + p.Inputs[inIndex] = *newInput + + return nil +} + +// finalizeWitnessInput attempts to create PsbtInFinalScriptSig field and +// PsbtInFinalScriptWitness field for input at index inIndex, and removes all +// other fields except for the utxo field, for an input of type witness, or +// returns an error. +func finalizeWitnessInput(p *Packet, inIndex int) error { + // If this input has already been finalized, then we'll return an error + // as we can't proceed. + if checkFinalScriptSigWitness(p, inIndex) { + return ErrInputAlreadyFinalized + } + + // Depending on the actual output type, we'll either populate a + // serializedWitness or a witness as well asa sigScript. + var ( + sigScript []byte + serializedWitness []byte + ) + + pInput := p.Inputs[inIndex] + + // First we'll validate and collect the pubkey+sig pairs from the set + // of partial signatures. + var ( + pubKeys [][]byte + sigs [][]byte + ) + for _, ps := range pInput.PartialSigs { + pubKeys = append(pubKeys, ps.PubKey) + + sigOK := checkSigHashFlags(ps.Signature, &pInput) + if !sigOK { + return ErrInvalidSigHashFlags + + } + + sigs = append(sigs, ps.Signature) + } + + // If at this point, we don't have any pubkey+sig pairs, then we bail + // as we can't proceed. + if len(sigs) == 0 || len(pubKeys) == 0 { + return ErrNotFinalizable + } + + containsRedeemScript := pInput.RedeemScript != nil + cointainsWitnessScript := pInput.WitnessScript != nil + + // If there's no redeem script, then we assume that this is native + // segwit input. + var err error + if !containsRedeemScript { + // If we have only a sigley pubkey+sig pair, and no witness + // script, then we assume this is a P2WKH input. + if len(pubKeys) == 1 && len(sigs) == 1 && + !cointainsWitnessScript { + + serializedWitness, err = writePKHWitness( + sigs[0], pubKeys[0], + ) + if err != nil { + return err + } + } else { + // Otherwise, we must have a witnessScript field, so + // we'll generate a valid multi-sig witness. + // + // NOTE: We tacitly assume multisig. + // + // TODO(roasbeef): need to add custom finalize for + // non-multisig P2WSH outputs (HTLCs, delay outputs, + // etc). + if !cointainsWitnessScript { + return ErrNotFinalizable + } + + serializedWitness, err = getMultisigScriptWitness( + pInput.WitnessScript, pubKeys, sigs, + ) + if err != nil { + return err + } + } + } else { + // Otherwise, we assume that this is a p2wsh multi-sig output, + // which is nested in a p2sh, or a p2wkh nested in a p2sh. + // + // In this case, we'll take the redeem script (the witness + // program in this case), and push it on the stack within the + // sigScript. + builder := txscript.NewScriptBuilder() + builder.AddData(pInput.RedeemScript) + sigScript, err = builder.Script() + if err != nil { + return err + } + + // If don't have a witness script, then we assume this is a + // nested p2wkh output. + if !cointainsWitnessScript { + // Assumed p2sh-p2wkh Here the witness is just (sig, + // pub) as for p2pkh case + if len(sigs) != 1 || len(pubKeys) != 1 { + return ErrNotFinalizable + } + + serializedWitness, err = writePKHWitness(sigs[0], pubKeys[0]) + if err != nil { + return err + } + + } else { + // Otherwise, we assume that this is a p2wsh multi-sig, + // so we generate the proper witness. + serializedWitness, err = getMultisigScriptWitness( + pInput.WitnessScript, pubKeys, sigs, + ) + if err != nil { + return err + } + } + } + + // At this point, a witness has been constructed, and a sigScript (if + // nested; else it's []). Remove all fields other than witness utxo + // (01) and finalscriptsig (07), finalscriptwitness (08). + newInput := NewPsbtInput(nil, pInput.WitnessUtxo) + if len(sigScript) > 0 { + newInput.FinalScriptSig = sigScript + } + + newInput.FinalScriptWitness = serializedWitness + + // Finally, we overwrite the entry in the input list at the correct + // index. + p.Inputs[inIndex] = *newInput + return nil +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/go.mod b/vendor/github.com/btcsuite/btcutil/psbt/go.mod new file mode 100644 index 0000000..d47c286 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/go.mod @@ -0,0 +1,9 @@ +module github.com/btcsuite/btcutil/psbt + +go 1.13 + +require ( + github.com/btcsuite/btcd v0.20.1-beta + github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d + github.com/davecgh/go-spew v1.1.1 +) diff --git a/vendor/github.com/btcsuite/btcutil/psbt/go.sum b/vendor/github.com/btcsuite/btcutil/psbt/go.sum new file mode 100644 index 0000000..4267a6f --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/go.sum @@ -0,0 +1,36 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f h1:bAs4lUbRJpnnkd9VhRV3jjAVU7DJVjMaK+IsvSeZvFo= +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 v0.0.0-20191219182022-e17c9730c422 h1:EqnrgSSg0SFWRlEZLExgjtuUR/IPnuQ6qw6nwRda4Uk= +github.com/btcsuite/btcutil v0.0.0-20191219182022-e17c9730c422/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +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/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44 h1:9lP3x0pW80sDI6t1UMSLA4to18W7R7imwAI/sWS9S8Q= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/btcsuite/btcutil/psbt/partial_input.go b/vendor/github.com/btcsuite/btcutil/psbt/partial_input.go new file mode 100644 index 0000000..3db042f --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/partial_input.go @@ -0,0 +1,367 @@ +package psbt + +import ( + "bytes" + "encoding/binary" + "io" + "sort" + + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" +) + +// PInput is a struct encapsulating all the data that can be attached to any +// specific input of the PSBT. +type PInput struct { + NonWitnessUtxo *wire.MsgTx + WitnessUtxo *wire.TxOut + PartialSigs []*PartialSig + SighashType txscript.SigHashType + RedeemScript []byte + WitnessScript []byte + Bip32Derivation []*Bip32Derivation + FinalScriptSig []byte + FinalScriptWitness []byte + Unknowns []*Unknown +} + +// NewPsbtInput creates an instance of PsbtInput given either a nonWitnessUtxo +// or a witnessUtxo. +// +// NOTE: Only one of the two arguments should be specified, with the other +// being `nil`; otherwise the created PsbtInput object will fail IsSane() +// checks and will not be usable. +func NewPsbtInput(nonWitnessUtxo *wire.MsgTx, + witnessUtxo *wire.TxOut) *PInput { + + return &PInput{ + NonWitnessUtxo: nonWitnessUtxo, + WitnessUtxo: witnessUtxo, + PartialSigs: []*PartialSig{}, + SighashType: 0, + RedeemScript: nil, + WitnessScript: nil, + Bip32Derivation: []*Bip32Derivation{}, + FinalScriptSig: nil, + FinalScriptWitness: nil, + Unknowns: nil, + } +} + +// IsSane returns true only if there are no conflicting values in the Psbt +// PInput. It checks that witness and non-witness utxo entries do not both +// exist, and that witnessScript entries are only added to witness inputs. +func (pi *PInput) IsSane() bool { + + if pi.NonWitnessUtxo != nil && pi.WitnessUtxo != nil { + return false + } + if pi.WitnessUtxo == nil && pi.WitnessScript != nil { + return false + } + if pi.WitnessUtxo == nil && pi.FinalScriptWitness != nil { + return false + } + + return true +} + +// deserialize attempts to deserialize a new PInput from the passed io.Reader. +func (pi *PInput) deserialize(r io.Reader) error { + for { + keyint, keydata, err := getKey(r) + if err != nil { + return err + } + if keyint == -1 { + // Reached separator byte + break + } + value, err := wire.ReadVarBytes( + r, 0, MaxPsbtValueLength, "PSBT value", + ) + if err != nil { + return err + } + + switch InputType(keyint) { + + case NonWitnessUtxoType: + if pi.NonWitnessUtxo != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + tx := wire.NewMsgTx(2) + + err := tx.Deserialize(bytes.NewReader(value)) + if err != nil { + return err + } + pi.NonWitnessUtxo = tx + + case WitnessUtxoType: + if pi.WitnessUtxo != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + txout, err := readTxOut(value) + if err != nil { + return err + } + pi.WitnessUtxo = txout + + case PartialSigType: + newPartialSig := PartialSig{ + PubKey: keydata, + Signature: value, + } + + if !newPartialSig.checkValid() { + return ErrInvalidPsbtFormat + } + + // Duplicate keys are not allowed + for _, x := range pi.PartialSigs { + if bytes.Equal(x.PubKey, newPartialSig.PubKey) { + return ErrDuplicateKey + } + } + + pi.PartialSigs = append(pi.PartialSigs, &newPartialSig) + + case SighashType: + if pi.SighashType != 0 { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + + // Bounds check on value here since the sighash type must be a + // 32-bit unsigned integer. + if len(value) != 4 { + return ErrInvalidKeydata + } + + shtype := txscript.SigHashType( + binary.LittleEndian.Uint32(value), + ) + pi.SighashType = shtype + + case RedeemScriptInputType: + if pi.RedeemScript != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + pi.RedeemScript = value + + case WitnessScriptInputType: + if pi.WitnessScript != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + pi.WitnessScript = value + + case Bip32DerivationInputType: + if !validatePubkey(keydata) { + return ErrInvalidPsbtFormat + } + master, derivationPath, err := readBip32Derivation(value) + if err != nil { + return err + } + + // Duplicate keys are not allowed + for _, x := range pi.Bip32Derivation { + if bytes.Equal(x.PubKey, keydata) { + return ErrDuplicateKey + } + } + + pi.Bip32Derivation = append( + pi.Bip32Derivation, + &Bip32Derivation{ + PubKey: keydata, + MasterKeyFingerprint: master, + Bip32Path: derivationPath, + }, + ) + + case FinalScriptSigType: + if pi.FinalScriptSig != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + + pi.FinalScriptSig = value + + case FinalScriptWitnessType: + if pi.FinalScriptWitness != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + + pi.FinalScriptWitness = value + + default: + // A fall through case for any proprietary types. + keyintanddata := []byte{byte(keyint)} + keyintanddata = append(keyintanddata, keydata...) + newUnknown := &Unknown{ + Key: keyintanddata, + Value: value, + } + + // Duplicate key+keydata are not allowed + for _, x := range pi.Unknowns { + if bytes.Equal(x.Key, newUnknown.Key) && + bytes.Equal(x.Value, newUnknown.Value) { + return ErrDuplicateKey + } + } + + pi.Unknowns = append(pi.Unknowns, newUnknown) + } + } + + return nil +} + +// serialize attempts to serialize the target PInput into the passed io.Writer. +func (pi *PInput) serialize(w io.Writer) error { + + if !pi.IsSane() { + return ErrInvalidPsbtFormat + } + + if pi.NonWitnessUtxo != nil { + var buf bytes.Buffer + err := pi.NonWitnessUtxo.Serialize(&buf) + if err != nil { + return err + } + + err = serializeKVPairWithType( + w, uint8(NonWitnessUtxoType), nil, buf.Bytes(), + ) + if err != nil { + return err + } + } + if pi.WitnessUtxo != nil { + var buf bytes.Buffer + err := wire.WriteTxOut(&buf, 0, 0, pi.WitnessUtxo) + if err != nil { + return err + } + + err = serializeKVPairWithType( + w, uint8(WitnessUtxoType), nil, buf.Bytes(), + ) + if err != nil { + return err + } + } + + if pi.FinalScriptSig == nil && pi.FinalScriptWitness == nil { + sort.Sort(PartialSigSorter(pi.PartialSigs)) + for _, ps := range pi.PartialSigs { + err := serializeKVPairWithType( + w, uint8(PartialSigType), ps.PubKey, + ps.Signature, + ) + if err != nil { + return err + } + } + + if pi.SighashType != 0 { + var shtBytes [4]byte + binary.LittleEndian.PutUint32( + shtBytes[:], uint32(pi.SighashType), + ) + + err := serializeKVPairWithType( + w, uint8(SighashType), nil, shtBytes[:], + ) + if err != nil { + return err + } + } + + if pi.RedeemScript != nil { + err := serializeKVPairWithType( + w, uint8(RedeemScriptInputType), nil, + pi.RedeemScript, + ) + if err != nil { + return err + } + } + + if pi.WitnessScript != nil { + err := serializeKVPairWithType( + w, uint8(WitnessScriptInputType), nil, + pi.WitnessScript, + ) + if err != nil { + return err + } + } + + sort.Sort(Bip32Sorter(pi.Bip32Derivation)) + for _, kd := range pi.Bip32Derivation { + err := serializeKVPairWithType( + w, + uint8(Bip32DerivationInputType), kd.PubKey, + SerializeBIP32Derivation( + kd.MasterKeyFingerprint, kd.Bip32Path, + ), + ) + if err != nil { + return err + } + } + } + + if pi.FinalScriptSig != nil { + err := serializeKVPairWithType( + w, uint8(FinalScriptSigType), nil, pi.FinalScriptSig, + ) + if err != nil { + return err + } + } + + if pi.FinalScriptWitness != nil { + err := serializeKVPairWithType( + w, uint8(FinalScriptWitnessType), nil, pi.FinalScriptWitness, + ) + if err != nil { + return err + } + } + + // Unknown is a special case; we don't have a key type, only a key and + // a value field + for _, kv := range pi.Unknowns { + err := serializeKVpair(w, kv.Key, kv.Value) + if err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/partial_output.go b/vendor/github.com/btcsuite/btcutil/psbt/partial_output.go new file mode 100644 index 0000000..64d1bd4 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/partial_output.go @@ -0,0 +1,139 @@ +package psbt + +import ( + "bytes" + "io" + "sort" + + "github.com/btcsuite/btcd/wire" +) + +// POutput is a struct encapsulating all the data that can be attached +// to any specific output of the PSBT. +type POutput struct { + RedeemScript []byte + WitnessScript []byte + Bip32Derivation []*Bip32Derivation +} + +// NewPsbtOutput creates an instance of PsbtOutput; the three parameters +// redeemScript, witnessScript and Bip32Derivation are all allowed to be +// `nil`. +func NewPsbtOutput(redeemScript []byte, witnessScript []byte, + bip32Derivation []*Bip32Derivation) *POutput { + return &POutput{ + RedeemScript: redeemScript, + WitnessScript: witnessScript, + Bip32Derivation: bip32Derivation, + } +} + +// deserialize attempts to recode a new POutput from the passed io.Reader. +func (po *POutput) deserialize(r io.Reader) error { + for { + keyint, keydata, err := getKey(r) + if err != nil { + return err + } + if keyint == -1 { + // Reached separator byte + break + } + + value, err := wire.ReadVarBytes( + r, 0, MaxPsbtValueLength, "PSBT value", + ) + if err != nil { + return err + } + + switch OutputType(keyint) { + + case RedeemScriptOutputType: + if po.RedeemScript != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + po.RedeemScript = value + + case WitnessScriptOutputType: + if po.WitnessScript != nil { + return ErrDuplicateKey + } + if keydata != nil { + return ErrInvalidKeydata + } + po.WitnessScript = value + + case Bip32DerivationOutputType: + if !validatePubkey(keydata) { + return ErrInvalidKeydata + } + master, derivationPath, err := readBip32Derivation(value) + if err != nil { + return err + } + + // Duplicate keys are not allowed + for _, x := range po.Bip32Derivation { + if bytes.Equal(x.PubKey, keydata) { + return ErrDuplicateKey + } + } + + po.Bip32Derivation = append(po.Bip32Derivation, + &Bip32Derivation{ + PubKey: keydata, + MasterKeyFingerprint: master, + Bip32Path: derivationPath, + }, + ) + + default: + // Unknown type is allowed for inputs but not outputs. + return ErrInvalidPsbtFormat + } + } + + return nil +} + +// serialize attempts to write out the target POutput into the passed +// io.Writer. +func (po *POutput) serialize(w io.Writer) error { + if po.RedeemScript != nil { + err := serializeKVPairWithType( + w, uint8(RedeemScriptOutputType), nil, po.RedeemScript, + ) + if err != nil { + return err + } + } + if po.WitnessScript != nil { + err := serializeKVPairWithType( + w, uint8(WitnessScriptOutputType), nil, po.WitnessScript, + ) + if err != nil { + return err + } + } + + sort.Sort(Bip32Sorter(po.Bip32Derivation)) + for _, kd := range po.Bip32Derivation { + err := serializeKVPairWithType(w, + uint8(Bip32DerivationOutputType), + kd.PubKey, + SerializeBIP32Derivation( + kd.MasterKeyFingerprint, + kd.Bip32Path, + ), + ) + if err != nil { + return err + } + } + + return nil +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/partialsig.go b/vendor/github.com/btcsuite/btcutil/psbt/partialsig.go new file mode 100644 index 0000000..7211d25 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/partialsig.go @@ -0,0 +1,58 @@ +package psbt + +import ( + "bytes" + + "github.com/btcsuite/btcd/btcec" +) + +// PartialSig encapsulate a (BTC public key, ECDSA signature) +// pair, note that the fields are stored as byte slices, not +// btcec.PublicKey or btcec.Signature (because manipulations will +// be with the former not the latter, here); compliance with consensus +// serialization is enforced with .checkValid() +type PartialSig struct { + PubKey []byte + Signature []byte +} + +// PartialSigSorter implements sort.Interface for PartialSig. +type PartialSigSorter []*PartialSig + +func (s PartialSigSorter) Len() int { return len(s) } + +func (s PartialSigSorter) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func (s PartialSigSorter) Less(i, j int) bool { + return bytes.Compare(s[i].PubKey, s[j].PubKey) < 0 +} + +// validatePubkey checks if pubKey is *any* valid pubKey serialization in a +// Bitcoin context (compressed/uncomp. OK). +func validatePubkey(pubKey []byte) bool { + _, err := btcec.ParsePubKey(pubKey, btcec.S256()) + if err != nil { + return false + } + return true +} + +// validateSignature checks that the passed byte slice is a valid DER-encoded +// ECDSA signature, including the sighash flag. It does *not* of course +// validate the signature against any message or public key. +func validateSignature(sig []byte) bool { + _, err := btcec.ParseDERSignature(sig, btcec.S256()) + if err != nil { + return false + } + return true +} + +// checkValid checks that both the pbukey and sig are valid. See the methods +// (PartialSig, validatePubkey, validateSignature) for more details. +// +// TODO(waxwing): update for Schnorr will be needed here if/when that +// activates. +func (ps *PartialSig) checkValid() bool { + return validatePubkey(ps.PubKey) && validateSignature(ps.Signature) +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/psbt.go b/vendor/github.com/btcsuite/btcutil/psbt/psbt.go new file mode 100644 index 0000000..73126c3 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/psbt.go @@ -0,0 +1,407 @@ +// 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 psbt is an implementation of Partially Signed Bitcoin +// Transactions (PSBT). The format is defined in BIP 174: +// https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki +package psbt + +import ( + "bytes" + "encoding/base64" + "errors" + + "io" + + "github.com/btcsuite/btcd/wire" +) + +// psbtMagicLength is the length of the magic bytes used to signal the start of +// a serialized PSBT packet. +const psbtMagicLength = 5 + +var ( + // psbtMagic is the separator + psbtMagic = [psbtMagicLength]byte{0x70, + 0x73, 0x62, 0x74, 0xff, // = "psbt" + 0xff sep + } +) + +// MaxPsbtValueLength is the size of the largest transaction serialization +// that could be passed in a NonWitnessUtxo field. This is definitely +//less than 4M. +const MaxPsbtValueLength = 4000000 + +// MaxPsbtKeyLength is the length of the largest key that we'll successfully +// deserialize from the wire. Anything more will return ErrInvalidKeydata. +const MaxPsbtKeyLength = 10000 + +var ( + + // ErrInvalidPsbtFormat is a generic error for any situation in which a + // provided Psbt serialization does not conform to the rules of BIP174. + ErrInvalidPsbtFormat = errors.New("Invalid PSBT serialization format") + + // ErrDuplicateKey indicates that a passed Psbt serialization is invalid + // due to having the same key repeated in the same key-value pair. + ErrDuplicateKey = errors.New("Invalid Psbt due to duplicate key") + + // ErrInvalidKeydata indicates that a key-value pair in the PSBT + // serialization contains data in the key which is not valid. + ErrInvalidKeydata = errors.New("Invalid key data") + + // ErrInvalidMagicBytes indicates that a passed Psbt serialization is invalid + // due to having incorrect magic bytes. + ErrInvalidMagicBytes = errors.New("Invalid Psbt due to incorrect magic bytes") + + // ErrInvalidRawTxSigned indicates that the raw serialized transaction in the + // global section of the passed Psbt serialization is invalid because it + // contains scriptSigs/witnesses (i.e. is fully or partially signed), which + // is not allowed by BIP174. + ErrInvalidRawTxSigned = errors.New("Invalid Psbt, raw transaction must " + + "be unsigned.") + + // ErrInvalidPrevOutNonWitnessTransaction indicates that the transaction + // hash (i.e. SHA256^2) of the fully serialized previous transaction + // provided in the NonWitnessUtxo key-value field doesn't match the prevout + // hash in the UnsignedTx field in the PSBT itself. + ErrInvalidPrevOutNonWitnessTransaction = errors.New("Prevout hash does " + + "not match the provided non-witness utxo serialization") + + // ErrInvalidSignatureForInput indicates that the signature the user is + // trying to append to the PSBT is invalid, either because it does + // not correspond to the previous transaction hash, or redeem script, + // or witness script. + // NOTE this does not include ECDSA signature checking. + ErrInvalidSignatureForInput = errors.New("Signature does not correspond " + + "to this input") + + // ErrInputAlreadyFinalized indicates that the PSBT passed to a Finalizer + // already contains the finalized scriptSig or witness. + ErrInputAlreadyFinalized = errors.New("Cannot finalize PSBT, finalized " + + "scriptSig or scriptWitnes already exists") + + // ErrIncompletePSBT indicates that the Extractor object + // was unable to successfully extract the passed Psbt struct because + // it is not complete + ErrIncompletePSBT = errors.New("PSBT cannot be extracted as it is " + + "incomplete") + + // ErrNotFinalizable indicates that the PSBT struct does not have + // sufficient data (e.g. signatures) for finalization + ErrNotFinalizable = errors.New("PSBT is not finalizable") + + // ErrInvalidSigHashFlags indicates that a signature added to the PSBT + // uses Sighash flags that are not in accordance with the requirement + // according to the entry in PsbtInSighashType, or otherwise not the + // default value (SIGHASH_ALL) + ErrInvalidSigHashFlags = errors.New("Invalid Sighash Flags") + + // ErrUnsupportedScriptType indicates that the redeem script or + // scriptwitness given is not supported by this codebase, or is otherwise + // not valid. + ErrUnsupportedScriptType = errors.New("Unsupported script type") +) + +// Unknown is a struct encapsulating a key-value pair for which the key type is +// unknown by this package; these fields are allowed in both the 'Global' and +// the 'Input' section of a PSBT. +type Unknown struct { + Key []byte + Value []byte +} + +// Packet is the actual psbt repreesntation. It is a is a set of 1 + N + M +// key-value pair lists, 1 global, defining the unsigned transaction structure +// with N inputs and M outputs. These key-value pairs can contain scripts, +// signatures, key derivations and other transaction-defining data. +type Packet struct { + // UnsignedTx is the decoded unsigned transaction for this PSBT. + UnsignedTx *wire.MsgTx // Deserialization of unsigned tx + + // Inputs contains all the information needed to properly sign this + // target input within the above transaction. + Inputs []PInput + + // Outputs contains all information required to spend any outputs + // produced by this PSBT. + Outputs []POutput + + // Unknowns are the set of custom types (global only) within this PSBT. + Unknowns []Unknown +} + +// validateUnsignedTx returns true if the transaction is unsigned. Note that +// more basic sanity requirements, such as the presence of inputs and outputs, +// is implicitly checked in the call to MsgTx.Deserialize(). +func validateUnsignedTX(tx *wire.MsgTx) bool { + for _, tin := range tx.TxIn { + if len(tin.SignatureScript) != 0 || len(tin.Witness) != 0 { + return false + } + } + + return true +} + +// NewFromUnsignedTx creates a new Psbt struct, without any signatures (i.e. +// only the global section is non-empty) using the passed unsigned transaction. +func NewFromUnsignedTx(tx *wire.MsgTx) (*Packet, error) { + + if !validateUnsignedTX(tx) { + return nil, ErrInvalidRawTxSigned + } + + inSlice := make([]PInput, len(tx.TxIn)) + outSlice := make([]POutput, len(tx.TxOut)) + unknownSlice := make([]Unknown, 0) + + retPsbt := Packet{ + UnsignedTx: tx, + Inputs: inSlice, + Outputs: outSlice, + Unknowns: unknownSlice, + } + + return &retPsbt, nil +} + +// NewFromRawBytes returns a new instance of a Packet struct created by reading +// from a byte slice. If the format is invalid, an error is returned. If the +// argument b64 is true, the passed byte slice is decoded from base64 encoding +// before processing. +// +// NOTE: To create a Packet from one's own data, rather than reading in a +// serialization from a counterparty, one should use a psbt.New. +func NewFromRawBytes(r io.Reader, b64 bool) (*Packet, error) { + + // If the PSBT is encoded in bas64, then we'll create a new wrapper + // reader that'll allow us to incrementally decode the contents of the + // io.Reader. + if b64 { + based64EncodedReader := r + r = base64.NewDecoder(base64.StdEncoding, based64EncodedReader) + } + + // The Packet struct does not store the fixed magic bytes, but they + // must be present or the serialization must be explicitly rejected. + var magic [5]byte + if _, err := io.ReadFull(r, magic[:]); err != nil { + return nil, err + } + if magic != psbtMagic { + return nil, ErrInvalidMagicBytes + } + + // Next we parse the GLOBAL section. There is currently only 1 known + // key type, UnsignedTx. We insist this exists first; unknowns are + // allowed, but only after. + keyint, keydata, err := getKey(r) + if err != nil { + return nil, err + } + if GlobalType(keyint) != UnsignedTxType || keydata != nil { + return nil, ErrInvalidPsbtFormat + } + + // Now that we've verified the global type is present, we'll decode it + // into a proper unsigned transaction, and validate it. + value, err := wire.ReadVarBytes( + r, 0, MaxPsbtValueLength, "PSBT value", + ) + if err != nil { + return nil, err + } + msgTx := wire.NewMsgTx(2) + err = msgTx.Deserialize(bytes.NewReader(value)) + if err != nil { + // If there are no inputs in this yet incomplete transaction, + // the wire package still incorrectly assumes it's encoded in + // the witness format. We can fix this by just trying the non- + // witness encoding too. If that also fails, it's probably an + // invalid transaction. + msgTx = wire.NewMsgTx(2) + err2 := msgTx.DeserializeNoWitness(bytes.NewReader(value)) + + // If the second attempt also failed, something else is wrong + // and it probably makes more sense to return the original + // error instead of the error from the workaround. + if err2 != nil { + return nil, err + } + } + if !validateUnsignedTX(msgTx) { + return nil, ErrInvalidRawTxSigned + } + + // Next we parse any unknowns that may be present, making sure that we + // break at the separator. + var unknownSlice []Unknown + for { + keyint, keydata, err := getKey(r) + if err != nil { + return nil, ErrInvalidPsbtFormat + } + if keyint == -1 { + break + } + + value, err := wire.ReadVarBytes( + r, 0, MaxPsbtValueLength, "PSBT value", + ) + if err != nil { + return nil, err + } + + keyintanddata := []byte{byte(keyint)} + keyintanddata = append(keyintanddata, keydata...) + + newUnknown := Unknown{ + Key: keyintanddata, + Value: value, + } + unknownSlice = append(unknownSlice, newUnknown) + } + + // Next we parse the INPUT section. + inSlice := make([]PInput, len(msgTx.TxIn)) + for i := range msgTx.TxIn { + input := PInput{} + err = input.deserialize(r) + if err != nil { + return nil, err + } + + inSlice[i] = input + } + + // Next we parse the OUTPUT section. + outSlice := make([]POutput, len(msgTx.TxOut)) + for i := range msgTx.TxOut { + output := POutput{} + err = output.deserialize(r) + if err != nil { + return nil, err + } + + outSlice[i] = output + } + + // Populate the new Packet object + newPsbt := Packet{ + UnsignedTx: msgTx, + Inputs: inSlice, + Outputs: outSlice, + Unknowns: unknownSlice, + } + + // Extended sanity checking is applied here to make sure the + // externally-passed Packet follows all the rules. + if err = newPsbt.SanityCheck(); err != nil { + return nil, err + } + + return &newPsbt, nil +} + +// Serialize creates a binary serialization of the referenced Packet struct +// with lexicographical ordering (by key) of the subsections. +func (p *Packet) Serialize(w io.Writer) error { + + // First we write out the precise set of magic bytes that identify a + // valid PSBT transaction. + if _, err := w.Write(psbtMagic[:]); err != nil { + return err + } + + // Next we prep to write out the unsigned transaction by first + // serializing it into an intermediate buffer. + serializedTx := bytes.NewBuffer( + make([]byte, 0, p.UnsignedTx.SerializeSize()), + ) + if err := p.UnsignedTx.Serialize(serializedTx); err != nil { + return err + } + + // Now that we have the serialized transaction, we'll write it out to + // the proper global type. + err := serializeKVPairWithType( + w, uint8(UnsignedTxType), nil, serializedTx.Bytes(), + ) + if err != nil { + return err + } + + // With that our global section is done, so we'll write out the + // separator. + separator := []byte{0x00} + if _, err := w.Write(separator); err != nil { + return err + } + + for _, pInput := range p.Inputs { + err := pInput.serialize(w) + if err != nil { + return err + } + + if _, err := w.Write(separator); err != nil { + return err + } + } + + for _, pOutput := range p.Outputs { + err := pOutput.serialize(w) + if err != nil { + return err + } + + if _, err := w.Write(separator); err != nil { + return err + } + } + + return nil +} + +// B64Encode returns the base64 encoding of the serialization of +// the current PSBT, or an error if the encoding fails. +func (p *Packet) B64Encode() (string, error) { + var b bytes.Buffer + if err := p.Serialize(&b); err != nil { + return "", err + } + + return base64.StdEncoding.EncodeToString(b.Bytes()), nil +} + +// IsComplete returns true only if all of the inputs are +// finalized; this is particularly important in that it decides +// whether the final extraction to a network serialized signed +// transaction will be possible. +func (p *Packet) IsComplete() bool { + for i := 0; i < len(p.UnsignedTx.TxIn); i++ { + if !isFinalized(p, i) { + return false + } + } + return true +} + +// SanityCheck checks conditions on a PSBT to ensure that it obeys the +// rules of BIP174, and returns true if so, false if not. +func (p *Packet) SanityCheck() error { + + if !validateUnsignedTX(p.UnsignedTx) { + return ErrInvalidRawTxSigned + } + + for _, tin := range p.Inputs { + if !tin.IsSane() { + return ErrInvalidPsbtFormat + } + } + + return nil +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/signer.go b/vendor/github.com/btcsuite/btcutil/psbt/signer.go new file mode 100644 index 0000000..9680c90 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/signer.go @@ -0,0 +1,152 @@ +// 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 psbt + +// signer encapsulates the role 'Signer' as specified in BIP174; it controls +// the insertion of signatures; the Sign() function will attempt to insert +// signatures using Updater.addPartialSignature, after first ensuring the Psbt +// is in the correct state. + +import ( + "github.com/btcsuite/btcd/txscript" +) + +// SignOutcome is a enum-like value that expresses the outcome of a call to the +// Sign method. +type SignOutcome int + +const ( + // SignSuccesful indicates that the partial signature was successfully + // attached. + SignSuccesful = 0 + + // SignFinalized indicates that this input is already finalized, so the provided + // signature was *not* attached + SignFinalized = 1 + + // SignInvalid indicates that the provided signature data was not valid. In this case + // an error will also be returned. + SignInvalid = -1 +) + +// Sign allows the caller to sign a PSBT at a particular input; they +// must provide a signature and a pubkey, both as byte slices; they can also +// optionally provide both witnessScript and/or redeemScript, otherwise these +// arguments must be set as nil (and in that case, they must already be present +// in the PSBT if required for signing to succeed). +// +// This serves as a wrapper around Updater.addPartialSignature; it ensures that +// the redeemScript and witnessScript are updated as needed (note that the +// Updater is allowed to add redeemScripts and witnessScripts independently, +// before signing), and ensures that the right form of utxo field +// (NonWitnessUtxo or WitnessUtxo) is included in the input so that signature +// insertion (and then finalization) can take place. +func (u *Updater) Sign(inIndex int, sig []byte, pubKey []byte, + redeemScript []byte, witnessScript []byte) (SignOutcome, error) { + + if isFinalized(u.Upsbt, inIndex) { + return SignFinalized, nil + } + + // Add the witnessScript to the PSBT in preparation. If it already + // exists, it will be overwritten. + if witnessScript != nil { + err := u.AddInWitnessScript(witnessScript, inIndex) + if err != nil { + return SignInvalid, err + } + } + + // Add the redeemScript to the PSBT in preparation. If it already + // exists, it will be overwritten. + if redeemScript != nil { + err := u.AddInRedeemScript(redeemScript, inIndex) + if err != nil { + return SignInvalid, err + } + } + + // At this point, the PSBT must have the requisite witnessScript or + // redeemScript fields for signing to succeed. + // + // Case 1: if witnessScript is present, it must be of type witness; + // if not, signature insertion will of course fail. + switch { + case u.Upsbt.Inputs[inIndex].WitnessScript != nil: + if u.Upsbt.Inputs[inIndex].WitnessUtxo == nil { + err := nonWitnessToWitness(u.Upsbt, inIndex) + if err != nil { + return SignInvalid, err + } + } + + err := u.addPartialSignature(inIndex, sig, pubKey) + if err != nil { + return SignInvalid, err + } + + // Case 2: no witness script, only redeem script; can be legacy p2sh or + // p2sh-wrapped p2wkh. + case u.Upsbt.Inputs[inIndex].RedeemScript != nil: + // We only need to decide if the input is witness, and we don't + // rely on the witnessutxo/nonwitnessutxo in the PSBT, instead + // we check the redeemScript content. + if txscript.IsWitnessProgram(redeemScript) { + if u.Upsbt.Inputs[inIndex].WitnessUtxo == nil { + err := nonWitnessToWitness(u.Upsbt, inIndex) + if err != nil { + return SignInvalid, err + } + } + } + + // If it is not a valid witness program, we here assume that + // the provided WitnessUtxo/NonWitnessUtxo field was correct. + err := u.addPartialSignature(inIndex, sig, pubKey) + if err != nil { + return SignInvalid, err + } + + // Case 3: Neither provided only works for native p2wkh, or non-segwit + // non-p2sh. To check if it's segwit, check the scriptPubKey of the + // output. + default: + if u.Upsbt.Inputs[inIndex].WitnessUtxo == nil { + outIndex := u.Upsbt.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index + script := u.Upsbt.Inputs[inIndex].NonWitnessUtxo.TxOut[outIndex].PkScript + + if txscript.IsWitnessProgram(script) { + err := nonWitnessToWitness(u.Upsbt, inIndex) + if err != nil { + return SignInvalid, err + } + } + } + + err := u.addPartialSignature(inIndex, sig, pubKey) + if err != nil { + return SignInvalid, err + } + } + + return SignSuccesful, nil +} + +// nonWitnessToWitness extracts the TxOut from the existing NonWitnessUtxo +// field in the given PSBT input and sets it as type witness by replacing the +// NonWitnessUtxo field with a WitnessUtxo field. See +// https://github.com/bitcoin/bitcoin/pull/14197. +func nonWitnessToWitness(p *Packet, inIndex int) error { + outIndex := p.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index + txout := p.Inputs[inIndex].NonWitnessUtxo.TxOut[outIndex] + + // Remove the non-witness first, else sanity check will not pass: + p.Inputs[inIndex].NonWitnessUtxo = nil + u := Updater{ + Upsbt: p, + } + + return u.AddInWitnessUtxo(txout, inIndex) +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/types.go b/vendor/github.com/btcsuite/btcutil/psbt/types.go new file mode 100644 index 0000000..1b4a26a --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/types.go @@ -0,0 +1,149 @@ +package psbt + +// GlobalType is the set of types that are used at the global scope level +// within the PSBT. +type GlobalType uint8 + +const ( + // UnsignedTxType is the global scope key that houses the unsigned + // transaction of the PSBT. The value is a transaction in network + // serialization. The scriptSigs and witnesses for each input must be + // empty. The transaction must be in the old serialization format + // (without witnesses). A PSBT must have a transaction, otherwise it is + // invalid. + UnsignedTxType GlobalType = 0 + + // XpubType houses a global xpub for the entire PSBT packet. + // + // The key ({0x01}|{xpub}) is he 78 byte serialized extended public key + // as defined by BIP 32. Extended public keys are those that can be + // used to derive public keys used in the inputs and outputs of this + // transaction. It should be the public key at the highest hardened + // derivation index so that + // the unhardened child keys used in the transaction can be derived. + // + // The value is the master key fingerprint as defined by BIP 32 + // concatenated with the derivation path of the public key. The + // derivation path is represented as 32-bit little endian unsigned + // integer indexes concatenated with each other. The number of 32 bit + // unsigned integer indexes must match the depth provided in the + // extended public key. + XpubType GlobalType = 1 + + // VersionType houses the global version number of this PSBT. There is + // no key (only contains the byte type), then the value if omitted, is + // assumed to be zero. + VersionType GlobalType = 0xFB + + // ProprietaryGlobalType is used to house any proper chary global-scope + // keys within the PSBT. + // + // The key is ({0xFC}||{subtype}|{key data}) a variable length + // identifier prefix, followed by a subtype, followed by the key data + // itself. + // + // The value is any data as defined by the proprietary type user. + ProprietaryGlobalType = 0xFC +) + +// InputType is the set of types that are defined for each input included +// within the PSBT. +type InputType uint32 + +const ( + // NonWitnessUtxoType has no key ({0x00}) and houses the transaction in + // network serialization format the current input spends from. This + // should only be present for inputs which spend non-segwit outputs. + // However, if it is unknown whether an input spends a segwit output, + // this type should be used. The entire input transaction is needed in + // order to be able to verify the values of the input (pre-segwit they + // aren't in the signature digest). + NonWitnessUtxoType InputType = 0 + + // WitnessUtxoType has no key ({0x01}), and houses the entire + // transaction output in network serialization which the current input + // spends from. This should only be present for inputs which spend + // segwit outputs, including P2SH embedded ones (value || script). + WitnessUtxoType InputType = 1 + + // PartialSigType is used to include a partial signature with key + // ({0x02}|{public key}). + // + // The value is the signature as would be pushed to the stack from a + // scriptSig or witness.. + PartialSigType InputType = 2 + + // SighashType is an empty key ({0x03}). + // + // The value contains the 32-bit unsigned integer specifying the + // sighash type to be used for this input. Signatures for this input + // must use the sighash type, finalizers must fail to finalize inputs + // which have signatures that do not match the specified sighash type. + // Signers who cannot produce signatures with the sighash type must not + // provide a signature. + SighashType InputType = 3 + + // RedeemScriptInputType is an empty key ({0x40}). + // + // The value is the redeem script of the input if present. + RedeemScriptInputType InputType = 4 + + // WitnessScriptInputType is an empty key ({0x05}). + // + // The value is the witness script of this input, if it has one. + WitnessScriptInputType InputType = 5 + + // Bip32DerivationInputType is a type that carries the pubkey along + // with the key ({0x06}|{public key}). + // + // The value is master key fingerprint as defined by BIP 32 + // concatenated with the derivation path of the public key. The + // derivation path is represented as 32 bit unsigned integer indexes + // concatenated with each other. Public keys are those that will be + // needed to sign this input. + Bip32DerivationInputType InputType = 6 + + // FinalScriptSigType is an empty key ({0x07}). + // + // The value contains a fully constructed scriptSig with signatures and + // any other scripts necessary for the input to pass validation. + FinalScriptSigType InputType = 7 + + // FinalScriptWitnessType is an empty key ({0x08}). The value is a + // fully constructed scriptWitness with signatures and any other + // scripts necessary for the input to pass validation. + FinalScriptWitnessType InputType = 8 + + // ProprietaryInputType is a custom type for use by devs. + // + // The key ({0xFC}||{subtype}|{key data}), is a Variable length + // identifier prefix, followed by a subtype, followed by the key data + // itself. + // + // The value is any value data as defined by the proprietary type user. + ProprietaryInputType InputType = 0xFC +) + +// OutputType is the set of types defined per output within the PSBT. +type OutputType uint32 + +const ( + // RedeemScriptOutputType is an empty key ({0x00}> + // + // The value is the redeemScript for this output if it has one. + RedeemScriptOutputType OutputType = 0 + + // WitnessScriptOutputType is an empty key ({0x01}). + // + // The value is the witness script of this input, if it has one. + WitnessScriptOutputType OutputType = 1 + + j // Bip32DerivationOutputType is used to communicate derivation information + // needed to spend this output. The key is ({0x02}|{public key}). + // + // The value is master key fingerprint concatenated with the derivation + // path of the public key. The derivation path is represented as 32-bit + // little endian unsigned integer indexes concatenated with each other. + // Public keys are those needed to spend this output. + Bip32DerivationOutputType OutputType = 2 +) diff --git a/vendor/github.com/btcsuite/btcutil/psbt/updater.go b/vendor/github.com/btcsuite/btcutil/psbt/updater.go new file mode 100644 index 0000000..b8c2350 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/updater.go @@ -0,0 +1,367 @@ +// 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 psbt + +// The Updater requires provision of a single PSBT and is able to add data to +// both input and output sections. It can be called repeatedly to add more +// data. It also allows addition of signatures via the addPartialSignature +// function; this is called internally to the package in the Sign() function of +// Updater, located in signer.go + +import ( + "bytes" + "crypto/sha256" + + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" +) + +// Updater encapsulates the role 'Updater' as specified in BIP174; it accepts +// Psbt structs and has methods to add fields to the inputs and outputs. +type Updater struct { + Upsbt *Packet +} + +// NewUpdater returns a new instance of Updater, if the passed Psbt struct is +// in a valid form, else an error. +func NewUpdater(p *Packet) (*Updater, error) { + if err := p.SanityCheck(); err != nil { + return nil, err + } + + return &Updater{Upsbt: p}, nil + +} + +// AddInNonWitnessUtxo adds the utxo information for an input which is +// non-witness. This requires provision of a full transaction (which is the +// source of the corresponding prevOut), and the input index. If addition of +// this key-value pair to the Psbt fails, an error is returned. +func (p *Updater) AddInNonWitnessUtxo(tx *wire.MsgTx, inIndex int) error { + if inIndex > len(p.Upsbt.Inputs)-1 { + return ErrInvalidPrevOutNonWitnessTransaction + } + + p.Upsbt.Inputs[inIndex].NonWitnessUtxo = tx + + if err := p.Upsbt.SanityCheck(); err != nil { + return ErrInvalidPsbtFormat + } + + return nil +} + +// AddInWitnessUtxo adds the utxo information for an input which is witness. +// This requires provision of a full transaction *output* (which is the source +// of the corresponding prevOut); not the full transaction because BIP143 means +// the output information is sufficient, and the input index. If addition of +// this key-value pair to the Psbt fails, an error is returned. +func (p *Updater) AddInWitnessUtxo(txout *wire.TxOut, inIndex int) error { + if inIndex > len(p.Upsbt.Inputs)-1 { + return ErrInvalidPsbtFormat + } + + p.Upsbt.Inputs[inIndex].WitnessUtxo = txout + + if err := p.Upsbt.SanityCheck(); err != nil { + return ErrInvalidPsbtFormat + } + + return nil +} + +// addPartialSignature allows the Updater role to insert fields of type partial +// signature into a Psbt, consisting of both the pubkey (as keydata) and the +// ECDSA signature (as value). Note that the Signer role is encapsulated in +// this function; signatures are only allowed to be added that follow the +// sanity-check on signing rules explained in the BIP under `Signer`; if the +// rules are not satisfied, an ErrInvalidSignatureForInput is returned. +// +// NOTE: This function does *not* validate the ECDSA signature itself. +func (p *Updater) addPartialSignature(inIndex int, sig []byte, + pubkey []byte) error { + + partialSig := PartialSig{ + PubKey: pubkey, Signature: sig, + } + + // First validate the passed (sig, pub). + if !partialSig.checkValid() { + return ErrInvalidPsbtFormat + } + + pInput := p.Upsbt.Inputs[inIndex] + + // First check; don't add duplicates. + for _, x := range pInput.PartialSigs { + if bytes.Equal(x.PubKey, partialSig.PubKey) { + return ErrDuplicateKey + } + } + + // Next, we perform a series of additional sanity checks. + if pInput.NonWitnessUtxo != nil { + if len(p.Upsbt.UnsignedTx.TxIn) < inIndex+1 { + return ErrInvalidPrevOutNonWitnessTransaction + } + + if pInput.NonWitnessUtxo.TxHash() != + p.Upsbt.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Hash { + return ErrInvalidSignatureForInput + } + + // To validate that the redeem script matches, we must pull out + // the scriptPubKey of the corresponding output and compare + // that with the P2SH scriptPubKey that is generated by + // redeemScript. + if pInput.RedeemScript != nil { + outIndex := p.Upsbt.UnsignedTx.TxIn[inIndex].PreviousOutPoint.Index + scriptPubKey := pInput.NonWitnessUtxo.TxOut[outIndex].PkScript + scriptHash := btcutil.Hash160(pInput.RedeemScript) + + scriptHashScript, err := txscript.NewScriptBuilder(). + AddOp(txscript.OP_HASH160). + AddData(scriptHash). + AddOp(txscript.OP_EQUAL). + Script() + if err != nil { + return err + } + + if !bytes.Equal(scriptHashScript, scriptPubKey) { + return ErrInvalidSignatureForInput + } + } + + } else if pInput.WitnessUtxo != nil { + scriptPubKey := pInput.WitnessUtxo.PkScript + + var script []byte + if pInput.RedeemScript != nil { + scriptHash := btcutil.Hash160(pInput.RedeemScript) + scriptHashScript, err := txscript.NewScriptBuilder(). + AddOp(txscript.OP_HASH160). + AddData(scriptHash). + AddOp(txscript.OP_EQUAL). + Script() + if err != nil { + return err + } + + if !bytes.Equal(scriptHashScript, scriptPubKey) { + return ErrInvalidSignatureForInput + } + + script = pInput.RedeemScript + } else { + script = scriptPubKey + } + + // If a witnessScript field is present, this is a P2WSH, + // whether nested or not (that is handled by the assignment to + // `script` above); in that case, sanity check that `script` is + // the p2wsh of witnessScript. Contrariwise, if no + // witnessScript field is present, this will be signed as + // p2wkh. + if pInput.WitnessScript != nil { + witnessScriptHash := sha256.Sum256(pInput.WitnessScript) + witnessScriptHashScript, err := txscript.NewScriptBuilder(). + AddOp(txscript.OP_0). + AddData(witnessScriptHash[:]). + Script() + if err != nil { + return err + } + + if !bytes.Equal(script, witnessScriptHashScript[:]) { + return ErrInvalidSignatureForInput + } + } else { + // Otherwise, this is a p2wkh input. + pubkeyHash := btcutil.Hash160(pubkey) + pubkeyHashScript, err := txscript.NewScriptBuilder(). + AddOp(txscript.OP_0). + AddData(pubkeyHash). + Script() + if err != nil { + return err + } + + // Validate that we're able to properly reconstruct the + // witness program. + if !bytes.Equal(pubkeyHashScript, script) { + return ErrInvalidSignatureForInput + } + } + } else { + + // Attaching signature without utxo field is not allowed. + return ErrInvalidPsbtFormat + } + + p.Upsbt.Inputs[inIndex].PartialSigs = append( + p.Upsbt.Inputs[inIndex].PartialSigs, &partialSig, + ) + + if err := p.Upsbt.SanityCheck(); err != nil { + return err + } + + // Addition of a non-duplicate-key partial signature cannot violate + // sanity-check rules. + return nil +} + +// AddInSighashType adds the sighash type information for an input. The +// sighash type is passed as a 32 bit unsigned integer, along with the index +// for the input. An error is returned if addition of this key-value pair to +// the Psbt fails. +func (p *Updater) AddInSighashType(sighashType txscript.SigHashType, + inIndex int) error { + + p.Upsbt.Inputs[inIndex].SighashType = sighashType + + if err := p.Upsbt.SanityCheck(); err != nil { + return err + } + return nil +} + +// AddInRedeemScript adds the redeem script information for an input. The +// redeem script is passed serialized, as a byte slice, along with the index of +// the input. An error is returned if addition of this key-value pair to the +// Psbt fails. +func (p *Updater) AddInRedeemScript(redeemScript []byte, + inIndex int) error { + + p.Upsbt.Inputs[inIndex].RedeemScript = redeemScript + + if err := p.Upsbt.SanityCheck(); err != nil { + return ErrInvalidPsbtFormat + } + + return nil +} + +// AddInWitnessScript adds the witness script information for an input. The +// witness script is passed serialized, as a byte slice, along with the index +// of the input. An error is returned if addition of this key-value pair to the +// Psbt fails. +func (p *Updater) AddInWitnessScript(witnessScript []byte, + inIndex int) error { + + p.Upsbt.Inputs[inIndex].WitnessScript = witnessScript + + if err := p.Upsbt.SanityCheck(); err != nil { + return err + } + + return nil +} + +// AddInBip32Derivation takes a master key fingerprint as defined in BIP32, a +// BIP32 path as a slice of uint32 values, and a serialized pubkey as a byte +// slice, along with the integer index of the input, and inserts this data into +// that input. +// +// NOTE: This can be called multiple times for the same input. An error is +// returned if addition of this key-value pair to the Psbt fails. +func (p *Updater) AddInBip32Derivation(masterKeyFingerprint uint32, + bip32Path []uint32, pubKeyData []byte, inIndex int) error { + + bip32Derivation := Bip32Derivation{ + PubKey: pubKeyData, + MasterKeyFingerprint: masterKeyFingerprint, + Bip32Path: bip32Path, + } + + if !bip32Derivation.checkValid() { + return ErrInvalidPsbtFormat + } + + // Don't allow duplicate keys + for _, x := range p.Upsbt.Inputs[inIndex].Bip32Derivation { + if bytes.Equal(x.PubKey, bip32Derivation.PubKey) { + return ErrDuplicateKey + } + } + + p.Upsbt.Inputs[inIndex].Bip32Derivation = append( + p.Upsbt.Inputs[inIndex].Bip32Derivation, &bip32Derivation, + ) + + if err := p.Upsbt.SanityCheck(); err != nil { + return err + } + + return nil +} + +// AddOutBip32Derivation takes a master key fingerprint as defined in BIP32, a +// BIP32 path as a slice of uint32 values, and a serialized pubkey as a byte +// slice, along with the integer index of the output, and inserts this data +// into that output. +// +// NOTE: That this can be called multiple times for the same output. An error +// is returned if addition of this key-value pair to the Psbt fails. +func (p *Updater) AddOutBip32Derivation(masterKeyFingerprint uint32, + bip32Path []uint32, pubKeyData []byte, outIndex int) error { + + bip32Derivation := Bip32Derivation{ + PubKey: pubKeyData, + MasterKeyFingerprint: masterKeyFingerprint, + Bip32Path: bip32Path, + } + + if !bip32Derivation.checkValid() { + return ErrInvalidPsbtFormat + } + + // Don't allow duplicate keys + for _, x := range p.Upsbt.Outputs[outIndex].Bip32Derivation { + if bytes.Equal(x.PubKey, bip32Derivation.PubKey) { + return ErrDuplicateKey + } + } + + p.Upsbt.Outputs[outIndex].Bip32Derivation = append( + p.Upsbt.Outputs[outIndex].Bip32Derivation, &bip32Derivation, + ) + + if err := p.Upsbt.SanityCheck(); err != nil { + return err + } + + return nil +} + +// AddOutRedeemScript takes a redeem script as a byte slice and appends it to +// the output at index outIndex. +func (p *Updater) AddOutRedeemScript(redeemScript []byte, + outIndex int) error { + + p.Upsbt.Outputs[outIndex].RedeemScript = redeemScript + + if err := p.Upsbt.SanityCheck(); err != nil { + return ErrInvalidPsbtFormat + } + + return nil +} + +// AddOutWitnessScript takes a witness script as a byte slice and appends it to +// the output at index outIndex. +func (p *Updater) AddOutWitnessScript(witnessScript []byte, + outIndex int) error { + + p.Upsbt.Outputs[outIndex].WitnessScript = witnessScript + + if err := p.Upsbt.SanityCheck(); err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/btcsuite/btcutil/psbt/utils.go b/vendor/github.com/btcsuite/btcutil/psbt/utils.go new file mode 100644 index 0000000..c7f281e --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/psbt/utils.go @@ -0,0 +1,277 @@ +// 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 psbt + +import ( + "bytes" + "encoding/binary" + "errors" + "io" + "sort" + + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" +) + +// writeTxWitness is a A utility function due to non-exported witness +// serialization (writeTxWitness encodes the bitcoin protocol encoding for a +// transaction input's witness into w). +func writeTxWitness(w io.Writer, wit [][]byte) error { + if err := wire.WriteVarInt(w, 0, uint64(len(wit))); err != nil { + return err + } + + for _, item := range wit { + err := wire.WriteVarBytes(w, 0, item) + if err != nil { + return err + } + } + return nil +} + +// writePKHWitness writes a witness for a p2wkh spending input +func writePKHWitness(sig []byte, pub []byte) ([]byte, error) { + var ( + buf bytes.Buffer + witnessItems = [][]byte{sig, pub} + ) + + if err := writeTxWitness(&buf, witnessItems); err != nil { + return nil, err + } + + return buf.Bytes(), nil +} + +// checkIsMultisigScript is a utility function to check whether a given +// redeemscript fits the standard multisig template used in all P2SH based +// multisig, given a set of pubkeys for redemption. +func checkIsMultiSigScript(pubKeys [][]byte, sigs [][]byte, + script []byte) bool { + + // First insist that the script type is multisig. + if txscript.GetScriptClass(script) != txscript.MultiSigTy { + return false + } + + // Inspect the script to ensure that the number of sigs and pubkeys is + // correct + numSigs, numPubKeys, err := txscript.CalcMultiSigStats(script) + if err != nil { + return false + } + + // If the number of sigs provided, doesn't match the number of required + // pubkeys, then we can't proceed as we're not yet final. + if numPubKeys != len(pubKeys) || numSigs != len(sigs) { + return false + } + + return true +} + +// extractKeyOrderFromScript is a utility function to extract an ordered list +// of signatures, given a serialized script (redeemscript or witness script), a +// list of pubkeys and the signatures corresponding to those pubkeys. This +// function is used to ensure that the signatures will be embedded in the final +// scriptSig or scriptWitness in the correct order. +func extractKeyOrderFromScript(script []byte, expectedPubkeys [][]byte, + sigs [][]byte) ([][]byte, error) { + + // If this isn't a proper finalized multi-sig script, then we can't + // proceed. + if !checkIsMultiSigScript(expectedPubkeys, sigs, script) { + return nil, ErrUnsupportedScriptType + } + + // Arrange the pubkeys and sigs into a slice of format: + // * [[pub,sig], [pub,sig],..] + type sigWithPub struct { + pubKey []byte + sig []byte + } + var pubsSigs []sigWithPub + for i, pub := range expectedPubkeys { + pubsSigs = append(pubsSigs, sigWithPub{ + pubKey: pub, + sig: sigs[i], + }) + } + + // Now that we have the set of (pubkey, sig) pairs, we'll construct a + // position map that we can use to swap the order in the slice above to + // match how things are laid out in the script. + type positionEntry struct { + index int + value sigWithPub + } + var positionMap []positionEntry + + // For each pubkey in our pubsSigs slice, we'll now construct a proper + // positionMap entry, based on _where_ in the script the pubkey first + // appears. + for _, p := range pubsSigs { + pos := bytes.Index(script, p.pubKey) + if pos < 0 { + return nil, errors.New("script does not contain pubkeys") + } + + positionMap = append(positionMap, positionEntry{ + index: pos, + value: p, + }) + } + + // Now that we have the position map full populated, we'll use the + // index data to properly sort the entries in the map based on where + // they appear in the script. + sort.Slice(positionMap, func(i, j int) bool { + return positionMap[i].index < positionMap[j].index + }) + + // Finally, we can simply iterate through the position map in order to + // extract the proper signature ordering. + sortedSigs := make([][]byte, 0, len(positionMap)) + for _, x := range positionMap { + sortedSigs = append(sortedSigs, x.value.sig) + } + + return sortedSigs, nil +} + +// getMultisigScriptWitness creates a full psbt serialized Witness field for +// the transaction, given the public keys and signatures to be appended. This +// function will only accept witnessScripts of the type M of N multisig. This +// is used for both p2wsh and nested p2wsh multisig cases. +func getMultisigScriptWitness(witnessScript []byte, pubKeys [][]byte, + sigs [][]byte) ([]byte, error) { + + // First using the script as a guide, we'll properly order the sigs + // according to how their corresponding pubkeys appear in the + // witnessScript. + orderedSigs, err := extractKeyOrderFromScript( + witnessScript, pubKeys, sigs, + ) + if err != nil { + return nil, err + } + + // Now that we know the proper order, we'll append each of the + // signatures into a new witness stack, then top it off with the + // witness script at the end, prepending the nil as we need the extra + // pop.. + witnessElements := make(wire.TxWitness, 0, len(sigs)+2) + witnessElements = append(witnessElements, nil) + for _, os := range orderedSigs { + witnessElements = append(witnessElements, os) + } + witnessElements = append(witnessElements, witnessScript) + + // Now that we have the full witness stack, we'll serialize it in the + // expected format, and return the final bytes. + var buf bytes.Buffer + if err = writeTxWitness(&buf, witnessElements); err != nil { + return nil, err + } + return buf.Bytes(), nil +} + +// checkSigHashFlags compares the sighash flag byte on a signature with the +// value expected according to any PsbtInSighashType field in this section of +// the PSBT, and returns true if they match, false otherwise. +// If no SighashType field exists, it is assumed to be SIGHASH_ALL. +// +// TODO(waxwing): sighash type not restricted to one byte in future? +func checkSigHashFlags(sig []byte, input *PInput) bool { + expectedSighashType := txscript.SigHashAll + if input.SighashType != 0 { + expectedSighashType = input.SighashType + } + + return expectedSighashType == txscript.SigHashType(sig[len(sig)-1]) +} + +// serializeKVpair writes out a kv pair using a varbyte prefix for each. +func serializeKVpair(w io.Writer, key []byte, value []byte) error { + if err := wire.WriteVarBytes(w, 0, key); err != nil { + return err + } + + return wire.WriteVarBytes(w, 0, value) +} + +// serializeKVPairWithType writes out to the passed writer a type coupled with +// a key. +func serializeKVPairWithType(w io.Writer, kt uint8, keydata []byte, + value []byte) error { + + // If the key has no data, then we write a blank slice. + if keydata == nil { + keydata = []byte{} + } + + // The final key to be written is: {type} || {keyData} + serializedKey := append([]byte{byte(kt)}, keydata...) + return serializeKVpair(w, serializedKey, value) +} + +// getKey retrieves a single key - both the key type and the keydata (if +// present) from the stream and returns the key type as an integer, or -1 if +// the key was of zero length. This integer is is used to indicate the presence +// of a separator byte which indicates the end of a given key-value pair list, +// and the keydata as a byte slice or nil if none is present. +func getKey(r io.Reader) (int, []byte, error) { + + // For the key, we read the varint separately, instead of using the + // available ReadVarBytes, because we have a specific treatment of 0x00 + // here: + count, err := wire.ReadVarInt(r, 0) + if err != nil { + return -1, nil, ErrInvalidPsbtFormat + } + if count == 0 { + // A separator indicates end of key-value pair list. + return -1, nil, nil + } + + // Check that we don't attempt to decode a dangerously large key. + if count > MaxPsbtKeyLength { + return -1, nil, ErrInvalidKeydata + } + + // Next, we ready out the designated number of bytes, which may include + // a type, key, and optional data. + keyTypeAndData := make([]byte, count) + if _, err := io.ReadFull(r, keyTypeAndData[:]); err != nil { + return -1, nil, err + } + + keyType := int(string(keyTypeAndData)[0]) + + // Note that the second return value will usually be empty, since most + // keys contain no more than the key type byte. + if len(keyTypeAndData) == 1 { + return keyType, nil, nil + } + + // Otherwise, we return the key, along with any data that it may + // contain. + return keyType, keyTypeAndData[1:], nil + +} + +// readTxOut is a limited version of wire.ReadTxOut, because the latter is not +// exported. +func readTxOut(txout []byte) (*wire.TxOut, error) { + if len(txout) < 10 { + return nil, ErrInvalidPsbtFormat + } + + valueSer := binary.LittleEndian.Uint64(txout[:8]) + scriptPubKey := txout[9:] + + return wire.NewTxOut(int64(valueSer), scriptPubKey), nil +} diff --git a/vendor/github.com/btcsuite/btcutil/txsort/README.md b/vendor/github.com/btcsuite/btcutil/txsort/README.md new file mode 100644 index 0000000..bd410ec --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/txsort/README.md @@ -0,0 +1,31 @@ +txsort +====== + +[![Build Status](http://img.shields.io/travis/btcsuite/btcutil.svg)](https://travis-ci.org/btcsuite/btcutil) +[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![GoDoc](http://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/btcsuite/btcutil/txsort) + +Package txsort provides the transaction sorting according to [BIP 69](https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki). + +BIP 69 defines a standard lexicographical sort order of transaction inputs and +outputs. This is useful to standardize transactions for faster multi-party +agreement as well as preventing information leaks in a single-party use case. + +The BIP goes into more detail, but for a quick and simplistic overview, the +order for inputs is defined as first sorting on the previous output hash and +then on the index as a tie breaker. The order for outputs is defined as first +sorting on the amount and then on the raw public key script bytes as a tie +breaker. + +A comprehensive suite of tests is provided to ensure proper functionality. + +## Installation and Updating + +```bash +$ go get -u github.com/btcsuite/btcutil/txsort +``` + +## License + +Package txsort is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/vendor/github.com/btcsuite/btcutil/txsort/doc.go b/vendor/github.com/btcsuite/btcutil/txsort/doc.go new file mode 100644 index 0000000..e89c4d2 --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/txsort/doc.go @@ -0,0 +1,20 @@ +// 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 txsort provides the transaction sorting according to BIP 69. + +Overview + +BIP 69 defines a standard lexicographical sort order of transaction inputs and +outputs. This is useful to standardize transactions for faster multi-party +agreement as well as preventing information leaks in a single-party use case. + +The BIP goes into more detail, but for a quick and simplistic overview, the +order for inputs is defined as first sorting on the previous output hash and +then on the index as a tie breaker. The order for outputs is defined as first +sorting on the amount and then on the raw public key script bytes as a tie +breaker. +*/ +package txsort diff --git a/vendor/github.com/btcsuite/btcutil/txsort/txsort.go b/vendor/github.com/btcsuite/btcutil/txsort/txsort.go new file mode 100644 index 0000000..f72a7db --- /dev/null +++ b/vendor/github.com/btcsuite/btcutil/txsort/txsort.go @@ -0,0 +1,95 @@ +// 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. + +// Provides functions for sorting tx inputs and outputs according to BIP 69 +// (https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki) + +package txsort + +import ( + "bytes" + "sort" + + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/wire" +) + +// InPlaceSort modifies the passed transaction inputs and outputs to be sorted +// based on BIP 69. +// +// WARNING: This function must NOT be called with published transactions since +// it will mutate the transaction if it's not already sorted. This can cause +// issues if you mutate a tx in a block, for example, which would invalidate the +// block. It could also cause cached hashes, such as in a btcutil.Tx to become +// invalidated. +// +// The function should only be used if the caller is creating the transaction or +// is otherwise 100% positive mutating will not cause adverse affects due to +// other dependencies. +func InPlaceSort(tx *wire.MsgTx) { + sort.Sort(sortableInputSlice(tx.TxIn)) + sort.Sort(sortableOutputSlice(tx.TxOut)) +} + +// Sort returns a new transaction with the inputs and outputs sorted based on +// BIP 69. The passed transaction is not modified and the new transaction +// might have a different hash if any sorting was done. +func Sort(tx *wire.MsgTx) *wire.MsgTx { + txCopy := tx.Copy() + sort.Sort(sortableInputSlice(txCopy.TxIn)) + sort.Sort(sortableOutputSlice(txCopy.TxOut)) + return txCopy +} + +// IsSorted checks whether tx has inputs and outputs sorted according to BIP +// 69. +func IsSorted(tx *wire.MsgTx) bool { + if !sort.IsSorted(sortableInputSlice(tx.TxIn)) { + return false + } + if !sort.IsSorted(sortableOutputSlice(tx.TxOut)) { + return false + } + return true +} + +type sortableInputSlice []*wire.TxIn +type sortableOutputSlice []*wire.TxOut + +// For SortableInputSlice and SortableOutputSlice, three functions are needed +// to make it sortable with sort.Sort() -- Len, Less, and Swap +// Len and Swap are trivial. Less is BIP 69 specific. +func (s sortableInputSlice) Len() int { return len(s) } +func (s sortableOutputSlice) Len() int { return len(s) } +func (s sortableOutputSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s sortableInputSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// Input comparison function. +// First sort based on input hash (reversed / rpc-style), then index. +func (s sortableInputSlice) Less(i, j int) bool { + // Input hashes are the same, so compare the index. + ihash := s[i].PreviousOutPoint.Hash + jhash := s[j].PreviousOutPoint.Hash + if ihash == jhash { + return s[i].PreviousOutPoint.Index < s[j].PreviousOutPoint.Index + } + + // At this point, the hashes are not equal, so reverse them to + // big-endian and return the result of the comparison. + const hashSize = chainhash.HashSize + for b := 0; b < hashSize/2; b++ { + ihash[b], ihash[hashSize-1-b] = ihash[hashSize-1-b], ihash[b] + jhash[b], jhash[hashSize-1-b] = jhash[hashSize-1-b], jhash[b] + } + return bytes.Compare(ihash[:], jhash[:]) == -1 +} + +// Output comparison function. +// First sort based on amount (smallest first), then PkScript. +func (s sortableOutputSlice) Less(i, j int) bool { + if s[i].Value == s[j].Value { + return bytes.Compare(s[i].PkScript, s[j].PkScript) < 0 + } + return s[i].Value < s[j].Value +} diff --git a/vendor/github.com/btcsuite/btcwallet/chain/bitcoind_conn.go b/vendor/github.com/btcsuite/btcwallet/chain/bitcoind_conn.go index cbf4863..9029527 100644 --- a/vendor/github.com/btcsuite/btcwallet/chain/bitcoind_conn.go +++ b/vendor/github.com/btcsuite/btcwallet/chain/bitcoind_conn.go @@ -16,6 +16,28 @@ import ( "github.com/lightninglabs/gozmq" ) +const ( + // rawBlockZMQCommand is the command used to receive raw block + // notifications from bitcoind through ZMQ. + rawBlockZMQCommand = "rawblock" + + // rawTxZMQCommand is the command used to receive raw transaction + // notifications from bitcoind through ZMQ. + rawTxZMQCommand = "rawtx" + + // maxRawBlockSize is the maximum size in bytes for a raw block received + // from bitcoind through ZMQ. + maxRawBlockSize = 4e6 + + // maxRawTxSize is the maximum size in bytes for a raw transaction + // received from bitcoind through ZMQ. + maxRawTxSize = maxRawBlockSize + + // seqNumLen is the length of the sequence number of a message sent from + // bitcoind through ZMQ. + seqNumLen = 4 +) + // BitcoindConn represents a persistent client connection to a bitcoind node // that listens for events read from a ZMQ connection. type BitcoindConn struct { @@ -79,7 +101,7 @@ func NewBitcoindConn(chainParams *chaincfg.Params, // concern to ensure one type of event isn't dropped from the connection // queue due to another type of event filling it up. zmqBlockConn, err := gozmq.Subscribe( - zmqBlockHost, []string{"rawblock"}, zmqPollInterval, + zmqBlockHost, []string{rawBlockZMQCommand}, zmqPollInterval, ) if err != nil { return nil, fmt.Errorf("unable to subscribe for zmq block "+ @@ -87,7 +109,7 @@ func NewBitcoindConn(chainParams *chaincfg.Params, } zmqTxConn, err := gozmq.Subscribe( - zmqTxHost, []string{"rawtx"}, zmqPollInterval, + zmqTxHost, []string{rawTxZMQCommand}, zmqPollInterval, ) if err != nil { zmqBlockConn.Close() @@ -164,6 +186,20 @@ func (c *BitcoindConn) blockEventHandler() { log.Info("Started listening for bitcoind block notifications via ZMQ "+ "on", c.zmqBlockConn.RemoteAddr()) + // Set up the buffers we expect our messages to consume. ZMQ + // messages from bitcoind include three parts: the command, the + // data, and the sequence number. + // + // We'll allocate a fixed data slice that we'll reuse when reading + // blocks from bitcoind through ZMQ. There's no need to recycle this + // slice (zero out) after using it, as further reads will overwrite the + // slice and we'll only be deserializing the bytes needed. + var ( + command [len(rawBlockZMQCommand)]byte + seqNum [seqNumLen]byte + data = make([]byte, maxRawBlockSize) + ) + for { // Before attempting to read from the ZMQ socket, we'll make // sure to check if we've been requested to shut down. @@ -174,7 +210,11 @@ func (c *BitcoindConn) blockEventHandler() { } // Poll an event from the ZMQ socket. - msgBytes, err := c.zmqBlockConn.Receive() + var ( + bufs = [][]byte{command[:], data, seqNum[:]} + err error + ) + bufs, err = c.zmqBlockConn.Receive(bufs) if err != nil { // EOF should only be returned if the connection was // explicitly closed, so we can exit at this point. @@ -187,22 +227,24 @@ func (c *BitcoindConn) blockEventHandler() { // error to prevent spamming the logs. netErr, ok := err.(net.Error) if ok && netErr.Timeout() { + log.Trace("Re-establishing timed out ZMQ " + + "block connection") continue } - log.Errorf("Unable to receive ZMQ rawblock message: %v", - err) + log.Errorf("Unable to receive ZMQ %v message: %v", + rawBlockZMQCommand, err) continue } // We have an event! We'll now ensure it is a block event, // deserialize it, and report it to the different rescan // clients. - eventType := string(msgBytes[0]) + eventType := string(bufs[0]) switch eventType { - case "rawblock": + case rawBlockZMQCommand: block := &wire.MsgBlock{} - r := bytes.NewReader(msgBytes[1]) + r := bytes.NewReader(bufs[1]) if err := block.Deserialize(r); err != nil { log.Errorf("Unable to deserialize block: %v", err) @@ -229,8 +271,9 @@ func (c *BitcoindConn) blockEventHandler() { continue } - log.Warnf("Received unexpected event type from "+ - "rawblock subscription: %v", eventType) + log.Warnf("Received unexpected event type from %v "+ + "subscription: %v", rawBlockZMQCommand, + eventType) } } } @@ -245,6 +288,20 @@ func (c *BitcoindConn) txEventHandler() { log.Info("Started listening for bitcoind transaction notifications "+ "via ZMQ on", c.zmqTxConn.RemoteAddr()) + // Set up the buffers we expect our messages to consume. ZMQ + // messages from bitcoind include three parts: the command, the + // data, and the sequence number. + // + // We'll allocate a fixed data slice that we'll reuse when reading + // transactions from bitcoind through ZMQ. There's no need to recycle + // this slice (zero out) after using it, as further reads will overwrite + // the slice and we'll only be deserializing the bytes needed. + var ( + command [len(rawTxZMQCommand)]byte + seqNum [seqNumLen]byte + data = make([]byte, maxRawTxSize) + ) + for { // Before attempting to read from the ZMQ socket, we'll make // sure to check if we've been requested to shut down. @@ -255,7 +312,11 @@ func (c *BitcoindConn) txEventHandler() { } // Poll an event from the ZMQ socket. - msgBytes, err := c.zmqTxConn.Receive() + var ( + bufs = [][]byte{command[:], data, seqNum[:]} + err error + ) + bufs, err = c.zmqTxConn.Receive(bufs) if err != nil { // EOF should only be returned if the connection was // explicitly closed, so we can exit at this point. @@ -268,22 +329,24 @@ func (c *BitcoindConn) txEventHandler() { // error to prevent spamming the logs. netErr, ok := err.(net.Error) if ok && netErr.Timeout() { + log.Trace("Re-establishing timed out ZMQ " + + "transaction connection") continue } - log.Errorf("Unable to receive ZMQ rawtx message: %v", - err) + log.Errorf("Unable to receive ZMQ %v message: %v", + rawTxZMQCommand, err) continue } // We have an event! We'll now ensure it is a transaction event, // deserialize it, and report it to the different rescan // clients. - eventType := string(msgBytes[0]) + eventType := string(bufs[0]) switch eventType { - case "rawtx": + case rawTxZMQCommand: tx := &wire.MsgTx{} - r := bytes.NewReader(msgBytes[1]) + r := bytes.NewReader(bufs[1]) if err := tx.Deserialize(r); err != nil { log.Errorf("Unable to deserialize "+ "transaction: %v", err) @@ -310,8 +373,8 @@ func (c *BitcoindConn) txEventHandler() { continue } - log.Warnf("Received unexpected event type from rawtx "+ - "subscription: %v", eventType) + log.Warnf("Received unexpected event type from %v "+ + "subscription: %v", rawTxZMQCommand, eventType) } } } diff --git a/vendor/github.com/btcsuite/btcwallet/chain/neutrino.go b/vendor/github.com/btcsuite/btcwallet/chain/neutrino.go index 71ef800..28987f7 100644 --- a/vendor/github.com/btcsuite/btcwallet/chain/neutrino.go +++ b/vendor/github.com/btcsuite/btcwallet/chain/neutrino.go @@ -199,6 +199,11 @@ func (s *NeutrinoClient) FilterBlocks( // the filter returns a positive match, the full block is then requested // and scanned for addresses using the block filterer. for i, blk := range req.Blocks { + // TODO(wilmer): Investigate why polling it still necessary + // here. While testing, I ran into a few instances where the + // filter was not retrieved, leading to a panic. This should not + // happen in most cases thanks to the query logic revamp within + // Neutrino, but it seems there's still an uncovered edge case. filter, err := s.pollCFilter(&blk.Hash) if err != nil { return nil, err @@ -312,7 +317,9 @@ func (s *NeutrinoClient) pollCFilter(hash *chainhash.Hash) (*gcs.Filter, error) time.Sleep(100 * time.Millisecond) } - filter, err = s.CS.GetCFilter(*hash, wire.GCSFilterRegular) + filter, err = s.CS.GetCFilter( + *hash, wire.GCSFilterRegular, neutrino.OptimisticBatch(), + ) if err != nil { count++ continue diff --git a/vendor/github.com/btcsuite/btcwallet/internal/legacy/keystore/keystore.go b/vendor/github.com/btcsuite/btcwallet/internal/legacy/keystore/keystore.go new file mode 100644 index 0000000..f671f18 --- /dev/null +++ b/vendor/github.com/btcsuite/btcwallet/internal/legacy/keystore/keystore.go @@ -0,0 +1,3241 @@ +// 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 keystore + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha512" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "io" + "io/ioutil" + "math/big" + "os" + "path/filepath" + "sync" + "time" + + "golang.org/x/crypto/ripemd160" + + "github.com/btcsuite/btcd/btcec" + "github.com/btcsuite/btcd/chaincfg" + "github.com/btcsuite/btcd/chaincfg/chainhash" + "github.com/btcsuite/btcd/txscript" + "github.com/btcsuite/btcd/wire" + "github.com/btcsuite/btcutil" + "github.com/btcsuite/btcwallet/internal/legacy/rename" +) + +const ( + Filename = "wallet.bin" + + // Length in bytes of KDF output. + kdfOutputBytes = 32 + + // Maximum length in bytes of a comment that can have a size represented + // as a uint16. + maxCommentLen = (1 << 16) - 1 +) + +const ( + defaultKdfComputeTime = 0.25 + defaultKdfMaxMem = 32 * 1024 * 1024 +) + +// Possible errors when dealing with key stores. +var ( + ErrAddressNotFound = errors.New("address not found") + ErrAlreadyEncrypted = errors.New("private key is already encrypted") + ErrChecksumMismatch = errors.New("checksum mismatch") + ErrDuplicate = errors.New("duplicate key or address") + ErrMalformedEntry = errors.New("malformed entry") + ErrWatchingOnly = errors.New("keystore is watching-only") + ErrLocked = errors.New("keystore is locked") + ErrWrongPassphrase = errors.New("wrong passphrase") +) + +var fileID = [8]byte{0xba, 'W', 'A', 'L', 'L', 'E', 'T', 0x00} + +type entryHeader byte + +const ( + addrCommentHeader entryHeader = 1 << iota + txCommentHeader + deletedHeader + scriptHeader + addrHeader entryHeader = 0 +) + +// We want to use binaryRead and binaryWrite instead of binary.Read +// and binary.Write because those from the binary package do not return +// the number of bytes actually written or read. We need to return +// this value to correctly support the io.ReaderFrom and io.WriterTo +// interfaces. +func binaryRead(r io.Reader, order binary.ByteOrder, data interface{}) (n int64, err error) { + var read int + buf := make([]byte, binary.Size(data)) + if read, err = io.ReadFull(r, buf); err != nil { + return int64(read), err + } + return int64(read), binary.Read(bytes.NewBuffer(buf), order, data) +} + +// See comment for binaryRead(). +func binaryWrite(w io.Writer, order binary.ByteOrder, data interface{}) (n int64, err error) { + buf := bytes.Buffer{} + if err = binary.Write(&buf, order, data); err != nil { + return 0, err + } + + written, err := w.Write(buf.Bytes()) + return int64(written), err +} + +// pubkeyFromPrivkey creates an encoded pubkey based on a +// 32-byte privkey. The returned pubkey is 33 bytes if compressed, +// or 65 bytes if uncompressed. +func pubkeyFromPrivkey(privkey []byte, compress bool) (pubkey []byte) { + _, pk := btcec.PrivKeyFromBytes(btcec.S256(), privkey) + + if compress { + return pk.SerializeCompressed() + } + return pk.SerializeUncompressed() +} + +func keyOneIter(passphrase, salt []byte, memReqts uint64) []byte { + saltedpass := append(passphrase, salt...) + lutbl := make([]byte, memReqts) + + // Seed for lookup table + seed := sha512.Sum512(saltedpass) + copy(lutbl[:sha512.Size], seed[:]) + + for nByte := 0; nByte < (int(memReqts) - sha512.Size); nByte += sha512.Size { + hash := sha512.Sum512(lutbl[nByte : nByte+sha512.Size]) + copy(lutbl[nByte+sha512.Size:nByte+2*sha512.Size], hash[:]) + } + + x := lutbl[cap(lutbl)-sha512.Size:] + + seqCt := uint32(memReqts / sha512.Size) + nLookups := seqCt / 2 + for i := uint32(0); i < nLookups; i++ { + // Armory ignores endianness here. We assume LE. + newIdx := binary.LittleEndian.Uint32(x[cap(x)-4:]) % seqCt + + // Index of hash result at newIdx + vIdx := newIdx * sha512.Size + v := lutbl[vIdx : vIdx+sha512.Size] + + // XOR hash x with hash v + for j := 0; j < sha512.Size; j++ { + x[j] ^= v[j] + } + + // Save new hash to x + hash := sha512.Sum512(x) + copy(x, hash[:]) + } + + return x[:kdfOutputBytes] +} + +// kdf implements the key derivation function used by Armory +// based on the ROMix algorithm described in Colin Percival's paper +// "Stronger Key Derivation via Sequential Memory-Hard Functions" +// (http://www.tarsnap.com/scrypt/scrypt.pdf). +func kdf(passphrase []byte, params *kdfParameters) []byte { + masterKey := passphrase + for i := uint32(0); i < params.nIter; i++ { + masterKey = keyOneIter(masterKey, params.salt[:], params.mem) + } + return masterKey +} + +func pad(size int, b []byte) []byte { + // Prevent a possible panic if the input exceeds the expected size. + if len(b) > size { + size = len(b) + } + + p := make([]byte, size) + copy(p[size-len(b):], b) + return p +} + +// chainedPrivKey deterministically generates a new private key using a +// previous address and chaincode. privkey and chaincode must be 32 +// bytes long, and pubkey may either be 33 or 65 bytes. +func chainedPrivKey(privkey, pubkey, chaincode []byte) ([]byte, error) { + if len(privkey) != 32 { + return nil, fmt.Errorf("invalid privkey length %d (must be 32)", + len(privkey)) + } + if len(chaincode) != 32 { + return nil, fmt.Errorf("invalid chaincode length %d (must be 32)", + len(chaincode)) + } + switch n := len(pubkey); n { + case btcec.PubKeyBytesLenUncompressed, btcec.PubKeyBytesLenCompressed: + // Correct length + default: + return nil, fmt.Errorf("invalid pubkey length %d", n) + } + + xorbytes := make([]byte, 32) + chainMod := chainhash.DoubleHashB(pubkey) + for i := range xorbytes { + xorbytes[i] = chainMod[i] ^ chaincode[i] + } + chainXor := new(big.Int).SetBytes(xorbytes) + privint := new(big.Int).SetBytes(privkey) + + t := new(big.Int).Mul(chainXor, privint) + b := t.Mod(t, btcec.S256().N).Bytes() + return pad(32, b), nil +} + +// chainedPubKey deterministically generates a new public key using a +// previous public key and chaincode. pubkey must be 33 or 65 bytes, and +// chaincode must be 32 bytes long. +func chainedPubKey(pubkey, chaincode []byte) ([]byte, error) { + var compressed bool + switch n := len(pubkey); n { + case btcec.PubKeyBytesLenUncompressed: + compressed = false + case btcec.PubKeyBytesLenCompressed: + compressed = true + default: + // Incorrect serialized pubkey length + return nil, fmt.Errorf("invalid pubkey length %d", n) + } + if len(chaincode) != 32 { + return nil, fmt.Errorf("invalid chaincode length %d (must be 32)", + len(chaincode)) + } + + xorbytes := make([]byte, 32) + chainMod := chainhash.DoubleHashB(pubkey) + for i := range xorbytes { + xorbytes[i] = chainMod[i] ^ chaincode[i] + } + + oldPk, err := btcec.ParsePubKey(pubkey, btcec.S256()) + if err != nil { + return nil, err + } + newX, newY := btcec.S256().ScalarMult(oldPk.X, oldPk.Y, xorbytes) + if err != nil { + return nil, err + } + newPk := &btcec.PublicKey{ + Curve: btcec.S256(), + X: newX, + Y: newY, + } + + if compressed { + return newPk.SerializeCompressed(), nil + } + return newPk.SerializeUncompressed(), nil +} + +type version struct { + major byte + minor byte + bugfix byte + autoincrement byte +} + +// Enforce that version satisifies the io.ReaderFrom and +// io.WriterTo interfaces. +var _ io.ReaderFrom = &version{} +var _ io.WriterTo = &version{} + +// readerFromVersion is an io.ReaderFrom and io.WriterTo that +// can specify any particular key store file format for reading +// depending on the key store file version. +type readerFromVersion interface { + readFromVersion(version, io.Reader) (int64, error) + io.WriterTo +} + +func (v version) String() string { + str := fmt.Sprintf("%d.%d", v.major, v.minor) + if v.bugfix != 0x00 || v.autoincrement != 0x00 { + str += fmt.Sprintf(".%d", v.bugfix) + } + if v.autoincrement != 0x00 { + str += fmt.Sprintf(".%d", v.autoincrement) + } + return str +} + +func (v version) Uint32() uint32 { + return uint32(v.major)<<6 | uint32(v.minor)<<4 | uint32(v.bugfix)<<2 | uint32(v.autoincrement) +} + +func (v *version) ReadFrom(r io.Reader) (int64, error) { + // Read 4 bytes for the version. + var versBytes [4]byte + n, err := io.ReadFull(r, versBytes[:]) + if err != nil { + return int64(n), err + } + v.major = versBytes[0] + v.minor = versBytes[1] + v.bugfix = versBytes[2] + v.autoincrement = versBytes[3] + return int64(n), nil +} + +func (v *version) WriteTo(w io.Writer) (int64, error) { + // Write 4 bytes for the version. + versBytes := []byte{ + v.major, + v.minor, + v.bugfix, + v.autoincrement, + } + n, err := w.Write(versBytes) + return int64(n), err +} + +// LT returns whether v is an earlier version than v2. +func (v version) LT(v2 version) bool { + switch { + case v.major < v2.major: + return true + + case v.minor < v2.minor: + return true + + case v.bugfix < v2.bugfix: + return true + + case v.autoincrement < v2.autoincrement: + return true + + default: + return false + } +} + +// EQ returns whether v2 is an equal version to v. +func (v version) EQ(v2 version) bool { + switch { + case v.major != v2.major: + return false + + case v.minor != v2.minor: + return false + + case v.bugfix != v2.bugfix: + return false + + case v.autoincrement != v2.autoincrement: + return false + + default: + return true + } +} + +// GT returns whether v is a later version than v2. +func (v version) GT(v2 version) bool { + switch { + case v.major > v2.major: + return true + + case v.minor > v2.minor: + return true + + case v.bugfix > v2.bugfix: + return true + + case v.autoincrement > v2.autoincrement: + return true + + default: + return false + } +} + +// Various versions. +var ( + // VersArmory is the latest version used by Armory. + VersArmory = version{1, 35, 0, 0} + + // Vers20LastBlocks is the version where key store files now hold + // the 20 most recently seen block hashes. + Vers20LastBlocks = version{1, 36, 0, 0} + + // VersUnsetNeedsPrivkeyFlag is the bugfix version where the + // createPrivKeyNextUnlock address flag is correctly unset + // after creating and encrypting its private key after unlock. + // Otherwise, re-creating private keys will occur too early + // in the address chain and fail due to encrypting an already + // encrypted address. Key store versions at or before this + // version include a special case to allow the duplicate + // encrypt. + VersUnsetNeedsPrivkeyFlag = version{1, 36, 1, 0} + + // VersCurrent is the current key store file version. + VersCurrent = VersUnsetNeedsPrivkeyFlag +) + +type varEntries struct { + store *Store + entries []io.WriterTo +} + +func (v *varEntries) WriteTo(w io.Writer) (n int64, err error) { + ss := v.entries + + var written int64 + for _, s := range ss { + var err error + if written, err = s.WriteTo(w); err != nil { + return n + written, err + } + n += written + } + return n, nil +} + +func (v *varEntries) ReadFrom(r io.Reader) (n int64, err error) { + var read int64 + + // Remove any previous entries. + v.entries = nil + wts := v.entries + + // Keep reading entries until an EOF is reached. + for { + var header entryHeader + if read, err = binaryRead(r, binary.LittleEndian, &header); err != nil { + // EOF here is not an error. + if err == io.EOF { + return n + read, nil + } + return n + read, err + } + n += read + + var wt io.WriterTo + switch header { + case addrHeader: + var entry addrEntry + entry.addr.store = v.store + if read, err = entry.ReadFrom(r); err != nil { + return n + read, err + } + n += read + wt = &entry + case scriptHeader: + var entry scriptEntry + entry.script.store = v.store + if read, err = entry.ReadFrom(r); err != nil { + return n + read, err + } + n += read + wt = &entry + default: + return n, fmt.Errorf("unknown entry header: %d", uint8(header)) + } + if wt != nil { + wts = append(wts, wt) + v.entries = wts + } + } +} + +// Key stores use a custom network parameters type so it can be an io.ReaderFrom. +// Due to the way and order that key stores are currently serialized and how +// address reading requires the key store's network parameters, setting and +// erroring on unknown key store networks must happen on the read itself and not +// after the fact. This is admitidly a hack, but with a bip32 keystore on the +// horizon I'm not too motivated to clean this up. +type netParams chaincfg.Params + +func (net *netParams) ReadFrom(r io.Reader) (int64, error) { + var buf [4]byte + uint32Bytes := buf[:4] + + n, err := io.ReadFull(r, uint32Bytes) + n64 := int64(n) + if err != nil { + return n64, err + } + + switch wire.BitcoinNet(binary.LittleEndian.Uint32(uint32Bytes)) { + case wire.MainNet: + *net = (netParams)(chaincfg.MainNetParams) + case wire.TestNet3: + *net = (netParams)(chaincfg.TestNet3Params) + case wire.SimNet: + *net = (netParams)(chaincfg.SimNetParams) + default: + return n64, errors.New("unknown network") + } + return n64, nil +} + +func (net *netParams) WriteTo(w io.Writer) (int64, error) { + var buf [4]byte + uint32Bytes := buf[:4] + + binary.LittleEndian.PutUint32(uint32Bytes, uint32(net.Net)) + n, err := w.Write(uint32Bytes) + n64 := int64(n) + return n64, err +} + +// Stringified byte slices for use as map lookup keys. +type addressKey string +type transactionHashKey string + +type comment []byte + +func getAddressKey(addr btcutil.Address) addressKey { + return addressKey(addr.ScriptAddress()) +} + +// Store represents an key store in memory. It implements the +// io.ReaderFrom and io.WriterTo interfaces to read from and +// write to any type of byte streams, including files. +type Store struct { + // TODO: Use atomic operations for dirty so the reader lock + // doesn't need to be grabbed. + dirty bool + path string + dir string + file string + + mtx sync.RWMutex + vers version + net *netParams + flags walletFlags + createDate int64 + name [32]byte + desc [256]byte + highestUsed int64 + kdfParams kdfParameters + keyGenerator btcAddress + + // These are non-standard and fit in the extra 1024 bytes between the + // root address and the appended entries. + recent recentBlocks + + addrMap map[addressKey]walletAddress + + // The rest of the fields in this struct are not serialized. + passphrase []byte + secret []byte + chainIdxMap map[int64]btcutil.Address + importedAddrs []walletAddress + lastChainIdx int64 + missingKeysStart int64 +} + +// New creates and initializes a new Store. name's and desc's byte length +// must not exceed 32 and 256 bytes, respectively. All address private keys +// are encrypted with passphrase. The key store is returned locked. +func New(dir string, desc string, passphrase []byte, net *chaincfg.Params, + createdAt *BlockStamp) (*Store, error) { + + // Check sizes of inputs. + if len(desc) > 256 { + return nil, errors.New("desc exceeds 256 byte maximum size") + } + + // Randomly-generate rootkey and chaincode. + rootkey := make([]byte, 32) + if _, err := rand.Read(rootkey); err != nil { + return nil, err + } + chaincode := make([]byte, 32) + if _, err := rand.Read(chaincode); err != nil { + return nil, err + } + + // Compute AES key and encrypt root address. + kdfp, err := computeKdfParameters(defaultKdfComputeTime, defaultKdfMaxMem) + if err != nil { + return nil, err + } + aeskey := kdf(passphrase, kdfp) + + // Create and fill key store. + s := &Store{ + path: filepath.Join(dir, Filename), + dir: dir, + file: Filename, + vers: VersCurrent, + net: (*netParams)(net), + flags: walletFlags{ + useEncryption: true, + watchingOnly: false, + }, + createDate: time.Now().Unix(), + highestUsed: rootKeyChainIdx, + kdfParams: *kdfp, + recent: recentBlocks{ + lastHeight: createdAt.Height, + hashes: []*chainhash.Hash{ + createdAt.Hash, + }, + }, + addrMap: make(map[addressKey]walletAddress), + chainIdxMap: make(map[int64]btcutil.Address), + lastChainIdx: rootKeyChainIdx, + missingKeysStart: rootKeyChainIdx, + secret: aeskey, + } + copy(s.desc[:], []byte(desc)) + + // Create new root address from key and chaincode. + root, err := newRootBtcAddress(s, rootkey, nil, chaincode, + createdAt) + if err != nil { + return nil, err + } + + // Verify root address keypairs. + if err := root.verifyKeypairs(); err != nil { + return nil, err + } + + if err := root.encrypt(aeskey); err != nil { + return nil, err + } + + s.keyGenerator = *root + + // Add root address to maps. + rootAddr := s.keyGenerator.Address() + s.addrMap[getAddressKey(rootAddr)] = &s.keyGenerator + s.chainIdxMap[rootKeyChainIdx] = rootAddr + + // key store must be returned locked. + if err := s.Lock(); err != nil { + return nil, err + } + + return s, nil +} + +// ReadFrom reads data from a io.Reader and saves it to a key store, +// returning the number of bytes read and any errors encountered. +func (s *Store) ReadFrom(r io.Reader) (n int64, err error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + var read int64 + + s.net = &netParams{} + s.addrMap = make(map[addressKey]walletAddress) + s.chainIdxMap = make(map[int64]btcutil.Address) + + var id [8]byte + appendedEntries := varEntries{store: s} + s.keyGenerator.store = s + + // Iterate through each entry needing to be read. If data + // implements io.ReaderFrom, use its ReadFrom func. Otherwise, + // data is a pointer to a fixed sized value. + datas := []interface{}{ + &id, + &s.vers, + s.net, + &s.flags, + make([]byte, 6), // Bytes for Armory unique ID + &s.createDate, + &s.name, + &s.desc, + &s.highestUsed, + &s.kdfParams, + make([]byte, 256), + &s.keyGenerator, + newUnusedSpace(1024, &s.recent), + &appendedEntries, + } + for _, data := range datas { + var err error + switch d := data.(type) { + case readerFromVersion: + read, err = d.readFromVersion(s.vers, r) + + case io.ReaderFrom: + read, err = d.ReadFrom(r) + + default: + read, err = binaryRead(r, binary.LittleEndian, d) + } + n += read + if err != nil { + return n, err + } + } + + if id != fileID { + return n, errors.New("unknown file ID") + } + + // Add root address to address map. + rootAddr := s.keyGenerator.Address() + s.addrMap[getAddressKey(rootAddr)] = &s.keyGenerator + s.chainIdxMap[rootKeyChainIdx] = rootAddr + s.lastChainIdx = rootKeyChainIdx + + // Fill unserializied fields. + wts := appendedEntries.entries + for _, wt := range wts { + switch e := wt.(type) { + case *addrEntry: + addr := e.addr.Address() + s.addrMap[getAddressKey(addr)] = &e.addr + if e.addr.Imported() { + s.importedAddrs = append(s.importedAddrs, &e.addr) + } else { + s.chainIdxMap[e.addr.chainIndex] = addr + if s.lastChainIdx < e.addr.chainIndex { + s.lastChainIdx = e.addr.chainIndex + } + } + + // If the private keys have not been created yet, mark the + // earliest so all can be created on next key store unlock. + if e.addr.flags.createPrivKeyNextUnlock { + switch { + case s.missingKeysStart == rootKeyChainIdx: + fallthrough + case e.addr.chainIndex < s.missingKeysStart: + s.missingKeysStart = e.addr.chainIndex + } + } + + case *scriptEntry: + addr := e.script.Address() + s.addrMap[getAddressKey(addr)] = &e.script + // script are always imported. + s.importedAddrs = append(s.importedAddrs, &e.script) + + default: + return n, errors.New("unknown appended entry") + } + } + + return n, nil +} + +// WriteTo serializes a key store and writes it to a io.Writer, +// returning the number of bytes written and any errors encountered. +func (s *Store) WriteTo(w io.Writer) (n int64, err error) { + s.mtx.RLock() + defer s.mtx.RUnlock() + + return s.writeTo(w) +} + +func (s *Store) writeTo(w io.Writer) (n int64, err error) { + var wts []io.WriterTo + var chainedAddrs = make([]io.WriterTo, len(s.chainIdxMap)-1) + var importedAddrs []io.WriterTo + for _, wAddr := range s.addrMap { + switch btcAddr := wAddr.(type) { + case *btcAddress: + e := &addrEntry{ + addr: *btcAddr, + } + copy(e.pubKeyHash160[:], btcAddr.AddrHash()) + if btcAddr.Imported() { + // No order for imported addresses. + importedAddrs = append(importedAddrs, e) + } else if btcAddr.chainIndex >= 0 { + // Chained addresses are sorted. This is + // kind of nice but probably isn't necessary. + chainedAddrs[btcAddr.chainIndex] = e + } + + case *scriptAddress: + e := &scriptEntry{ + script: *btcAddr, + } + copy(e.scriptHash160[:], btcAddr.AddrHash()) + // scripts are always imported + importedAddrs = append(importedAddrs, e) + } + } + wts = append(chainedAddrs, importedAddrs...) + appendedEntries := varEntries{store: s, entries: wts} + + // Iterate through each entry needing to be written. If data + // implements io.WriterTo, use its WriteTo func. Otherwise, + // data is a pointer to a fixed size value. + datas := []interface{}{ + &fileID, + &VersCurrent, + s.net, + &s.flags, + make([]byte, 6), // Bytes for Armory unique ID + &s.createDate, + &s.name, + &s.desc, + &s.highestUsed, + &s.kdfParams, + make([]byte, 256), + &s.keyGenerator, + newUnusedSpace(1024, &s.recent), + &appendedEntries, + } + var written int64 + for _, data := range datas { + if s, ok := data.(io.WriterTo); ok { + written, err = s.WriteTo(w) + } else { + written, err = binaryWrite(w, binary.LittleEndian, data) + } + n += written + if err != nil { + return n, err + } + } + + return n, nil +} + +// TODO: set this automatically. +func (s *Store) MarkDirty() { + s.mtx.Lock() + defer s.mtx.Unlock() + + s.dirty = true +} + +func (s *Store) WriteIfDirty() error { + s.mtx.RLock() + if !s.dirty { + s.mtx.RUnlock() + return nil + } + + // TempFile creates the file 0600, so no need to chmod it. + fi, err := ioutil.TempFile(s.dir, s.file) + if err != nil { + s.mtx.RUnlock() + return err + } + fiPath := fi.Name() + + _, err = s.writeTo(fi) + if err != nil { + s.mtx.RUnlock() + fi.Close() + return err + } + err = fi.Sync() + if err != nil { + s.mtx.RUnlock() + fi.Close() + return err + } + fi.Close() + + err = rename.Atomic(fiPath, s.path) + s.mtx.RUnlock() + + if err == nil { + s.mtx.Lock() + s.dirty = false + s.mtx.Unlock() + } + + return err +} + +// OpenDir opens a new key store from the specified directory. If the file +// does not exist, the error from the os package will be returned, and can +// be checked with os.IsNotExist to differentiate missing file errors from +// others (including deserialization). +func OpenDir(dir string) (*Store, error) { + path := filepath.Join(dir, Filename) + fi, err := os.OpenFile(path, os.O_RDONLY, 0) + if err != nil { + return nil, err + } + defer fi.Close() + store := new(Store) + _, err = store.ReadFrom(fi) + if err != nil { + return nil, err + } + store.path = path + store.dir = dir + store.file = Filename + return store, nil +} + +// Unlock derives an AES key from passphrase and key store's KDF +// parameters and unlocks the root key of the key store. If +// the unlock was successful, the key store's secret key is saved, +// allowing the decryption of any encrypted private key. Any +// addresses created while the key store was locked without private +// keys are created at this time. +func (s *Store) Unlock(passphrase []byte) error { + s.mtx.Lock() + defer s.mtx.Unlock() + + if s.flags.watchingOnly { + return ErrWatchingOnly + } + + // Derive key from KDF parameters and passphrase. + key := kdf(passphrase, &s.kdfParams) + + // Unlock root address with derived key. + if _, err := s.keyGenerator.unlock(key); err != nil { + return err + } + + // If unlock was successful, save the passphrase and aes key. + s.passphrase = passphrase + s.secret = key + + return s.createMissingPrivateKeys() +} + +// Lock performs a best try effort to remove and zero all secret keys +// associated with the key store. +func (s *Store) Lock() (err error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + if s.flags.watchingOnly { + return ErrWatchingOnly + } + + // Remove clear text passphrase from key store. + if s.isLocked() { + err = ErrLocked + } else { + zero(s.passphrase) + s.passphrase = nil + zero(s.secret) + s.secret = nil + } + + // Remove clear text private keys from all address entries. + for _, addr := range s.addrMap { + if baddr, ok := addr.(*btcAddress); ok { + _ = baddr.lock() + } + } + + return err +} + +// ChangePassphrase creates a new AES key from a new passphrase and +// re-encrypts all encrypted private keys with the new key. +func (s *Store) ChangePassphrase(new []byte) error { + s.mtx.Lock() + defer s.mtx.Unlock() + + if s.flags.watchingOnly { + return ErrWatchingOnly + } + + if s.isLocked() { + return ErrLocked + } + + oldkey := s.secret + newkey := kdf(new, &s.kdfParams) + + for _, wa := range s.addrMap { + // Only btcAddresses curently have private keys. + a, ok := wa.(*btcAddress) + if !ok { + continue + } + + if err := a.changeEncryptionKey(oldkey, newkey); err != nil { + return err + } + } + + // zero old secrets. + zero(s.passphrase) + zero(s.secret) + + // Save new secrets. + s.passphrase = new + s.secret = newkey + + return nil +} + +func zero(b []byte) { + for i := range b { + b[i] = 0 + } +} + +// IsLocked returns whether a key store is unlocked (in which case the +// key is saved in memory), or locked. +func (s *Store) IsLocked() bool { + s.mtx.RLock() + defer s.mtx.RUnlock() + + return s.isLocked() +} + +func (s *Store) isLocked() bool { + return len(s.secret) != 32 +} + +// NextChainedAddress attempts to get the next chained address. If the key +// store is unlocked, the next pubkey and private key of the address chain are +// derived. If the key store is locke, only the next pubkey is derived, and +// the private key will be generated on next unlock. +func (s *Store) NextChainedAddress(bs *BlockStamp) (btcutil.Address, error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + return s.nextChainedAddress(bs) +} + +func (s *Store) nextChainedAddress(bs *BlockStamp) (btcutil.Address, error) { + addr, err := s.nextChainedBtcAddress(bs) + if err != nil { + return nil, err + } + return addr.Address(), nil +} + +// ChangeAddress returns the next chained address from the key store, marking +// the address for a change transaction output. +func (s *Store) ChangeAddress(bs *BlockStamp) (btcutil.Address, error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + addr, err := s.nextChainedBtcAddress(bs) + if err != nil { + return nil, err + } + + addr.flags.change = true + + // Create and return payment address for address hash. + return addr.Address(), nil +} + +func (s *Store) nextChainedBtcAddress(bs *BlockStamp) (*btcAddress, error) { + // Attempt to get address hash of next chained address. + nextAPKH, ok := s.chainIdxMap[s.highestUsed+1] + if !ok { + if s.isLocked() { + // Chain pubkeys. + if err := s.extendLocked(bs); err != nil { + return nil, err + } + } else { + // Chain private and pubkeys. + if err := s.extendUnlocked(bs); err != nil { + return nil, err + } + } + + // Should be added to the internal maps, try lookup again. + nextAPKH, ok = s.chainIdxMap[s.highestUsed+1] + if !ok { + return nil, errors.New("chain index map inproperly updated") + } + } + + // Look up address. + addr, ok := s.addrMap[getAddressKey(nextAPKH)] + if !ok { + return nil, errors.New("cannot find generated address") + } + + btcAddr, ok := addr.(*btcAddress) + if !ok { + return nil, errors.New("found non-pubkey chained address") + } + + s.highestUsed++ + + return btcAddr, nil +} + +// LastChainedAddress returns the most recently requested chained +// address from calling NextChainedAddress, or the root address if +// no chained addresses have been requested. +func (s *Store) LastChainedAddress() btcutil.Address { + s.mtx.RLock() + defer s.mtx.RUnlock() + + return s.chainIdxMap[s.highestUsed] +} + +// extendUnlocked grows address chain for an unlocked keystore. +func (s *Store) extendUnlocked(bs *BlockStamp) error { + // Get last chained address. New chained addresses will be + // chained off of this address's chaincode and private key. + a := s.chainIdxMap[s.lastChainIdx] + waddr, ok := s.addrMap[getAddressKey(a)] + if !ok { + return errors.New("expected last chained address not found") + } + + if s.isLocked() { + return ErrLocked + } + + lastAddr, ok := waddr.(*btcAddress) + if !ok { + return errors.New("found non-pubkey chained address") + } + + privkey, err := lastAddr.unlock(s.secret) + if err != nil { + return err + } + cc := lastAddr.chaincode[:] + + privkey, err = chainedPrivKey(privkey, lastAddr.pubKeyBytes(), cc) + if err != nil { + return err + } + newAddr, err := newBtcAddress(s, privkey, nil, bs, true) + if err != nil { + return err + } + if err := newAddr.verifyKeypairs(); err != nil { + return err + } + if err = newAddr.encrypt(s.secret); err != nil { + return err + } + a = newAddr.Address() + s.addrMap[getAddressKey(a)] = newAddr + newAddr.chainIndex = lastAddr.chainIndex + 1 + s.chainIdxMap[newAddr.chainIndex] = a + s.lastChainIdx++ + copy(newAddr.chaincode[:], cc) + + return nil +} + +// extendLocked creates one new address without a private key (allowing for +// extending the address chain from a locked key store) chained from the +// last used chained address and adds the address to the key store's internal +// bookkeeping structures. +func (s *Store) extendLocked(bs *BlockStamp) error { + a := s.chainIdxMap[s.lastChainIdx] + waddr, ok := s.addrMap[getAddressKey(a)] + if !ok { + return errors.New("expected last chained address not found") + } + + addr, ok := waddr.(*btcAddress) + if !ok { + return errors.New("found non-pubkey chained address") + } + + cc := addr.chaincode[:] + + nextPubkey, err := chainedPubKey(addr.pubKeyBytes(), cc) + if err != nil { + return err + } + newaddr, err := newBtcAddressWithoutPrivkey(s, nextPubkey, nil, bs) + if err != nil { + return err + } + a = newaddr.Address() + s.addrMap[getAddressKey(a)] = newaddr + newaddr.chainIndex = addr.chainIndex + 1 + s.chainIdxMap[newaddr.chainIndex] = a + s.lastChainIdx++ + copy(newaddr.chaincode[:], cc) + + if s.missingKeysStart == rootKeyChainIdx { + s.missingKeysStart = newaddr.chainIndex + } + + return nil +} + +func (s *Store) createMissingPrivateKeys() error { + idx := s.missingKeysStart + if idx == rootKeyChainIdx { + return nil + } + + // Lookup previous address. + apkh, ok := s.chainIdxMap[idx-1] + if !ok { + return errors.New("missing previous chained address") + } + prevWAddr := s.addrMap[getAddressKey(apkh)] + if s.isLocked() { + return ErrLocked + } + + prevAddr, ok := prevWAddr.(*btcAddress) + if !ok { + return errors.New("found non-pubkey chained address") + } + + prevPrivKey, err := prevAddr.unlock(s.secret) + if err != nil { + return err + } + + for i := idx; ; i++ { + // Get the next private key for the ith address in the address chain. + ithPrivKey, err := chainedPrivKey(prevPrivKey, + prevAddr.pubKeyBytes(), prevAddr.chaincode[:]) + if err != nil { + return err + } + + // Get the address with the missing private key, set, and + // encrypt. + apkh, ok := s.chainIdxMap[i] + if !ok { + // Finished. + break + } + waddr := s.addrMap[getAddressKey(apkh)] + addr, ok := waddr.(*btcAddress) + if !ok { + return errors.New("found non-pubkey chained address") + } + addr.privKeyCT = ithPrivKey + if err := addr.encrypt(s.secret); err != nil { + // Avoid bug: see comment for VersUnsetNeedsPrivkeyFlag. + if err != ErrAlreadyEncrypted || s.vers.LT(VersUnsetNeedsPrivkeyFlag) { + return err + } + } + addr.flags.createPrivKeyNextUnlock = false + + // Set previous address and private key for next iteration. + prevAddr = addr + prevPrivKey = ithPrivKey + } + + s.missingKeysStart = rootKeyChainIdx + return nil +} + +// Address returns an walletAddress structure for an address in a key store. +// This address may be typecast into other interfaces (like PubKeyAddress +// and ScriptAddress) if specific information e.g. keys is required. +func (s *Store) Address(a btcutil.Address) (WalletAddress, error) { + s.mtx.RLock() + defer s.mtx.RUnlock() + + // Look up address by address hash. + btcaddr, ok := s.addrMap[getAddressKey(a)] + if !ok { + return nil, ErrAddressNotFound + } + + return btcaddr, nil +} + +// Net returns the bitcoin network parameters for this key store. +func (s *Store) Net() *chaincfg.Params { + s.mtx.RLock() + defer s.mtx.RUnlock() + + return s.netParams() +} + +func (s *Store) netParams() *chaincfg.Params { + return (*chaincfg.Params)(s.net) +} + +// SetSyncStatus sets the sync status for a single key store address. This +// may error if the address is not found in the key store. +// +// When marking an address as unsynced, only the type Unsynced matters. +// The value is ignored. +func (s *Store) SetSyncStatus(a btcutil.Address, ss SyncStatus) error { + s.mtx.Lock() + defer s.mtx.Unlock() + + wa, ok := s.addrMap[getAddressKey(a)] + if !ok { + return ErrAddressNotFound + } + wa.setSyncStatus(ss) + return nil +} + +// SetSyncedWith marks already synced addresses in the key store to be in +// sync with the recently-seen block described by the blockstamp. +// Unsynced addresses are unaffected by this method and must be marked +// as in sync with MarkAddressSynced or MarkAllSynced to be considered +// in sync with bs. +// +// If bs is nil, the entire key store is marked unsynced. +func (s *Store) SetSyncedWith(bs *BlockStamp) { + s.mtx.Lock() + defer s.mtx.Unlock() + + if bs == nil { + s.recent.hashes = s.recent.hashes[:0] + s.recent.lastHeight = s.keyGenerator.firstBlock + s.keyGenerator.setSyncStatus(Unsynced(s.keyGenerator.firstBlock)) + return + } + + // Check if we're trying to rollback the last seen history. + // If so, and this bs is already saved, remove anything + // after and return. Otherwire, remove previous hashes. + if bs.Height < s.recent.lastHeight { + maybeIdx := len(s.recent.hashes) - 1 - int(s.recent.lastHeight-bs.Height) + if maybeIdx >= 0 && maybeIdx < len(s.recent.hashes) && + *s.recent.hashes[maybeIdx] == *bs.Hash { + + s.recent.lastHeight = bs.Height + // subslice out the removed hashes. + s.recent.hashes = s.recent.hashes[:maybeIdx] + return + } + s.recent.hashes = nil + } + + if bs.Height != s.recent.lastHeight+1 { + s.recent.hashes = nil + } + + s.recent.lastHeight = bs.Height + + if len(s.recent.hashes) == 20 { + // Make room for the most recent hash. + copy(s.recent.hashes, s.recent.hashes[1:]) + + // Set new block in the last position. + s.recent.hashes[19] = bs.Hash + } else { + s.recent.hashes = append(s.recent.hashes, bs.Hash) + } +} + +// SyncHeight returns details about the block that a wallet is marked at least +// synced through. The height is the height that rescans should start at when +// syncing a wallet back to the best chain. +// +// NOTE: If the hash of the synced block is not known, hash will be nil, and +// must be obtained from elsewhere. This must be explicitly checked before +// dereferencing the pointer. +func (s *Store) SyncedTo() (hash *chainhash.Hash, height int32) { + s.mtx.RLock() + defer s.mtx.RUnlock() + + switch h, ok := s.keyGenerator.SyncStatus().(PartialSync); { + case ok && int32(h) > s.recent.lastHeight: + height = int32(h) + default: + height = s.recent.lastHeight + if n := len(s.recent.hashes); n != 0 { + hash = s.recent.hashes[n-1] + } + } + for _, a := range s.addrMap { + var syncHeight int32 + switch e := a.SyncStatus().(type) { + case Unsynced: + syncHeight = int32(e) + case PartialSync: + syncHeight = int32(e) + case FullSync: + continue + } + if syncHeight < height { + height = syncHeight + hash = nil + + // Can't go lower than 0. + if height == 0 { + return + } + } + } + return +} + +// NewIterateRecentBlocks returns an iterator for recently-seen blocks. +// The iterator starts at the most recently-added block, and Prev should +// be used to access earlier blocks. +func (s *Store) NewIterateRecentBlocks() *BlockIterator { + s.mtx.RLock() + defer s.mtx.RUnlock() + + return s.recent.iter(s) +} + +// ImportPrivateKey imports a WIF private key into the keystore. The imported +// address is created using either a compressed or uncompressed serialized +// public key, depending on the CompressPubKey bool of the WIF. +func (s *Store) ImportPrivateKey(wif *btcutil.WIF, bs *BlockStamp) (btcutil.Address, error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + if s.flags.watchingOnly { + return nil, ErrWatchingOnly + } + + // First, must check that the key being imported will not result + // in a duplicate address. + pkh := btcutil.Hash160(wif.SerializePubKey()) + if _, ok := s.addrMap[addressKey(pkh)]; ok { + return nil, ErrDuplicate + } + + // The key store must be unlocked to encrypt the imported private key. + if s.isLocked() { + return nil, ErrLocked + } + + // Create new address with this private key. + privKey := wif.PrivKey.Serialize() + btcaddr, err := newBtcAddress(s, privKey, nil, bs, wif.CompressPubKey) + if err != nil { + return nil, err + } + btcaddr.chainIndex = importedKeyChainIdx + + // Mark as unsynced if import height is below currently-synced + // height. + if len(s.recent.hashes) != 0 && bs.Height < s.recent.lastHeight { + btcaddr.flags.unsynced = true + } + + // Encrypt imported address with the derived AES key. + if err = btcaddr.encrypt(s.secret); err != nil { + return nil, err + } + + addr := btcaddr.Address() + // Add address to key store's bookkeeping structures. Adding to + // the map will result in the imported address being serialized + // on the next WriteTo call. + s.addrMap[getAddressKey(addr)] = btcaddr + s.importedAddrs = append(s.importedAddrs, btcaddr) + + // Create and return address. + return addr, nil +} + +// ImportScript creates a new scriptAddress with a user-provided script +// and adds it to the key store. +func (s *Store) ImportScript(script []byte, bs *BlockStamp) (btcutil.Address, error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + if s.flags.watchingOnly { + return nil, ErrWatchingOnly + } + + if _, ok := s.addrMap[addressKey(btcutil.Hash160(script))]; ok { + return nil, ErrDuplicate + } + + // Create new address with this private key. + scriptaddr, err := newScriptAddress(s, script, bs) + if err != nil { + return nil, err + } + + // Mark as unsynced if import height is below currently-synced + // height. + if len(s.recent.hashes) != 0 && bs.Height < s.recent.lastHeight { + scriptaddr.flags.unsynced = true + } + + // Add address to key store's bookkeeping structures. Adding to + // the map will result in the imported address being serialized + // on the next WriteTo call. + addr := scriptaddr.Address() + s.addrMap[getAddressKey(addr)] = scriptaddr + s.importedAddrs = append(s.importedAddrs, scriptaddr) + + // Create and return address. + return addr, nil +} + +// CreateDate returns the Unix time of the key store creation time. This +// is used to compare the key store creation time against block headers and +// set a better minimum block height of where to being rescans. +func (s *Store) CreateDate() int64 { + s.mtx.RLock() + defer s.mtx.RUnlock() + + return s.createDate +} + +// ExportWatchingWallet creates and returns a new key store with the same +// addresses in w, but as a watching-only key store without any private keys. +// New addresses created by the watching key store will match the new addresses +// created the original key store (thanks to public key address chaining), but +// will be missing the associated private keys. +func (s *Store) ExportWatchingWallet() (*Store, error) { + s.mtx.RLock() + defer s.mtx.RUnlock() + + // Don't continue if key store is already watching-only. + if s.flags.watchingOnly { + return nil, ErrWatchingOnly + } + + // Copy members of w into a new key store, but mark as watching-only and + // do not include any private keys. + ws := &Store{ + vers: s.vers, + net: s.net, + flags: walletFlags{ + useEncryption: false, + watchingOnly: true, + }, + name: s.name, + desc: s.desc, + createDate: s.createDate, + highestUsed: s.highestUsed, + recent: recentBlocks{ + lastHeight: s.recent.lastHeight, + }, + + addrMap: make(map[addressKey]walletAddress), + + // todo oga make me a list + chainIdxMap: make(map[int64]btcutil.Address), + lastChainIdx: s.lastChainIdx, + } + + kgwc := s.keyGenerator.watchingCopy(ws) + ws.keyGenerator = *(kgwc.(*btcAddress)) + if len(s.recent.hashes) != 0 { + ws.recent.hashes = make([]*chainhash.Hash, 0, len(s.recent.hashes)) + for _, hash := range s.recent.hashes { + hashCpy := *hash + ws.recent.hashes = append(ws.recent.hashes, &hashCpy) + } + } + for apkh, addr := range s.addrMap { + if !addr.Imported() { + // Must be a btcAddress if !imported. + btcAddr := addr.(*btcAddress) + + ws.chainIdxMap[btcAddr.chainIndex] = + addr.Address() + } + apkhCopy := apkh + ws.addrMap[apkhCopy] = addr.watchingCopy(ws) + } + if len(s.importedAddrs) != 0 { + ws.importedAddrs = make([]walletAddress, 0, + len(s.importedAddrs)) + for _, addr := range s.importedAddrs { + ws.importedAddrs = append(ws.importedAddrs, addr.watchingCopy(ws)) + } + } + + return ws, nil +} + +// SyncStatus is the interface type for all sync variants. +type SyncStatus interface { + ImplementsSyncStatus() +} + +type ( + // Unsynced is a type representing an unsynced address. When this is + // returned by a key store method, the value is the recorded first seen + // block height. + Unsynced int32 + + // PartialSync is a type representing a partially synced address (for + // example, due to the result of a partially-completed rescan). + PartialSync int32 + + // FullSync is a type representing an address that is in sync with the + // recently seen blocks. + FullSync struct{} +) + +// ImplementsSyncStatus is implemented to make Unsynced a SyncStatus. +func (u Unsynced) ImplementsSyncStatus() {} + +// ImplementsSyncStatus is implemented to make PartialSync a SyncStatus. +func (p PartialSync) ImplementsSyncStatus() {} + +// ImplementsSyncStatus is implemented to make FullSync a SyncStatus. +func (f FullSync) ImplementsSyncStatus() {} + +// WalletAddress is an interface that provides acces to information regarding an +// address managed by a key store. Concrete implementations of this type may +// provide further fields to provide information specific to that type of +// address. +type WalletAddress interface { + // Address returns a btcutil.Address for the backing address. + Address() btcutil.Address + // AddrHash returns the key or script hash related to the address + AddrHash() string + // FirstBlock returns the first block an address could be in. + FirstBlock() int32 + // Compressed returns true if the backing address was imported instead + // of being part of an address chain. + Imported() bool + // Compressed returns true if the backing address was created for a + // change output of a transaction. + Change() bool + // Compressed returns true if the backing address is compressed. + Compressed() bool + // SyncStatus returns the current synced state of an address. + SyncStatus() SyncStatus +} + +// SortedActiveAddresses returns all key store addresses that have been +// requested to be generated. These do not include unused addresses in +// the key pool. Use this when ordered addresses are needed. Otherwise, +// ActiveAddresses is preferred. +func (s *Store) SortedActiveAddresses() []WalletAddress { + s.mtx.RLock() + defer s.mtx.RUnlock() + + addrs := make([]WalletAddress, 0, + s.highestUsed+int64(len(s.importedAddrs))+1) + for i := int64(rootKeyChainIdx); i <= s.highestUsed; i++ { + a := s.chainIdxMap[i] + info, ok := s.addrMap[getAddressKey(a)] + if ok { + addrs = append(addrs, info) + } + } + for _, addr := range s.importedAddrs { + addrs = append(addrs, addr) + } + return addrs +} + +// ActiveAddresses returns a map between active payment addresses +// and their full info. These do not include unused addresses in the +// key pool. If addresses must be sorted, use SortedActiveAddresses. +func (s *Store) ActiveAddresses() map[btcutil.Address]WalletAddress { + s.mtx.RLock() + defer s.mtx.RUnlock() + + addrs := make(map[btcutil.Address]WalletAddress) + for i := int64(rootKeyChainIdx); i <= s.highestUsed; i++ { + a := s.chainIdxMap[i] + addr := s.addrMap[getAddressKey(a)] + addrs[addr.Address()] = addr + } + for _, addr := range s.importedAddrs { + addrs[addr.Address()] = addr + } + return addrs +} + +// ExtendActiveAddresses gets or creates the next n addresses from the +// address chain and marks each as active. This is used to recover +// deterministic (not imported) addresses from a key store backup, or to +// keep the active addresses in sync between an encrypted key store with +// private keys and an exported watching key store without. +// +// A slice is returned with the btcutil.Address of each new address. +// The blockchain must be rescanned for these addresses. +func (s *Store) ExtendActiveAddresses(n int) ([]btcutil.Address, error) { + s.mtx.Lock() + defer s.mtx.Unlock() + + last := s.addrMap[getAddressKey(s.chainIdxMap[s.highestUsed])] + bs := &BlockStamp{Height: last.FirstBlock()} + + addrs := make([]btcutil.Address, n) + for i := 0; i < n; i++ { + addr, err := s.nextChainedAddress(bs) + if err != nil { + return nil, err + } + addrs[i] = addr + } + return addrs, nil +} + +type walletFlags struct { + useEncryption bool + watchingOnly bool +} + +func (wf *walletFlags) ReadFrom(r io.Reader) (int64, error) { + var b [8]byte + n, err := io.ReadFull(r, b[:]) + if err != nil { + return int64(n), err + } + + wf.useEncryption = b[0]&(1<<0) != 0 + wf.watchingOnly = b[0]&(1<<1) != 0 + + return int64(n), nil +} + +func (wf *walletFlags) WriteTo(w io.Writer) (int64, error) { + var b [8]byte + if wf.useEncryption { + b[0] |= 1 << 0 + } + if wf.watchingOnly { + b[0] |= 1 << 1 + } + n, err := w.Write(b[:]) + return int64(n), err +} + +type addrFlags struct { + hasPrivKey bool + hasPubKey bool + encrypted bool + createPrivKeyNextUnlock bool + compressed bool + change bool + unsynced bool + partialSync bool +} + +func (af *addrFlags) ReadFrom(r io.Reader) (int64, error) { + var b [8]byte + n, err := io.ReadFull(r, b[:]) + if err != nil { + return int64(n), err + } + + af.hasPrivKey = b[0]&(1<<0) != 0 + af.hasPubKey = b[0]&(1<<1) != 0 + af.encrypted = b[0]&(1<<2) != 0 + af.createPrivKeyNextUnlock = b[0]&(1<<3) != 0 + af.compressed = b[0]&(1<<4) != 0 + af.change = b[0]&(1<<5) != 0 + af.unsynced = b[0]&(1<<6) != 0 + af.partialSync = b[0]&(1<<7) != 0 + + // Currently (at least until watching-only key stores are implemented) + // btcwallet shall refuse to open any unencrypted addresses. This + // check only makes sense if there is a private key to encrypt, which + // there may not be if the keypool was extended from just the last + // public key and no private keys were written. + if af.hasPrivKey && !af.encrypted { + return int64(n), errors.New("private key is unencrypted") + } + + return int64(n), nil +} + +func (af *addrFlags) WriteTo(w io.Writer) (int64, error) { + var b [8]byte + if af.hasPrivKey { + b[0] |= 1 << 0 + } + if af.hasPubKey { + b[0] |= 1 << 1 + } + if af.hasPrivKey && !af.encrypted { + // We only support encrypted privkeys. + return 0, errors.New("address must be encrypted") + } + if af.encrypted { + b[0] |= 1 << 2 + } + if af.createPrivKeyNextUnlock { + b[0] |= 1 << 3 + } + if af.compressed { + b[0] |= 1 << 4 + } + if af.change { + b[0] |= 1 << 5 + } + if af.unsynced { + b[0] |= 1 << 6 + } + if af.partialSync { + b[0] |= 1 << 7 + } + + n, err := w.Write(b[:]) + return int64(n), err +} + +// recentBlocks holds at most the last 20 seen block hashes as well as +// the block height of the most recently seen block. +type recentBlocks struct { + hashes []*chainhash.Hash + lastHeight int32 +} + +func (rb *recentBlocks) readFromVersion(v version, r io.Reader) (int64, error) { + if !v.LT(Vers20LastBlocks) { + // Use current version. + return rb.ReadFrom(r) + } + + // Old file versions only saved the most recently seen + // block height and hash, not the last 20. + + var read int64 + + // Read height. + var heightBytes [4]byte // 4 bytes for a int32 + n, err := io.ReadFull(r, heightBytes[:]) + read += int64(n) + if err != nil { + return read, err + } + rb.lastHeight = int32(binary.LittleEndian.Uint32(heightBytes[:])) + + // If height is -1, the last synced block is unknown, so don't try + // to read a block hash. + if rb.lastHeight == -1 { + rb.hashes = nil + return read, nil + } + + // Read block hash. + var syncedBlockHash chainhash.Hash + n, err = io.ReadFull(r, syncedBlockHash[:]) + read += int64(n) + if err != nil { + return read, err + } + + rb.hashes = []*chainhash.Hash{ + &syncedBlockHash, + } + + return read, nil +} + +func (rb *recentBlocks) ReadFrom(r io.Reader) (int64, error) { + var read int64 + + // Read number of saved blocks. This should not exceed 20. + var nBlockBytes [4]byte // 4 bytes for a uint32 + n, err := io.ReadFull(r, nBlockBytes[:]) + read += int64(n) + if err != nil { + return read, err + } + nBlocks := binary.LittleEndian.Uint32(nBlockBytes[:]) + if nBlocks > 20 { + return read, errors.New("number of last seen blocks exceeds maximum of 20") + } + + // Read most recently seen block height. + var heightBytes [4]byte // 4 bytes for a int32 + n, err = io.ReadFull(r, heightBytes[:]) + read += int64(n) + if err != nil { + return read, err + } + height := int32(binary.LittleEndian.Uint32(heightBytes[:])) + + // height should not be -1 (or any other negative number) + // since at this point we should be reading in at least one + // known block. + if height < 0 { + return read, errors.New("expected a block but specified height is negative") + } + + // Set last seen height. + rb.lastHeight = height + + // Read nBlocks block hashes. Hashes are expected to be in + // order of oldest to newest, but there's no way to check + // that here. + rb.hashes = make([]*chainhash.Hash, 0, nBlocks) + for i := uint32(0); i < nBlocks; i++ { + var blockHash chainhash.Hash + n, err := io.ReadFull(r, blockHash[:]) + read += int64(n) + if err != nil { + return read, err + } + rb.hashes = append(rb.hashes, &blockHash) + } + + return read, nil +} + +func (rb *recentBlocks) WriteTo(w io.Writer) (int64, error) { + var written int64 + + // Write number of saved blocks. This should not exceed 20. + nBlocks := uint32(len(rb.hashes)) + if nBlocks > 20 { + return written, errors.New("number of last seen blocks exceeds maximum of 20") + } + if nBlocks != 0 && rb.lastHeight < 0 { + return written, errors.New("number of block hashes is positive, but height is negative") + } + var nBlockBytes [4]byte // 4 bytes for a uint32 + binary.LittleEndian.PutUint32(nBlockBytes[:], nBlocks) + n, err := w.Write(nBlockBytes[:]) + written += int64(n) + if err != nil { + return written, err + } + + // Write most recently seen block height. + var heightBytes [4]byte // 4 bytes for a int32 + binary.LittleEndian.PutUint32(heightBytes[:], uint32(rb.lastHeight)) + n, err = w.Write(heightBytes[:]) + written += int64(n) + if err != nil { + return written, err + } + + // Write block hashes. + for _, hash := range rb.hashes { + n, err := w.Write(hash[:]) + written += int64(n) + if err != nil { + return written, err + } + } + + return written, nil +} + +// BlockIterator allows for the forwards and backwards iteration of recently +// seen blocks. +type BlockIterator struct { + storeMtx *sync.RWMutex + height int32 + index int + rb *recentBlocks +} + +func (rb *recentBlocks) iter(s *Store) *BlockIterator { + if rb.lastHeight == -1 || len(rb.hashes) == 0 { + return nil + } + return &BlockIterator{ + storeMtx: &s.mtx, + height: rb.lastHeight, + index: len(rb.hashes) - 1, + rb: rb, + } +} + +func (it *BlockIterator) Next() bool { + it.storeMtx.RLock() + defer it.storeMtx.RUnlock() + + if it.index+1 >= len(it.rb.hashes) { + return false + } + it.index++ + return true +} + +func (it *BlockIterator) Prev() bool { + it.storeMtx.RLock() + defer it.storeMtx.RUnlock() + + if it.index-1 < 0 { + return false + } + it.index-- + return true +} + +func (it *BlockIterator) BlockStamp() BlockStamp { + it.storeMtx.RLock() + defer it.storeMtx.RUnlock() + + return BlockStamp{ + Height: it.rb.lastHeight - int32(len(it.rb.hashes)-1-it.index), + Hash: it.rb.hashes[it.index], + } +} + +// unusedSpace is a wrapper type to read or write one or more types +// that btcwallet fits into an unused space left by Armory's key store file +// format. +type unusedSpace struct { + nBytes int // number of unused bytes that armory left. + rfvs []readerFromVersion +} + +func newUnusedSpace(nBytes int, rfvs ...readerFromVersion) *unusedSpace { + return &unusedSpace{ + nBytes: nBytes, + rfvs: rfvs, + } +} + +func (u *unusedSpace) readFromVersion(v version, r io.Reader) (int64, error) { + var read int64 + + for _, rfv := range u.rfvs { + n, err := rfv.readFromVersion(v, r) + if err != nil { + return read + n, err + } + read += n + if read > int64(u.nBytes) { + return read, errors.New("read too much from armory's unused space") + } + } + + // Read rest of actually unused bytes. + unused := make([]byte, u.nBytes-int(read)) + n, err := io.ReadFull(r, unused) + return read + int64(n), err +} + +func (u *unusedSpace) WriteTo(w io.Writer) (int64, error) { + var written int64 + + for _, wt := range u.rfvs { + n, err := wt.WriteTo(w) + if err != nil { + return written + n, err + } + written += n + if written > int64(u.nBytes) { + return written, errors.New("wrote too much to armory's unused space") + } + } + + // Write rest of actually unused bytes. + unused := make([]byte, u.nBytes-int(written)) + n, err := w.Write(unused) + return written + int64(n), err +} + +// walletAddress is the internal interface used to abstracted around the +// different address types. +type walletAddress interface { + io.ReaderFrom + io.WriterTo + WalletAddress + watchingCopy(*Store) walletAddress + setSyncStatus(SyncStatus) +} + +type btcAddress struct { + store *Store + address btcutil.Address + flags addrFlags + chaincode [32]byte + chainIndex int64 + chainDepth int64 // unused + initVector [16]byte + privKey [32]byte + pubKey *btcec.PublicKey + firstSeen int64 + lastSeen int64 + firstBlock int32 + partialSyncHeight int32 // This is reappropriated from armory's `lastBlock` field. + privKeyCT []byte // non-nil if unlocked. +} + +const ( + // Root address has a chain index of -1. Each subsequent + // chained address increments the index. + rootKeyChainIdx = -1 + + // Imported private keys are not part of the chain, and have a + // special index of -2. + importedKeyChainIdx = -2 +) + +const ( + pubkeyCompressed byte = 0x2 + pubkeyUncompressed byte = 0x4 +) + +type publicKey []byte + +func (k *publicKey) ReadFrom(r io.Reader) (n int64, err error) { + var read int64 + var format byte + read, err = binaryRead(r, binary.LittleEndian, &format) + if err != nil { + return n + read, err + } + n += read + + // Remove the oddness from the format + noodd := format + noodd &= ^byte(0x1) + + var s []byte + switch noodd { + case pubkeyUncompressed: + // Read the remaining 64 bytes. + s = make([]byte, 64) + + case pubkeyCompressed: + // Read the remaining 32 bytes. + s = make([]byte, 32) + + default: + return n, errors.New("unrecognized pubkey format") + } + + read, err = binaryRead(r, binary.LittleEndian, &s) + if err != nil { + return n + read, err + } + n += read + + *k = append([]byte{format}, s...) + return +} + +func (k *publicKey) WriteTo(w io.Writer) (n int64, err error) { + return binaryWrite(w, binary.LittleEndian, []byte(*k)) +} + +// PubKeyAddress implements WalletAddress and additionally provides the +// pubkey for a pubkey-based address. +type PubKeyAddress interface { + WalletAddress + // PubKey returns the public key associated with the address. + PubKey() *btcec.PublicKey + // ExportPubKey returns the public key associated with the address + // serialised as a hex encoded string. + ExportPubKey() string + // PrivKey returns the private key for the address. + // It can fail if the key store is watching only, the key store is locked, + // or the address doesn't have any keys. + PrivKey() (*btcec.PrivateKey, error) + // ExportPrivKey exports the WIF private key. + ExportPrivKey() (*btcutil.WIF, error) +} + +// newBtcAddress initializes and returns a new address. privkey must +// be 32 bytes. iv must be 16 bytes, or nil (in which case it is +// randomly generated). +func newBtcAddress(wallet *Store, privkey, iv []byte, bs *BlockStamp, compressed bool) (addr *btcAddress, err error) { + if len(privkey) != 32 { + return nil, errors.New("private key is not 32 bytes") + } + + addr, err = newBtcAddressWithoutPrivkey(wallet, + pubkeyFromPrivkey(privkey, compressed), iv, bs) + if err != nil { + return nil, err + } + + addr.flags.createPrivKeyNextUnlock = false + addr.flags.hasPrivKey = true + addr.privKeyCT = privkey + + return addr, nil +} + +// newBtcAddressWithoutPrivkey initializes and returns a new address with an +// unknown (at the time) private key that must be found later. pubkey must be +// 33 or 65 bytes, and iv must be 16 bytes or empty (in which case it is +// randomly generated). +func newBtcAddressWithoutPrivkey(s *Store, pubkey, iv []byte, bs *BlockStamp) (addr *btcAddress, err error) { + var compressed bool + switch n := len(pubkey); n { + case btcec.PubKeyBytesLenCompressed: + compressed = true + case btcec.PubKeyBytesLenUncompressed: + compressed = false + default: + return nil, fmt.Errorf("invalid pubkey length %d", n) + } + if len(iv) == 0 { + iv = make([]byte, 16) + if _, err := rand.Read(iv); err != nil { + return nil, err + } + } else if len(iv) != 16 { + return nil, errors.New("init vector must be nil or 16 bytes large") + } + + pk, err := btcec.ParsePubKey(pubkey, btcec.S256()) + if err != nil { + return nil, err + } + + address, err := btcutil.NewAddressPubKeyHash(btcutil.Hash160(pubkey), s.netParams()) + if err != nil { + return nil, err + } + + addr = &btcAddress{ + flags: addrFlags{ + hasPrivKey: false, + hasPubKey: true, + encrypted: false, + createPrivKeyNextUnlock: true, + compressed: compressed, + change: false, + unsynced: false, + }, + store: s, + address: address, + firstSeen: time.Now().Unix(), + firstBlock: bs.Height, + pubKey: pk, + } + copy(addr.initVector[:], iv) + + return addr, nil +} + +// newRootBtcAddress generates a new address, also setting the +// chaincode and chain index to represent this address as a root +// address. +func newRootBtcAddress(s *Store, privKey, iv, chaincode []byte, + bs *BlockStamp) (addr *btcAddress, err error) { + + if len(chaincode) != 32 { + return nil, errors.New("chaincode is not 32 bytes") + } + + // Create new btcAddress with provided inputs. This will + // always use a compressed pubkey. + addr, err = newBtcAddress(s, privKey, iv, bs, true) + if err != nil { + return nil, err + } + + copy(addr.chaincode[:], chaincode) + addr.chainIndex = rootKeyChainIdx + + return addr, err +} + +// verifyKeypairs creates a signature using the parsed private key and +// verifies the signature with the parsed public key. If either of these +// steps fail, the keypair generation failed and any funds sent to this +// address will be unspendable. This step requires an unencrypted or +// unlocked btcAddress. +func (a *btcAddress) verifyKeypairs() error { + if len(a.privKeyCT) != 32 { + return errors.New("private key unavailable") + } + + privKey := &btcec.PrivateKey{ + PublicKey: *a.pubKey.ToECDSA(), + D: new(big.Int).SetBytes(a.privKeyCT), + } + + data := "String to sign." + sig, err := privKey.Sign([]byte(data)) + if err != nil { + return err + } + + ok := sig.Verify([]byte(data), privKey.PubKey()) + if !ok { + return errors.New("pubkey verification failed") + } + return nil +} + +// ReadFrom reads an encrypted address from an io.Reader. +func (a *btcAddress) ReadFrom(r io.Reader) (n int64, err error) { + var read int64 + + // Checksums + var chkPubKeyHash uint32 + var chkChaincode uint32 + var chkInitVector uint32 + var chkPrivKey uint32 + var chkPubKey uint32 + var pubKeyHash [ripemd160.Size]byte + var pubKey publicKey + + // Read serialized key store into addr fields and checksums. + datas := []interface{}{ + &pubKeyHash, + &chkPubKeyHash, + make([]byte, 4), // version + &a.flags, + &a.chaincode, + &chkChaincode, + &a.chainIndex, + &a.chainDepth, + &a.initVector, + &chkInitVector, + &a.privKey, + &chkPrivKey, + &pubKey, + &chkPubKey, + &a.firstSeen, + &a.lastSeen, + &a.firstBlock, + &a.partialSyncHeight, + } + for _, data := range datas { + if rf, ok := data.(io.ReaderFrom); ok { + read, err = rf.ReadFrom(r) + } else { + read, err = binaryRead(r, binary.LittleEndian, data) + } + if err != nil { + return n + read, err + } + n += read + } + + // Verify checksums, correct errors where possible. + checks := []struct { + data []byte + chk uint32 + }{ + {pubKeyHash[:], chkPubKeyHash}, + {a.chaincode[:], chkChaincode}, + {a.initVector[:], chkInitVector}, + {a.privKey[:], chkPrivKey}, + {pubKey, chkPubKey}, + } + for i := range checks { + if err = verifyAndFix(checks[i].data, checks[i].chk); err != nil { + return n, err + } + } + + if !a.flags.hasPubKey { + return n, errors.New("read in an address without a public key") + } + pk, err := btcec.ParsePubKey(pubKey, btcec.S256()) + if err != nil { + return n, err + } + a.pubKey = pk + + addr, err := btcutil.NewAddressPubKeyHash(pubKeyHash[:], a.store.netParams()) + if err != nil { + return n, err + } + a.address = addr + + return n, nil +} + +func (a *btcAddress) WriteTo(w io.Writer) (n int64, err error) { + var written int64 + + pubKey := a.pubKeyBytes() + + hash := a.address.ScriptAddress() + datas := []interface{}{ + &hash, + walletHash(hash), + make([]byte, 4), //version + &a.flags, + &a.chaincode, + walletHash(a.chaincode[:]), + &a.chainIndex, + &a.chainDepth, + &a.initVector, + walletHash(a.initVector[:]), + &a.privKey, + walletHash(a.privKey[:]), + &pubKey, + walletHash(pubKey), + &a.firstSeen, + &a.lastSeen, + &a.firstBlock, + &a.partialSyncHeight, + } + for _, data := range datas { + if wt, ok := data.(io.WriterTo); ok { + written, err = wt.WriteTo(w) + } else { + written, err = binaryWrite(w, binary.LittleEndian, data) + } + if err != nil { + return n + written, err + } + n += written + } + return n, nil +} + +// encrypt attempts to encrypt an address's clear text private key, +// failing if the address is already encrypted or if the private key is +// not 32 bytes. If successful, the encryption flag is set. +func (a *btcAddress) encrypt(key []byte) error { + if a.flags.encrypted { + return ErrAlreadyEncrypted + } + if len(a.privKeyCT) != 32 { + return errors.New("invalid clear text private key") + } + + aesBlockEncrypter, err := aes.NewCipher(key) + if err != nil { + return err + } + aesEncrypter := cipher.NewCFBEncrypter(aesBlockEncrypter, a.initVector[:]) + + aesEncrypter.XORKeyStream(a.privKey[:], a.privKeyCT) + + a.flags.hasPrivKey = true + a.flags.encrypted = true + return nil +} + +// lock removes the reference this address holds to its clear text +// private key. This function fails if the address is not encrypted. +func (a *btcAddress) lock() error { + if !a.flags.encrypted { + return errors.New("unable to lock unencrypted address") + } + + zero(a.privKeyCT) + a.privKeyCT = nil + return nil +} + +// unlock decrypts and stores a pointer to an address's private key, +// failing if the address is not encrypted, or the provided key is +// incorrect. The returned clear text private key will always be a copy +// that may be safely used by the caller without worrying about it being +// zeroed during an address lock. +func (a *btcAddress) unlock(key []byte) (privKeyCT []byte, err error) { + if !a.flags.encrypted { + return nil, errors.New("unable to unlock unencrypted address") + } + + // Decrypt private key with AES key. + aesBlockDecrypter, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + aesDecrypter := cipher.NewCFBDecrypter(aesBlockDecrypter, a.initVector[:]) + privkey := make([]byte, 32) + aesDecrypter.XORKeyStream(privkey, a.privKey[:]) + + // If secret is already saved, simply compare the bytes. + if len(a.privKeyCT) == 32 { + if !bytes.Equal(a.privKeyCT, privkey) { + return nil, ErrWrongPassphrase + } + privKeyCT := make([]byte, 32) + copy(privKeyCT, a.privKeyCT) + return privKeyCT, nil + } + + x, y := btcec.S256().ScalarBaseMult(privkey) + if x.Cmp(a.pubKey.X) != 0 || y.Cmp(a.pubKey.Y) != 0 { + return nil, ErrWrongPassphrase + } + + privkeyCopy := make([]byte, 32) + copy(privkeyCopy, privkey) + a.privKeyCT = privkey + return privkeyCopy, nil +} + +// changeEncryptionKey re-encrypts the private keys for an address +// with a new AES encryption key. oldkey must be the old AES encryption key +// and is used to decrypt the private key. +func (a *btcAddress) changeEncryptionKey(oldkey, newkey []byte) error { + // Address must have a private key and be encrypted to continue. + if !a.flags.hasPrivKey { + return errors.New("no private key") + } + if !a.flags.encrypted { + return errors.New("address is not encrypted") + } + + privKeyCT, err := a.unlock(oldkey) + if err != nil { + return err + } + + aesBlockEncrypter, err := aes.NewCipher(newkey) + if err != nil { + return err + } + newIV := make([]byte, len(a.initVector)) + if _, err := rand.Read(newIV); err != nil { + return err + } + copy(a.initVector[:], newIV) + aesEncrypter := cipher.NewCFBEncrypter(aesBlockEncrypter, a.initVector[:]) + aesEncrypter.XORKeyStream(a.privKey[:], privKeyCT) + + return nil +} + +// Address returns the pub key address, implementing AddressInfo. +func (a *btcAddress) Address() btcutil.Address { + return a.address +} + +// AddrHash returns the pub key hash, implementing WalletAddress. +func (a *btcAddress) AddrHash() string { + return string(a.address.ScriptAddress()) +} + +// FirstBlock returns the first block the address is seen in, implementing +// AddressInfo. +func (a *btcAddress) FirstBlock() int32 { + return a.firstBlock +} + +// Imported returns the pub if the address was imported, or a chained address, +// implementing AddressInfo. +func (a *btcAddress) Imported() bool { + return a.chainIndex == importedKeyChainIdx +} + +// Change returns true if the address was created as a change address, +// implementing AddressInfo. +func (a *btcAddress) Change() bool { + return a.flags.change +} + +// Compressed returns true if the address backing key is compressed, +// implementing AddressInfo. +func (a *btcAddress) Compressed() bool { + return a.flags.compressed +} + +// SyncStatus returns a SyncStatus type for how the address is currently +// synced. For an Unsynced type, the value is the recorded first seen +// block height of the address. +func (a *btcAddress) SyncStatus() SyncStatus { + switch { + case a.flags.unsynced && !a.flags.partialSync: + return Unsynced(a.firstBlock) + case a.flags.unsynced && a.flags.partialSync: + return PartialSync(a.partialSyncHeight) + default: + return FullSync{} + } +} + +// PubKey returns the hex encoded pubkey for the address. Implementing +// PubKeyAddress. +func (a *btcAddress) PubKey() *btcec.PublicKey { + return a.pubKey +} + +func (a *btcAddress) pubKeyBytes() []byte { + if a.Compressed() { + return a.pubKey.SerializeCompressed() + } + return a.pubKey.SerializeUncompressed() +} + +// ExportPubKey returns the public key associated with the address serialised as +// a hex encoded string. Implemnts PubKeyAddress +func (a *btcAddress) ExportPubKey() string { + return hex.EncodeToString(a.pubKeyBytes()) +} + +// PrivKey implements PubKeyAddress by returning the private key, or an error +// if the key store is locked, watching only or the private key is missing. +func (a *btcAddress) PrivKey() (*btcec.PrivateKey, error) { + if a.store.flags.watchingOnly { + return nil, ErrWatchingOnly + } + + if !a.flags.hasPrivKey { + return nil, errors.New("no private key for address") + } + + // Key store must be unlocked to decrypt the private key. + if a.store.isLocked() { + return nil, ErrLocked + } + + // Unlock address with key store secret. unlock returns a copy of + // the clear text private key, and may be used safely even + // during an address lock. + privKeyCT, err := a.unlock(a.store.secret) + if err != nil { + return nil, err + } + + return &btcec.PrivateKey{ + PublicKey: *a.pubKey.ToECDSA(), + D: new(big.Int).SetBytes(privKeyCT), + }, nil +} + +// ExportPrivKey exports the private key as a WIF for encoding as a string +// in the Wallet Import Formt. +func (a *btcAddress) ExportPrivKey() (*btcutil.WIF, error) { + pk, err := a.PrivKey() + if err != nil { + return nil, err + } + // NewWIF only errors if the network is nil. In this case, panic, + // as our program's assumptions are so broken that this needs to be + // caught immediately, and a stack trace here is more useful than + // elsewhere. + wif, err := btcutil.NewWIF((*btcec.PrivateKey)(pk), a.store.netParams(), + a.Compressed()) + if err != nil { + panic(err) + } + return wif, nil +} + +// watchingCopy creates a copy of an address without a private key. +// This is used to fill a watching a key store with addresses from a +// normal key store. +func (a *btcAddress) watchingCopy(s *Store) walletAddress { + return &btcAddress{ + store: s, + address: a.address, + flags: addrFlags{ + hasPrivKey: false, + hasPubKey: true, + encrypted: false, + createPrivKeyNextUnlock: false, + compressed: a.flags.compressed, + change: a.flags.change, + unsynced: a.flags.unsynced, + }, + chaincode: a.chaincode, + chainIndex: a.chainIndex, + chainDepth: a.chainDepth, + pubKey: a.pubKey, + firstSeen: a.firstSeen, + lastSeen: a.lastSeen, + firstBlock: a.firstBlock, + partialSyncHeight: a.partialSyncHeight, + } +} + +// setSyncStatus sets the address flags and possibly the partial sync height +// depending on the type of s. +func (a *btcAddress) setSyncStatus(s SyncStatus) { + switch e := s.(type) { + case Unsynced: + a.flags.unsynced = true + a.flags.partialSync = false + a.partialSyncHeight = 0 + + case PartialSync: + a.flags.unsynced = true + a.flags.partialSync = true + a.partialSyncHeight = int32(e) + + case FullSync: + a.flags.unsynced = false + a.flags.partialSync = false + a.partialSyncHeight = 0 + } +} + +// note that there is no encrypted bit here since if we had a script encrypted +// and then used it on the blockchain this provides a simple known plaintext in +// the key store file. It was determined that the script in a p2sh transaction is +// not a secret and any sane situation would also require a signature (which +// does have a secret). +type scriptFlags struct { + hasScript bool + change bool + unsynced bool + partialSync bool +} + +// ReadFrom implements the io.ReaderFrom interface by reading from r into sf. +func (sf *scriptFlags) ReadFrom(r io.Reader) (int64, error) { + var b [8]byte + n, err := io.ReadFull(r, b[:]) + if err != nil { + return int64(n), err + } + + // We match bits from addrFlags for similar fields. hence hasScript uses + // the same bit as hasPubKey and the change bit is the same for both. + sf.hasScript = b[0]&(1<<1) != 0 + sf.change = b[0]&(1<<5) != 0 + sf.unsynced = b[0]&(1<<6) != 0 + sf.partialSync = b[0]&(1<<7) != 0 + + return int64(n), nil +} + +// WriteTo implements the io.WriteTo interface by writing sf into w. +func (sf *scriptFlags) WriteTo(w io.Writer) (int64, error) { + var b [8]byte + if sf.hasScript { + b[0] |= 1 << 1 + } + if sf.change { + b[0] |= 1 << 5 + } + if sf.unsynced { + b[0] |= 1 << 6 + } + if sf.partialSync { + b[0] |= 1 << 7 + } + + n, err := w.Write(b[:]) + return int64(n), err +} + +// p2SHScript represents the variable length script entry in a key store. +type p2SHScript []byte + +// ReadFrom implements the ReaderFrom interface by reading the P2SH script from +// r in the format <4 bytes little endian length>