Pages:
Author

Topic: How to run your own P2Pool in Ubuntu 14.04 LTS with merged mining - page 4. (Read 54246 times)

sr. member
Activity: 295
Merit: 250
*sigh* I'm really starting to get irritated at the taste of humble pie ... fixed some display bugs in the script's output. New code in my post above.

Also, I just realized I can make this script work for updates, not just the initial installation. That is, if you run it a second time, it will just download and process updates, instead of resetting everything.  I'll start working on that too.
full member
Activity: 196
Merit: 100
Great stuff Kyros!

Will update the guide with your script sometime tomorrow!

Thanks for all your feedback.
sr. member
Activity: 295
Merit: 250
And behold! The entire guide, compressed into one install script. Smiley

Murdof, this basically replaces your download script.  It doesn't need sudo to run; instead, it handles the sudo requirement inside the script itself, and only for the system update portion. I also put all the source code downloads for the various daemons into a subdirectory, so they don't clutter the user's home dir.

You can also update your .gz file to only include the compiled binaries.  The "batch files" and config files are created by this script; they'll overwrite what's in your archive.

It's self-documenting, and fairly clear.  I've been using it over and over on a VM I made, to test different configurations, and I can't find any bugs.

Code:
#!/bin/bash

# A function to display help and exit.
Usage()
{
echo "$(basename $0): Downloads and installs bitcoind, p2pool, and other coins for merged mining." >&2
echo "Usage:" >&2
echo "To download precompiled binaries (faster but less secure):" >&2
echo "        $(basename $0) --download" >&2
echo "To download the source code and compile yourself (slower but more secure):" >&2
echo "        $(basename $0) --compile" >&2
echo "You may also choose to download the bitcoin blockchain via http. Add the following to the command line:" >&2
echo "        --http" >&2
echo "If you don't use this, the blockchain will instead download using the (much slower) built-in peer-to-peer process." >&2
echo >&2
exit 1
}

# Determine what the user wants to do, or display help
if [ $# -eq 0 ] ; then
Usage
else
while [ $# -gt 0 ] ; do
if [ "--download" = "$1" ] ; then
Method="download"
elif [ "--compile" = "$1" ] ; then
Method="compile"
# elif [ "--torrent" = "$1" ] ; then
# Blockchain="torrent"
elif [ "--http" = "$1" ] ; then
Blockchain="http"
else
echo "Error: Unrecognized parameter on command line. Aborting" >2
Usage
fi
shift
done
fi

# Make sure the user specified where to compile or download
if [ -z "$Method" ] ; then
echo "Error: No installation method specified (compile or download). Aborting" >2
Usage
fi

# Create a script to update the system.  This requires sudo, so we can't run it directly.

cat <~/sudoscript.sh
#!/bin/sh

# Install the pre-req for add-apt-repository
apt-get -y install software-properties-common

# Add the bitcoin repository
add-apt-repository -y ppa:bitcoin/bitcoin

# Update installed packages
apt-get -y update
apt-get -y dist-upgrade

# Install the needed prerequisites
# Note that bitcoind is always installed as a binary, not compiled.
apt-get -y install bitcoind python-software-properties screen git python-rrdtool python-pygame python-scipy python-twisted python-twisted-web python-imaging build-essential libglib2.0-dev libglibmm-2.4-dev libqt4-dev python-dev libssl-dev libdb5.1++-dev libboost1.55-all-dev dh-autoreconf libcurl4-openssl-dev libminiupnpc-dev ufw p7zip-full

# Set up and configure a firewall
# Note that we do NOT enable the RPC port for any coins!
ufw default deny    # Deny everything unless expressly permitted
ufw allow 22/tcp    # SSH
ufw allow 8333/tcp  # bitcoin peer to peer
ufw allow 8334/tcp  # namecoin peer to peer
ufw allow 8337/tcp  # ixcoin peer to peer
ufw allow 6334/tcp  # devcoin peer to peer
ufw allow 7337/tcp  # i0coin peer to peer
ufw allow 8492/tcp  # fusioncoin peer to peer
ufw allow 8398/tcp  # huntercoin peer to peer
ufw allow 9333/tcp  # P2pool peer to peer
ufw allow 9332/tcp  # P2Pool connections and Web interface
ufw --force enable  # Turn it on

EOF

echo "About to update your system.  This requires elevated privileges. Please enter your password when prompted."
sleep 3 # pause so the user has a chance to see and read the message.
sudo sh ~/sudoscript.sh
rm ~/sudoscript.sh

# Install p2pool
git clone git://github.com/forrestv/p2pool.git

# Now either download or compile the binaries.
if [ "$Method" = "download" ] ; then
# Download and unpack scripts and binaries for other coins
wget http://pool.nitro.gr/p2pool-files.tar.gz

# Ensure the compiled binaries archive is valid! This checksum has to be updated each time the binaries are repackaged.
# Too much manual work, Murdof can enable this if he wants to maintain it. (Switch "false" to "true")
if false; then
checksum="$(md5sum p2pool-files.tar.gz | awk '{print $1;}')"
if [ "$checksum" != "0e35d6a1ee234b1a90975588917275eb" ] ;  then
echo "ERROR: Downloaded binaries are corrupt or have been tampered with! Please try running this script again.  If this error repeats, please contact the script author here:" >&2
echo "https://bitcointalk.org/index.php?topic=651819.0" >&2
exit 3
fi
fi

Status="$Status\nDownload succeeded."

# Unpack the binaries and delete the downloaded archive.
tar xvzf p2pool-files.tar.gz
rm p2pool-files.tar.gz

elif [ "$Method" = "compile" ] ; then
# Make the local binaries directory
mkdir -p ~/bin

# Make a directory to download and store all the alt-coin sources
mkdir -p ~/coin_source

# Download and compile Namecoin.
cd ~/coin_source
git clone https://github.com/namecoin/namecoin
cd ~/coin_source/namecoin/src
make -f Makefile
if [ -f namecoind ] ; then
Status="$Status\nNamecoin compilation succeeded."
strip namecoind
cp namecoind ~/bin
else
Status="$Status\nNamecoin compilation FAILED."
fi

# Download and compile iXcoin.
cd ~/coin_source
git clone https://github.com/FrictionlessCoin/iXcoin
cd ~/coin_source/iXcoin/src
make -f makefile.unix
if [ -f ixcoind ] ; then
Status="$Status\nIxcoin compilation succeeded."
strip ixcoind
cp ixcoind ~/bin
else
Status="$Status\nIxcoin compilation FAILED."
fi

# Download and compile Devcoin.
cd ~/coin_source
git clone git://gitorious.org/devcoin/devcoin.git
cd ~/coin_source/devcoin/src
make -f makefile.unix USE_PNP=1 devcoind
if [ -f devcoind ] ; then
Status="$Status\nDevcoin compilation succeeded."
strip devcoind
cp devcoind ~/bin
else
Status="$Status\nDevcoin compilation FAILED."
fi

# Download and compile i0coin.
cd ~/coin_source
git clone http://github.com/rsnel/i0coin/
cd ~/coin_source/i0coin/src
make -f makefile.unix i0coind
if [ -f i0coind ] ; then
Status="$Status\ni0coin compilation succeeded."
strip i0coind
cp i0coind ~/bin
else
Status="$Status\ni0coin compilation FAILED."
fi

# Download and compile Fusioncoin.
cd ~/coin_source
git clone https://github.com/fusioncoin/fusioncoin
cd ~/coin_source/fusioncoin/src
make -f makefile.unix
if [ -f fusioncoind ] ; then
Status="$Status\nFusioncoin compilation succeeded."
strip fusioncoind
cp fusioncoind ~/bin
else
Status="$Status\nFusioncoin compilation FAILED."
fi

# Download and compile Huntercoin.
cd ~/coin_source
git clone https://github.com/chronokings/huntercoin
cd ~/coin_source/huntercoin/src
make -f Makefile
if [ -f huntercoind ] ; then
Status="$Status\nHuntercoin compilation succeeded."
strip huntercoind
cp huntercoind ~/bin
else
Status="$Status\nHuntercoin compilation FAILED."
fi

else
# This should never happen! It means there's an error in this script itself.
echo "Unhandled error! Bad programmer! No cookie!" >&2
exit 2
fi


# Make directories for everything
mkdir -p ~/.bitcoin
mkdir -p ~/.namecoin
mkdir -p ~/.ixcoin
mkdir -p ~/.devcoin
mkdir -p ~/.i0coin
mkdir -p ~/.fusioncoin
mkdir -p ~/.huntercoin

# Set up the various RPC usernames and passwords. Note that you never need to remember these; they just have to exist and be unguessable.
Bitcoin_User=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`
Bitcoin_Password=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`

Namecoin_User=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`
Namecoin_Password=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`

Ixcoin_User=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`
Ixcoin_Password=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`

Devcoin_User=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`
Devcoin_Password=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`

i0coin_User=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`
i0coin_Password=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`

Fusioncoin_User=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`
Fusioncoin_Password=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`

Huntercoin_User=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`
Huntercoin_Password=`< /dev/urandom tr -dc A-Za-z0-9 | head -c40`


# Create the various configuration files
cat >~/.bitcoin/bitcoin.conf <server=1
daemon=1
rpcuser=$Bitcoin_User
rpcpassword=$Bitcoin_Password
rpcallowip=127.0.0.1

EOF

cat >~/.namecoin/namecoin.conf <server=1
daemon=1
rpcuser=$Namecoin_User
rpcpassword=$Namecoin_Password
port=8334
rpcport=7333
rpcallowip=127.0.0.1

EOF

cat >~/.ixcoin/ixcoin.conf <server=1
daemon=1
rpcuser=$Ixcoin_User
rpcpassword=$Ixcoin_Password
port=8337
rpcport=8338
rpcallowip=127.0.0.1

EOF

cat >~/.devcoin/devcoin.conf <server=1
daemon=1
rpcuser=$Devcoin_User
rpcpassword=$Devcoin_Password
rpcport=6333
port=6334
rpcallowip=127.0.0.1

EOF

cat >~/.i0coin/i0coin.conf <server=1
daemon=1
rpcuser=$i0coin_User
rpcpassword=$i0coin_Password
port=7337
rpcport=7338
rpcallowip=127.0.0.1

EOF

cat >~/.fusioncoin/fusioncoin.conf <server=1
daemon=1
rpcuser=$Fusioncoin_User
rpcpassword=$Fusioncoin_Password
port=8492
rpcport=18491
rpcallowip=127.0.0.1

EOF

cat >~/.huntercoin/huntercoin.conf <server=1
daemon=1
rpcuser=$Huntercoin_User
rpcpassword=$Huntercoin_Password
port=8398
rpcport=8399
rpcallowip=127.0.0.1

EOF


# Create the startup script for all coins and p2pool.
cat >~/start-p2pool <#!/bin/sh
/usr/bin/bitcoind -daemon
~/bin/namecoind -daemon
~/bin/ixcoind -daemon
~/bin/devcoind -daemon >/dev/null # For some reason, devcoin writes to the terminal, even when started as a daemon.
~/bin/i0coind -daemon
~/bin/fusioncoind -daemon
~/bin/huntercoind -daemon
screen -d -m -S p2pool \
~/p2pool/run_p2pool.py $Bitcoin_User $Bitcoin_Password \
--merged http://$Namecoin_User:[email protected]:7333 \
--merged http://$Ixcoin_User:[email protected]:8338 \
--merged http://$Devcoin_User:[email protected]:6333 \
--merged http://$i0coin_User:[email protected]:7338 \
--merged http://$Fusioncoin_User:[email protected]:18491 \
--merged http://$Huntercoin_User:[email protected]:8399

EOF
chmod 755 ~/start-p2pool


# Create a script to list the value of all coin wallets.
cat >~/listallcoins <#!/bin/sh
echo "BTC: \$(/usr/bin/bitcoind -rpcpassword=$Bitcoin_Password listaccounts | awk '{getline; print \$NF;exit;}')"
echo "NMC: \$(~/bin/namecoind -rpcpassword=$Namecoin_Password listaccounts | awk '{getline; print \$NF;exit;}')"
echo "IXC: \$(~/bin/ixcoind -rpcpassword=$Ixcoin_Password listaccounts | awk '{getline; print \$NF;exit;}')"
echo "DVC: \$(~/bin/devcoind -rpcpassword=$Devcoin_Password listaccounts | awk '{getline; print \$NF;exit;}')"
echo "I0C: \$(~/bin/i0coind -rpcpassword=$i0coin_Password listaccounts | awk '{getline; print \$NF;exit;}')"
echo "FSC: \$(~/bin/fusioncoind -rpcpassword=$Fusioncoin_Password listaccounts | awk '{getline; print \$NF;exit;}')"
echo "Huntercoin: \$(~/bin/huntercoind -rpcpassword=$Huntercoin_Password listaccounts | awk '{getline; print \$NF;exit;}')"

EOF
chmod 755 ~/listallcoins


# If requested, download the blockchain.
if [ "$Blockchain" = "http" ] ; then
cd ~/.bitcoin

#wget https://bitfetch.com/static/bootstrap.7z
# Note: as of this writing, the SSL certificate for bitfetch.com has expired.
# If you just try to wget the file, wget will fail, complaining about it.
# So, we have to force wget to ignore the expired certificate. Once the
# certificate on the site has been properly renewed, delete the line below
# and uncomment the line above.
wget --no-check-certificate https://bitfetch.com/static/bootstrap.7z

# unzip it.
7z x bootstrap.7z
#elif [ "$Blockchain" = "torrent" ] ; then
# @TODO: No clue how torrenting works on Unix. Someone else can fill this in.
fi


# Wrap up; tell the user we succeeded, and ask him to reboot.
echo
echo
echo
echo "Installation results:"
echo -e "$Status"
echo
echo "It is strongly advised that you reboot at this point. After rebooting,"
echo "start p2pool and all the coin daemons with this command:"
echo "      ~/start-p2pool"
echo
echo "You may also add this line to your cron so it starts automatically:"
echo "      @reboot $HOME/start-p2pool"
echo
echo "You may check your coin balances at any time with this command:"
echo "      ~/listallcoins"
echo
echo "Thank you for helping to protect the bitcoin network by participating"
echo "in p2pool, and good luck with your mining!"



Edit: This script also removes the need for the chmod commands you added to the lazy install.
Edit 2: I've been testing this with Ubuntu 14.04 desktop, so yup, it does work with that. Smiley It should be identical on a server install, too.
full member
Activity: 196
Merit: 100
The huntercoin bug appears to be fixed in git.  I cloned the repository, and the missing include file is now in there.

Year already have updated binaries and included the guise how to compile it.
member
Activity: 118
Merit: 100
Do you need miners to run this ?
sr. member
Activity: 295
Merit: 250
The huntercoin bug appears to be fixed in git.  I cloned the repository, and the missing include file is now in there.
zvs
legendary
Activity: 1680
Merit: 1000
https://web.archive.org/web/*/nogleg.com
You could run it on a VPS w/ 2 GB of (dedicated, not shared) RAM, but I suspect you'd have to edit the source to block all transactions, or set the correct variables (limitfreerelay in bitcoin?)....   limitfreerelay I believe is what would stop the transactions from even entering memory, unlike maxblocksize.
full member
Activity: 196
Merit: 100
Hey KyrosKrane,

i integrated your suggestions.

About daemon i don't think it is needed cause i declare it in the config files.
I've been using it like that and of course i'm not logged in all day long Smiley

Thanks for the feedback - keep it coming.

Also about the rpcpasswords since this is something that is used only locally i don't think it really matters.
But on the other hands everyone can just edit the password and set up their own.
So I don't know if it is worth it to add randomized passwords.
sr. member
Activity: 295
Merit: 250
Also just noticed you added a section on the firewall.  Two things there.

1) You never actually install ufw.  You have to add it to the apt-get line.
2) You don't open ports for any of the alt-coins.  They won't connect to peers if you don't do that.  Here's the revised list.

Code:
# Set up and configure a firewall
# Note that we do NOT enable the RPC port for any coins!
sudo ufw default deny    # Deny everything unless expressly permitted
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 8333/tcp  # bitcoin peer to peer
sudo ufw allow 8334/tcp  # namecoin peer to peer
sudo ufw allow 8337/tcp  # ixcoin peer to peer
sudo ufw allow 6334/tcp  # devcoin peer to peer
sudo ufw allow 7337/tcp  # i0coin peer to peer
sudo ufw allow 8492/tcp  # fusioncoin peer to peer
sudo ufw allow 9333/tcp  # P2pool peer to peer
sudo ufw allow 9332/tcp  # P2Pool connections and Web interface
sudo ufw --force enable  # Turn it on

That said, you might want to consider sticking all that in a shell script and calling that with sudo, rather than using sudo on each individual command.
sr. member
Activity: 295
Merit: 250
Caught another error.  In the section for creating start-p2pool, you have this:

Code:
cat >~/start-p2pool
/usr/bin/bitcoind
/home/mine/bin/ixcoind
/home/mine/bin/namecoind
/home/mine/bin/devcoind

You should change the paths from /home/mine to ~.  Also you should add -daemon after each one; otherwise the process will terminate as soon as you log out of that machine.  Finally, you forgot to start i0coin. So, something like this:

Code:
/usr/bin/bitcoind -daemon
~/bin/namecoind -daemon
~/bin/ixcoind -daemon
~/bin/devcoind -daemon
~/bin/i0coind -daemon
~/bin/fusioncoind -daemon # only if you enabled that too
hero member
Activity: 924
Merit: 1000
Watch out for the "Neg-Rep-Dogie-Police".....
I was merge mining BTC, NMC, FSC, DVC, I0C, IXC, GRP & HUC using 16GB RAM on a unlocked & OC'd 65W Phenom Quad-core quite comfortably with a constant 0.2 sec bitcoind latency.

I say "was" because I have recently sold my last remaining p2pool compatible hardware (S1's) due to the cost of electricity here in the UK making them non profitable at the current BTC rate. All my remaining hardware - S2's, Dragons etc don't work with p2pool - so I am now forced to ditch running my node after nearly 3 years of p2pool mining.......

Sad days indeed  Embarrassed

I suggest inserting "--give-author 0" into the code on this guide, as it is because of the lack of development that I am forced to quit mining with p2pool after all this time. Unless Kano can work his magic, or something remarkable happens to the p2pool code, it's not looking like I or many others will be able to get back to supporting & mining with p2pool.

Peace.
full member
Activity: 124
Merit: 251
Murdof, how much of your RAM are you actually using on p2pool and Bitcoin client (aswell as the server OS)?

If you plan to run a P2Pool node with merged mining that actually gets a decent amount of traffic, plan on at least 4GB, minimum. In fact, you might out of memory on that pretty easily. I know I certainly have.


Most VPS providers allow you to exceed the allocated memory by atleast 10-20% anyway Wink

If you're using a VPS provider that allows you to go over your set RAM limit, I would stay far far away from them.
full member
Activity: 196
Merit: 100
Thanks Kyros!

Please do go ahead and make the changes.

Post them here and I will be happy to integrate them!
sr. member
Activity: 295
Merit: 250
OK, so I threw together a VM and loaded Ubuntu Desktop 14.04 on it.

Next I ran the two "lazy install" commands -- but they failed.

Code:
./install-p2pool.sh: 5: ./install-p2pool.sh: aptitude: not found
./install-p2pool.sh: 6: ./install-p2pool.sh: git: not found

So, two things.

First, use apt-get, not aptitude.  apt-get will work fine on both server and desktop versions of Ubuntu. (I'm guessing that aptitude is installed by default on the server version; but it's not on the desktop version.)

Second, I'd suggest reordering the commands in the script as follows. Yes, I added comments. Smiley

Code:
#!/bin/bash

# Install the pre-req for add-apt-repository
apt-get -y install software-properties-common

# Add the bitcoin repository
add-apt-repository -y ppa:bitcoin/bitcoin

# Update installed packages
apt-get -y update
apt-get -y dist-upgrade

# Install bitcoind and other needed prerequisites
apt-get -y install bitcoind python-software-properties screen git python-rrdtool python-pygame python-scipy python-twisted python-twisted-web python-imaging build-essential libglib2.0-dev libglibmm-2.4-dev libqt4-dev python-dev libssl-dev libdb5.1++-dev libboost1.55-all-dev dh-autoreconf libcurl4-openssl-dev libminiupnpc-dev

# Install p2pool
git clone git://github.com/forrestv/p2pool.git

# Download and unpack scripts and binaries for other coins
wget http://pool.nitro.gr/p2pool-files.tar.gz
tar xvzf p2pool-files.tar.gz
rm p2pool-files.tar.gz

My one biggest concern is that the RPC passwords are hardcoded in your config files. While it's true you limit connections to 127.0.0.1, that still makes me nervous. I really suggest randomizing the passwords.  You can use something similar to what I have in my script; I'd be happy to adapt the logic for your script if you like.

I'd also strongly suggest that you incorporate the bootstrap download logic I have in my script -- that will shave off days of download time for the bitcoin blockchain. I'd even suggest you consider setting it up as a bittorrent download, although if someone uses this script on a VPS, they could get in trouble if their VPS provider doesn't allow torrents.  Http is safer in that sense, but less "polite" on the network.  Maybe prompt the user whether they'd like to download the blockchain via torrent, via http, or via the normal bitcoind client download?  And set the client download as the default option, as that's the "safest."

Finally, I'd suggest putting the "screen" commands and other useful scripts you mention later in your guide into shell scripts that are also included in the tar file.  Essentially you want it to be similar to a Windows install -- download the installer, run it, and magically p2pool works, with easy-to-use commands all ready to use.

More as I play further with this setup.
sr. member
Activity: 434
Merit: 250
see for yourself; http://pool.centralcavern.uk:9332/

 Smiley

looks ok to me.. how is yours locally?

3.18TH/s (1.7% DOA)

so that is a bit of difference

very good indeed.please always mine p2pool  Grin
legendary
Activity: 889
Merit: 1000
Bitcoin calls me an Orphan
see for yourself; http://pool.centralcavern.uk:9332/

 Smiley

looks ok to me.. how is yours locally?

3.18TH/s (1.7% DOA)

so that is a bit of difference
sr. member
Activity: 434
Merit: 250
see for yourself; http://pool.centralcavern.uk:9332/

 Smiley

looks ok to me.. how is yours locally?
legendary
Activity: 889
Merit: 1000
Bitcoin calls me an Orphan

definitely, 100% agree, unfortunately I don't have the ability to run a local node, so VPS is a good option for folks like me.
and with murdof's guide and how-to, those who can, can, and those who can't, can too!

Since i have no done it with bitcoin on a VPS.. how are the results? Are you seeing a lot more stales/DOA?
sr. member
Activity: 434
Merit: 250
While memory used to be more expensive, it is stil nice to know what the actual requirements are.

I would therefore think it is fair to say that you should get away with a 3 GB Ram VPS safely.

Most VPS providers allow you to exceed the allocated memory by atleast 10-20% anyway Wink

Totally passed up the idea of a VPS concept.. good point.. though i like to keep my memory on a even number Smiley call me old fashioned. 4GB Ram would be ideal and yes I have run it on a vps at 4GB and no problems.. course it was for litecoin

The only reason I stay away from VPS is i want something local. Local is always the best results with p2pool shares

definitely, 100% agree, unfortunately I don't have the ability to run a local node, so VPS is a good option for folks like me.
and with murdof's guide and how-to, those who can, can, and those who can't, can too!
legendary
Activity: 889
Merit: 1000
Bitcoin calls me an Orphan
While memory used to be more expensive, it is stil nice to know what the actual requirements are.

I would therefore think it is fair to say that you should get away with a 3 GB Ram VPS safely.

Most VPS providers allow you to exceed the allocated memory by atleast 10-20% anyway Wink

Totally passed up the idea of a VPS concept.. good point.. though i like to keep my memory on a even number Smiley call me old fashioned. 4GB Ram would be ideal and yes I have run it on a vps at 4GB and no problems.. course it was for litecoin

The only reason I stay away from VPS is i want something local. Local is always the best results with p2pool shares
Pages:
Jump to: