Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Dunitrust
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
nodes
rust
Dunitrust
Merge requests
!155
WIP: Resolve "DUBP local validation"
Code
Review changes
Check out branch
Download
Patches
Plain diff
Expand sidebar
Closed
WIP: Resolve "DUBP local validation"
jawaka-146-dubp-local-validation
into
dev
Overview
21
Commits
12
Pipelines
0
Changes
2
Closed
jawaka
requested to merge
jawaka-146-dubp-local-validation
into
dev
6 years ago
Overview
21
Commits
12
Pipelines
0
Changes
2
Closes
#146 (closed)
0
0
Merge request reports
Compare
dev
version 15
e8c1b646
5 years ago
version 14
97894794
5 years ago
version 13
2a961baa
6 years ago
version 12
be1a336d
6 years ago
version 11
e3356f0e
6 years ago
version 10
641a2447
6 years ago
version 9
dcfcc577
6 years ago
version 8
5379d9f3
6 years ago
version 7
919bab9e
6 years ago
version 6
02ea5448
6 years ago
version 5
28d03e39
6 years ago
version 4
d0bf6712
6 years ago
version 3
c7ebcfd5
6 years ago
version 2
bfc7d775
6 years ago
version 1
b385e1df
6 years ago
dev (base)
and
version 4
latest version
e8c1b646
12 commits,
5 years ago
version 15
e8c1b646
12 commits,
5 years ago
version 14
97894794
11 commits,
5 years ago
version 13
2a961baa
11 commits,
6 years ago
version 12
be1a336d
11 commits,
6 years ago
version 11
e3356f0e
10 commits,
6 years ago
version 10
641a2447
9 commits,
6 years ago
version 9
dcfcc577
8 commits,
6 years ago
version 8
5379d9f3
6 commits,
6 years ago
version 7
919bab9e
6 commits,
6 years ago
version 6
02ea5448
5 commits,
6 years ago
version 5
28d03e39
4 commits,
6 years ago
version 4
d0bf6712
3 commits,
6 years ago
version 3
c7ebcfd5
6 commits,
6 years ago
version 2
bfc7d775
1 commit,
6 years ago
version 1
b385e1df
1 commit,
6 years ago
2 files
+
379
−
1
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
Files
2
lib/modules/blockchain/blockchain/src/dubp/check/mod.rs
+
376
−
1
View file @ d0bf6712
Show full file
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! Sub-module
checking if a block complies with all the rules of the
(DUBP DUniter Blockchain Protocol).
//! Sub-module
that checks and applies the content of a block according to the DUBP
(DUBP DUniter Blockchain Protocol).
pub
mod
hashs
;
@@ -25,12 +25,387 @@ use durs_blockchain_dal::*;
use
durs_wot
::
*
;
use
std
::
collections
::
HashMap
;
use
dubp_documents
::
documents
::
block
::
TxDocOrTxHash
;
use
dubp_documents
::
text_document_traits
::
CompactTextDocument
;
use
dubp_documents
::
VerificationResult
;
use
durs_common_tools
::
fatal_error
;
pub
static
ZERO_STRING
:
&
'static
str
=
"0"
;
#[derive(Debug,
Copy,
Clone)]
pub
enum
InvalidBlockError
{
NoPreviousBlock
,
VersionDecrease
,
}
#[derive(Debug,
Clone)]
///
pub
enum
TransactionDocumentError
{
// todo
LengthError
,
// too_short or too_large
NumberSourcesError
,
// ...Error uselesse
UnlocksError
,
SignatureIssuerError
,
VersionError
,
SignatureCountError
,
// SIGError(SIGError) existe déjà
SignaturesOrderError
,
SignatureConstructionError
,
VerificationResult
(
VerificationResult
),
}
/*
impl From<VerificationResult> for TransactionDocumentError {
fn from(err: VerificationResult) -> Self {
VerificationResult(err)
}
}
*/
// #[derive(Debug, Clone, Fail)]
#[derive(Debug,
Clone)]
// todo : documenter variante et fail
/// Local verification of a block error
pub
enum
LocalVerifyBlockError
{
// todo
VerifyBlockHashsError
,
// invalidHash (expected_hash, actual_hash), verifiy inner hash à changer
/// the block version was not in the expected versions
Version
{
expected_version
:
Vec
<
usize
>
,
actual_version
:
u32
,
},
LocalVerifyGenesisBlockError
(
LocalVerifyGenesisBlockError
),
LocalVerifyNotGenesisBlockError
(
LocalVerifyNotGenesisBlockError
),
BlockTimeError
,
ZerosHashBlockError
,
SignaturesLenBlockError
,
// supprimer
SignatureBlockError
,
// SIGError, faudra faire une vérif sur le nb d'issuer "too many issuers"
SignatureMembershipDocumentError
,
SignatureRevocationDocumentError
,
TextDocumentFormat
,
//#[fail(display = "blabl {}", tx_post)]
TransactionDocumentError
(
TransactionDocumentError
),
// innerTx document error{tx_post : usize, error : TransactionDocumentError }
/* TransactionDocumentError {
/// Protocole version
tx_post : usize,
error : TransactionDocumentError,
} */
}
// from tuple usize regarder gitlab
impl
From
<
LocalVerifyGenesisBlockError
>
for
LocalVerifyBlockError
{
fn
from
(
err
:
LocalVerifyGenesisBlockError
)
->
Self
{
LocalVerifyGenesisBlockError
(
err
)
}
}
// from tuple usize regarder gitlab
impl
From
<
LocalVerifyNotGenesisBlockError
>
for
LocalVerifyBlockError
{
fn
from
(
err
:
LocalVerifyNotGenesisBlockError
)
->
Self
{
LocalVerifyNotGenesisBlockError
(
err
)
}
}
// from tuple usize regarder gitlab
impl
From
<
TransactionDocumentError
>
for
LocalVerifyBlockError
{
fn
from
(
err
:
TransactionDocumentError
)
->
Self
{
TransactionDocumentError
(
err
)
}
}
use
crate
::
dubp
::
check
::
LocalVerifyBlockError
::
*
;
use
crate
::
dubp
::
check
::
LocalVerifyGenesisBlockError
::
*
;
use
crate
::
dubp
::
check
::
LocalVerifyNotGenesisBlockError
::
*
;
use
crate
::
dubp
::
check
::
TransactionDocumentError
::
*
;
#[derive(Debug,
Clone)]
/// Local verification error particular of a Genesis Block
pub
enum
LocalVerifyGenesisBlockError
{
//NotGenesisBlock,
/// A previous hash is provided
UnexpectedPreviousHash
,
/// A previous issuer is provided
UnexpectedPreviousIssuer
,
/// No paramters are provided
MissingParameters
,
/// No dividend is provided
MissingDividend
,
/// Unit base is not zero
NonZeroUnitBase
,
/// The block time is different from the median time
BlockTimeDifferentFromMedianTime
,
}
pub
fn
local_verification_genesis_block
(
block
:
&
BlockDocument
,
)
->
Result
<
(),
(
LocalVerifyGenesisBlockError
)
>
{
/*
if block.number.0 > 0 {
return Err(NotGenesisBlock);
}
*/
// Previous Hash
if
block
.previous_hash
.is_some
()
{
return
Err
(
UnexpectedPreviousHash
);
}
// Previous issuer
if
block
.previous_issuer
.is_some
()
{
return
Err
(
UnexpectedPreviousIssuer
);
}
// Parameters
if
block
.parameters
.is_none
()
{
return
Err
(
MissingParameters
);
}
// Universal Dividend
if
block
.dividend
.is_none
()
{
return
Err
(
MissingDividend
);
}
// UnitBase
if
block
.unit_base
>
0
{
return
Err
(
NonZeroUnitBase
);
}
// Date
if
block
.time
!=
block
.median_time
{
return
Err
(
BlockTimeDifferentFromMedianTime
);
}
return
Ok
(());
}
#[derive(Debug,
Clone)]
/// Local verification error particular of a not-genesis Block
pub
enum
LocalVerifyNotGenesisBlockError
{
/// No previous hash is provided
MissingPreviousHash
,
/// No previous issuer is provided
MissingPreviousIssuer
,
/// Some Paramters are provided
UnexpectedParameters
,
}
/// Verification of local rules of a block which is supposed to be not-genesis
pub
fn
local_verification_not_genesis_block
(
block
:
&
BlockDocument
,
)
->
Result
<
(),
LocalVerifyNotGenesisBlockError
>
{
// PreviousHash
if
block
.previous_hash
.is_none
()
{
return
Err
(
MissingPreviousHash
);
}
// PreviousIssuer
if
block
.previous_issuer
.is_none
()
{
return
Err
(
MissingPreviousIssuer
);
}
// Parameters
if
block
.parameters
.is_some
()
{
return
Err
(
UnexpectedParameters
);
}
return
Ok
(());
}
pub
fn
local_verification
(
block
:
&
BlockDocument
)
->
Result
<
(),
LocalVerifyBlockError
>
{
if
block
.number
.0
==
0
{
// Verify local rules for a genesis block
local_verification_genesis_block
(
block
)
?
;
}
else
{
// Verify local rules for a not genesis block
local_verification_not_genesis_block
(
block
)
?
;
}
// Version
if
!
(
block
.version
==
10
||
block
.version
==
11
)
{
return
Err
(
Version
{
expected_version
:
vec!
[
10
,
11
],
actual_version
:
block
.version
,
});
}
// InnerHash
// todo : + compliqué car faut changer le retour de verify
if
!
block
.verify_inner_hash
()
{
return
Err
(
VerifyBlockHashsError
);
}
// Nonce
// nothing to do
// Proof of work
if
let
Some
(
h
)
=
block
.hash
{
let
hash_string
=
h
.0
.to_hex
();
let
remainder
=
block
.pow_min
%
16
;
let
nb_zeros
=
(
block
.pow_min
-
remainder
)
/
16
;
let
repeated_zero_string
=
ZERO_STRING
.repeat
(
nb_zeros
);
if
!
hash_string
.starts_with
(
&
repeated_zero_string
)
{
return
Err
(
ZerosHashBlockError
);
// plus explicite excpeted pattern 00000[0-3]* et le actual_hash format (hexa)
}
}
// Signature
if
block
.signatures
.len
()
!=
1
{
// optimisable en ne calculant pas toute la longueur du tableau ?
return
Err
(
SignaturesLenBlockError
);
}
match
block
.verify_signatures
()
{
VerificationResult
::
Valid
()
=>
(),
_
=>
return
Err
(
SignatureBlockError
),
}
// récuperer les deux autres erreurs et renvoyer une SIG_error : invalid sig et
// Dates
//let avg_gen_time = block.parameters.avg_gen_time as f64;
//let maxGenTime = avg_gen_time * 1.189;
let
max_acceleration
=
1
;
// todo: max_acceleration = CEIL(maxGenTime * median_time_blocks) // rajouter currency parameters en argument Option utiliser unwrap!(option)
if
block
.time
<
block
.median_time
||
block
.median_time
+
max_acceleration
<
block
.time
{
return
Err
(
BlockTimeError
);
}
// Identities
for
x
in
&
block
.identities
{
match
x
.verify_signatures
()
{
VerificationResult
::
Valid
()
=>
(),
_
=>
return
Err
(
SignatureBlockError
),
}
}
// Memberships (Joiners, Actives, Leavers)
for
x
in
&
block
.joiners
{
match
x
.verify_signatures
()
{
VerificationResult
::
Valid
()
=>
(),
_
=>
return
Err
(
SignatureMembershipDocumentError
),
}
}
for
x
in
&
block
.actives
{
match
x
.verify_signatures
()
{
VerificationResult
::
Valid
()
=>
(),
_
=>
return
Err
(
SignatureMembershipDocumentError
),
}
}
for
x
in
&
block
.leavers
{
match
x
.verify_signatures
()
{
VerificationResult
::
Valid
()
=>
(),
_
=>
return
Err
(
SignatureMembershipDocumentError
),
}
}
// Revoked // pas une vérif locale en fait, erreur de conception
for
x
in
&
block
.revoked
{
match
x
{
dubp_documents
::
text_document_traits
::
TextDocumentFormat
::
Complete
(
y
)
=>
{
match
y
.verify_signatures
()
{
VerificationResult
::
Valid
()
=>
(),
_
=>
return
Err
(
SignatureRevocationDocumentError
),
}
// deplacer dans compact // dans complete dire que c'est une erreur
}
dubp_documents
::
text_document_traits
::
TextDocumentFormat
::
Compact
(
y
)
=>
{
/*match y.verify_signatures() {
VerificationResult::Valid() => (),
_ => return Err(SignatureRevocationDocumentError),
}*/
// verify_signatures à implementer
}
_
=>
(),
// compact n'existe pas // ne pas utiliser de _
}
}
// Transactions
for
x
in
&
block
.transactions
{
match
x
{
TxDocOrTxHash
::
TxDoc
(
y
)
=>
{
// A transaction in compact format cannot measure more than 100 lines
if
y
.as_compact_text
()
.lines
()
.count
()
>=
100
{
// question : c'est strict ?
return
Err
(
TransactionDocumentError
(
LengthError
));
}
// A transaction must have at least 1 source
if
y
.get_inputs
()
.is_empty
()
{
return
Err
(
TransactionDocumentError
(
NumberSourcesError
));
}
// A transaction cannot have `SIG(INDEX)` unlocks with `INDEX >= ` issuers count. ??
/*if y.get_unlocks().len() >= y.issuers().len() {
return Err(TransactionDocumentError(SignatureIssuerError));
}*/
// A transaction's version must be equal to 10
if
y
.version
()
!=
10
{
return
Err
(
TransactionDocumentError
(
VersionError
));
}
// Signatures count must be the same as issuers count
if
y
.signatures
()
.len
()
!=
y
.issuers
()
.len
()
{
return
Err
(
TransactionDocumentError
(
SignatureCountError
));
}
/*
* A transaction **must** have signatures matching its content **for each issuer**
* Signatures are ordered by issuer
* Signatures are made over the transaction's content, signatures excepted
*/
let
result
=
y
.verify_signatures
();
match
result
{
VerificationResult
::
Valid
()
=>
(),
_
=>
return
Err
(
TransactionDocumentError
(
VerificationResult
(
result
))),
}
// invalid -> invalid SIG, incomplete : dans les transactions même paramètre, pour les autres il faut indiquer invlaid nb of signatures
}
TxDocOrTxHash
::
TxHash
(
y
)
=>
{
fatal_error!
(
"Block contains a Transaction Hash (and not a Transaction Document)"
)
}
}
}
Ok
(())
}
/*#[cfg(test)]
mod tests {
#[test]
fn generate_and_verify_block() {
let mut block = BlockDocument {
nonce: 0,
version: 10,
number: BlockNumber(107_984),
pow_min: 88,
time: 1_522_685_861,
median_time: 1522683184,
members_count: 896,
monetary_mass: 140_469_765,
unit_base: 0,
issuers_count: 42,
issuers_frame: 211,
issuers_frame_var: 0,
currency: CurrencyName(String::from("g1")),
issuers: vec![PubKey::Ed25519(ed25519::PublicKey::from_base58("DA4PYtXdvQqk1nCaprXH52iMsK5Ahxs1nRWbWKLhpVkQ").unwrap())],
signatures: vec![Sig::Ed25519(ed25519::Signature::from_base64("92id58VmkhgVNee4LDqBGSm8u/ooHzAD67JM6fhAE/CV8LCz7XrMF1DvRl+eRpmlaVkp6I+Iy8gmZ1WUM5C8BA==").unwrap())],
hash: None,
parameters: None,
previous_hash: Hash::from_hex("000001144968D0C3516BE6225E4662F182E28956AF46DD7FB228E3D0F9413FEB").expect("fail to parse previous_hash"),
previous_issuer: Some(PubKey::Ed25519(ed25519::PublicKey::from_base58("D3krfq6J9AmfpKnS3gQVYoy7NzGCc61vokteTS8LJ4YH").unwrap())),
inner_hash: None,
dividend: None,
identities: Vec::new(),
joiners: Vec::new(),
actives: Vec::new(),
leavers: Vec::new(),
revoked: Vec::new(),
excluded: Vec::new(),
certifications: vec![TextDocumentFormat::Complete(cert1)],
transactions: vec![TxDocOrTxHash::TxDoc(Box::new(tx1)), TxDocOrTxHash::TxDoc(Box::new(tx2))],
inner_hash_and_nonce_str: String::new(),
};
assert_eq!(local_verification(&block), Ok);
}
}*/
pub
fn
verify_block_validity
<
W
:
WebOfTrust
>
(
block
:
&
BlockDocument
,
blockchain_db
:
&
BinDB
<
LocalBlockchainV10Datas
>
,
Loading