Bitcoin Forum
March 19, 2024, 05:06:25 AM *
News: Latest Bitcoin Core release: 26.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 [52] 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 ... 814 »
  Print  
Author Topic: [1500 TH] p2pool: Decentralized, DoS-resistant, Hop-Proof pool  (Read 2591571 times)
spiccioli
Legendary
*
Offline Offline

Activity: 1378
Merit: 1003

nec sine labore


View Profile
February 29, 2012, 01:29:54 PM
 #1021

Hi,

does p2pool support RollNTime extension to miners?

spiccioli.
1710824785
Hero Member
*
Offline Offline

Posts: 1710824785

View Profile Personal Message (Offline)

Ignore
1710824785
Reply with quote  #2

1710824785
Report to moderator
1710824785
Hero Member
*
Offline Offline

Posts: 1710824785

View Profile Personal Message (Offline)

Ignore
1710824785
Reply with quote  #2

1710824785
Report to moderator
The trust scores you see are subjective; they will change depending on who you have in your trust list.
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1063


Gerald Davis


View Profile
February 29, 2012, 01:44:41 PM
Last edit: February 29, 2012, 02:58:50 PM by DeathAndTaxes
 #1022

Hi,

does p2pool support RollNTime extension to miners?

spiccioli.


No I don't believe it does.  However there is really no reason.
I was 100% wrong.  p2pool DOES support RollNTime but as indicated below it likely doesn't have that much of an impact.

RollNTime is useful to reduce # of getworks per share.

A 400 MH/s miner mining diff 1 shares:
2^32 / (400 * 1000^2) = ~10s.

So every 10 seconds this miner will need one getwork.  Having a rolling of say 60 seconds would require 1/6th the getworks.

p2pool has an average time between LP of 10 seconds.  Most GPU will never finish a single nonce range before an LP so they will never get a chance to roll the ntime.  (D&T tip of the day: this is why in cgminer it is optimal to reduce intensity by 1, and set # of threads per GPU and queue depth both to 1)

Even with 400 MH/s GPU RollNTime would only reduce getworks on the rounds that are > 10 seconds.  If you are using 2 threads and say a 250 MH/s GPU it would only reduce getworks on the rounds that are > 32 seconds.  Also the workload is relatively small since you are hosting your own "pool server".  A pool server like Deepbit (~3TH/s) has to issue roughly 700 getworks per second.  Using RollNTime can reduce that significantly.  Looks like you have ~9GH/s.  Without RollNTime that requires only ~2 getworks per second.  An underclocked single core Atom CPU could handle that with minimal CPU load %.
twmz
Hero Member
*****
Offline Offline

Activity: 737
Merit: 500



View Profile
February 29, 2012, 01:52:43 PM
 #1023

does p2pool support RollNTime extension to miners?
No I don't believe it does.  However there is really no reason.

All of your reasons for why it doesn't matter are correct but you are wrong that it isn't supported.  But, p2pool does use RollNTime (with a 10 second expiration).

Was I helpful?  1TwmzX1wBxNF2qtAJRhdKmi2WyLZ5VHRs
WoT, GPG

Bitrated user: ewal.
spiccioli
Legendary
*
Offline Offline

Activity: 1378
Merit: 1003

nec sine labore


View Profile
February 29, 2012, 01:53:39 PM
 #1024

Hi,

does p2pool support RollNTime extension to miners?

spiccioli.


No I don't believe it does.  However there is really no reason.



Thanks for the explanation Death&Taxes.

spiccioli
spiccioli
Legendary
*
Offline Offline

Activity: 1378
Merit: 1003

nec sine labore


View Profile
February 29, 2012, 01:56:11 PM
 #1025

does p2pool support RollNTime extension to miners?
No I don't believe it does.  However there is really no reason.

All of your reasons for why it doesn't matter are correct but you are wrong that it isn't supported.  But, p2pool does use RollNTime (with a 10 second expiration).

twmz,

wait, it should have longer timeouts for longer rounds, if a round lasts less than 10 seconds the miner will throw away current getwork anyway, so while does it limit RollNTime to 10 seconds?

spiccioli
twmz
Hero Member
*****
Offline Offline

Activity: 737
Merit: 500



View Profile
February 29, 2012, 01:58:55 PM
 #1026

wait, it should have longer timeouts for longer rounds, if a round lasts less than 10 seconds the miner will throw away current getwork anyway, so while does it limit RollNTime to 10 seconds?

I don't know (ask forrest), but it does.  I just looked at the HTTP header it returns and it says 10 seconds.

Was I helpful?  1TwmzX1wBxNF2qtAJRhdKmi2WyLZ5VHRs
WoT, GPG

Bitrated user: ewal.
forrestv (OP)
Hero Member
*****
Offline Offline

Activity: 516
Merit: 643


View Profile
February 29, 2012, 02:46:29 PM
 #1027

wait, it should have longer timeouts for longer rounds, if a round lasts less than 10 seconds the miner will throw away current getwork anyway, so while does it limit RollNTime to 10 seconds?

I don't know (ask forrest), but it does.  I just looked at the HTTP header it returns and it says 10 seconds.

It's so a miner can roll the work locally so that they only have to do one getwork to get enough work for all their cards. I think CGminer does this when it receives a long poll.

1J1zegkNSbwX4smvTdoHSanUfwvXFeuV23
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1063


Gerald Davis


View Profile
February 29, 2012, 02:56:39 PM
Last edit: February 29, 2012, 03:09:17 PM by DeathAndTaxes
 #1028

wait, it should have longer timeouts for longer rounds, if a round lasts less than 10 seconds the miner will throw away current getwork anyway, so while does it limit RollNTime to 10 seconds?

I don't know (ask forrest), but it does.  I just looked at the HTTP header it returns and it says 10 seconds.

It's so a miner can roll the work locally so that they only have to do one getwork to get enough work for all their cards. I think CGminer does this when it receives a long poll.

Hmm I wasn't aware of that.

I may be wrong (have already been wrong once in last 2 minutes) but I don't think cgminer splits a single getwork across threads.  IIRC it does 1 getwork per thread (so if you are running 8 GPU w/ 2 threads each it pulls 16 getworks).  That would be a useful optimization in cgminer.  

Technically though to optimize that wouldn't it need to either split the nonce range into sub nonce ranges or "cheat" (use slightly wrong time for each thread)?
rjk
Sr. Member
****
Offline Offline

Activity: 448
Merit: 250


1ngldh


View Profile
February 29, 2012, 02:57:36 PM
 #1029

wait, it should have longer timeouts for longer rounds, if a round lasts less than 10 seconds the miner will throw away current getwork anyway, so while does it limit RollNTime to 10 seconds?

I don't know (ask forrest), but it does.  I just looked at the HTTP header it returns and it says 10 seconds.

It's so a miner can roll the work locally so that they only have to do one getwork to get enough work for all their cards. I think CGminer does this when it receives a long poll.

I don't think cgminer splits 1 single getwork across cards.  I am pretty sure it does 1 getwork per thread (so if you are running 8 GPU w/ 2 threads each it pulls 16 getworks).  That would be one useful optimization in cgminer. 
Correct. cgminer really needs a work splitting engine, badly.

Mining Rig Extraordinaire - the Trenton BPX6806 18-slot PCIe backplane [PICS] Dead project is dead, all hail the coming of the mighty ASIC!
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1063


Gerald Davis


View Profile
February 29, 2012, 03:04:04 PM
 #1030

wait, it should have longer timeouts for longer rounds, if a round lasts less than 10 seconds the miner will throw away current getwork anyway, so while does it limit RollNTime to 10 seconds?

You can always modify your code (see doesn't open source rock) or maybe it can be added as a parameter but there might be unforeseen implications of an ultra long NTime that should be tested before adjusting the default network wide.

Most pools have an NTime of 60 sec or less and that is on chains with an average LP interval of 300 sec (BTC/NMC merged mining) or 600 sec (BTC only).  There likely should be some testing before changing NTime to larger than expected LP interval.   Lots of different miner software out there and they may make some assumptions/optimizations which may clash with NTime > expected LP interval.  Maybe not but given the small impact and low priority of a change testing seems wise.  Maybe I am just a code coward. Smiley
spiccioli
Legendary
*
Offline Offline

Activity: 1378
Merit: 1003

nec sine labore


View Profile
February 29, 2012, 04:47:35 PM
 #1031

wait, it should have longer timeouts for longer rounds, if a round lasts less than 10 seconds the miner will throw away current getwork anyway, so while does it limit RollNTime to 10 seconds?

You can always modify your code (see doesn't open source rock) or maybe it can be added as a parameter but there might be unforeseen implications of an ultra long NTime that should be tested before adjusting the default network wide.

Most pools have an NTime of 60 sec or less and that is on chains with an average LP interval of 300 sec (BTC/NMC merged mining) or 600 sec (BTC only).  There likely should be some testing before changing NTime to larger than expected LP interval.   Lots of different miner software out there and they may make some assumptions/optimizations which may clash with NTime > expected LP interval.  Maybe not but given the small impact and low priority of a change testing seems wise.  Maybe I am just a code coward. Smiley

DeathAndTaxes,

I was wrong as well in the way I thought RollNTime works

https://en.bitcoin.it/wiki/Getwork#rollntime

It seems to me now that 10 (seconds) is a good value for p2pool rounds.

spiccioli
Diapolo
Hero Member
*****
Offline Offline

Activity: 769
Merit: 500



View Profile WWW
February 29, 2012, 06:23:03 PM
 #1032

What happens, if I let p2pool running, but have no miner running? Will this help the network / will this generate any income?

Dia

Liked my former work for Bitcoin Core? Drop me a donation via:
1PwnvixzVAKnAqp8LCV8iuv7ohzX2pbn5x
bitcoin:1PwnvixzVAKnAqp8LCV8iuv7ohzX2pbn5x?label=Diapolo
twmz
Hero Member
*****
Offline Offline

Activity: 737
Merit: 500



View Profile
February 29, 2012, 07:01:15 PM
 #1033

What happens, if I let p2pool running, but have no miner running? Will this help the network / will this generate any income?

Dia

No, it will not generate any income, and I don't think it provides any practical help to the p2pool network.  At the same time, it doesn't really hurt anything, either.

Was I helpful?  1TwmzX1wBxNF2qtAJRhdKmi2WyLZ5VHRs
WoT, GPG

Bitrated user: ewal.
twmz
Hero Member
*****
Offline Offline

Activity: 737
Merit: 500



View Profile
February 29, 2012, 07:10:35 PM
 #1034

Another payment sent.

Here is the list of transactions:

2/28/12 - http://blockchain.info/tx/7f5658c8cd2868cfc87e1ed921be74b80c06b0cb8c60b98fa709b0a23d971c31
2/29/12 - http://blockchain.info/tx/02cfe0ee7caa9342127b6c2255e22033c386bc9863da9e837e45c0e3bb7ddbca

Was I helpful?  1TwmzX1wBxNF2qtAJRhdKmi2WyLZ5VHRs
WoT, GPG

Bitrated user: ewal.
shakti
Member
**
Offline Offline

Activity: 60
Merit: 10



View Profile
February 29, 2012, 07:12:26 PM
 #1035

Updated to latest Version but still getting weird errors sometimes :

[qouote]

2012-02-29 20:09:28.633938 RECV shares 0100a80100000066e30ead841d6283dbeb9fb65407effc8c5de7f5e77434b4543405ddd5e000419 10b0477a3e69488325b1e2311e959e3f95a1b39df3aed2df1bebeb3d0768340d8774e4ff192001d 358502809e70b847507b6d5a1a32b2897c35503c19...
2012-02-29 20:09:28.634282 > Traceback (most recent call last):
2012-02-29 20:09:28.634320 >   File "/usr/lib/python2.6/dist-packages/twisted/internet/selectreactor.py", line 146, in _doReadOrWrite
2012-02-29 20:09:28.634347 >     why = getattr(selectable, method)()
2012-02-29 20:09:28.634372 >   File "/usr/lib/python2.6/dist-packages/twisted/internet/tcp.py", line 460, in doRead
2012-02-29 20:09:28.634397 >     return self.protocol.dataReceived(data)
2012-02-29 20:09:28.634421 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/p2p.py", line 55, in new_dataReceived
2012-02-29 20:09:28.634445 >     old_dataReceived(data)
2012-02-29 20:09:28.634469 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/util/datachunker.py", line 40, in _DataChunker
2012-02-29 20:09:28.634494 >     wants = receiver.send(buf.get(wants))
2012-02-29 20:09:28.634518 > --- <exception caught here> ---
2012-02-29 20:09:28.634541 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/bitcoin/p2p.py", line 53, in dataReceiver
2012-02-29 20:09:28.634566 >     self.packetReceived(command, type_.unpack(payload))
2012-02-29 20:09:28.634590 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/p2p.py", line 68, in packetReceived
2012-02-29 20:09:28.634614 >     bitcoin_p2p.BaseProtocol.packetReceived(self, command, payload2)
2012-02-29 20:09:28.634638 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/bitcoin/p2p.py", line 66, in packetReceived
2012-02-29 20:09:28.634663 >     handler(**payload2)
2012-02-29 20:09:28.634686 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/p2p.py", line 199, in handle_shares
2012-02-29 20:09:28.634711 >     self.node.handle_shares([p2pool_data.Share.from_share(share, self.node.net, self) for share in shares], self)
2012-02-29 20:09:28.634736 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/data.py", line 124, in from_share
2012-02-29 20:09:28.634761 >     res = cls(net, peer, **share1a_type.unpack(share['contents']))
2012-02-29 20:09:28.634785 >   File "/home/grom/ltc/p2pool_clean/p2pool/p2pool/data.py", line 166, in __init__
2012-02-29 20:09:28.634809 >     raise ValueError('old share an hour after switch time')
2012-02-29 20:09:28.634833 > exceptions.ValueError: old share an hour after switch time
[/quote]


mining Ltc on p2pool

TravisE
Full Member
***
Offline Offline

Activity: 121
Merit: 100


View Profile
February 29, 2012, 07:29:17 PM
 #1036

Hmm, getting the same here with Litecoin, though it seems to not be quite as frequently as it was before upgrading.
TheHarbinger
Sr. Member
****
Offline Offline

Activity: 378
Merit: 250


Why is it so damn hot in here?


View Profile
March 01, 2012, 12:40:08 AM
 #1037

Over 300Gh/s now!   Grin

12Um6jfDE7q6crm1s6tSksMvda8s1hZ3Vj
martychubbs
Hero Member
*****
Offline Offline

Activity: 742
Merit: 503


View Profile
March 01, 2012, 04:22:56 PM
 #1038

Yet, I am not sold on hopping with P2P cause I have little hashes (2 GH) and I hop out before completed P2P share and thus get no credit?  I might not understand how it all works.

Hoppers like control and cutting edge tech, P2pool is all that but I don't know how to compare P2p shared against 1/difficulty that I use for non-p2pools.  And if I stop mining for 30-90 minutes, do I pickup on the P2p share where I left off or do I have to start a new share?  Anyone clear up my confusion?


There is no such thing as "progress" toward any share or block.  In the long run you will earn shares at the same rate.  You might hop in provide half the work required ON AVERAGE for a share and get a share (or two, or ten), and you may also hop in and get no shares.

In the LONG RUN yuor # of shares thus your compensation will be the same regardless of if you mine intermitently, intentionally hop in/out, or mine continually 24/7/365.

You can't work toward a share (any share in any pool) because there is no progress.  You either find a share or you don't.  Each hash is completely independent and the prior "chances" have no effect on the odds of finding a hash. 
There is no penalty to hopping PPLNS pools and p2p is no exception. 

It is "hop proof" in that you can never get greater than 100% PPS expected value.  You can't steal revenue from other miners (like you do in the Prop pools you hop) as each miner is paid fairly for the work they complete.


Thanks for the help DnT!  That was the answer I was looking for, using P2p compared to PPS while intentionally hop in/out....  Also, did you know I turned P4man to the darkside?  Anywho, thanks again... 


              ▄▄▄▄▄▄▄▄
          ▄▄████████████▄▄
       ▄████████████████████▄
     ▄██████████████▀█████████▄
   ▄███████████████   ██████████▄
  ▐█████████████████   ██████████▌
 ▐█████████████████▀    ██████████▌
 ███████████████▀        ██████████
▐████████████▀     ▄███   █████████▌
████████████    ▄████▀██▄███████████
██████████▀██▄████▀    █████████████
█████████   ███▀     ▄██████████████
▐█████████        ▄████████████████▌
 ██████████    ▄███████████████████
 ▐██████████   ███████████████████▌
  ▐██████████   █████████████████▌
   ▀██████████▄█████████████████▀
     ▀████████████████████████▀
       ▀████████████████████▀
          ▀▀████████████▀▀
              ▀▀▀▀▀▀▀▀




     █
    ██
   ████
  ██▌███
 ▐██▌███▌
 ███ ██▀▌
 ▀██ █▄██
 █▄█ ███▀
 ▀██ ██▄█
 █▄█ ███▌
  ██▌███
  ▐█▌██
   ▐█▌
    █
    █
     ▀
 




░░██████
░░██████
░░██████

░░░░░░░░░░░██████
░░░░░░░░░░░██████
░░░░░░░░░░░██████

██████
██████
██████

░░░░░░░░░░░░░░░░░░░██████
░░░░░░░░░░░░░░░░░░░██████
░░░░░░░░░░░░░░░░░░░██████
 







        ▄▄██████▄▄
       ▐██▀    ▀██▌
       ██        ██
       ██        ██
       ██        ██
      ██████████████
      █████  ███████     ██ 
  ██  █  ████████  █ ██   
      ███████  █████    ██   
      ██████████████
 








▄██▄
▀██▀         ▄██▄
             ▀██▀

       ▄██▄
       ▀██▀

           ▄██▄
  ▄██▄     ▀██▀
  ▀██▀
 


           ▄▄█▄▄   ▄
█▄        ████████▀▄
███      █████████▀
▐███▄    ████████▌
▄▄█████▄▄▄███████▌
  ▀█████████████
  ▄▄██████████▀
    ▄████████▀
▀▀████████▀
    ▀▀▀
 

    ▄█▀▀ ▄▄▄▄▄▄ ▀▀█▄
   ▐█▄████████████▄█▌
  ▐██████████████████▌
  █████▀▀▀████▀▀▀█████
 █████     ██     █████
▐██████▄▄▄████▄▄▄██████▌
 ████▄▀▀▀██████▀▀▀▄████
  ▀▀████        ████▀▀
      ▀▀        ▀▀
 

         █▀▀▄▄▄█▄
         █    ▀█▀
       ▄▄█▄▄
▄██▄▄████████▄▄██▄
█████▀▀████▀▀█████
 ███▄  ▄██▄  ▄███
  ▀████▀██▀████▀
    ▀███▄▄███▀
       ▀▀▀▀

██ ██ ██ ██

   ██ ██ ██

      ██ ██

      ██ ██
   
Homepage

      ██ ██

      ██ ██

   ██ ██ ██

██ ██ ██ ██
   
White Paper
DeathAndTaxes
Donator
Legendary
*
Offline Offline

Activity: 1218
Merit: 1063


Gerald Davis


View Profile
March 01, 2012, 04:55:51 PM
Last edit: March 01, 2012, 07:06:44 PM by DeathAndTaxes
 #1039

Thanks for the help DnT!  That was the answer I was looking for, using P2p compared to PPS while intentionally hop in/out....

Intentionally leaving mid round or not in the long run any fair pool pays 100% PPS (no more no less minus fees, stales, and downtime).  PPS, PPLNS, DGM, SMPPS, ESMPPS, CPPSRB all pay the same expected value per share.

p2pool is no different in this respect.
Schleicher
Hero Member
*****
Offline Offline

Activity: 675
Merit: 513



View Profile
March 01, 2012, 06:47:38 PM
 #1040

I just updated from Bitcoin 0.6.0 rc1 to rc2.
I have no idea what this error could mean:
Code:
2012-03-01 19:28:47.838000 Initializing work...
2012-03-01 19:28:47.868000 > Error:
2012-03-01 19:28:47.869000 > Traceback (most recent call last):
2012-03-01 19:28:47.869000 >   File "d:\python27\lib\site-packages\twisted\internet\defer.py", line 545, in _runCallbacks
2012-03-01 19:28:47.869000 >     current.result = callback(current.result, *args, **kw)
2012-03-01 19:28:47.869000 >   File "d:\python27\lib\site-packages\twisted\internet\defer.py", line 1095, in gotResult
2012-03-01 19:28:47.870000 >     _inlineCallbacks(r, g, deferred)
2012-03-01 19:28:47.870000 >   File "d:\python27\lib\site-packages\twisted\internet\defer.py", line 1037, in _inlineCallbacks
2012-03-01 19:28:47.870000 >     result = result.throwExceptionIntoGenerator(g)
2012-03-01 19:28:47.870000 >   File "d:\python27\lib\site-packages\twisted\python\failure.py", line 382, in throwExceptionIntoGenerator
2012-03-01 19:28:47.871000 >     return g.throw(self.type, self.value, self.tb)
2012-03-01 19:28:47.871000 > --- <exception caught here> ---
2012-03-01 19:28:47.871000 >   File "D:\forrestv-p2pool-b839ff8\p2pool\util\deferral.py", line 30, in f
2012-03-01 19:28:47.872000 >     result = yield func(*args, **kwargs)
2012-03-01 19:28:47.872000 >   File "d:\python27\lib\site-packages\twisted\internet\defer.py", line 1037, in _inlineCallbacks
2012-03-01 19:28:47.872000 >     result = result.throwExceptionIntoGenerator(g)
2012-03-01 19:28:47.873000 >   File "d:\python27\lib\site-packages\twisted\python\failure.py", line 382, in throwExceptionIntoGenerator
2012-03-01 19:28:47.873000 >     return g.throw(self.type, self.value, self.tb)
2012-03-01 19:28:47.873000 >   File "D:\forrestv-p2pool-b839ff8\p2pool\util\deferral.py", line 147, in __call__
2012-03-01 19:28:47.873000 >     value = yield self.func(key)
2012-03-01 19:28:47.874000 >   File "d:\python27\lib\site-packages\twisted\internet\defer.py", line 1039, in _inlineCallbacks
2012-03-01 19:28:47.874000 >     result = g.send(result)
2012-03-01 19:28:47.874000 >   File "D:\forrestv-p2pool-b839ff8\p2pool\main.py", line 171, in <lambda>
2012-03-01 19:28:47.874000 >     height_cacher = deferral.DeferredCacher(defer.inlineCallbacks(lambda block_hash: defer.returnValue((yield bitcoind.rpc_getblock('%x' % (block_hash,)))['blockcount'])))
2012-03-01 19:28:47.875000 > exceptions.KeyError: 'blockcount'
With rc1 everything works fine.

Pages: « 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 [52] 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 ... 814 »
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!