Exponentially Subjective Scoring & Entering the final phases for LaunchSo here's something I alluded to in a previous post. I wanted to take a look at eliminating the possibility of a long range re-org attack on the chain as this has been observed in other Ethereum forks. Ultimately the best security for proof of work is having "sufficient" hash rate such that such an attack reaches the point of "not being feasible." The first idea I had for this was setting a limit on re-org depth, say 1 day. This solution on the surface seemed simple.. a little too simple so I sent Vitalik an email to see if he had any thoughts.
Here is Vitalik's reply:
The problem with limiting reorg depth to 1 day is that there's an attack vector where someone does a 51% attack that some nodes will see as being 1 day - 1 second and some nodes will see as being 1 day + 1 second, leading to a permanent split. One approach that could work is what I call "exponentially subjective scoring", which is defined as follows:
* Suppose that you are on a chain with score S1 (score = total difficulty). Suppose that there appears a new longer chain.
* Compute the "common ancestor" of the two chains; say that this ancestor has a score of S_a.
* Switch to the new chain only if (S2 - S_a) / (S1 - S_a) > 1.0001 ** (number of seconds between when S1 was received and when S2 was received)
The intention here is that you have a scoring mechanism which prevents long reorgs, as a reorg from one day ago would be penalized by a factor of 5650, but at the same time is friendly to timing discrepancies between nodes as if two nodes saw some block even one minute away then the chains would need to be almost exactly the same length for nodes to disagree as to the correct head of the chain.
I'd actually be quite excited to see this kind of mechanism tried out in a chain.
Exponentially Subjective Scoring is also further mentioned in this article that Vitalik wrote November 2014 -
https://blog.ethereum.org/2014/11/25/proof-stake-learned-love-weak-subjectivity/I'm pleased to say that I have coded this up and it works great. Here are some log lines which demonstrate this. ESS is basically another check which decides whether or not a re-org should take place.
I0924 00:59:07.674562 core/blockchain.go:797] == BlockChain exponentialSubjectiveScoring ==
I0924 00:59:07.674702 core/blockchain.go:800] ESS currentTime: 1474714747
I0924 00:59:07.674829 core/blockchain.go:814] ESS ptd (S_a): 1723872944000
I0924 00:59:07.675027 core/blockchain.go:822] oldBlock (S1) number: 14255
I0924 00:59:07.675169 core/blockchain.go:823] oldBlock (S1) difficulty:16380851
I0924 00:59:07.675350 core/blockchain.go:824] oldBlock (S1) Td:1723889324851
I0924 00:59:07.675471 core/blockchain.go:825] oldBlock (S1) time:1474714358
I0924 00:59:07.675637 core/blockchain.go:827] newBlock (S2) number:14256
I0924 00:59:07.675797 core/blockchain.go:828] newBlock (S2) difficulty:16345471
I0924 00:59:07.675972 core/blockchain.go:829] newBlock (S2) Td:1723905670322
I0924 00:59:07.676108 core/blockchain.go:830] newBlock (S2) time:1474714417
c: 1.9978401610514618
d: 1.0396644897858596
ESS Reorg
I0924 00:59:07.676607 core/blockchain.go:902] WriteBlock calling reorg
I0924 00:59:07.676730 core/blockchain.go:1096] == BlockChain reorg ==
The above lines are additional debug lines which I which are from a live test I did on the Testnet. It's slightly confusing so here is a re-written version in Go which outlines the function using the exact figures from above.
package main
import (
"fmt"
"math"
"math/big"
)
func main() {
now := big.NewInt(1474714747)
S_a := big.NewInt(1723872944000)
S1 := big.NewInt(1723889324851)
S2 := big.NewInt(1723905670322)
S1_time := big.NewInt(1474714358)
// (S2 - S_a) / (S1 - S_a)
a := new(big.Int)
b := new(big.Int)
a.Sub(S2, S_a)
b.Sub(S1, S_a)
c := float64(a.Uint64()) / float64(b.Uint64())
fmt.Println("c: ", c)
// 1.0001 ** (now - S1_time)
d := math.Pow(1.0001, float64(now.Uint64())-float64(S1_time.Uint64()))
fmt.Println("d:", d)
// Comparison
if c > d {
fmt.Println("Reorg")
} else {
fmt.Println("No reorg")
}
}
The output is as follows.
c: 1.9978401610514618
d: 1.0396644897858596
Reorg
This code change actually took a bit longer as it required a lot of testing and learning how Ethereum handles new blocks being processed and the different scenarios. i.e. had to run through a lot of the following cases:
1 new block comes in
2 new blocks come in
3+ new blocks come in
1 new mined block pushed out the network
2 new mined blocks pushed out to the network
3+ new mined blocks pushed out the network
So most of the work was actually figuring out how block processing works and testing the scenarios and thinking more about "when should this be checked?" and further thinking of other cases where it could go wrong.
So just to re-cap JBSEE will come out with
2 new consensus level changes. These are:
Exponentially Subjective Scoring - A deterministic scoring system when comparing two chains. The longer the reorg, the higher penalization, and the less likely the new chain will become the main chain. It is more expensive to attack a well publicized good chain.
Rewritten difficulty algorithm based on Digibyte's Digishield V3 - Difficulty algorithm that is battle tested on numerous coins and is far better suited to longer block times and fluctuations in hash rate.
It is also worth noting that no other Ethereum fork has the level of new code and consensus changes that the JBSEE network will have.
Here are the priority items in the next few weeks. It is a tight deadline but we are aiming for a launch of the network before October 11th next month.
Launch of new coinAll the technical details set and we are co-ordinating with exchanges.
PRE-ANN threadThe details are being written up. This will be up shortly.
Swap systemThis has been outlined in a previous post and will again be outlined in the PRE-ANN. The sites for a non-exchange swap are being completed.
Code modificationsThese are complete for the launch. We are also thinking of paying a Geth dev to code review the new code changes I have made just to have another pair of eyes go through the code.
Logo and brandingThe new logo and name has been chosen.