[NOD-816] Remove addsubnetwork. (#654)

This commit is contained in:
stasatdaglabs 2020-03-10 11:09:33 +02:00 committed by GitHub
parent 5a99e4d2f3
commit 4dfc8cf5b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 0 additions and 361 deletions

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -1,10 +0,0 @@
package main
import (
"github.com/kaspanet/kaspad/logs"
)
var (
backendLog = logs.NewBackend()
log = backendLog.Logger("ASUB")
)

View File

@ -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
}

View File

@ -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
}