-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve emai-1d's handling of huge/0/negative block times, and add "ema2-1d" #34
Conversation
…to huge/0/negative block times (using a new max_timestamp State field); similarly improved resilience of emai-1d; and added some explanatory comments to ema-1d.
(Apologies if I'm screwing up any of the PR process here... Just let me know...) |
The weakness of emai is its approximation may not |
Ahh OK I think I see how to handle both long & short blocks cleanly, but gotta run, please hold off on this PR for now |
…ultiply old_target by is ~the same for 0 and (eg) IDEAL_BLOCK_TIME / 100, so just floor block_time at the latter value.
OK, I think I was able to get ema2-1d to handle both very short and very long blocks sensibly. ema2 is now my recommended algo, if not for production use at least as a benchmark for other algos. Specifically, I believe:
I was not able to restrict ema2 to integer math - I think achieving the two properties above requires exponentiation (or great trickery). Oh well, integer math, whatev... |
You can't use the e^x =~ 1+x+x^2/2 to get integer math? |
I think that's better when x is an integer? What I have is stuff like [large integer] * e[fraction < 1]. I can see ways to approximate it but, gets pretty messy. How beneficial is integer math anyway? Perhaps the real goal should be to avoid numerically unstable math (division by numbers near 0, etc)? |
No, However, I really like being able to use negative solvetimes. A dev told me some compilers on some systems may cause the e^x to give something different, so those nodes would reject a block. Tom and Neil's comments seem to concur there's possible problem. I guess division is handled better. Another dev was concerned about overflow from WT (my WHM), which they mentioned here to. (64 bit seems plenty but if they they don't have enough leading zeros in the coin's max_target (which scales difficulty down by 2^x) I think there could be a problem). I guess integer division is reliable enough on systems. But primarily devs want to change existing code as little as possible. Making variable declaration changes might have hard to find errors appear out of no where after the fact compared to other work they're doing when they make clones. |
Sure, my point was just that your formula doesn't help me calculate e^x using integer math, when x itself is a fraction. |
You can't just scaled everything up by something like (NT)^2 before starting the calculations then divide out at the end? |
I could! It just seemed a little elaborate ("pretty messy")... Maybe I'll give it a shot |
Then we'd have the exact equation, and as I showed in the other thread the exact equation for EMA-TH is the same as EMA-JE so now we can have EMA-Z to replace them :) |
This is what I get:
|
… fn exp_int_approx(). The good news is emai2-1d matches ema2-1d quite exactly, even for very long block times; bad news is exp_int_approx() is hairy...
I added emai2-1d, a version of ema2 which matches its behavior very closely (even for very long block times) using only integer math. But, gak. Hairy. |
… e**(k*(block_time-IDEAL_BLOCK_TIME)) for some k), and an integer-math-only version, simpexpi-1d.
mining.py
Outdated
@@ -84,7 +84,7 @@ def target_to_hex(target): | |||
|
|||
IDEAL_BLOCK_TIME = 10 * 60 | |||
|
|||
State = namedtuple('State', 'height wall_time timestamp bits chainwork fx ' | |||
State = namedtuple('State', 'height wall_time timestamp max_timestamp bits chainwork fx ' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid adding another member?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I could probably do something hackier like max(state.timestamp for state in states[-100:-1])
. Anyway I think @zawy12 may be convincing me that the max timestamp approach isn't needed... So I'm OK making that change if you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer that. If every algo started putting stuff in the state it would become problematic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
This implements an approach to handling huge/0/negative block times that I mailed @zawy12 about in early Dec: define block_time as max(0, timestamp - highest_previous_timestamp). So timestamps in the past ("negative block times") just result in a single 0 block time, and timestamps in the future result in one large block time which may be followed by some 0 block times.
I left ema-1d unchanged and implemented a more-resilient version, ema2-1d, as well as incorporating the resilience into emai-1d. Of the three (ema, ema2, emai) I think emai is probably the one worth focusing on.