mirror of
https://github.com/Retropex/knots-startos.git
synced 2025-05-12 19:30:45 +02:00
Merge ab693fa484
into 4c573b1b76
This commit is contained in:
commit
ef9d160683
@ -83,6 +83,7 @@ COPY --from=bitcoin-core /opt /opt
|
||||
COPY ./manager/target/${ARCH}-unknown-linux-musl/release/bitcoind-manager \
|
||||
./docker_entrypoint.sh \
|
||||
./actions/reindex.sh \
|
||||
./actions/reindex_chainstate.sh \
|
||||
./actions/prioritise-transaction.sh \
|
||||
./check-rpc.sh \
|
||||
./check-synced.sh \
|
||||
|
34
actions/reindex_chainstate.sh
Normal file
34
actions/reindex_chainstate.sh
Normal file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
action_result_running=" {
|
||||
\"version\": \"0\",
|
||||
\"message\": \"Bitcoin Core restarting in reindex chainstate mode\",
|
||||
\"value\": null,
|
||||
\"copyable\": false,
|
||||
\"qr\": false
|
||||
}"
|
||||
action_result_stopped=" {
|
||||
\"version\": \"0\",
|
||||
\"message\": \"Bitcoin Core will reindex the chainstate the next time the service is started\",
|
||||
\"value\": null,
|
||||
\"copyable\": false,
|
||||
\"qr\": false
|
||||
}"
|
||||
action_result_pruned=" {
|
||||
\"version\": \"0\",
|
||||
\"message\": \"Bitcoin Core does not allow reindex-chainstate for pruned nodes. If the Chainstate is corrupted on a pruned node the entire blockchain will need to be re-downloaded from genesis with the 'Reindex Blockchain' action\",
|
||||
\"value\": null,
|
||||
\"copyable\": false,
|
||||
\"qr\": false
|
||||
}"
|
||||
|
||||
pruned=$(yq e '.advanced.pruning.mode' /root/.bitcoin/start9/config.yaml)
|
||||
|
||||
if [ "$pruned" != "disabled" ]; then
|
||||
echo $action_result_pruned
|
||||
else
|
||||
touch /root/.bitcoin/requires.reindex_chainstate
|
||||
bitcoin-cli -rpcconnect=bitcoind.embassy stop >/dev/null 2>/dev/null && echo $action_result_running || echo $action_result_stopped
|
||||
fi
|
@ -124,6 +124,11 @@ zmqpubsequence=tcp://0.0.0.0:28333
|
||||
txindex=1
|
||||
}}
|
||||
|
||||
## COINSTATSINDEX
|
||||
{{#IF coinstatsindex
|
||||
coinstatsindex=1
|
||||
}}
|
||||
|
||||
## DATACARRIER
|
||||
{{#IF blkconstr.datacarrier
|
||||
datacarrier=1
|
||||
@ -219,4 +224,4 @@ blockmaxsize={{advanced.templateconstruction.blockmaxsize}}
|
||||
|
||||
{{#IF advanced.templateconstruction.blockmaxweight
|
||||
blockmaxweight={{advanced.templateconstruction.blockmaxweight}}
|
||||
}}
|
||||
}}
|
||||
|
@ -547,7 +547,7 @@ if mempool_info.status.success() {
|
||||
}
|
||||
|
||||
|
||||
fn inner_main(reindex: bool) -> Result<(), Box<dyn Error>> {
|
||||
fn inner_main(reindex: bool, reindex_chainstate: bool) -> Result<(), Box<dyn Error>> {
|
||||
while !Path::new("/root/.bitcoin/start9/config.yaml").exists() {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
}
|
||||
@ -585,32 +585,29 @@ fn inner_main(reindex: bool) -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
if reindex {
|
||||
btc_args.push("-reindex".to_owned());
|
||||
}
|
||||
|
||||
std::io::copy(
|
||||
&mut TemplatingReader::new(
|
||||
std::fs::File::open("/mnt/assets/bitcoin.conf.template")?,
|
||||
&config,
|
||||
&"{{var}}".parse()?,
|
||||
b'%',
|
||||
),
|
||||
&mut std::fs::File::create("/root/.bitcoin/bitcoin.conf")?,
|
||||
)?;
|
||||
let mut child = std::process::Command::new("bitcoind")
|
||||
.args(btc_args)
|
||||
.spawn()?;
|
||||
if reindex {
|
||||
match fs::remove_file("/root/.bitcoin/requires.reindex") {
|
||||
Ok(()) => (),
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => (),
|
||||
a => a?,
|
||||
}
|
||||
} else if reindex_chainstate {
|
||||
btc_args.push("-reindex-chainstate".to_owned());
|
||||
match fs::remove_file("/root/.bitcoin/requires.reindex_chainstate") {
|
||||
Ok(()) => (),
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => (),
|
||||
a => a?,
|
||||
}
|
||||
}
|
||||
|
||||
let mut child = std::process::Command::new("bitcoind")
|
||||
.args(btc_args)
|
||||
.spawn()?;
|
||||
|
||||
let raw_child = child.id();
|
||||
*CHILD_PID.lock().unwrap() = Some(raw_child);
|
||||
|
||||
let pruned = {
|
||||
config[&Value::from("advanced")][&Value::from("pruning")][&Value::from("mode")]
|
||||
== "automatic"
|
||||
config[&Value::from("advanced")][&Value::from("pruning")][&Value::from("mode")] == "automatic"
|
||||
};
|
||||
let _proxy = if pruned {
|
||||
let state = Arc::new(btc_rpc_proxy::State {
|
||||
@ -656,13 +653,17 @@ fn inner_main(reindex: bool) -> Result<(), Box<dyn Error>> {
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
|
||||
std::process::exit(code)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init();
|
||||
let reindex = Path::new("/root/.bitcoin/requires.reindex").exists();
|
||||
let reindex_chainstate = Path::new("/root/.bitcoin/requires.reindex_chainstate").exists();
|
||||
ctrlc::set_handler(move || {
|
||||
if let Some(raw_child) = *CHILD_PID.lock().unwrap() {
|
||||
use nix::{
|
||||
@ -674,7 +675,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
std::process::exit(143)
|
||||
}
|
||||
})?;
|
||||
inner_main(reindex)
|
||||
inner_main(reindex, reindex_chainstate)
|
||||
}
|
||||
|
||||
fn human_readable_timestamp(unix_time: u64) -> String {
|
||||
|
@ -146,6 +146,22 @@ actions:
|
||||
mounts:
|
||||
main: /root/.bitcoin
|
||||
io-format: json
|
||||
reindex-chainstate:
|
||||
name: "Reindex Chainstate"
|
||||
description: "Rebuilds the chainstate database using existing block index data; as the block index is not rebuilt, 'reindex_chainstate' should be strictly faster than 'reindex'. This action should only be used in the case of chainstate corruption; if the blocks stored on disk are corrupted, the 'reindex' action will need to be run instead."
|
||||
warning: While faster than 'Reindex', 'Reindex Chainstate' can still take several days or more to complete. Pruned nodes do not allow 'reindex-chainstate'; if you are running a pruned node and suspect chainstate corruption the 'reindex' action (requiring redownloading the entire Blockchain) should be run instead.
|
||||
allowed-statuses:
|
||||
- running
|
||||
- stopped
|
||||
implementation:
|
||||
type: docker
|
||||
image: main
|
||||
system: false
|
||||
entrypoint: reindex_chainstate.sh
|
||||
args: []
|
||||
mounts:
|
||||
main: /root/.bitcoin
|
||||
io-format: json
|
||||
delete-txindex:
|
||||
name: "Delete Transaction Index"
|
||||
description: "Deletes the Transaction Index (txindex) in case it gets corrupted."
|
||||
@ -154,6 +170,14 @@ actions:
|
||||
- stopped
|
||||
implementation:
|
||||
type: script
|
||||
delete-coinstatsindex:
|
||||
name: "Delete Coinstats Index"
|
||||
description: "Deletes the Coinstats Index (coinstatsindex) in case it gets corrupted."
|
||||
warning: The Coinstats Index will be rebuilt once Bitcoin Core is started again, unless you deactivate it in the config settings. Please don't do this unless instructed to by Start9 support staff.
|
||||
allowed-statuses:
|
||||
- stopped
|
||||
implementation:
|
||||
type: script
|
||||
delete-peers:
|
||||
name: "Delete Peer List"
|
||||
description: "Deletes the Peer List (peers.dat) in case it gets corrupted."
|
||||
|
@ -57,4 +57,32 @@ export const action = {
|
||||
},
|
||||
};
|
||||
},
|
||||
async "delete-coinstatsindex"(
|
||||
effect: T.Effects,
|
||||
_input?: T.Config,
|
||||
): Promise<T.ResultType<T.ActionResult>> {
|
||||
const coinstatsinfoLocation = {
|
||||
path: "indexes/coinstats",
|
||||
volumeId: "main",
|
||||
};
|
||||
if (await util.exists(effect, coinstatsinfoLocation) === false) {
|
||||
return {
|
||||
result: {
|
||||
copyable: false,
|
||||
message: "coinstatsindex doesn't exist",
|
||||
version: "0",
|
||||
qr: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
await effect.removeDir(coinstatsinfoLocation);
|
||||
return {
|
||||
result: {
|
||||
copyable: false,
|
||||
message: "Deleted coinstatsindex",
|
||||
version: "0",
|
||||
qr: false,
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
@ -329,6 +329,12 @@ export const getConfig: T.ExpectedExports.getConfig = async (effects) => {
|
||||
description: "Enable the Transaction Index (txindex)",
|
||||
default: allowUnpruned,
|
||||
},
|
||||
coinstatsindex: {
|
||||
type: "boolean",
|
||||
name: "Coinstats Index",
|
||||
description: "Enabling Coinstats Index reduces the time for the gettxoutsetinfo RPC to complete at the cost of using additional disk space",
|
||||
default: false,
|
||||
},
|
||||
wallet: {
|
||||
type: "object",
|
||||
name: "Wallet",
|
||||
@ -410,7 +416,7 @@ export const getConfig: T.ExpectedExports.getConfig = async (effects) => {
|
||||
type: "boolean",
|
||||
name: "Use V2 P2P Transport Protocol",
|
||||
description: "Enable or disable the use of BIP324 V2 P2P transport protocol.",
|
||||
default: false,
|
||||
default: true,
|
||||
},
|
||||
addnode: {
|
||||
name: "Add Nodes",
|
||||
|
@ -1,36 +1,39 @@
|
||||
import {
|
||||
matches,
|
||||
compat,
|
||||
types,
|
||||
YAML
|
||||
} from "../dependencies.ts";
|
||||
const { number, shape, boolean } = matches;
|
||||
import { matches, types, YAML } from "../dependencies.ts";
|
||||
const { number } = matches;
|
||||
|
||||
export const setConfig: types.ExpectedExports.setConfig = async (
|
||||
effects: types.Effects,
|
||||
// deno-lint-ignore no-explicit-any
|
||||
newConfig: any,
|
||||
newConfig: any
|
||||
) => {
|
||||
if (!(newConfig?.rpc?.enable || !(newConfig.advanced?.pruning?.mode === "manual"))) {
|
||||
if (newConfig.advanced.pruning.mode === "manual" && !newConfig.rpc.enable) {
|
||||
return {
|
||||
error: "RPC must be enabled for manual.",
|
||||
error: "RPC must be enabled for manual pruning.",
|
||||
};
|
||||
}
|
||||
if (
|
||||
!(!newConfig.txindex || (newConfig.advanced?.pruning?.mode === "disabled"))
|
||||
) {
|
||||
|
||||
if (newConfig.txindex && newConfig.advanced.pruning.mode !== "disabled") {
|
||||
return {
|
||||
error: "Txindex not allowed on pruned nodes.",
|
||||
};
|
||||
}
|
||||
// true, false only fail case
|
||||
|
||||
if (
|
||||
!(!newConfig.advanced.blockfilters.peerblockfilters ||
|
||||
(newConfig.advanced.blockfilters.blockfilterindex))
|
||||
newConfig.coinstatsindex &&
|
||||
newConfig.advanced.pruning.mode !== "disabled"
|
||||
) {
|
||||
return {
|
||||
error: "Coinstats index not allowed on pruned nodes.",
|
||||
};
|
||||
}
|
||||
|
||||
if (
|
||||
newConfig.advanced.blockfilters.peerblockfilters &&
|
||||
!newConfig.advanced.blockfilters.blockfilterindex
|
||||
) {
|
||||
return {
|
||||
error:
|
||||
"'Compute Compact Block Filters' must be enabled if 'Serve Compact Block Filters to Peers' is enabled.",
|
||||
'"Compute Compact Block Filters" must be enabled if "Serve Compact Block Filters to Peers" is enabled.',
|
||||
};
|
||||
}
|
||||
|
||||
@ -41,10 +44,12 @@ export const setConfig: types.ExpectedExports.setConfig = async (
|
||||
|
||||
// config-set.sh
|
||||
|
||||
const oldConfig = await effects.readFile({
|
||||
path: "start9/config.yaml",
|
||||
volumeId: "main",
|
||||
}).catch(() => null);
|
||||
const oldConfig = await effects
|
||||
.readFile({
|
||||
path: "start9/config.yaml",
|
||||
volumeId: "main",
|
||||
})
|
||||
.catch(() => null);
|
||||
if (oldConfig) {
|
||||
await effects.writeFile({
|
||||
path: "start9/config-old.yaml",
|
||||
@ -56,7 +61,7 @@ export const setConfig: types.ExpectedExports.setConfig = async (
|
||||
let oldPruningSize = 0;
|
||||
if (oldPruningTl !== "disabled") {
|
||||
oldPruningSize = number.unsafeCast(
|
||||
oldConfigParsed?.advanced?.pruning?.size,
|
||||
oldConfigParsed?.advanced?.pruning?.size
|
||||
);
|
||||
}
|
||||
const newPruningTl = newConfig.advanced.pruning.mode;
|
||||
@ -67,7 +72,8 @@ export const setConfig: types.ExpectedExports.setConfig = async (
|
||||
if (oldPruningTl == "disabled" || !oldPruningTl) {
|
||||
effects.debug("No reindex required");
|
||||
} else if (
|
||||
oldPruningTl === newPruningTl && oldPruningSize >= newPruningSize
|
||||
oldPruningTl === newPruningTl &&
|
||||
oldPruningSize >= newPruningSize
|
||||
) {
|
||||
effects.debug("No reindex required");
|
||||
} else {
|
||||
@ -81,7 +87,7 @@ export const setConfig: types.ExpectedExports.setConfig = async (
|
||||
} else {
|
||||
effects.debug("No reindex required");
|
||||
}
|
||||
|
||||
|
||||
await effects.writeFile({
|
||||
path: "start9/config.yaml",
|
||||
toWrite: YAML.stringify(newConfig),
|
||||
|
Loading…
Reference in New Issue
Block a user