Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ rlimit = "0.10"
rstest = "0.24"
rusqlite = "0.33"
schnorrkel = "0.11"
semver = "1.0"
serde = "1.0"
serde_json = "1.0"
serde_test = "1.0"
Expand Down Expand Up @@ -248,8 +249,8 @@ zeroize = "1.5"

[workspace.dependencies.trezor-client]
git = "https://github.com/mintlayer/mintlayer-trezor-firmware"
# The commit "Remove destination from MintlayerFillOrderV1; fail if the host asks to sign a FillOrder input"
rev = "198346c2f731e7ff34be03b7a16818008eeeae0d"
# The commit "Mintlayer firmware versioning"
rev = "397155e26660993a044e78447dad893852fa44d1"
features = ["bitcoin", "mintlayer"]

[workspace.metadata.dist.dependencies.apt]
Expand Down
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

Welcome to the official Github repository for Mintlayer, an innovative, open-source blockchain project. For detailed technical insights, we recommend visiting our [documentation](https://docs.mintlayer.org/).

Please note, the code in this repository is currently under active development. Consequently, it should not be deemed production-ready. Nonetheless, you're invited to test the code in our active testnet environment.

## Security

Discovered a potential security issue? We urge you to contact us directly at security@mintlayer.org. When reporting, please encrypt your report using Ben's GPG key which can be found [here](https://www.mintlayer.org/assets/keys/ben).
Expand Down Expand Up @@ -54,24 +52,26 @@ You can either keep running the code from source, using `cargo run --release --b

### Running software and how to control logging

The logging of mintlayer-core is configured via the `RUST_LOG` environment variable. All log messages are printed to the terminal screen; we prefer simplicity over complicated log machinery. For example, to see all logs of the `info` level and above (the default level for normal operation), you can run the node with `RUST_LOG=info cargo run --bin node-daemon -- testnet`. If you're facing an issue, it's recommended to use `RUST_LOG=debug` instead. We recommend using these commands that not only print the logs on the screen, but also write them to a file in case you face an issue. On Linux, this can be achieved using `tee` as shown below.
Normally, the logging of mintlayer-core is configured via the `RUST_LOG` environment variable and all log messages are printed to the terminal screen. For example, to see all logs of the `info` level and above (the default level for normal operation), you can run the node with `RUST_LOG=info cargo run --bin node-daemon -- testnet`. If you're facing an issue, it's recommended to use `RUST_LOG=debug` instead. We recommend using the commands that not only print the logs on the screen, but also write them to a file in case you face an issue. On Linux, this can be achieved using `tee` as shown below.

If the `RUST_LOG` environment variable is not specified, the log level `info` will be used by default.

Additionally, independent of what is printed to the console, node's logs may also be automatically written to the data directory (on Linux, they will be inside `~/.mintlayer/mainnet/logs/` and `~/.mintlayer/testnet/logs/` for mainnet and testnet respectively); this is controlled by the `--log-to-file` option (e.g. `--log-to-file true`), which is accepted by both node-daemon and node-gui. By default, its value is false for node-daemon and true for node-gui. The log files are rotated based on size, so older logs will be automatically deleted eventually. Also note that the log level used in this case is always `info`, regardless of the value of `RUST_LOG`.

Here are the commands as recommended for different scenarios:

#### Assuming you're using the source code

Every release has a tag and a release branch. Make sure you checkout the release you need. For example, if you need v0.5.1, you should first run the following to check out the release branch:
Every release has a tag and a release branch. Make sure you checkout the release you need. For example, if you need v1.0.0, you should first run the following to check out the release branch:

```sh
git checkout release-v0.5.1
git checkout release-v1.0.0
```

or to checkout the tag:

```sh
git checkout tags/v0.5.1
git checkout tags/v1.0.0
```

Release branches are more recommended than tags, because they get necessary security patches, if any. Tags are just markers.
Expand Down Expand Up @@ -156,11 +156,16 @@ cargo build --bin wallet-cli --target=aarch64-unknown-linux-gnu --release

The artifacts can be found in `target/aarch64-unknown-linux-gnu/release`, or a similar directory name.


## Wallets

For more information about the wallets and their usage, [visit this readme file](wallet/README.md).

## Trezor support

Mintlayer wallets support Trezor hardware wallets, though it's still in Beta at this moment.

For details, [visit this readme file](wallet/TREZOR_SUPPORT.md).

## The API server

The API server is a tool for indexing the blockchain. Its source code is contained in this repository and its [readme can be found in its directory](api-server/README.md).
Expand Down
2 changes: 1 addition & 1 deletion api-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

The Mintlayer API server is a tool that scans the blockchain and publishes its data in a database for easy access. Technically speaking, this is done to achieve the trade-off where the blockchain itself contains the minimal required amount of data, while the API server indexes all the data for easy reach. The API server is used by block explorers and web wallets. The API server is made to be usable in many ways, including in exchanges, by people interested in writing tooling for the blockchain, or anything else.

For example to understand what problem the API server solves, the node software only stores blocks of the blockchain, but it does not index the transactions by their id. Meaning: Attempting to find a transaction by its id is virtually impossible without going through all blocks. This same applies to more information that's not directly, minimally, required to operate the blockchain. In that case, using the API server solves all these problems, since the API server is made to index the information and put it in the database.
For example to understand what problem the API server solves, the node software only stores blocks of the blockchain, but it does not index the transactions by their id. Meaning: Attempting to find a transaction by its id is virtually impossible without going through all blocks. The same applies to more information that's not directly, minimally, required to operate the blockchain. In that case, using the API server solves all these problems, since the API server is made to index the information and put it in the database.

## Architecture

Expand Down
2 changes: 1 addition & 1 deletion build-tools/linux-systemd-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Note: If you're running mintlayer in your home or behind a consumer router, thes

Also, there are managed services that do this for you, but they're more expensive. We never had to use any of them, but it's up to you. One that comes to mind is Plesk. It's made to make server management easier. But it's not free.

1. NEVER run mintlayer software as root or a user that has access to root. It's preferable to create a separate user for this
1. NEVER run mintlayer software as root or a user that has access to root. It's preferable to create a separate user for this.
2. NEVER keep all your server ports open. This is a huge security flaw that can endanger both your server and make stealing your coins easy. Mintlayer needs only port 13031 (testnet p2p) or 3031 (mainnet p2p). All other ports (maybe besides ssh) should be blocked by a firewall.
3. DO NOT allow public access to RPC (port 13030 for testnet, 3030 for mainnet). RPC basically gives full control and it's meant for the owner.
4. DO NOT bind RPC to 0.0.0.0 unless you know what you're doing. The correct way to reach your RPC is with an ssh tunnel, not by opening the RPC to the public.
Expand Down
6 changes: 3 additions & 3 deletions consensus/src/pos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,9 +230,9 @@ pub fn stake(
let first_timestamp = *block_timestamp;

log::debug!(
"Search for a valid block ({}..{}), pool_id: {}",
first_timestamp,
max_block_timestamp,
"Search for a valid block, start: {}, slots count: {}, pool_id: {}",
first_timestamp.into_time(),
max_block_timestamp.as_int_seconds() - first_timestamp.as_int_seconds() + 1,
Address::new(chain_config, *pos_data.stake_pool_id())
.expect("Pool id to address cannot fail")
);
Expand Down
2 changes: 2 additions & 0 deletions node-gui/backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ wallet-cli-commands = { path = "../../wallet/wallet-cli-commands"}
anyhow.workspace = true
chrono.workspace = true
futures.workspace = true
itertools.workspace = true
semver.workspace = true
serde = { workspace = true, features = ["derive"] }
serde_json.workspace = true
serde_with.workspace = true
Expand Down
54 changes: 46 additions & 8 deletions node-gui/backend/src/backend_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,30 @@

use std::{collections::BTreeMap, fmt::Debug, path::PathBuf, str::FromStr, sync::Arc};

use futures::{stream::FuturesOrdered, TryStreamExt};
use tokio::{
sync::mpsc::{UnboundedReceiver, UnboundedSender},
task::JoinHandle,
};

use common::{
address::{Address, RpcAddress},
chain::{ChainConfig, GenBlock, SignedTransaction},
primitives::{per_thousand::PerThousand, BlockHeight, Id},
};
use crypto::key::hdkd::{child_number::ChildNumber, u31::U31};
use futures::{stream::FuturesOrdered, TryStreamExt};
use logging::log;
use node_comm::rpc_client::ColdWalletClient;
use node_lib::node_controller::NodeController;
use serialization::hex_encoded::HexEncoded;
use tokio::{
sync::mpsc::{UnboundedReceiver, UnboundedSender},
task::JoinHandle,
};
use wallet::{account::transaction_list::TransactionList, wallet::Error, WalletError};
use wallet_cli_commands::{
get_repl_command, parse_input, CommandHandler, ConsoleCommand, ManageableWalletCommand,
WalletCommand,
};
use wallet_controller::{
make_cold_wallet_rpc_client,
types::{Balances, WalletCreationOptions, WalletTypeArgs},
types::{Balances, WalletCreationOptions, WalletExtraInfo, WalletTypeArgs},
ControllerConfig, NodeInterface, UtxoState, WalletHandlesClient,
};
use wallet_rpc_client::handles_client::WalletRpcHandlesClient;
Expand Down Expand Up @@ -361,6 +362,7 @@ impl Backend {
};

let encryption = EncryptionState::Disabled;
let wallet_extra_info = Self::get_wallet_extra_info(&wallet_data.controller).await?;

let wallet_info = WalletInfo {
wallet_id,
Expand All @@ -369,13 +371,31 @@ impl Backend {
accounts: accounts_info,
best_block,
wallet_type,
extra_info: wallet_extra_info,
};

self.wallets.insert(wallet_id, wallet_data);

Ok(wallet_info)
}

async fn get_wallet_extra_info(
controller: &GuiHotColdController,
) -> Result<WalletExtraInfo, BackendError> {
let wallet_info_from_rpc = match controller {
GuiHotColdController::Hot(wallet_rpc, _) => wallet_rpc
.wallet_info()
.await
.map_err(|err| BackendError::WalletError(err.to_string()))?,
GuiHotColdController::Cold(wallet_rpc, _) => wallet_rpc
.wallet_info()
.await
.map_err(|err| BackendError::WalletError(err.to_string()))?,
};

Ok(wallet_info_from_rpc.extra_info)
}

async fn create_wallet<N>(
&mut self,
handles_client: N,
Expand Down Expand Up @@ -414,10 +434,18 @@ impl Backend {
overwrite_wallet_file: true,
scan_blockchain: import.should_scan_blockchain(),
};
wallet_rpc
let created_wallet = wallet_rpc
.create_wallet(file_path, wallet_args, options)
.await
.map_err(|err| BackendError::WalletError(err.to_string()))?;
match created_wallet {
wallet_controller::types::CreatedWallet::UserProvidedMnemonic
| wallet_controller::types::CreatedWallet::NewlyGeneratedMnemonic(_) => {}
#[cfg(feature = "trezor")]
wallet_controller::types::CreatedWallet::TrezorDeviceSelection(found_devices) => {
return Err(BackendError::MultipleTrezorDevicesFound(found_devices))
}
}
tokio::spawn(forward_events(
wallet_events,
wallet_service
Expand Down Expand Up @@ -572,13 +600,16 @@ impl Backend {
}
};

let wallet_extra_info = Self::get_wallet_extra_info(&wallet_data.controller).await?;

let wallet_info = WalletInfo {
wallet_id,
path: file_path,
encryption,
accounts: accounts_info,
best_block,
wallet_type,
extra_info: wallet_extra_info,
};

self.wallets.insert(wallet_id, wallet_data);
Expand Down Expand Up @@ -619,7 +650,7 @@ impl Backend {
let node_rpc = wallet_service.node_rpc().clone();
let chain_config = wallet_service.chain_config().clone();
let wallet_rpc = WalletRpc::new(wallet_handle, node_rpc.clone(), chain_config.clone());
wallet_rpc
let opened_wallet = wallet_rpc
.open_wallet(
file_path,
None,
Expand All @@ -629,6 +660,13 @@ impl Backend {
)
.await
.map_err(|err| BackendError::WalletError(err.to_string()))?;
match opened_wallet {
| wallet_controller::types::OpenedWallet::Opened => {}
#[cfg(feature = "trezor")]
wallet_controller::types::OpenedWallet::TrezorDeviceSelection(found_devices) => {
return Err(BackendError::MultipleTrezorDevicesFound(found_devices))
}
}
tokio::spawn(forward_events(
wallet_events,
wallet_service
Expand Down
19 changes: 19 additions & 0 deletions node-gui/backend/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use itertools::Itertools as _;

#[cfg(feature = "trezor")]
use wallet::signer::trezor_signer;

use super::{account_id::AccountId, messages::WalletId};

#[derive(thiserror::Error, Debug, Clone)]
Expand Down Expand Up @@ -47,4 +52,18 @@ pub enum BackendError {
InvalidConsoleCommand(String),
#[error("Empty console command")]
EmptyConsoleCommand,

#[cfg(feature = "trezor")]
#[error(
"Multiple Trezor devices found: {}.\nLeave only one of them connected and try again.",
format_multiple_trezor_devices_err(_0)
)]
MultipleTrezorDevicesFound(Vec<trezor_signer::FoundDevice>),
}

fn format_multiple_trezor_devices_err(devices: &[trezor_signer::FoundDevice]) -> String {
devices
.iter()
.map(|device| format!("{} (device id = {})", device.device_name, device.device_id))
.join(", ")
}
3 changes: 2 additions & 1 deletion node-gui/backend/src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use p2p::P2pEvent;
use serialization::hex_encoded::hex_encoded_serialization;
use wallet::account::transaction_list::TransactionList;
use wallet_cli_commands::ConsoleCommand;
use wallet_controller::types::{Balances, WalletTypeArgs};
use wallet_controller::types::{Balances, WalletExtraInfo, WalletTypeArgs};
use wallet_rpc_lib::types::PoolInfo;
use wallet_types::wallet_type::WalletType;

Expand All @@ -58,6 +58,7 @@ pub struct WalletInfo {
pub accounts: BTreeMap<AccountId, AccountInfo>,
pub best_block: (Id<GenBlock>, BlockHeight),
pub wallet_type: WalletType,
pub extra_info: WalletExtraInfo,
}

#[derive(Debug, Clone, Serialize)]
Expand Down
Loading
Loading