Merge branch 'dev' into duke

This commit is contained in:
Duke
2024-10-01 08:58:09 -04:00
14 changed files with 125 additions and 48 deletions

View File

@@ -8,7 +8,7 @@
| :---: | :---: | :---: | :---: | :---: |
| [What is Hush?](#what-is-hush) | [Windows 10 - Video Tutorial](#install-on-windows-10) | [Build on Debian or Ubuntu](#build-on-debian-or-ubuntu) | [Where can I buy Hush?](#where-can-i-buy-hush) | [Cross compiling Windows binaries](#windows-cross-compiled-on-linux)
| [Why not GitHub?](#banned-by-github) | [Build on Mac](#build-on-mac) | [Build on Arch](#build-on-arch) | [Can I mine with CPU or GPU?](#can-i-mine-with-cpu-or-gpu) | [Hush DevOps for pools and CEXs](https://git.hush.is/hush/docs/src/branch/master/advanced/devops.md)
| [What is HushChat?](#what-is-hushchat) | [Debian and Ubuntu](#installing-hush-binaries) | [Build on Fedora](#build-on-fedora) | [Claiming funds from old Hush wallets](https://git.hush.is/hush/hush3/src/branch/dev/doc/OLD_WALLETS.md) | [Earn Hush bounty](#earn-hush-bounty)
| [What is HushChat?](#what-is-hushchat) | [Debian and Ubuntu](#installing-hush-binaries) | [Build on Fedora](#build-on-fedora) | [Claiming funds from old Hush wallets](https://git.hush.is/hush/hush3/src/branch/master/doc/OLD_WALLETS.md) | [Earn Hush bounty](#earn-hush-bounty)
| [What is SilentDagon?](#what-is-silentdagon) | [Raspberry Pi](#install-on-arm-architecture) | [Build on Ubuntu 16.04 or older](#building-on-ubuntu-16-04-and-older-systems) | [Where can I spend Hush?](#where-can-i-spend-hush) | [Cross compiling from amd64 to arm64](https://git.hush.is/hush/docs/src/branch/master/advanced/cross-compile-hush-full-node-to-aarch64-with-docker.md)
</h3>
@@ -50,7 +50,7 @@ cd hush3
# This uses 3 build processes, you need 2GB of RAM for each.
./build.sh -j3
```
Video Tutorial: https://videos.hush.is/w/3kKQt81r7UUPWLHVuwK2BZ
Video Tutorial: https://videos.hush.is/videos/how-to-install-on-linux
# Build on Arch
@@ -80,7 +80,7 @@ cd hush3
# Install on Windows 10
Video Tutorial: https://videos.hush.is/w/oGXff7of3EjmGENtDtYTUX
Video Tutorial: https://videos.hush.is/videos/how-to-install-on-windows
# Install on ARM Architecture
@@ -90,6 +90,8 @@ Use this if you have a Raspberry Pi or similar computer. Currently, any ARMv7 ma
1. Install the Debian package, substituting "VERSION-NUMBER" for the version you have downloaded: `sudo dpkg -i hush-VERSION-NUMBER-aarch64.deb`.
1. Run with: `hushd`.
If you would like to compile this for ARM yourself, then please refer to the [Cross compiling a Hush full node daemon from AMD64 to ARM64(aarch64) CPU architecture with Docker](https://git.hush.is/jahway603/hush-docs/src/branch/master/advanced/cross-compile-hush-full-node-to-aarch64-with-docker.md) documentation to do that.
# Building On Ubuntu 16.04 and older systems
Some older compilers may not be able to compile modern code, such as gcc 5.4 which comes with Ubuntu 16.04 by default. Here is how to install gcc 7 on Ubuntu 16.04. Run these commands as root:
@@ -172,7 +174,7 @@ Hush cannot be efficiently mined with CPU or GPU, only ASIC mining is recommende
# Where can I spend Hush?
AgoraX market (in progress)
AgoraX market: https://agorax.is
# Earn Hush bounty
@@ -192,4 +194,4 @@ Developers can earn bounty by fixing bugs or solving feature requests listed in
# License
For license information see the file [COPYING](COPYING).
For license information see the file [COPYING](COPYING).

View File

@@ -1,3 +1,22 @@
hush (3.10.3) stable; urgency=high
* Use WolfSSL 4.8.1 which prevents nodes from getting stuck in general and when shutting down
* Set minimum fee to 0.1 HUSH per 1 KB of data if `OP_RETURN` is used.
* A feature in absurd fee that allows sending amount < fee, can be used only in a full node by advanced users.
* Fixed various bugs relating to lock ordering and missing locks
* Fixed RPC docs for addnode and disconnectnode having the incorrect port for HACs
* Value of DEBUG_LOCKORDER is now logged to debug.log on node startup
* New script ./debug-build.sh to make it easier to make debug builds
* DragonX nodes now have their own list of seed nodes
* Hush nodes now have their own protocol version which is independent from HACs
* Fixed off-by-one bug in `newSietchRecipient`
* Performance improvement to `ActivateBestChainStep` ed86f2dd1d
* Improved navigation in README for new users.
* Updated doc/release-process.md to resolve Issue #407
* Added build.sh checks for as and ld to be installed to resolve Issue #73
-- Hush Core <myhushteam@gmail.com> Mon, 30 Sep 2024 11:22:33 -0700
hush (3.10.2) stable; urgency=medium
* Upgraded WolfSSL to 5.2.0 on Linux and Mac: #380.

View File

@@ -1,5 +1,5 @@
Files: *
Copyright: 2016-2020, The Hush developers
Copyright: 2016-2024, The Hush developers
2009-2016, Bitcoin Core developers
License: GPLv3
Comment: https://hush.is

View File

@@ -1,14 +1,14 @@
# node1.hush.land
91.208.127.81
103.69.128.148
# node2.hush.land
87.251.76.166
194.29.100.208
# node3.hush.land
45.82.68.233
45.132.75.69
# node4.hush.land
87.251.76.33
170.205.39.39
# node5.hush.land
178.250.189.141
@@ -28,8 +28,11 @@ hushv3h6mbxd2pptj42reko3jcexcgnz5zvp3mqcu6myto3jhhn4yzyd.onion
hushv3xvheqh42ms3ld2nh555muscietkib7gycb7s4psbrjsysfywqd.onion
# ipv6
2a0c:b641:6f1:34::2
2a0c:b641:6f1:c::2
2a0c:b641:6f1:18e::2
2406:ef80:3:1269::1
2406:ef80:2:3b59::1
2406:ef80:1:146e::1
2406:ef80:4:2132::1
# i2p
7oumuppuzgbzlkahavx7qrtjnvbhkixjqdmeg7f6fhndgfhz7mlq.b32.i2p

View File

@@ -8,22 +8,25 @@ $(package)_sha256_hash=67df06ed50f288bd7b1ec6907973684fb7cf1196f2cb368b59d423e42
$(package)_git_commit=42ba95387cdfd67399f7aac52fddb8d6e1258ee6
$(package)_dependencies=
$(package)_config_opts=--enable-cxx --disable-shared
else ifeq ($(build_os),darwin)
else
#else ifeq ($(build_os),darwin)
$(package)_version=6.1.1
$(package)_download_path=https://git.hush.is/attachments
$(package)_file_name=d613c855-cd92-4efb-b893-658496852019
$(package)_download_file=d613c855-cd92-4efb-b893-658496852019
$(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6
$(package)_config_opts=--enable-cxx --disable-shared
else
$(package)_version=6.1.1
$(package)_download_path=https://ftp.gnu.org/gnu/gmp
$(package)_file_name=gmp-$($(package)_version).tar.bz2
$(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6
$(package)_dependencies=
$(package)_config_opts=--enable-cxx --disable-shared
endif
#else
#$(package)_version=6.1.1
#$(package)_download_path=https://ftp.gnu.org/gnu/gmp
#$(package)_file_name=gmp-$($(package)_version).tar.bz2
#$(package)_sha256_hash=a8109865f2893f1373b0a8ed5ff7429de8db696fc451b1036bd7bdf95bbeffd6
#$(package)_dependencies=
#$(package)_config_opts=--enable-cxx --disable-shared
#endif
define $(package)_config_cmds
$($(package)_autoconf) --host=$(host) --build=$(build)
endef

View File

@@ -111,20 +111,24 @@ Install deps on Linux:
- Make sure git tag starts with a `v` such as `v3.9.2`
- Use util/gen-linux-binary-release.sh to make a Linux release binary
- Upload Linux binary to Gitea release and add SHA256 sum
- Use util/build-debian-package.sh to make an x86 Debian package for the release
- Create an x86 Debian package for the release:
- Edit contrib/debian/changelog to add information about the new release
- Use `util/build-debian-package.sh` to make an x86 Debian package for the release
- Debian packages should be done after you make manpages, because those are included in Debian packages
- `lintian` is an optional dependency, it's not needed to build the .deb
- Upload .deb to Gitea release
- Add SHA256 checksum of .deb to release
- Use util/build-debian-package-ARM.sh (does this still work?) to make an ARM Debian package for the release
- Upload the debian packages to the Gitea release page, with SHA256 sums
- Figure out how to update https://faq.hush.is/rpc/ for new release
- Update the rpc.hush.is repo for new release by [following these instructions](https://git.hush.is/hush/rpc.hush.is/src/branch/master/README.md)
- Update https://faq.hush.is/rpc/ for new release after updating the rpc.hush.is repo
## Platform-specific notes
Use `./util/build-mac.sh` to compile on Apple/Mac systems, use `./util/build-win.sh` to build on Windows and `./util/build-arm.sh` to build on ARMv8 systems.
Use `./util/build-debian-package.sh aarch64` to build a Debian package for aarch64 .
- Use `./util/build-mac.sh` to compile on Apple/Mac systems
- Use `./util/build-win.sh` to build on Windows
- Use [these cross compile instructions](https://git.hush.is/jahway603/hush-docs/src/branch/master/advanced/cross-compile-hush-full-node-to-aarch64-with-docker.md) to build the release for ARMv8 (aarch64) systems, as the current build system does not permit us to natively build this on the SBC device
- Then use `./util/build-debian-package.sh aarch64` to build a Debian package for ARMv8 (aarch64)
## Optional things

View File

@@ -10,8 +10,11 @@ and no longer on Github, since they banned Duke Leto and
also because they censor many people around the world and work with
evil organizations.
# Hush 3.10.3 ""
# Hush 3.10.3 "Persistent Pezoporus"
* Use WolfSSL 4.8.1 which prevents nodes from getting stuck in general and when shutting down
* Set minimum fee to 0.1 HUSH per 1 KB of data if `OP_RETURN` is used.
* A feature in absurd fee that allows sending amount < fee, can be used only in a full node by advanced users.
* Fixed various bugs relating to lock ordering and missing locks
* Fixed RPC docs for addnode and disconnectnode having the incorrect port for HACs
* Value of DEBUG_LOCKORDER is now logged to debug.log on node startup
@@ -20,6 +23,9 @@ evil organizations.
* Hush nodes now have their own protocol version which is independent from HACs
* Fixed off-by-one bug in `newSietchRecipient`
* Performance improvement to `ActivateBestChainStep` https://git.hush.is/hush/hush3/commit/ed86f2dd1da370fe2dbf7db475afc41b218cbc5f
* Improved navigation in README for new users.
* Updated doc/release-process.md to resolve Issue #407
* Added build.sh checks for as and ld to be installed to resolve Issue #73
# Hush 3.10.2 "Fiendish Fenrir"

View File

@@ -11,10 +11,10 @@
// Each line contains a BIP155 serialized address.
//
static const uint8_t chainparams_seed_main[] = {
0x01,0x04,0x5b,0xd0,0x7f,0x51,0x00,0x00, // 91.208.127.81
0x01,0x04,0x57,0xfb,0x4c,0xa6,0x00,0x00, // 87.251.76.166
0x01,0x04,0x2d,0x52,0x44,0xe9,0x00,0x00, // 45.82.68.233
0x01,0x04,0x57,0xfb,0x4c,0x21,0x00,0x00, // 87.251.76.33
0x01,0x04,0x67,0x45,0x80,0x94,0x00,0x00, // 103.69.128.148
0x01,0x04,0xc2,0x1d,0x64,0xd0,0x00,0x00, // 194.29.100.208
0x01,0x04,0x2d,0x84,0x4b,0x45,0x00,0x00, // 45.132.75.69
0x01,0x04,0xaa,0xcd,0x27,0x27,0x00,0x00, // 170.205.39.39
0x01,0x04,0xb2,0xfa,0xbd,0x8d,0x00,0x00, // 178.250.189.141
0x01,0x04,0x95,0x1c,0x66,0xdb,0x00,0x00, // 149.28.102.219
0x01,0x04,0x9b,0x8a,0xe4,0x44,0x00,0x00, // 155.138.228.68
@@ -22,8 +22,11 @@ static const uint8_t chainparams_seed_main[] = {
0x04,0x20,0xef,0xad,0x0c,0x95,0x3e,0x61,0xee,0x69,0x57,0x67,0xdb,0x4f,0xb7,0x8d,0xc2,0x35,0x1c,0x6b,0x96,0xf4,0x1f,0x7a,0xb4,0x06,0x09,0x3a,0x64,0x33,0xf4,0x0b,0x2c,0x94,0x00,0x00, // 56wqzfj6mhxgsv3h3nh3pdocguogxfxud55libqjhjsdh5alfsko2iqd.onion
0x04,0x20,0x3d,0x24,0x7a,0xec,0xfe,0x60,0x6e,0x3d,0x3d,0xf3,0x4f,0x35,0x12,0x29,0xdb,0x48,0x89,0x71,0x19,0xb9,0xee,0x6a,0xfd,0xb2,0x02,0xa7,0x99,0x89,0xbb,0x69,0x39,0xdb,0x00,0x00, // hushv3h6mbxd2pptj42reko3jcexcgnz5zvp3mqcu6myto3jhhn4yzyd.onion
0x04,0x20,0x3d,0x24,0x7a,0xee,0xf5,0x39,0x20,0x7e,0x69,0x92,0xda,0xc7,0xa6,0x9f,0xbd,0xeb,0x29,0x21,0x20,0x93,0x52,0x03,0xf3,0x60,0x41,0xfc,0xb8,0xf9,0x06,0x29,0x96,0x24,0x00,0x00, // hushv3xvheqh42ms3ld2nh555muscietkib7gycb7s4psbrjsysfywqd.onion
0x02,0x10,0x2a,0x0c,0xb6,0x41,0x06,0xf1,0x00,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00, // 2a0c:b641:6f1:34::2
0x02,0x10,0x2a,0x0c,0xb6,0x41,0x06,0xf1,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00, // 2a0c:b641:6f1:c::2
0x02,0x10,0x2a,0x0c,0xb6,0x41,0x06,0xf1,0x01,0x8e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00, // 2a0c:b641:6f1:18e::2
0x02,0x10,0x24,0x06,0xef,0x80,0x00,0x03,0x12,0x69,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, // 2406:ef80:3:1269::1
0x02,0x10,0x24,0x06,0xef,0x80,0x00,0x02,0x3b,0x59,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, // 2406:ef80:2:3b59::1
0x02,0x10,0x24,0x06,0xef,0x80,0x00,0x01,0x14,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, // 2406:ef80:1:146e::1
0x02,0x10,0x24,0x06,0xef,0x80,0x00,0x04,0x21,0x32,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, // 2406:ef80:4:2132::1
0x05,0x20,0xfb,0xa8,0xca,0x3d,0xf4,0xc9,0x83,0x95,0xa8,0x07,0x05,0x6f,0xf8,0x46,0x69,0x6d,0x42,0x75,0x22,0xe9,0x80,0xd8,0x43,0x7c,0xbe,0x29,0xda,0x33,0x14,0xf9,0xfb,0x17,0x00,0x00, // 7oumuppuzgbzlkahavx7qrtjnvbhkixjqdmeg7f6fhndgfhz7mlq.b32.i2p
};

View File

@@ -479,7 +479,6 @@ std::string HelpMessage(HelpMessageMode mode)
if (showDebug)
strUsage += HelpMessageOpt("-mintxfee=<amt>", strprintf("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)",
CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK())));
strUsage += HelpMessageOpt("-opretmintxfee=<amt>", strprintf(_("Minimum fee (in %s/kB) to allow for OP_RETURN transactions (default: %s)"), CURRENCY_UNIT, 400000 ));
strUsage += HelpMessageOpt("-paytxfee=<amt>", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK())));
// If this is used incorrectly (-rescanheight too large), then the local wallet may attempt to spend funds which it does not have witness data about
// which will cause a "missing inputs" error when added to the mempool. Rescanning from correct height will fix this.

View File

@@ -1948,7 +1948,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
dFreeCount += nSize;
}
fRejectAbsurdFee = false;
if ( fRejectAbsurdFee && nFees > ::minRelayTxFee.GetFee(nSize) * 10000 && nFees > nValueOut/19)
// Disable checks for absurd fees when adding to the mempool. Instead, this check is done
// when a user attempts to make a transaction with an absurd fee and only rejects absurd
// fees when OP_RETURN data is NOT being used. This means users making normal financial
// transactions (z2z) are protected from absurd fees, it is only users who are storing
// arbitrary data via a z2t transaction are allowed to (or potentially required) to pay high fees
// It would be nice to detect the use of OP_RETURN right here but it seems to only be known
// inside of IsStandard() inside of IsStandardTx() and we want to avoid doing expensive checks
// multiple times.
{
string errmsg = strprintf("absurdly high fees %s, %d > %d",
hash.ToString(),
@@ -1956,7 +1966,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
LogPrint("mempool", errmsg.c_str());
return state.Error("AcceptToMemoryPool: " + errmsg);
}
//fprintf(stderr,"addmempool 6\n");
//fprintf(stderr,"addmempool 6\n");
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.

View File

@@ -476,14 +476,10 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
// fprintf(stderr,"%s: nTxSize = %u\n", __func__, nTxSize);
// Opret spam limits
if (mapArgs.count("-opretmintxfee"))
const bool opretminfee = true;
if (opretminfee)
{
CAmount n = 0;
CFeeRate opretMinFeeRate;
if (ParseMoney(mapArgs["-opretmintxfee"], n) && n > 0)
opretMinFeeRate = CFeeRate(n);
else
opretMinFeeRate = CFeeRate(400000); // default opretMinFeeRate (1 HUSH per 250 Kb = 0.004 per 1 Kb = 400000 puposhis per 1 Kb)
CFeeRate opretMinFeeRate = CFeeRate(10000000); // default opretMinFeeRate 0.1 HUSH
bool fSpamTx = false;
unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
@@ -502,9 +498,13 @@ CBlockTemplate* CreateNewBlock(CPubKey _pk,const CScript& _scriptPubKeyIn, int32
}
}
if ((nTxOpretSize > 256) && (feeRate < opretMinFeeRate)) fSpamTx = true;
// std::cerr << tx.GetHash().ToString() << " nTxSize." << nTxSize << " nTxOpretSize." << nTxOpretSize << " feeRate." << feeRate.ToString() << " opretMinFeeRate." << opretMinFeeRate.ToString() << " fSpamTx." << fSpamTx << std::endl;
if (fSpamTx) continue;
// opreturns of this size or smaller get amnesty and do not have to pay increased fees
int amnestySize = 128;
if ((nTxOpretSize > amnestySize) && (feeRate < opretMinFeeRate)) {
fSpamTx = true;
std::cerr << __func__ << ": " << tx.GetHash().ToString() << " nTxSize=" << nTxSize << " nTxOpretSize=" << nTxOpretSize << " feeRate=" << feeRate.ToString() << " opretMinFeeRate=" << opretMinFeeRate.ToString() << " fSpamTx=" << fSpamTx << std::endl;
continue;
}
// std::cerr << tx.GetHash().ToString() << " vecPriority.size() = " << vecPriority.size() << std::endl;
}

View File

@@ -25,9 +25,14 @@
#include <boost/foreach.hpp>
#include <boost/thread.hpp>
#ifdef _WIN32
#include <windows.h>
#include <dbghelp.h>
#else
#include <execinfo.h> /* backtrace, backtrace_symbols_fd */
#include <unistd.h> /* STDOUT_FILENO */
#endif
#include <unistd.h> /* STDOUT_FILENO */
#ifdef DEBUG_LOCKCONTENTION
void PrintLockContention(const char* pszName, const char* pszFile, int nLine)

View File

@@ -5155,6 +5155,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
CAmount nTotalOut = 0;
// Optional OP_RETURN data
CScript opret;
// TODO: enforce that only a single opreturn exists
UniValue opretValue;
bool containsSaplingOutput = false;
@@ -5189,7 +5191,10 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
// throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+address);
setAddress.insert(address);
UniValue opretValue = find_value(o, "opreturn");
UniValue this_opret = find_value(o, "opreturn");
if (!this_opret.isNull()) {
opretValue = this_opret;
}
// Create the CScript representation of the OP_RETURN
if (!opretValue.isNull()) {
@@ -5342,12 +5347,18 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
// or anything less than nDefaultFee instead of being forced to use a custom fee and leak metadata
if (nTotalOut < nDefaultFee) {
if (nFee > nDefaultFee) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Small transaction amount %s has fee %s that is greater than the default fee %s", FormatMoney(nTotalOut), FormatMoney(nFee), FormatMoney(nDefaultFee)));
// Allow large fees if OP_RETURN is being used
if( opretValue.isNull() ) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Small transaction amount %s has fee %s that is greater than the default fee %s", FormatMoney(nTotalOut), FormatMoney(nFee), FormatMoney(nDefaultFee)));
}
}
} else {
// Check that the user specified fee is not absurd.
if (nFee > nTotalOut) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s and also greater than the default fee", FormatMoney(nFee), FormatMoney(nTotalOut)));
// Allow large fees if OP_RETURN is being used
if( opretValue.isNull() ) {
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee %s is greater than the sum of outputs %s and also greater than the default fee", FormatMoney(nFee), FormatMoney(nTotalOut)));
}
}
}
}

View File

@@ -17,6 +17,18 @@ if ! [ -x "$(command -v autoreconf)" ]; then
exit 1
fi
if ! [ -x "$(command -v as)" ]; then
echo 'Error: as is not installed. Install as and try again.' >&2
echo 'On Debian-like systems: apt install binutils' >&2
exit 1
fi
if ! [ -x "$(command -v ld)" ]; then
echo 'Error: ld is not installed. Install ld and try again.' >&2
echo 'On Debian-like systems: apt install binutils' >&2
exit 1
fi
function cmd_pref() {
if type -p "$2" > /dev/null; then
eval "$1=$2"