diff --git a/cmd/addsubnetwork/addsubnetwork.go b/cmd/addsubnetwork/addsubnetwork.go deleted file mode 100644 index 914b033fd..000000000 --- a/cmd/addsubnetwork/addsubnetwork.go +++ /dev/null @@ -1,88 +0,0 @@ -package main - -import ( - "github.com/kaspanet/kaspad/blockdag" - "github.com/kaspanet/kaspad/rpcclient" - "github.com/kaspanet/kaspad/rpcmodel" - "github.com/kaspanet/kaspad/util/subnetworkid" - "github.com/pkg/errors" - "time" -) - -const ( - getSubnetworkRetryDelay = 5 * time.Second - maxGetSubnetworkRetries = 12 -) - -func main() { - cfg, err := parseConfig() - if err != nil { - panic(errors.Errorf("error parsing command-line arguments: %s", err)) - } - - privateKey, addrPubKeyHash, err := decodeKeys(cfg) - if err != nil { - panic(errors.Errorf("error decoding public key: %s", err)) - } - - client, err := connect(cfg) - if err != nil { - panic(errors.Errorf("could not connect to RPC server: %s", err)) - } - log.Infof("Connected to server %s", cfg.RPCServer) - - fundingOutpoint, fundingTx, err := findUnspentTXO(cfg, client, addrPubKeyHash) - if err != nil { - panic(errors.Errorf("error finding unspent transactions: %s", err)) - } - if fundingOutpoint == nil || fundingTx == nil { - panic(errors.Errorf("could not find any unspent transactions this for key")) - } - log.Infof("Found transaction to spend: %s:%d", fundingOutpoint.TxID, fundingOutpoint.Index) - - registryTx, err := buildSubnetworkRegistryTx(cfg, fundingOutpoint, fundingTx, privateKey) - if err != nil { - panic(errors.Errorf("error building subnetwork registry tx: %s", err)) - } - - _, err = client.SendRawTransaction(registryTx, true) - if err != nil { - panic(errors.Errorf("failed sending subnetwork registry tx: %s", err)) - } - log.Infof("Successfully sent subnetwork registry transaction") - - subnetworkID, err := blockdag.TxToSubnetworkID(registryTx) - if err != nil { - panic(errors.Errorf("could not build subnetwork ID: %s", err)) - } - - err = waitForSubnetworkToBecomeAccepted(client, subnetworkID) - if err != nil { - panic(errors.Errorf("error waiting for subnetwork to become accepted: %s", err)) - } - log.Infof("Subnetwork '%s' was successfully registered.", subnetworkID) -} - -func waitForSubnetworkToBecomeAccepted(client *rpcclient.Client, subnetworkID *subnetworkid.SubnetworkID) error { - retries := 0 - for { - _, err := client.GetSubnetwork(subnetworkID.String()) - if err != nil { - var rpcError *rpcmodel.RPCError - if ok := errors.As(err, &rpcError); ok && rpcError.Code == rpcmodel.ErrRPCSubnetworkNotFound { - log.Infof("Subnetwork not found") - - retries++ - if retries == maxGetSubnetworkRetries { - return errors.Errorf("failed to get subnetwork %d times: %s", maxGetSubnetworkRetries, err) - } - - log.Infof("Waiting %d seconds...", int(getSubnetworkRetryDelay.Seconds())) - <-time.After(getSubnetworkRetryDelay) - continue - } - return errors.Errorf("failed getting subnetwork: %s", err) - } - return nil - } -} diff --git a/cmd/addsubnetwork/config.go b/cmd/addsubnetwork/config.go deleted file mode 100644 index df0417802..000000000 --- a/cmd/addsubnetwork/config.go +++ /dev/null @@ -1,65 +0,0 @@ -package main - -import ( - "github.com/jessevdk/go-flags" - "github.com/kaspanet/kaspad/config" - "github.com/pkg/errors" -) - -var activeConfig *ConfigFlags - -// ActiveConfig returns the active configuration struct -func ActiveConfig() *ConfigFlags { - return activeConfig -} - -// ConfigFlags holds the configurations set by the command line argument -type ConfigFlags struct { - PrivateKey string `short:"k" long:"private-key" description:"Private key" required:"true"` - RPCUser string `short:"u" long:"rpcuser" description:"RPC username" required:"true"` - RPCPassword string `short:"P" long:"rpcpass" default-mask:"-" description:"RPC password" required:"true"` - RPCServer string `short:"s" long:"rpcserver" description:"RPC server to connect to" required:"true"` - RPCCert string `short:"c" long:"rpccert" description:"RPC server certificate chain for validation"` - DisableTLS bool `long:"notls" description:"Disable TLS"` - GasLimit uint64 `long:"gaslimit" description:"The gas limit of the new subnetwork"` - RegistryTxFee uint64 `long:"regtxfee" description:"The fee for the subnetwork registry transaction"` - config.NetworkFlags -} - -const ( - defaultSubnetworkGasLimit = 1000 - defaultRegistryTxFee = 3000 -) - -func parseConfig() (*ConfigFlags, error) { - activeConfig = &ConfigFlags{} - parser := flags.NewParser(activeConfig, flags.PrintErrors|flags.HelpFlag) - _, err := parser.Parse() - - if err != nil { - return nil, err - } - - if activeConfig.RPCCert == "" && !activeConfig.DisableTLS { - return nil, errors.New("--notls has to be disabled if --cert is used") - } - - if activeConfig.RPCCert != "" && activeConfig.DisableTLS { - return nil, errors.New("--cert should be omitted if --notls is used") - } - - err = activeConfig.ResolveNetwork(parser) - if err != nil { - return nil, err - } - - if activeConfig.GasLimit == 0 { - activeConfig.GasLimit = defaultSubnetworkGasLimit - } - - if activeConfig.RegistryTxFee == 0 { - activeConfig.RegistryTxFee = defaultRegistryTxFee - } - - return activeConfig, nil -} diff --git a/cmd/addsubnetwork/connect.go b/cmd/addsubnetwork/connect.go deleted file mode 100644 index e5decf275..000000000 --- a/cmd/addsubnetwork/connect.go +++ /dev/null @@ -1,37 +0,0 @@ -package main - -import ( - "github.com/kaspanet/kaspad/rpcclient" - "github.com/pkg/errors" - "io/ioutil" -) - -func connect(cfg *ConfigFlags) (*rpcclient.Client, error) { - var cert []byte - if !cfg.DisableTLS { - var err error - cert, err = ioutil.ReadFile(cfg.RPCCert) - if err != nil { - return nil, errors.Errorf("error reading certificates file: %s", err) - } - } - - connCfg := &rpcclient.ConnConfig{ - Host: cfg.RPCServer, - Endpoint: "ws", - User: cfg.RPCUser, - Pass: cfg.RPCPassword, - DisableTLS: cfg.DisableTLS, - } - - if !cfg.DisableTLS { - connCfg.Certificates = cert - } - - client, err := rpcclient.New(connCfg, nil) - if err != nil { - return nil, errors.Errorf("error connecting to address %s: %s", cfg.RPCServer, err) - } - - return client, nil -} diff --git a/cmd/addsubnetwork/keys.go b/cmd/addsubnetwork/keys.go deleted file mode 100644 index 606997abc..000000000 --- a/cmd/addsubnetwork/keys.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "github.com/kaspanet/kaspad/ecc" - "github.com/kaspanet/kaspad/util" - "github.com/kaspanet/kaspad/util/base58" -) - -func decodeKeys(cfg *ConfigFlags) (*ecc.PrivateKey, *util.AddressPubKeyHash, error) { - privateKeyBytes := base58.Decode(cfg.PrivateKey) - privateKey, _ := ecc.PrivKeyFromBytes(ecc.S256(), privateKeyBytes) - serializedPrivateKey := privateKey.PubKey().SerializeCompressed() - - addr, err := util.NewAddressPubKeyHashFromPublicKey(serializedPrivateKey, ActiveConfig().NetParams().Prefix) - if err != nil { - return nil, nil, err - } - return privateKey, addr, nil -} diff --git a/cmd/addsubnetwork/log.go b/cmd/addsubnetwork/log.go deleted file mode 100644 index b10046f64..000000000 --- a/cmd/addsubnetwork/log.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -import ( - "github.com/kaspanet/kaspad/logs" -) - -var ( - backendLog = logs.NewBackend() - log = backendLog.Logger("ASUB") -) diff --git a/cmd/addsubnetwork/registrytx.go b/cmd/addsubnetwork/registrytx.go deleted file mode 100644 index 6feb6f356..000000000 --- a/cmd/addsubnetwork/registrytx.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "github.com/kaspanet/kaspad/ecc" - "github.com/kaspanet/kaspad/txscript" - "github.com/kaspanet/kaspad/wire" - "github.com/pkg/errors" -) - -func buildSubnetworkRegistryTx(cfg *ConfigFlags, fundingOutpoint *wire.Outpoint, fundingTx *wire.MsgTx, privateKey *ecc.PrivateKey) (*wire.MsgTx, error) { - txIn := &wire.TxIn{ - PreviousOutpoint: *fundingOutpoint, - Sequence: wire.MaxTxInSequenceNum, - } - txOut := &wire.TxOut{ - ScriptPubKey: fundingTx.TxOut[fundingOutpoint.Index].ScriptPubKey, - Value: fundingTx.TxOut[fundingOutpoint.Index].Value - cfg.RegistryTxFee, - } - registryTx := wire.NewRegistryMsgTx(1, []*wire.TxIn{txIn}, []*wire.TxOut{txOut}, cfg.GasLimit) - - SignatureScript, err := txscript.SignatureScript(registryTx, 0, fundingTx.TxOut[fundingOutpoint.Index].ScriptPubKey, - txscript.SigHashAll, privateKey, true) - if err != nil { - return nil, errors.Errorf("failed to build signature script: %s", err) - } - txIn.SignatureScript = SignatureScript - - return registryTx, nil -} diff --git a/cmd/addsubnetwork/utxo.go b/cmd/addsubnetwork/utxo.go deleted file mode 100644 index b8c0c7270..000000000 --- a/cmd/addsubnetwork/utxo.go +++ /dev/null @@ -1,113 +0,0 @@ -package main - -import ( - "bytes" - "encoding/hex" - "github.com/kaspanet/kaspad/rpcclient" - "github.com/kaspanet/kaspad/rpcmodel" - "github.com/kaspanet/kaspad/util" - "github.com/kaspanet/kaspad/wire" - "github.com/pkg/errors" -) - -const ( - resultsCount = 1000 - minConfirmations = 10 -) - -func findUnspentTXO(cfg *ConfigFlags, client *rpcclient.Client, addrPubKeyHash *util.AddressPubKeyHash) (*wire.Outpoint, *wire.MsgTx, error) { - txs, err := collectTransactions(client, addrPubKeyHash) - if err != nil { - return nil, nil, err - } - - utxos := buildUTXOs(txs) - for outpoint, tx := range utxos { - // Skip TXOs that can't pay for registration - if tx.TxOut[outpoint.Index].Value < cfg.RegistryTxFee { - continue - } - - return &outpoint, tx, nil - } - - return nil, nil, nil -} - -func collectTransactions(client *rpcclient.Client, addrPubKeyHash *util.AddressPubKeyHash) ([]*wire.MsgTx, error) { - txs := make([]*wire.MsgTx, 0) - skip := 0 - for { - results, err := client.SearchRawTransactionsVerbose(addrPubKeyHash, skip, resultsCount, true, false, nil) - if err != nil { - // Break when there are no further txs - var rpcError *rpcmodel.RPCError - if ok := errors.As(err, &rpcError); ok && rpcError.Code == rpcmodel.ErrRPCNoTxInfo { - break - } - - return nil, err - } - - for _, result := range results { - // Mempool transactions bring about unnecessary complexity, so - // simply don't bother processing them - if result.IsInMempool { - continue - } - - tx, err := parseRawTransactionResult(result) - if err != nil { - return nil, errors.Errorf("failed to process SearchRawTransactionResult: %s", err) - } - if tx == nil { - continue - } - if !isTxMatured(tx, *result.Confirmations) { - continue - } - - txs = append(txs, tx) - } - - skip += resultsCount - } - return txs, nil -} - -func parseRawTransactionResult(result *rpcmodel.SearchRawTransactionsResult) (*wire.MsgTx, error) { - txBytes, err := hex.DecodeString(result.Hex) - if err != nil { - return nil, errors.Errorf("failed to decode transaction bytes: %s", err) - } - var tx wire.MsgTx - reader := bytes.NewReader(txBytes) - err = tx.Deserialize(reader) - if err != nil { - return nil, errors.Errorf("failed to deserialize transaction: %s", err) - } - return &tx, nil -} - -func isTxMatured(tx *wire.MsgTx, confirmations uint64) bool { - if !tx.IsCoinBase() { - return confirmations >= minConfirmations - } - return confirmations >= ActiveConfig().NetParams().BlockCoinbaseMaturity -} - -func buildUTXOs(txs []*wire.MsgTx) map[wire.Outpoint]*wire.MsgTx { - utxos := make(map[wire.Outpoint]*wire.MsgTx) - for _, tx := range txs { - for i := range tx.TxOut { - outpoint := wire.NewOutpoint(tx.TxID(), uint32(i)) - utxos[*outpoint] = tx - } - } - for _, tx := range txs { - for _, input := range tx.TxIn { - delete(utxos, input.PreviousOutpoint) - } - } - return utxos -}