Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
timothe
duniter
Commits
2bc114cd
Commit
2bc114cd
authored
Nov 20, 2018
by
Cédric Moreau
Browse files
[enh] Protocol: allow document v11 upgrade
parent
642f3300
Changes
10
Hide whitespace changes
Inline
Side-by-side
app/lib/common-libs/constants.ts
View file @
2bc114cd
...
...
@@ -20,7 +20,7 @@ const SIGNATURE = "[A-Za-z0-9+\\/=]{87,88}"
const
USER_ID
=
"
[A-Za-z0-9_-]{2,100}
"
const
INTEGER
=
"
(0|[1-9]
\\
d{0,18})
"
const
FINGERPRINT
=
"
[A-F0-9]{64}
"
const
BLOCK_VERSION
=
"
(10)
"
const
BLOCK_VERSION
=
"
(10
|11
)
"
const
TX_VERSION
=
"
(10)
"
const
DIVIDEND
=
"
[1-9][0-9]{0,5}
"
const
ZERO_OR_POSITIVE_INT
=
"
0|[1-9][0-9]{0,18}
"
...
...
@@ -106,6 +106,7 @@ export const CommonConstants = {
},
BLOCK_GENERATED_VERSION
:
10
,
BLOCK_NEW_GENERATED_VERSION
:
11
,
LAST_VERSION_FOR_TX
:
10
,
TRANSACTION_VERSION
:
10
,
DOCUMENTS_VERSION
:
10
,
...
...
app/lib/rules/local_rules.ts
View file @
2bc114cd
...
...
@@ -22,6 +22,7 @@ import {CommonConstants} from "../common-libs/constants"
import
{
IdentityDTO
}
from
"
../dto/IdentityDTO
"
import
{
MembershipDTO
}
from
"
../dto/MembershipDTO
"
import
{
Underscore
}
from
"
../common-libs/underscore
"
import
{
FileDAL
}
from
"
../dal/fileDAL
"
const
constants
=
CommonConstants
const
maxAcceleration
=
require
(
'
./helpers
'
).
maxAcceleration
...
...
@@ -522,13 +523,28 @@ export const LOCAL_RULES_HELPERS = {
}
},
getMaxPossibleVersionNumber
:
async
(
current
:
DBBlock
|
null
)
=>
{
getMaxPossibleVersionNumber
:
async
(
current
:
DBBlock
|
null
,
dal
:
FileDAL
)
=>
{
// Looking at current blockchain, find what is the next maximum version we can produce
// 1. We follow previous block's version
let
version
=
current
?
current
.
version
:
constants
.
BLOCK_GENERATED_VERSION
;
return
!
current
// 2. If we can, we go to the next version
return
version
;
// 1. We use legacy version
?
constants
.
BLOCK_GENERATED_VERSION
:
(
async
()
=>
{
// 2. If we can, we go to the next version
const
blocksInFrame
=
(
await
dal
.
getBlocksBetween
(
current
.
number
-
current
.
issuersFrame
+
1
,
current
.
number
))
.
sort
((
b1
,
b2
)
=>
b1
.
number
-
b2
.
number
)
const
uniqIssuersInFrame
=
Underscore
.
uniq
(
blocksInFrame
.
map
(
b
=>
b
.
issuer
))
const
lastNonceOfEachIssuer
=
uniqIssuersInFrame
.
map
(
issuer
=>
String
(
blocksInFrame
.
filter
(
b
=>
b
.
issuer
===
issuer
)[
0
].
nonce
))
const
nbNoncesWithNextVersionCode
=
lastNonceOfEachIssuer
.
filter
(
nonce
=>
nonce
.
substr
(
-
11
,
3
)
===
'
999
'
).
length
// More than 70% of the computing network converted? Let's go to next version.
if
(
Math
.
floor
(
nbNoncesWithNextVersionCode
/
uniqIssuersInFrame
.
length
)
>
0.7
)
{
return
constants
.
BLOCK_NEW_GENERATED_VERSION
}
// Otherwise, we stay on same version
return
current
.
version
})()
}
}
app/modules/prover/lib/blockGenerator.ts
View file @
2bc114cd
...
...
@@ -104,6 +104,7 @@ export class BlockGenerator {
vHEAD_1
.
medianTime
=
simulationValues
.
medianTime
}
const
current
=
await
this
.
dal
.
getCurrentBlockOrNull
();
const
blockVersion
=
(
manualValues
&&
manualValues
.
version
)
||
(
await
LOCAL_RULES_HELPERS
.
getMaxPossibleVersionNumber
(
current
,
this
.
dal
))
const
revocations
=
await
this
.
dal
.
getRevocatingMembers
();
const
exclusions
=
await
this
.
dal
.
getToBeKickedPubkeys
();
const
wereExcludeds
=
await
this
.
dal
.
getRevokedPubkeys
();
...
...
@@ -126,7 +127,7 @@ export class BlockGenerator {
});
});
// Create the block
return
this
.
createBlock
(
current
,
newcomers
,
leavers
,
newCertsFromWoT
,
revocations
,
exclusions
,
wereExcludeds
,
transactions
,
manualValues
);
return
this
.
createBlock
(
blockVersion
,
current
,
newcomers
,
leavers
,
newCertsFromWoT
,
revocations
,
exclusions
,
wereExcludeds
,
transactions
,
manualValues
);
}
private
async
findTransactions
(
current
:
DBBlock
|
null
,
options
:{
dontCareAboutChaining
?:
boolean
})
{
...
...
@@ -450,6 +451,7 @@ export class BlockGenerator {
}
private
async
createBlock
(
blockVersion
:
number
,
current
:
DBBlock
|
null
,
joinData
:{
[
pub
:
string
]:
PreJoin
},
leaveData
:{
[
pub
:
string
]:
LeaveData
},
...
...
@@ -501,7 +503,7 @@ export class BlockGenerator {
block
.
medianTime
=
vHEAD
.
medianTime
;
}
// Choose the version
block
.
version
=
(
manualValues
&&
manualValues
.
version
)
||
(
await
LOCAL_RULES_HELPERS
.
getMaxPossibleVersionNumber
(
current
));
block
.
version
=
blockVersion
block
.
currency
=
current
?
current
.
currency
:
this
.
conf
.
currency
;
block
.
nonce
=
0
;
if
(
!
this
.
conf
.
dtReeval
)
{
...
...
app/modules/prover/lib/blockProver.ts
View file @
2bc114cd
...
...
@@ -93,7 +93,7 @@ export class WorkerFarm {
* Starts a new computation of PoW
* @param stuff The necessary data for computing the PoW
*/
async
askNewProof
(
stuff
:
any
)
{
async
askNewProof
(
stuff
:
ProofAsk
)
{
// Starts the PoW
this
.
powPromise
=
querablep
(
this
.
theEngine
.
prove
(
stuff
))
const
res
=
await
this
.
powPromise
...
...
@@ -163,6 +163,7 @@ export class BlockProver {
const
remainder
=
difficulty
%
16
;
const
nbZeros
=
(
difficulty
-
remainder
)
/
16
;
const
highMark
=
CommonConstants
.
PROOF_OF_WORK
.
UPPER_BOUND
[
remainder
];
const
notifyVersionJumpReady
=
block
.
version
===
10
&&
CommonConstants
.
BLOCK_NEW_GENERATED_VERSION
===
11
return
(
async
()
=>
{
...
...
@@ -189,7 +190,7 @@ export class BlockProver {
conf
:
{
powNoSecurity
:
this
.
conf
.
powNoSecurity
,
cpu
:
this
.
conf
.
cpu
,
prefix
:
this
.
conf
.
prefix
,
prefix
:
this
.
conf
.
prefix
?
String
(
this
.
conf
.
prefix
)
:
''
,
avgGenTime
:
this
.
conf
.
avgGenTime
,
medianTimeBlocks
:
this
.
conf
.
medianTimeBlocks
},
...
...
@@ -198,7 +199,8 @@ export class BlockProver {
highMark
:
highMark
,
forcedTime
:
forcedTime
,
pair
:
this
.
pair
}
},
specialNonce
:
notifyVersionJumpReady
?
999
*
(
ProverConstants
.
NONCE_RANGE
/
1000
)
:
0
,
});
if
(
!
result
)
{
this
.
logger
.
info
(
'
GIVEN proof-of-work for block#%s with %s leading zeros followed by [0-
'
+
highMark
+
'
]! stop PoW for %s
'
,
block
.
number
,
nbZeros
,
this
.
pair
&&
this
.
pair
.
pub
.
slice
(
0
,
6
));
...
...
@@ -231,3 +233,25 @@ export class BlockProver {
this
.
server
&&
this
.
server
.
push
({
pow
:
{
found
,
hash
}
});
}
}
export
interface
ProofAsk
{
initialTestsPerRound
?:
number
maxDuration
?:
number
specialNonce
?:
number
newPoW
:
{
conf
:
{
powNoSecurity
?:
boolean
cpu
?:
number
prefix
?:
string
nbCores
?:
number
avgGenTime
:
number
medianTimeBlocks
:
number
},
block
:
any
,
zeros
:
number
highMark
:
string
forcedTime
?:
number
pair
:
Keypair
|
null
turnDuration
?:
number
}
}
app/modules/prover/lib/engine.ts
View file @
2bc114cd
...
...
@@ -13,7 +13,8 @@
import
{
Master
as
PowCluster
}
from
"
./powCluster
"
import
{
ConfDTO
}
from
"
../../../lib/dto/ConfDTO
"
import
{
FileDAL
}
from
"
../../../lib/dal/fileDAL
"
;
import
{
FileDAL
}
from
"
../../../lib/dal/fileDAL
"
import
{
ProofAsk
}
from
"
./blockProver
"
const
os
=
require
(
'
os
'
)
...
...
@@ -46,7 +47,7 @@ export class PowEngine {
return
this
.
cluster
.
initCluster
()
}
async
prove
(
stuff
:
any
)
{
async
prove
(
stuff
:
ProofAsk
)
{
await
this
.
cluster
.
cancelWork
()
return
await
this
.
cluster
.
proveByWorkers
(
stuff
)
}
...
...
app/modules/prover/lib/powCluster.ts
View file @
2bc114cd
...
...
@@ -15,8 +15,9 @@ import {ConfDTO} from "../../../lib/dto/ConfDTO"
import
{
ProverConstants
}
from
"
./constants
"
import
{
createPowWorker
}
from
"
./proof
"
import
{
PowWorker
}
from
"
./PowWorker
"
import
{
FileDAL
}
from
"
../../../lib/dal/fileDAL
"
;
import
{
FileDAL
}
from
"
../../../lib/dal/fileDAL
"
import
{
Underscore
}
from
"
../../../lib/common-libs/underscore
"
import
{
ProofAsk
}
from
"
./blockProver
"
const
nuuid
=
require
(
'
node-uuid
'
);
const
cluster
=
require
(
'
cluster
'
)
...
...
@@ -171,7 +172,7 @@ export class Master {
this
.
slaves
=
[]
}
async
proveByWorkers
(
stuff
:
any
)
{
async
proveByWorkers
(
stuff
:
ProofAsk
)
{
// Eventually spawn the workers
if
(
this
.
slaves
.
length
===
0
)
{
...
...
@@ -194,6 +195,7 @@ export class Master {
// Start the salves' job
const
asks
=
this
.
slaves
.
map
(
async
(
s
,
index
)
=>
{
const
nonceBeginning
=
stuff
.
specialNonce
||
s
.
nonceBeginning
const
proof
=
await
s
.
worker
.
askProof
({
uuid
,
command
:
'
newPoW
'
,
...
...
@@ -202,7 +204,7 @@ export class Master {
initialTestsPerRound
:
stuff
.
initialTestsPerRound
,
maxDuration
:
stuff
.
maxDuration
,
block
:
stuff
.
newPoW
.
block
,
nonceBeginning
:
s
.
nonceBeginning
,
nonceBeginning
,
zeros
:
stuff
.
newPoW
.
zeros
,
highMark
:
stuff
.
newPoW
.
highMark
,
pair
:
Underscore
.
clone
(
stuff
.
newPoW
.
pair
),
...
...
doc/Protocol.md
View file @
2bc114cd
...
...
@@ -1177,7 +1177,7 @@ Local validation verifies the coherence of a well-formatted block, without any o
Rule:
HEAD.version == 10
HEAD.version == 10
|| HEAD.version == 11
##### InnerHash
...
...
test/integration/branches/branches_revert2.ts
View file @
2bc114cd
...
...
@@ -117,7 +117,7 @@ describe("Revert two blocks", function() {
res
.
sources
[
0
].
should
.
have
.
property
(
'
type
'
).
equal
(
'
D
'
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
noffset
'
).
equal
(
2
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
amount
'
).
equal
(
120
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
identifier
'
).
equal
(
'
46D1D89CA40FBDD95A9412EF6547292CB9741DDE7D2B8A9C1D53648EFA794D44
'
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
identifier
'
).
equal
(
'
5F91D05DD1B1C9CAFDBCF5538C63DAF770A20790D08C9A88E0625A8D5599825D
'
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
type
'
).
equal
(
'
T
'
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
noffset
'
).
equal
(
0
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
amount
'
).
equal
(
51
);
...
...
@@ -257,7 +257,7 @@ describe("Revert two blocks", function() {
return
expectAnswer
(
rp
(
'
http://127.0.0.1:7712/tx/sources/HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd
'
),
(
body
:
string
)
=>
{
let
res
=
JSON
.
parse
(
body
);
res
.
sources
.
should
.
have
.
length
(
1
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
identifier
'
).
equal
(
'
7F951D4B73FB65995A1F343366A8CD3B0C76028120FD590170B251EB109926FB
'
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
identifier
'
).
equal
(
'
EE74E456FC16888FF24C3A9749B9E3A8D5005A9CCE988B2CFF4619AFEA50F890
'
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
type
'
).
equal
(
'
T
'
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
noffset
'
).
equal
(
1
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
amount
'
).
equal
(
101
);
...
...
@@ -272,7 +272,7 @@ describe("Revert two blocks", function() {
res
.
sources
[
0
].
should
.
have
.
property
(
'
type
'
).
equal
(
'
D
'
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
noffset
'
).
equal
(
2
);
res
.
sources
[
0
].
should
.
have
.
property
(
'
amount
'
).
equal
(
120
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
identifier
'
).
equal
(
'
7F951D4B73FB65995A1F343366A8CD3B0C76028120FD590170B251EB109926FB
'
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
identifier
'
).
equal
(
'
EE74E456FC16888FF24C3A9749B9E3A8D5005A9CCE988B2CFF4619AFEA50F890
'
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
type
'
).
equal
(
'
T
'
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
noffset
'
).
equal
(
0
);
res
.
sources
[
1
].
should
.
have
.
property
(
'
amount
'
).
equal
(
19
);
...
...
test/integration/fork-resolution/register-fork-blocks.ts
View file @
2bc114cd
...
...
@@ -133,11 +133,11 @@ describe("Fork blocks", function() {
it
(
'
should exist a different third block on each node
'
,
async
()
=>
{
await
s1
.
expectJSON
(
'
/blockchain/current
'
,
{
number
:
3
,
hash
:
"
74AB356F0E6CD9AA6F752E58FFCD65D5F8C95CDAA93576A40457CC3598C4E3D
1
"
hash
:
"
2C0451EA29CA759AE8296D0751989067AEEC35050BC8CD5623B05C0665C2447
1
"
})
await
s2
.
expectJSON
(
'
/blockchain/current
'
,
{
number
:
3
,
hash
:
"
2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B
"
hash
:
"
33038E3E9C1BFB8328234CDD42D1F47B8D362A78161B03E43732CA7432D10A76
"
})
})
...
...
@@ -145,16 +145,16 @@ describe("Fork blocks", function() {
await
s1
.
expect
(
'
/blockchain/branches
'
,
(
res
:
HttpBranches
)
=>
{
assert
.
equal
(
res
.
blocks
.
length
,
2
)
assert
.
equal
(
res
.
blocks
[
0
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B
'
)
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
33038E3E9C1BFB8328234CDD42D1F47B8D362A78161B03E43732CA7432D10A76
'
)
assert
.
equal
(
res
.
blocks
[
1
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
74AB356F0E6CD9AA6F752E58FFCD65D5F8C95CDAA93576A40457CC3598C4E3D
1
'
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
2C0451EA29CA759AE8296D0751989067AEEC35050BC8CD5623B05C0665C2447
1
'
)
})
await
s2
.
expect
(
'
/blockchain/branches
'
,
(
res
:
HttpBranches
)
=>
{
assert
.
equal
(
res
.
blocks
.
length
,
2
)
assert
.
equal
(
res
.
blocks
[
0
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
74AB356F0E6CD9AA6F752E58FFCD65D5F8C95CDAA93576A40457CC3598C4E3D
1
'
)
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
2C0451EA29CA759AE8296D0751989067AEEC35050BC8CD5623B05C0665C2447
1
'
)
assert
.
equal
(
res
.
blocks
[
1
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B
'
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
33038E3E9C1BFB8328234CDD42D1F47B8D362A78161B03E43732CA7432D10A76
'
)
})
})
...
...
@@ -203,11 +203,11 @@ describe("Fork blocks", function() {
it
(
'
should exist a same current block on each node
'
,
async
()
=>
{
await
s1
.
expectJSON
(
'
/blockchain/current
'
,
{
number
:
8
,
hash
:
"
B8D2AA2A5556F7A2837FB4B881FCF50595F855D0BF8F71C0B432E27216BBA40B
"
hash
:
"
C41F10519A24950C051F3ABBBF71775D9EF836374EF538897DFFF08E7A3F5E50
"
})
await
s2
.
expectJSON
(
'
/blockchain/current
'
,
{
number
:
8
,
hash
:
"
B8D2AA2A5556F7A2837FB4B881FCF50595F855D0BF8F71C0B432E27216BBA40B
"
hash
:
"
C41F10519A24950C051F3ABBBF71775D9EF836374EF538897DFFF08E7A3F5E50
"
})
})
...
...
@@ -215,20 +215,20 @@ describe("Fork blocks", function() {
await
s1
.
expect
(
'
/blockchain/branches
'
,
(
res
:
HttpBranches
)
=>
{
assert
.
equal
(
res
.
blocks
.
length
,
3
)
assert
.
equal
(
res
.
blocks
[
0
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B
'
)
// This is s2 fork!
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
33038E3E9C1BFB8328234CDD42D1F47B8D362A78161B03E43732CA7432D10A76
'
)
// This is s2 fork!
assert
.
equal
(
res
.
blocks
[
1
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
9A0FA1F0899124444ADC5B2C0AB66AC5B4303A0D851BED2E7382BB57E10AA2C5
'
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
7A1982E7746DE1993F8900C2D453A1E7C010B2BDF304DB83BCBF84932CE8A630
'
)
assert
.
equal
(
res
.
blocks
[
2
].
number
,
8
)
assert
.
equal
(
res
.
blocks
[
2
].
hash
,
'
B8D2AA2A5556F7A2837FB4B881FCF50595F855D0BF8F71C0B432E27216BBA40B
'
)
assert
.
equal
(
res
.
blocks
[
2
].
hash
,
'
C41F10519A24950C051F3ABBBF71775D9EF836374EF538897DFFF08E7A3F5E50
'
)
})
await
s2
.
expect
(
'
/blockchain/branches
'
,
(
res
:
HttpBranches
)
=>
{
assert
.
equal
(
res
.
blocks
.
length
,
3
)
assert
.
equal
(
res
.
blocks
[
0
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
2C3555F4009461C81F7209EAAD7DA831D8451708D06BB1173CCB40746CD0641B
'
)
// This is s2 fork!
assert
.
equal
(
res
.
blocks
[
0
].
hash
,
'
33038E3E9C1BFB8328234CDD42D1F47B8D362A78161B03E43732CA7432D10A76
'
)
// This is s2 fork!
assert
.
equal
(
res
.
blocks
[
1
].
number
,
3
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
9A0FA1F0899124444ADC5B2C0AB66AC5B4303A0D851BED2E7382BB57E10AA2C5
'
)
assert
.
equal
(
res
.
blocks
[
1
].
hash
,
'
7A1982E7746DE1993F8900C2D453A1E7C010B2BDF304DB83BCBF84932CE8A630
'
)
assert
.
equal
(
res
.
blocks
[
2
].
number
,
8
)
assert
.
equal
(
res
.
blocks
[
2
].
hash
,
'
B8D2AA2A5556F7A2837FB4B881FCF50595F855D0BF8F71C0B432E27216BBA40B
'
)
assert
.
equal
(
res
.
blocks
[
2
].
hash
,
'
C41F10519A24950C051F3ABBBF71775D9EF836374EF538897DFFF08E7A3F5E50
'
)
})
})
})
test/integration/membership_chainability.ts
View file @
2bc114cd
...
...
@@ -12,6 +12,7 @@
// GNU Affero General Public License for more details.
import
{
simpleNodeWith2Users
}
from
"
./tools/toolbox
"
import
{
CommonConstants
}
from
"
../../app/lib/common-libs/constants
"
describe
(
"
Membership chainability
"
,
function
()
{
...
...
@@ -34,11 +35,14 @@ describe("Membership chainability", function() {
const
res1
=
await
simpleNodeWith2Users
(
conf
)
s1
=
res1
.
s1
cat
=
res1
.
cat
const
nowVersion
=
CommonConstants
.
BLOCK_NEW_GENERATED_VERSION
CommonConstants
.
BLOCK_NEW_GENERATED_VERSION
=
10
await
s1
.
commit
({
time
:
now
})
await
s1
.
commit
({
time
:
now
})
await
s1
.
commit
({
time
:
now
,
actives
:
[
'
HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd:rppB5NEwmdMUCxw3N/QPMk+V1h2Jpn0yxTzdO2xxcNN3MACv6x8vNTChWwM6DOq+kXiQHTczFzoux+82WkMfDQ==:1-12D7B9BEBE941F6929A4A61CDC06DEEEFCB00FD1DA72E42FFF7B19A338D421E1:0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855:cat
'
]})
CommonConstants
.
BLOCK_NEW_GENERATED_VERSION
=
nowVersion
})
it
(
'
current should be the 2nd
'
,
()
=>
s1
.
expect
(
'
/blockchain/current
'
,
(
res
:
any
)
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment