Skip to content

Commit

Permalink
Add upgrade command line helper
Browse files Browse the repository at this point in the history
  • Loading branch information
sisuresh committed Nov 14, 2023
1 parent 4a14c29 commit d61e69d
Show file tree
Hide file tree
Showing 13 changed files with 987 additions and 59 deletions.
279 changes: 269 additions & 10 deletions Cargo.lock

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions docs/software/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,25 @@ Command options can only by placed after command.
* **fuzz <FILE-NAME>**: Run a single fuzz input and exit.
* **gen-fuzz <FILE-NAME>**: Generate a random fuzzer input file.
* **gen-seed**: Generate and print a random public/private key and then exit.
* **get-settings-upgrade-txs <PUBLIC-KEY> <SEQ-NUM> <NETWORK-PASSPHRASE>**: Generates the three transactions needed to propose
a Soroban Settings upgrade from scratch, as will as the XDR `ConfigUpgradeSetKey` to submit to the `upgrades` endpoint. The results will be dumped to standard output. <PUBLIC-KEY> is the key that will be used as the source account on the transactions.
<SEQ-NUM> is the current sequence number of the Stellar account corresponding to <PUBLIC-KEY>.

Option (required) **--xdr** takes a base64 encoded XDR serialized `ConfigUpgradeSet`.
Example:
`stellar-core get-settings-upgrade-txs GAUQW73V52I2WLIPKCKYXZBHIYFTECS7UPSG4OSVUHNDXEZJJWFXZG56 73014444032 "Standalone Network ; February 2017" --xdr AAAAAQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= --signtxs`.<br>

Option **--signtxs** will prompt for a secret key and sign the TransactionEnvelopes.<br>

Output format by line -
1. Base64 upload tx envelope XDR
2. Hex tx ID for the upload tx.
3. Base 64 create tx envelope XDR
4. Hex tx ID for the create tx.
5. Base64 invoke tx envelope XDR
6. Hex tx ID for the invoke tx.
7. Base64 ConfigUpgradeSetKey XDR.

* **help**: Print the available command line options and then exit..
* **http-command <COMMAND>** Send an [HTTP command](#http-commands) to an
already running local instance of stellar-core and then exit. For example:
Expand Down Expand Up @@ -316,6 +335,13 @@ format.
ConfigUpgradeSet will be used to update the existing network ConfigSettingEntry
that exists at the corresponding CONFIG_SETTING LedgerKey.

* **dumpproposedsettings**
`dumpproposedsettings?blob=Base64`<br>
blob is a base64 encoded XDR serialized `ConfigUpgradeSetKey`.
This command outputs the `ConfigUpgradeSet` (if it's valid and it exists) in a readable format
that corresponds to the `ConfigUpgradeSetKey` passed in. This can be used by validators
to verify Soroban Settings upgrades before voting on them.

* **surveytopology**
`surveytopology?duration=DURATION&node=NODE_ID`<br>
Starts a survey that will request peer connectivity information from nodes
Expand Down
44 changes: 44 additions & 0 deletions src/main/CommandHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ CommandHandler::CommandHandler(Application& app) : mApp(app)
addRoute("tx", &CommandHandler::tx);
addRoute("getledgerentry", &CommandHandler::getLedgerEntry);
addRoute("upgrades", &CommandHandler::upgrades);
addRoute("dumpproposedsettings", &CommandHandler::dumpProposedSettings);
addRoute("self-check", &CommandHandler::selfCheck);

#ifdef BUILD_TESTS
Expand Down Expand Up @@ -606,6 +607,49 @@ CommandHandler::upgrades(std::string const& params, std::string& retStr)
}
}

void
CommandHandler::dumpProposedSettings(std::string const& params,
std::string& retStr)
{
ZoneScoped;
std::map<std::string, std::string> retMap;
http::server::server::parseParams(params, retMap);
auto blob = retMap["blob"];
if (!blob.empty())
{
auto lhhe = mApp.getLedgerManager().getLastClosedLedgerHeader();
if (protocolVersionIsBefore(lhhe.header.ledgerVersion,
SOROBAN_PROTOCOL_VERSION))
{
retStr = "The dumpProposedSettings command is not allowed pre-v20";
return;
}

std::vector<uint8_t> buffer;
decoder::decode_b64(blob, buffer);
ConfigUpgradeSetKey key;
xdr::xdr_from_opaque(buffer, key);
LedgerTxn ltx(mApp.getLedgerTxnRoot());

auto ptr = ConfigUpgradeSetFrame::makeFromKey(ltx, key);

if (!ptr || ptr->isValidForApply() != Upgrades::UpgradeValidity::VALID)
{
retStr = "configUpgradeSet is missing or invalid";
return;
}

retStr = xdr_to_string(ptr->toXDR(), "ConfigUpgradeSet");
}
else
{
throw std::invalid_argument(
"Must specify a ConfigUpgradeSetKey blob: "
"dumpproposedsettings?blob=<ConfigUpgradeSetKey in "
"xdr format>");
}
}

void
CommandHandler::selfCheck(std::string const&, std::string& retStr)
{
Expand Down
1 change: 1 addition & 0 deletions src/main/CommandHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class CommandHandler
void getLedgerEntry(std::string const& params, std::string& retStr);
void unban(std::string const& params, std::string& retStr);
void upgrades(std::string const& params, std::string& retStr);
void dumpProposedSettings(std::string const& params, std::string& retStr);
void surveyTopology(std::string const&, std::string& retStr);
void stopSurvey(std::string const&, std::string& retStr);
void getSurveyResult(std::string const&, std::string& retStr);
Expand Down
139 changes: 139 additions & 0 deletions src/main/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
// under the Apache License, Version 2.0. See the COPYING file at the root
// of this distribution or at http://www.apache.org/licenses/LICENSE-2.0

// clang-format off
// This needs to be included first
#include "rust/RustVecXdrMarshal.h"
// clang-format on

#include "main/CommandLine.h"
#include "bucket/BucketManager.h"
#include "catchup/CatchupConfiguration.h"
Expand All @@ -18,15 +23,20 @@
#include "main/Diagnostics.h"
#include "main/ErrorMessages.h"
#include "main/PersistentState.h"
#include "main/SettingsUpgradeUtils.h"
#include "main/StellarCoreVersion.h"
#include "main/dumpxdr.h"
#include "overlay/OverlayManager.h"
#include "rust/RustBridge.h"
#include "scp/QuorumSetUtils.h"
#include "transactions/TransactionUtils.h"
#include "util/Logging.h"
#include "util/types.h"
#include "work/WorkScheduler.h"

#include <cereal/archives/json.hpp>
#include <cereal/cereal.hpp>

#ifdef BUILD_TESTS
#include "test/Fuzzer.h"
#include "test/fuzz.h"
Expand Down Expand Up @@ -1225,6 +1235,131 @@ runUpgradeDB(CommandLineArgs const& args)
});
}

int
getSettingsUpgradeTransactions(CommandLineArgs const& args)
{
std::string netId;

int64_t seqNum;
std::string upgradeFile;

bool signTxs = false;

auto signTxnOption =
clara::Opt{signTxs}["--signtxs"]("sign all transactions");

auto netIdOption = clara::Opt(netId, "NETWORK-PASSPHRASE")["--netid"](
"network ID used for signing")
.required();

auto netIdParser = ParserWithValidation{
netIdOption, required(netId, "NETWORK-PASSPHRASE")};

std::string id;

std::string base64Xdr;
auto base64Option = clara::Opt{base64Xdr, "XDR-BASE64"}["--xdr"](
"ConfigUpgradeSet in base64")
.required();

auto base64Parser =
ParserWithValidation{base64Option, required(base64Xdr, "XDR-BASE64")};

ParserWithValidation seqNumParser{
clara::Arg(seqNum, "SequenceNumber").required(),
[&] { return seqNum >= 0 ? "" : "SequenceNumber must be >= 0"; }};

return runWithHelp(
args,
{requiredArgParser(id, "PublicKey"), seqNumParser,
requiredArgParser(netId, "NetworkPassphrase"), base64Parser,
signTxnOption},
[&] {
ConfigUpgradeSet upgradeSet;
std::vector<uint8_t> binBlob;
decoder::decode_b64(base64Xdr, binBlob);
xdr::xdr_from_opaque(binBlob, upgradeSet);

PublicKey pk = KeyUtils::fromStrKey<PublicKey>(id);

std::vector<TransactionEnvelope> txsToSign;

auto uploadRes = getUploadTx(pk, seqNum + 1);
txsToSign.emplace_back(uploadRes.first);
auto const& contractCodeLedgerKey = uploadRes.second;

auto createRes =
getCreateTx(pk, contractCodeLedgerKey, netId, seqNum + 2);
txsToSign.emplace_back(std::get<0>(createRes));
auto const& contractSourceRefLedgerKey = std::get<1>(createRes);
auto const& contractID = std::get<2>(createRes);

auto invokeRes = getInvokeTx(pk, contractCodeLedgerKey,
contractSourceRefLedgerKey, contractID,
upgradeSet, seqNum + 3);
txsToSign.emplace_back(invokeRes.first);
auto const& upgradeSetKey = invokeRes.second;

if (signTxs)
{
signtxns(txsToSign, netId, true, false, true);
}
else
{
TransactionSignaturePayload payload;
payload.networkId = sha256(netId);
payload.taggedTransaction.type(ENVELOPE_TYPE_TX);

auto tx1 =
decoder::encode_b64(xdr::xdr_to_opaque(txsToSign.at(0)));
auto payload1 = payload;
payload1.taggedTransaction.tx() = txsToSign.at(0).v1().tx;

auto tx2 =
decoder::encode_b64(xdr::xdr_to_opaque(txsToSign.at(1)));
auto payload2 = payload;
payload2.taggedTransaction.tx() = txsToSign.at(1).v1().tx;

auto tx3 =
decoder::encode_b64(xdr::xdr_to_opaque(txsToSign.at(2)));
auto payload3 = payload;
payload3.taggedTransaction.tx() = txsToSign.at(2).v1().tx;

std::cerr
<< "Unsigned TransactionEnvelope to upload upgrade WASM "
<< std::endl;
std::cout << tx1 << std::endl;
std::cout << binToHex(xdr::xdr_to_opaque(
sha256(xdr::xdr_to_opaque(payload1))))
<< std::endl;

std::cerr << "Unsigned TransactionEnvelope to create upgrade "
"contract "
<< std::endl;

std::cout << tx2 << std::endl;
std::cout << binToHex(xdr::xdr_to_opaque(
sha256(xdr::xdr_to_opaque(payload2))))
<< std::endl;

std::cerr
<< "Unsigned TransactionEnvelope to invoke contract with "
"upgrade bytes "
<< std::endl;
std::cout << tx3 << std::endl;
std::cout << binToHex(xdr::xdr_to_opaque(
sha256(xdr::xdr_to_opaque(payload3))))
<< std::endl;
}

std::cerr << "ConfigUpgradeSetKey ";
std::cout << decoder::encode_b64(xdr::xdr_to_opaque(upgradeSetKey))
<< std::endl;

return 0;
});
}

int
runNewHist(CommandLineArgs const& args)
{
Expand Down Expand Up @@ -1685,6 +1820,10 @@ handleCommandLine(int argc, char* const* argv)
runSignTransaction},
{"upgrade-db", "upgrade database schema to current version",
runUpgradeDB},
{"get-settings-upgrade-txs",
"returns all transactions that need to be submitted to do a settings "
"upgrade",
getSettingsUpgradeTransactions},
#ifdef BUILD_TESTS
{"load-xdr", "load an XDR bucket file, for testing", runLoadXDR},
{"rebuild-ledger-from-buckets",
Expand Down
Loading

0 comments on commit d61e69d

Please sign in to comment.