Bitcoin Forum
August 18, 2018, 10:06:33 PM *
News: Latest stable version of Bitcoin Core: 0.16.2  [Torrent].
 
   Home   Help Search Donate Login Register  
Pages: « 1 ... 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 [759] 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 ... 815 »
  Print  
Author Topic: [1500 TH] p2pool: Decentralized, DoS-resistant, Hop-Proof pool  (Read 2564856 times)
jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 14, 2017, 02:56:42 AM
 #15161

I'm probably going to fork off of p2pool soon in order to increase the limit of 50 kB of new transactions per share.
Yesterday, my company mined a 51 kB block. That reminded me that I need to finish that fork.

Today, I got a working prototype of the fork running. I now have three nodes running the new code draft, with one of the three mining, and it seems to be working okay. I'm also trying to squeeze a few performance improvements and cleanups at the same time. The current code that I'm running is not in my github yet, but I'll push it fairly soon (I still have a few changes that I've recently made that I haven't fully vetted). If anyone wants to help test, let me know and I'll prioritize getting the code out.

I've also noticed what seems to be another design flaw/bug with p2pool. This issue seems to result in unnecessarily high share orphan rates. The issue seems to be with the "Punishing share for Block-stale detected!" mechanic. When your node receives a share based on block N-1 after your node has already heard about block N, your node will refuse to build off of that share under nearly all circumstances, even if there's no competing share at that height in the share chain. For example, consider this sequence of events:

1. Alice mines share A on bitcoin block 1.
2. Bob and Carol both receive share A.
3. Bob mines share B on block 1 with A as the parent.
4. Bitcoin block 2 gets mined by Slush.
5. Carol receives block 2.
6. Carol receives share B.
7. Carol marks share B as block-stale, and chooses to mine share C based on share A instead of share B.

This seems wrong to me. If Carol were choosing between using share B (based on block 1) as the parent instead of share D (based on block 2) as the parent, where B and D are siblings (using A as their parent), then I think that Carol should choose share D. However, Carol should never prefer to use a parent rather than a child just because she heard about the child after the cutoff. In other words, block-stale should be used as a way to resolve share orphan races, not as a reason to cause them.

But right now, one of my nodes is doing exactly that. On my mining node (Andrew), I mined a share 0db22594 using share cc867ac0 as the parent. One of my listening nodes (Beth) downloaded share 0db22594 a few minutes later (it wasn't running at first). It marked share 0db22594 as block-stale, and preferred to use cc867ac0 even though cc86 is much older, from an older bitcoin block, has less absolute work behind it, and is 0db's direct parent. I had to mine several more shares on top of 0db22594 before Beth switched over to a share that included it as an ancestor, and *even now* Beth is still overlooking a better share (2ddf4538) in favor of its parent (46ae27c1). 46ae27c1 is the grandchild of 0db22594, at least, so Beth eventually accepted it.

I see "Block-stale detected!" quite frequently on my non-forked (v16) nodes too, and I've also seen a few shares of mine on the v16 branch that have ended up orphaned in ways that don't make sense to me when I look back at the timestamps, so I don't think this is a bug that I've somehow introduced recently. Which means that it's a preexisting issue.

And it should be fairly easy to fix. I'll try. If it works, this should reduce share orphan rates for everyone on the fork that I'm making.



Edit: After reading the code, it looks like the behavior is even stranger than I first thought:

1. Alice mines share A on block 1.
2. Bob receives share A, and mines share B based on share A and block 1.
3. Carol receives share B, and starts work on share C based on share B and block 1.
3. Carol receives block 2.
4. Carol notices that the otherwise-best share, share B, is not based on block 2, the best-known block, and marks share B as block-stale. To punish share B, Carol switches to work on a new share, share D, based on block 2 and the parent of share B, which is share A.
5. Share B gets orphaned, even though it was perfectly valid at the time it was mined and published.

I'm seeing this bug a lot more often right now than normally, since I'm mining one share every 15-30 minutes instead of the normal 30 seconds, which means that basically *every* share gets marked as block-stale instead of roughly every 20th share. This probably accounts for a 5% orphan rate on Bitcoin/p2pool, and probably much more on other blockchains with shorter block intervals.

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
1534629993
Hero Member
*
Offline Offline

Posts: 1534629993

View Profile Personal Message (Offline)

Ignore
1534629993
Reply with quote  #2

1534629993
Report to moderator
1534629993
Hero Member
*
Offline Offline

Posts: 1534629993

View Profile Personal Message (Offline)

Ignore
1534629993
Reply with quote  #2

1534629993
Report to moderator
BOUNTY PORTALS
BLOG
WHERE BOUNTY MANAGEMENT
MEETS AUTOMATION
SIGNATURE CAMPAIGNS
TWITTER
FACEBOOK
MEDIA CAMPAIGNS
AND MORE!
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
forrestv
Hero Member
*****
Offline Offline

Activity: 516
Merit: 513


View Profile
April 14, 2017, 07:15:11 AM
 #15162

Hey, jtoomim. All of what you described (including the edit) are not bugs.

First of all, remember that orphaned shares are not inherently bad. If everyone on P2Pool has the same orphan rate, then everyone's payouts are fair. Now, with that in mind...

Here's an example scenario:
Code:
A1
|  \
B1  C2
(letter is share ID, number is block it refers to)

You noticed that a node will always prefer building off of C2 rather than B1, even if C2 came in way later than B1. I think that most would agree with this policy, on the basis that C2's work is much more useful, since it was entirely on a new block, instead of possibly partially on an old block (and therefore possibly partially useless). You implied that you agree with this, so I won't go any further.

Given that rule, the optimal (selfish) strategy for any node mining is to try to make a share C2 if it doesn't exist yet (assuming B1 isn't theirs), since they will benefit from the pool ignoring share B1. This situation is when the "Punishing share for Block-stale detected!" message is printed.

Doing anything else, as you proposed, would (slightly) disadvantage the people doing it. If the software didn't follow the optimal strategy by default, people would be (slightly) motivated to patch their P2Pool instances to implement the optimal strategy. Right now, every node follows the optimal strategy, and so we're at a Nash equilibrium. Everyone does everything the same, so all is fair, and there's nothing better to do.

Yes, the current strategy results in one share being orphaned per block (the last share that was mined for a given block). However, the current state of things:
  • Is unavoidable, by the argument above
  • Is still fair (just a slight variance increase) if everyone gets the new blocks at the same
  • Punishes people with slow bitcoind instances in a manner that I believe is fair (which is good for the pool, as people with fast bitcoinds aren't paying those with slow bitcoinds for useless work)

Also, note that a node will not try to orphan a share if it has the same payout address as theirs, so running a few nodes with the same payout address won't disadvantage you compared to running a single node.

1J1zegkNSbwX4smvTdoHSanUfwvXFeuV23
jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 14, 2017, 09:01:11 AM
 #15163

Thanks for the reply, forrestv. It's always good to see your text.

I didn't think about it from a selfish mining perspective. Interesting. I don't think we're at the Nash equilibrium, though.

I agree that C2 is more helpful to the pool than B1, and ceteris paribus, I think that for the sake of the pool it's better if people follow C2 instead of B1 when the choice is forced; however, I do not agree that a self-interested miner would always choose to mine on top of C2 instead of B1 when given the choice. Let's say both D2 (based on B1) and E2 (based on C2) get mined. Which one gets preferred?

Code:
A1
|  \
B1  C2
|   |
D2  E2

(In this diagram, the letter refers to the person who mined it and the number refers to the Bitcoin block height.)

Note: The section below was heavily edited a few hours after posting.

At the point shown in the diagram, neither of the valid heads (D2 and E2) are block-stale, so neither one gets punished for that. Ultimately, the share that wins is the one at the greatest height (edited: not the most work), or the one that was propagated first if the heights are the same. As such, there is no direct incentive to guide miners to prefer to mine like D2 versus like E2. As for indirect (pro-social) incentives, some miners might prefer to punish shares that are block-stale, whereas other miners might prefer to punish shares that are share-stale and which may be selfish mining attempts. Personally, I'm a lot more worried about selfish mining attempts on p2pool than I am about block-stale shares, so I personally would prefer to make or build off of D2 rather than E2. But let's say miners are split 50/50 on that issue.

Since there's no clear incentive why a miner would prefer to make E2 instead of D2, C2's choice to mine on A1 instead of B1 comes at a substantial cost. If D2 has already been mined and C just hasn't heard of it yet, then C2 will be at a substantial disadvantage. C2 will always lose against D2 if C2 is based on A1, but C2 has a roughly 50% chance of winning if C2 is based on B1. As we know that B will be trying to mine on top of their own blocks even after C2 is mined, it is clearly disadvantageous for C to try to orphan B1 if B has more hashrate than C and if bystanders are indifferent. It is also disadvantageous if bystanders prefer C2 but B has more than 50% of the hashrate -- which, as it happens, is currently often the case.

So C loses if D2 is in flight (maybe a 10% chance) or if B mines the next block (maybe a 10% chance); or if other miners don't clearly punish block-stale before share-stale (maybe a 50% chance). P(C_wins) is around 0.3 to 0.8. If C wins, the benefit to C is one fewer competing share in the share chain (maybe worth 10% of a share if C has 10% of the hashrate). Thus, even if all miners punish block-stale shares first, there's still roughly a (1 - 0.8*110%)=12% cost to the current strategy; and if the punishment strategies are 50/50, then there's a (1 - 0.3*110%)=67% cost to the current strategy. (End of edits.)

By choosing to base C2 on A1 instead of B1, the miner of C2 is gaining a small benefit from orphaning a competitor's share, but is paying the cost of C2 having lower absolute work. This generally works against C's best interest. A self-interested (but not large and maliciously selfish) C always acts in their own best interest when building off the chain head with the most work.

If everyone on P2Pool has the same orphan rate, then everyone's payouts are fair.
Agreed. However, high orphan rates worsen the UX in a few ways: (a) they increase reward variance; (b) they confuse people who don't understand that it's only the difference in orphan rates that affects revenue; and (c) they can be pathological in some edge cases, such as when the pool hashrate drops dramatically (e.g. during my hard fork) and the time between shares is greater than or comparable to the time between blocks, or for altcoins with naturally short block intervals.

I also think that creating orphan races results in greater reward unfairness, since winning an orphan race depends unfairly on miner hashrate and bandwidth, whereas sequential mining does not. While I agree that the stale-block rule would have the same chance of putting any miner's share into an orphan race, I do not agree that it gives every miner's share the same chance of being orphaned.

So looking back at your list of rationales:
Quote
Is unavoidable, by the argument above
I disagree that it's the optimal strategy or a Nash equilibrium, so I think it's avoidable.

Quote
Is still fair (just a slight variance increase) if everyone gets the new blocks at the same <time>
I disagree that it's fair, as large miners are more likely to win an orphan race.

Quote
Punishes people with slow bitcoind instances in a manner that I believe is fair (which is good for the pool, as people with fast bitcoinds aren't paying those with slow bitcoinds for useless work)
I'm on board with incentivizing fast bitcoind instances. But maybe there's a better way? Rather than a stick, why not a carrot? We could give a small revenue bonus (or lower difficulty) to any share that uses a block with more total work than the block of the share's parent. The current strategy seems to me to have more drawbacks than advantages, but I think a carrot wouldn't have any major drawbacks. Edit: a carrot incentivizes people to intentionally orphan the first share on a new block. The perverse incentive might be weak enough to never be worthwhile, but it would require some care and may not be worth the complexity cost.

Quote
Also, note that a node will not try to orphan a share if it has the same payout address as theirs, so running a few nodes with the same payout address won't disadvantage you compared to running a single node.
Which means that with the current code, big miners are playing to win when it comes to orphan races, and small miners would be wise not to start an orphan race with a large miner. Given that we currently have one miner with around 70% of p2pool's hashrate, this makes this block-stale punishment strategy suboptimal in practice, not just theory.

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
Rw13enlib88
Legendary
*
Offline Offline

Activity: 1540
Merit: 1023



View Profile
April 14, 2017, 10:03:30 AM
 #15164


Thanks for the info
any site where I can check what % of p2pool hashrate is mmining PTC?
forrestv
Hero Member
*****
Offline Offline

Activity: 516
Merit: 513


View Profile
April 14, 2017, 10:39:12 AM
 #15165

At this point, neither of the valid heads (D2 and E2) are block-stale, so neither one gets punished for that. Ultimately, the one that wins is the one with the most work. Not all shares have the same difficulty. If B1 was higher difficulty than C2, and D2 is equal to E2, then the total work behind D2 will be greater than E2, and E2 will get preferentially orphaned.

Shares are compared using the total work of their 5th parent, rather than their own work (data.py line 836). As a result of that, practically, forks are chosen between based on height with arrival time breaking ties. Difficulty doesn't come into it.

Can you correct that in your post? I think most of your arguments are unaffected.

1J1zegkNSbwX4smvTdoHSanUfwvXFeuV23
jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 14, 2017, 01:22:32 PM
 #15166

forrestv: edits made.


Progress update:
I'm getting the following error some of the time on my new fork when my mining node attempts to broadcast a just-mined share to its peers:
Code:
2017-04-14 05:24:01.842353 >     assert tx_hash in known_txs, 'tried to broadcast share without knowing all its new transactions'

The number of transactions that are missing from known_txs varies substantially. The last two shares that had this issue:

Code:
2017-04-14 05:24:01.841583 Missing 701 of 843 transactions for broadcast
...
2017-04-14 05:26:16.618400 Missing 9 of 1183 transactions for broadcast

It shows up for about 80% of newly mined shares, and I think 0% of shares that are requested more than a minute after they've been mined. I'm working on tracking down the cause of this bug, but for now the fork isn't ready for more than one mining node. My guesses are that either transactions aren't being added to known_txs properly when they show up in a block template, or that transactions are getting evicted too quickly, or that send_shares needs to check the eviction caches in addition to known_txs.

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
veqtrus
Member
**
Offline Offline

Activity: 107
Merit: 10


View Profile WWW
April 14, 2017, 05:38:15 PM
 #15167

More nodes have upgraded to bitcoind with segwit.


P2Pool donation button | Bitrated user: veqtrus.
OgNasty
Donator
Legendary
*
Offline Offline

Activity: 2646
Merit: 1310


I 💚 Bitcoin


View Profile WWW
April 14, 2017, 05:55:56 PM
 #15168


Thanks for the info
any site where I can check what % of p2pool hashrate is mmining PTC?

No, and I imagine the % is quite low given that the pool operator must go out of their way to enable it and run a PTC client.

jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 15, 2017, 05:38:09 AM
 #15169

I tracked down and (in my working branch) fixed a bug that's worth mentioning. When assigning new stratum jobs to miners, p2pool will guess what difficulty to use (for pseudoshares) based on the node's hashrate. If the node just started, it doesn't know what hashrate to use, and often ends up assigning insanely low difficulty, usually around 4 GH per share. If a substantial amount of miners connect to the node quickly after starting up, the node can get flooded with thousands of shares per second, which will either saturate the CPU or (if you've got less than about 100 kB/s of bandwidth) the network. This can be avoided by making p2pool use the default share difficulty (which is based on the share chain) divided by e.g. 1000 until the node has an estimate for its own hashrate.

When this bug occurs, it looks like this:

Code:
2017-04-14 21:30:07.152590 > Traceback (most recent call last):
2017-04-14 21:30:07.152619 >   File "p2pool/util/variable.py", line 74, in set
2017-04-14 21:30:07.152647 >     self.changed.happened(value)
2017-04-14 21:30:07.152664 >   File "p2pool/util/variable.py", line 42, in happened
2017-04-14 21:30:07.152681 >     func(*event)
2017-04-14 21:30:07.152698 >   File "p2pool/work.py", line 130, in <lambda>
2017-04-14 21:30:07.152715 >     self.node.best_share_var.changed.watch(lambda _: self.new_work_event.happened())
2017-04-14 21:30:07.152732 >   File "p2pool/util/variable.py", line 42, in happened
2017-04-14 21:30:07.152759 >     func(*event)
2017-04-14 21:30:07.152785 > --- <exception caught here> ---
2017-04-14 21:30:07.152801 >   File "p2pool/bitcoin/stratum.py", line 38, in _send_work
2017-04-14 21:30:07.152817 >     x, got_response = self.wb.get_work(*self.wb.preprocess_request('' if self.username is None else self.username))
2017-04-14 21:30:07.152835 >   File "p2pool/work.py", line 212, in preprocess_request
2017-04-14 21:30:07.152852 >     raise jsonrpc.Error_for_code(-12345)(u'lost contact with bitcoind')
2017-04-14 21:30:07.152868 > p2pool.util.jsonrpc.NarrowError: -12345 lost contact with bitcoind

and this:

Code:
2017-04-14 21:28:37.035488 > Watchdog timer went off at:
2017-04-14 21:28:37.035549 >   File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
2017-04-14 21:28:37.035592 >     "__main__", fname, loader, pkg_name)
2017-04-14 21:28:37.035623 >   File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
2017-04-14 21:28:37.035652 >     exec code in run_globals
2017-04-14 21:28:37.035691 >   File "/usr/lib/python2.7/cProfile.py", line 199, in <module>
2017-04-14 21:28:37.035728 >     main()
2017-04-14 21:28:37.035756 >   File "/usr/lib/python2.7/cProfile.py", line 192, in main
2017-04-14 21:28:37.035782 >     runctx(code, globs, None, options.outfile, options.sort)
2017-04-14 21:28:37.035828 >   File "/usr/lib/python2.7/cProfile.py", line 49, in runctx
2017-04-14 21:28:37.035853 >     prof = prof.runctx(statement, globals, locals)
2017-04-14 21:28:37.035879 >   File "/usr/lib/python2.7/cProfile.py", line 140, in runctx
2017-04-14 21:28:37.035923 >     exec cmd in globals, locals
2017-04-14 21:28:37.035948 >   File "run_p2pool.py", line 5, in <module>
2017-04-14 21:28:37.035973 >     main.run()
2017-04-14 21:28:37.035998 >   File "p2pool/main.py", line 669, in run
2017-04-14 21:28:37.036022 >     reactor.run()
2017-04-14 21:28:37.036067 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1192, in run
2017-04-14 21:28:37.036104 >     self.mainLoop()
2017-04-14 21:28:37.036130 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/base.py", line 1204, in mainLoop
2017-04-14 21:28:37.036156 >     self.doIteration(t)
2017-04-14 21:28:37.036182 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/epollreactor.py", line 396, in doPoll
2017-04-14 21:28:37.036207 >     log.callWithLogger(selectable, _drdw, selectable, fd, event)
2017-04-14 21:28:37.036233 >   File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 88, in callWithLogger
2017-04-14 21:28:37.036259 >     return callWithContext({"system": lp}, func, *args, **kw)
2017-04-14 21:28:37.036285 >   File "/usr/lib/python2.7/dist-packages/twisted/python/log.py", line 73, in callWithContext
2017-04-14 21:28:37.036310 >     return context.call({ILogContext: newCtx}, func, *args, **kw)
2017-04-14 21:28:37.036336 >   File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
2017-04-14 21:28:37.036371 >     return self.currentContext().callWithContext(ctx, func, *args, **kw)
2017-04-14 21:28:37.036395 >   File "/usr/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
2017-04-14 21:28:37.036421 >     return func(*args,**kw)
2017-04-14 21:28:37.036446 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 614, in _doReadOrWrite
2017-04-14 21:28:37.036470 >     why = selectable.doRead()
2017-04-14 21:28:37.036496 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 214, in doRead
2017-04-14 21:28:37.036520 >     return self._dataReceived(data)
2017-04-14 21:28:37.036545 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 220, in _dataReceived
2017-04-14 21:28:37.036570 >     rval = self.protocol.dataReceived(data)
2017-04-14 21:28:37.036595 >   File "p2pool/util/switchprotocol.py", line 11, in dataReceived
2017-04-14 21:28:37.036619 >     self.p.dataReceived(data)
2017-04-14 21:28:37.036644 >   File "/usr/lib/python2.7/dist-packages/twisted/protocols/basic.py", line 454, in dataReceived
2017-04-14 21:28:37.036667 >     self.lineReceived(line)
2017-04-14 21:28:37.036693 >   File "p2pool/util/jsonrpc.py", line 164, in lineReceived
2017-04-14 21:28:37.036718 >     _handle(line, self, response_handler=self._matcher.got_response).addCallback(lambda line2: self.sendLine(line2) if line2 is not None else None)
2017-04-14 21:28:37.036744 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1237, in unwindGenerator
2017-04-14 21:28:37.036767 >     return _inlineCallbacks(None, gen, Deferred())
2017-04-14 21:28:37.036795 >   File "/usr/lib/python2.7/dist-packages/twisted/internet/defer.py", line 1099, in _inlineCallbacks
2017-04-14 21:28:37.036814 >     result = g.send(result)
2017-04-14 21:28:37.036831 >   File "p2pool/util/jsonrpc.py", line 85, in _handle
2017-04-14 21:28:37.036847 >     result = yield method_meth(*list(preargs) + list(params))
2017-04-14 21:28:37.036873 >   File "p2pool/bitcoin/stratum.py", line 75, in rpc_submit
2017-04-14 21:28:37.036899 >     return got_response(header, worker_name, coinb_nonce)
2017-04-14 21:28:37.036915 >   File "p2pool/bitcoin/worker_interface.py", line 136, in <lambda>
2017-04-14 21:28:37.036932 >     lambda header, user, coinbase_nonce: handler(header, user, pack.IntType(self._my_bits).pack(nonce) + coinbase_nonce),
2017-04-14 21:28:37.036949 >   File "p2pool/work.py", line 387, in got_response
2017-04-14 21:28:37.036966 >     new_gentx = bitcoin_data.tx_type.unpack(new_packed_gentx) if coinbase_nonce != '\0'*self.COINBASE_NONCE_LENGTH else gentx
2017-04-14 21:28:37.036984 >   File "p2pool/util/pack.py", line 63, in unpack
2017-04-14 21:28:37.037000 >     obj = self._unpack(data, ignore_trailing)
2017-04-14 21:28:37.037016 >   File "p2pool/util/pack.py", line 42, in _unpack
2017-04-14 21:28:37.037033 >     obj, (data2, pos) = self.read((data, 0))
2017-04-14 21:28:37.037048 >   File "p2pool/util/pack.py", line 295, in read
2017-04-14 21:28:37.037065 >     item[key], file = type_.read(file)
2017-04-14 21:28:37.037081 >   File "p2pool/util/pack.py", line 171, in read
2017-04-14 21:28:37.037097 >     res[i], file = self.type.read(file)
2017-04-14 21:28:37.037113 >   File "p2pool/util/pack.py", line 295, in read
2017-04-14 21:28:37.037129 >     item[key], file = type_.read(file)
2017-04-14 21:28:37.037145 >   File "p2pool/util/pack.py", line 131, in read
2017-04-14 21:28:37.037161 >     length, file = self._inner_size.read(file)
2017-04-14 21:28:37.037177 >   File "p2pool/util/pack.py", line 97, in read
2017-04-14 21:28:37.037193 >     data, file = read(file, 1)
2017-04-14 21:28:37.037209 >   File "p2pool/util/pack.py", line 14, in read
2017-04-14 21:28:37.037225 >     data2 = data[pos:pos + length]
2017-04-14 21:28:37.037241 >   File "p2pool/main.py", line 313, in <lambda>
2017-04-14 21:28:37.037258 >     sys.stderr.write, 'Watchdog timer went off at:\n' + ''.join(traceback.format_stack())

And you'll see 100% CPU usage and ~100 kB/s of traffic to your miners.

The fix (work.py line 344):
Code:
       if desired_pseudoshare_target is None:
            target = 2**256-1
            local_hash_rate = self._estimate_local_hash_rate()
            if local_hash_rate is not None:
                target = min(target,
                    bitcoin_data.average_attempts_to_target(local_hash_rate * 1)) # limit to 1 share response every second by modulating pseudoshare difficulty
            else:
+                # If we don't yet have an estimated node hashrate, then we still need to not undershoot the difficulty.
+                # Otherwise, we might get 1 PH/s of hashrate on difficulty settings appropriate for 1 GH/s.
+                # 1/100th the difficulty of a full share should be a reasonable upper bound. That way, if
+                # one node has the whole p2pool hashrate, it will still only need to process one pseudoshare
+                # every 0.3 seconds.
+                target = min(target, 100 * bitcoin_data.average_attempts_to_target((bitcoin_data.target_to_average_attempts(
+                    self.node.bitcoind_work.value['bits'].target)*self.node.net.SPREAD)*self.node.net.PARENT.DUST_THRESHOLD/block_subsidy))
        else:
            target = desired_pseudoshare_target
        target = max(target, share_info['bits'].target)

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
kano
Legendary
*
Offline Offline

Activity: 2548
Merit: 1052


Linux since 1997 RedHat 4


View Profile
April 15, 2017, 06:30:08 AM
 #15170

... or just pick 1042
Most miners that's ok.

Pool: https://kano.is Here on Bitcointalk: Forum BTC: 1KanoPb8cKYqNrswjaA8cRDk4FAS9eDMLU
FreeNode IRC: irc.freenode.net channel #kano.is Majority developer of the ckpool code
Help keep Bitcoin secure by mining on pools with full block verification on all blocks - and NO empty blocks!
jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 15, 2017, 06:49:08 AM
 #15171

Kano, p2pool code needs to support altcoins as well. There's no hardcoded value that will work for all alts and also Bitcoin.

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 15, 2017, 11:06:14 AM
 #15172

Progress update:
I'm getting the following error some of the time on my new fork when my mining node attempts to broadcast a just-mined share to its peers:
Code:
2017-04-14>     assert tx_hash in known_txs, 'tried to broadcast share without knowing all its new transactions'
...

I found the bug. It's a bug that was present before my edits, but rarely triggered without my changes.

P2pool keeps in memory a dictionary of known transactions, and evicts transactions from that dict when they're believed to no longer be needed. The transactions for a share must be in the dict in order for p2pool to be able to broadcast the share. P2pool will keep transactions in that dict if the transaction is present in the block template most recently received from bitcoind. However, the stratum jobs that miners are working on may be significantly older than the most recent block template. When a new block template arrives, p2pool will evict any transactions that are not in the new template within 10 seconds. These evictions will usually be the low-fee transactions at the end of the block, and the old version of p2pool only occasionally assigns those transactions to miners. Looking at the log files from one of my non-upgraded nodes, this happened 4 times out of its last 15 shares, causing a 26% increase in orphan rate over that interval. However, my fork assigns those transactions to miners pretty much every time, so this bug had a much larger impact on my node, causing about ~80% of my shares to fail to propagate.

I have a fix in my code now and am currently testing it on a single node. If it works, I'll start cleaning up my code and testing it with multiple nodes mining simultaneously. If that goes well, I'll publish my code and encourage other people to test it or switch permanently.

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 16, 2017, 02:19:53 AM
 #15173

tl;dr: My fork is working, and you can review my code now, but it's better not to run it until I'm done making changes.


All of my nodes have been migrated to the 1mb_hardforked branch, and things appear to be working properly. The two nodes that I had mining over the last half day now have 22 and 41 shares mined for :9332 and :9336, respectively, with 0 orphans between them. (Given, that's on localhost, and the share interval is currently much longer than normal due to the reduced network hashrate on my fork, but it's still promising.)

The current code has one known deficiency: shares on my branch are still considered valid by nodes not on my branch. If my branch overtakes the legacy branch in terms of total work performed, and if these shares are somehow propagated to nodes on the old branch (e.g. via a modified client, or via saved shares in the p2pool/data/bitcoin directory that are loaded on startup after switching code versions), then they will wipe out the old branch's work. I haven't yet added protection against this scenario, but I will soon. Until I add this replay protection, I would prefer that nobody else runs my code so that it's easier for me to make those modifications.

However, if you guys want to start reviewing my almost-complete code and commenting on the commits, you can do so here:

https://github.com/jtoomim/p2pool/commits/1mb_hardforked

If you want to watch the mining on my new fork, the nodes running the new fork are these:

http://ml.toom.im:9332/
http://ml.toom.im:9334/
http://ml.toom.im:9336/

If you wish to mine on the new fork and don't want to wait for me to finalize the code, you may hash to stratum+tcp://ml.toom.im:9332 or :9334. (I prefer to keep :9336 for use on our LAN only, and may close that port in the future.) Keep in mind that any shares mined on this new fork will not be recognized by any other p2pool nodes yet, and will only have a value when blocks get mined on my fork. That said, I personally do not intend to switch my nodes back to the old branch, so it's likely that blocks will get mined.

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
leri4
Newbie
*
Offline Offline

Activity: 6
Merit: 0


View Profile WWW
April 16, 2017, 06:19:11 AM
 #15174

If you want to watch the mining on my new fork, the nodes running the new fork are these:

http://ml.toom.im:9332/
http://ml.toom.im:9334/
http://ml.toom.im:9336/

First of all, thank you very much for your work. I wanted to try to connect to your node http://ml.toom.im:9334/, but unfortunately for some reason it did not work. I will wait for the completed code.

My PublicNode: http://109.87.83.144:9332
jtoomim
Hero Member
*****
Offline Offline

Activity: 818
Merit: 1001


View Profile WWW
April 16, 2017, 07:58:53 AM
 #15175

I wanted to try to connect to your node http://ml.toom.im:9334/, but unfortunately for some reason it did not work.
If you want to view the stats, use http://. If you want to actually mine to it, you need to use stratum+tcp://ml.toom.im:9334. Does that help?

Hosting bitcoin miners for $65 to $80/kW/month on clean, cheap hydro power.
http://Toom.im
leri4
Newbie
*
Offline Offline

Activity: 6
Merit: 0


View Profile WWW
April 16, 2017, 09:02:11 AM
 #15176

I wanted to try to connect to your node http://ml.toom.im:9334/, but unfortunately for some reason it did not work.
If you want to view the stats, use http://. If you want to actually mine to it, you need to use stratum+tcp://ml.toom.im:9334. Does that help?

Unfortunately not, if I connected the miner directly, there is no connection, but if I connect through the ckproxy, the miner is connected and after a minute goes into reboot, and so constantly. I see it in the first.
http://uploads.ru/w3xzr.jpg


My PublicNode: http://109.87.83.144:9332
Meuh6879
Legendary
*
Offline Offline

Activity: 1512
Merit: 1000



View Profile
April 16, 2017, 11:42:07 AM
 #15177

Good month at 10PH/s ...  Smiley



sawa
Legendary
*
Offline Offline

Activity: 1282
Merit: 1005



View Profile
April 16, 2017, 04:46:25 PM
 #15178

I tracked down and (in my working branch) fixed a bug that's worth mentioning. When assigning new stratum jobs to miners, p2pool will guess what difficulty to use (for pseudoshares) based on the node's hashrate. If the node just started, it doesn't know what hashrate to use, and often ends up assigning insanely low difficulty, usually around 4 GH per share. If a substantial amount of miners connect to the node quickly after starting up, the node can get flooded with thousands of shares per second, which will either saturate the CPU or (if you've got less than about 100 kB/s of bandwidth) the network. This can be avoided by making p2pool use the default share difficulty (which is based on the share chain) divided by e.g. 1000 until the node has an estimate for its own hashrate.

When this bug occurs, it looks like this:

Code:
2017-04-14 21:30:07.152590 > Traceback (most recent call last):
2017-04-14 21:30:07.152619 >   File "p2pool/util/variable.py", line 74, in set
2017-04-14 21:30:07.152647 >     self.changed.happened(value)
2017-04-14 21:30:07.152664 >   File "p2pool/util/variable.py", line 42, in happened
2017-04-14 21:30:07.152681 >     func(*event)
2017-04-14 21:30:07.152698 >   File "p2pool/work.py", line 130, in <lambda>
2017-04-14 21:30:07.152715 >     self.node.best_share_var.changed.watch(lambda _: self.new_work_event.happened())
2017-04-14 21:30:07.152732 >   File "p2pool/util/variable.py", line 42, in happened
2017-04-14 21:30:07.152759 >     func(*event)
2017-04-14 21:30:07.152785 > --- <exception caught here> ---
2017-04-14 21:30:07.152801 >   File "p2pool/bitcoin/stratum.py", line 38, in _send_work
2017-04-14 21:30:07.152817 >     x, got_response = self.wb.get_work(*self.wb.preprocess_request('' if self.username is None else self.username))
2017-04-14 21:30:07.152835 >   File "p2pool/work.py", line 212, in preprocess_request
2017-04-14 21:30:07.152852 >     raise jsonrpc.Error_for_code(-12345)(u'lost contact with bitcoind')
2017-04-14 21:30:07.152868 > p2pool.util.jsonrpc.NarrowError: -12345 lost contact with bitcoind
...

A similar problem occurs not only if local_hash_rate is None
The same consequences will be when you mine on altcoin p2pool for a long time with a low hashrate and then add big power.

And you'll see 100% CPU usage and ~100 kB/s of traffic to your miners.
As a result, the miner who entered with a big power sees a huge DOA and disconnects.
http://crypto.office-on-the.net:12347/static/

windpath
Legendary
*
Offline Offline

Activity: 1233
Merit: 1000


View Profile WWW
April 16, 2017, 09:35:27 PM
 #15179

Have not seen a block party like this in a few years Smiley

tubexc
Hero Member
*****
Offline Offline

Activity: 501
Merit: 500


View Profile
April 16, 2017, 09:44:39 PM
 #15180

You bet
I have never encountered any blocks in person but this certainly increases my confidence in p2pool  Cheesy
Pages: « 1 ... 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 [759] 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 ... 815 »
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!