Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
Breeze
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DeStream-public
Breeze
Commits
a37e8004
Commit
a37e8004
authored
May 16, 2017
by
Jeremy Bokobza
Committed by
GitHub
May 16, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #59 from bokobza/master
Removed some unused code
parents
7822b524
cfb48d71
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
0 additions
and
1150 deletions
+0
-1150
Breeze.Wallet.csproj
Breeze/src/Breeze.Wallet/Breeze.Wallet.csproj
+0
-1
ConcurrentObservableDictionary.cs
.../src/Breeze.Wallet/Temp/ConcurrentObservableDictionary.cs
+0
-234
ConcurrentObservableHashSet.cs
Breeze/src/Breeze.Wallet/Temp/ConcurrentObservableHashSet.cs
+0
-75
Height.cs
Breeze/src/Breeze.Wallet/Temp/Height.cs
+0
-107
SmartMerkleBlock.cs
Breeze/src/Breeze.Wallet/Temp/SmartMerkleBlock.cs
+0
-125
SmartTransaction.cs
Breeze/src/Breeze.Wallet/Temp/SmartTransaction.cs
+0
-128
Tracker.cs
Breeze/src/Breeze.Wallet/Temp/Tracker.cs
+0
-369
UnprocessedBlockBuffer.cs
Breeze/src/Breeze.Wallet/Temp/UnprocessedBlockBuffer.cs
+0
-56
Util.cs
Breeze/src/Breeze.Wallet/Temp/Util.cs
+0
-55
No files found.
Breeze/src/Breeze.Wallet/Breeze.Wallet.csproj
View file @
a37e8004
...
...
@@ -16,7 +16,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConcurrentHashSet" Version="1.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="1.0.3" />
<PackageReference Include="System.ValueTuple" Version="4.3.1" />
<PackageReference Include="Stratis.Bitcoin" Version="1.0.1.6-alpha" />
...
...
Breeze/src/Breeze.Wallet/Temp/ConcurrentObservableDictionary.cs
deleted
100644 → 0
View file @
7822b524
//from https://github.com/brianchance/MonoTouchMVVMCrossValidationTester/blob/master/Validation.Core/ConcurrentObservableDictionary.cs
//modified
using
System
;
using
System.Collections.Concurrent
;
using
System.Linq
;
using
System.ComponentModel
;
using
System.Collections.Generic
;
using
System.Collections.Specialized
;
namespace
System.Collections.ObjectModel
{
public
class
ConcurrentObservableDictionary
<
TKey
,
TValue
>
:
IDictionary
<
TKey
,
TValue
>,
INotifyCollectionChanged
,
INotifyPropertyChanged
{
private
const
string
CountString
=
"Count"
;
private
const
string
IndexerName
=
"Item[]"
;
private
const
string
KeysName
=
"Keys"
;
private
const
string
ValuesName
=
"Values"
;
private
readonly
object
Lock
=
new
object
();
protected
ConcurrentDictionary
<
TKey
,
TValue
>
ConcurrentDictionary
{
get
;
private
set
;
}
#
region
Constructors
public
ConcurrentObservableDictionary
()
{
ConcurrentDictionary
=
new
ConcurrentDictionary
<
TKey
,
TValue
>();
}
public
ConcurrentObservableDictionary
(
ConcurrentDictionary
<
TKey
,
TValue
>
dictionary
)
{
ConcurrentDictionary
=
new
ConcurrentDictionary
<
TKey
,
TValue
>(
dictionary
);
}
public
ConcurrentObservableDictionary
(
IEqualityComparer
<
TKey
>
comparer
)
{
ConcurrentDictionary
=
new
ConcurrentDictionary
<
TKey
,
TValue
>(
comparer
);
}
public
ConcurrentObservableDictionary
(
IDictionary
<
TKey
,
TValue
>
dictionary
,
IEqualityComparer
<
TKey
>
comparer
)
{
ConcurrentDictionary
=
new
ConcurrentDictionary
<
TKey
,
TValue
>(
dictionary
,
comparer
);
}
#
endregion
#
region
IDictionary
<
TKey
,
TValue
>
Members
public
void
Add
(
TKey
key
,
TValue
value
)
=>
Insert
(
key
,
value
,
true
);
public
bool
ContainsKey
(
TKey
key
)
=>
ConcurrentDictionary
.
ContainsKey
(
key
);
public
ICollection
<
TKey
>
Keys
=>
ConcurrentDictionary
.
Keys
;
public
bool
Remove
(
TKey
key
)
=>
Remove
(
key
,
suppressNotifications
:
false
);
private
bool
Remove
(
TKey
key
,
bool
suppressNotifications
)
{
lock
(
Lock
)
{
TValue
value
;
var
ret
=
ConcurrentDictionary
.
TryRemove
(
key
,
out
value
);
if
(
ret
&&
!
suppressNotifications
)
OnCollectionChanged
();
return
ret
;
}
}
public
bool
TryGetValue
(
TKey
key
,
out
TValue
value
)
=>
ConcurrentDictionary
.
TryGetValue
(
key
,
out
value
);
public
ICollection
<
TValue
>
Values
=>
ConcurrentDictionary
.
Values
;
public
TValue
this
[
TKey
key
]
{
get
{
TValue
value
;
return
TryGetValue
(
key
,
out
value
)
?
value
:
default
(
TValue
);
}
set
{
Insert
(
key
,
value
,
false
);
}
}
#
endregion
#
region
ICollection
<
KeyValuePair
<
TKey
,
TValue
>>
Members
public
void
Add
(
KeyValuePair
<
TKey
,
TValue
>
item
)
=>
Insert
(
item
.
Key
,
item
.
Value
,
true
);
public
void
Clear
()
{
lock
(
Lock
)
{
if
(
ConcurrentDictionary
.
Count
>
0
)
{
ConcurrentDictionary
.
Clear
();
OnCollectionChanged
();
}
}
}
public
bool
Contains
(
KeyValuePair
<
TKey
,
TValue
>
item
)
=>
ConcurrentDictionary
.
Contains
(
item
);
/// <summary>
/// NotImplementedException
/// </summary>
/// <param name="array"></param>
/// <param name="arrayIndex"></param>
public
void
CopyTo
(
KeyValuePair
<
TKey
,
TValue
>[]
array
,
int
arrayIndex
)
{
throw
new
NotImplementedException
();
}
/// <summary>
/// NotImplementedException
/// </summary>
public
bool
IsReadOnly
{
get
{
throw
new
NotImplementedException
();
}
}
public
int
Count
=>
ConcurrentDictionary
.
Count
;
public
bool
Remove
(
KeyValuePair
<
TKey
,
TValue
>
item
)
=>
Remove
(
item
.
Key
);
#
endregion
#
region
IEnumerable
<
KeyValuePair
<
TKey
,
TValue
>>
Members
public
IEnumerator
<
KeyValuePair
<
TKey
,
TValue
>>
GetEnumerator
()
=>
ConcurrentDictionary
.
GetEnumerator
();
#
endregion
#
region
IEnumerable
Members
IEnumerator
IEnumerable
.
GetEnumerator
()
=>
((
IEnumerable
)
ConcurrentDictionary
).
GetEnumerator
();
#
endregion
#
region
INotifyCollectionChanged
Members
public
event
NotifyCollectionChangedEventHandler
CollectionChanged
;
#
endregion
#
region
INotifyPropertyChanged
Members
public
event
PropertyChangedEventHandler
PropertyChanged
;
#
endregion
public
void
AddOrReplace
(
TKey
key
,
TValue
value
)
{
if
(
ContainsKey
(
key
))
{
Remove
(
key
,
suppressNotifications
:
true
);
Add
(
key
,
value
);
}
else
{
Add
(
key
,
value
);
}
}
/// <summary>
/// NotImplementedException
/// </summary>
/// <param name="items"></param>
public
void
AddRange
(
IDictionary
<
TKey
,
TValue
>
items
)
{
throw
new
NotImplementedException
();
}
private
void
Insert
(
TKey
key
,
TValue
value
,
bool
add
)
{
lock
(
Lock
)
{
if
(
key
==
null
)
throw
new
ArgumentNullException
(
nameof
(
key
));
TValue
item
;
if
(
ConcurrentDictionary
.
TryGetValue
(
key
,
out
item
))
{
if
(
add
)
throw
new
ArgumentException
(
"An item with the same key has already been added."
);
if
(
Equals
(
item
,
value
))
return
;
ConcurrentDictionary
[
key
]
=
value
;
OnCollectionChanged
(
NotifyCollectionChangedAction
.
Replace
,
new
KeyValuePair
<
TKey
,
TValue
>(
key
,
value
),
new
KeyValuePair
<
TKey
,
TValue
>(
key
,
item
));
OnPropertyChanged
(
key
.
ToString
());
}
else
{
ConcurrentDictionary
[
key
]
=
value
;
OnCollectionChanged
(
NotifyCollectionChangedAction
.
Add
,
new
KeyValuePair
<
TKey
,
TValue
>(
key
,
value
));
OnPropertyChanged
(
key
.
ToString
());
}
}
}
private
void
OnPropertyChanged
()
{
OnPropertyChanged
(
CountString
);
OnPropertyChanged
(
IndexerName
);
OnPropertyChanged
(
KeysName
);
OnPropertyChanged
(
ValuesName
);
}
protected
virtual
void
OnPropertyChanged
(
string
propertyName
)
{
PropertyChanged
?.
Invoke
(
this
,
new
PropertyChangedEventArgs
(
propertyName
));
}
private
void
OnCollectionChanged
()
{
OnPropertyChanged
();
CollectionChanged
?.
Invoke
(
this
,
new
NotifyCollectionChangedEventArgs
(
NotifyCollectionChangedAction
.
Reset
));
}
private
void
OnCollectionChanged
(
NotifyCollectionChangedAction
action
,
KeyValuePair
<
TKey
,
TValue
>
changedItem
)
{
OnPropertyChanged
();
CollectionChanged
?.
Invoke
(
this
,
new
NotifyCollectionChangedEventArgs
(
action
,
changedItem
,
0
));
}
private
void
OnCollectionChanged
(
NotifyCollectionChangedAction
action
,
KeyValuePair
<
TKey
,
TValue
>
newItem
,
KeyValuePair
<
TKey
,
TValue
>
oldItem
)
{
OnPropertyChanged
();
CollectionChanged
?.
Invoke
(
this
,
new
NotifyCollectionChangedEventArgs
(
action
,
newItem
,
oldItem
,
0
));
}
private
void
OnCollectionChanged
(
NotifyCollectionChangedAction
action
,
IList
newItems
)
{
OnPropertyChanged
();
CollectionChanged
?.
Invoke
(
this
,
new
NotifyCollectionChangedEventArgs
(
action
,
newItems
,
0
));
}
}
}
\ No newline at end of file
Breeze/src/Breeze.Wallet/Temp/ConcurrentObservableHashSet.cs
deleted
100644 → 0
View file @
7822b524
using
System
;
using
System.Collections
;
using
System.Collections.Concurrent
;
using
System.Linq
;
using
System.ComponentModel
;
using
System.Collections.Generic
;
using
System.Collections.Specialized
;
using
ConcurrentCollections
;
namespace
System.Collections.ObjectModel
{
public
class
ConcurrentObservableHashSet
<
T
>
:
INotifyCollectionChanged
,
IReadOnlyCollection
<
T
>
{
protected
ConcurrentHashSet
<
T
>
ConcurrentHashSet
{
get
;
}
private
readonly
object
Lock
=
new
object
();
public
ConcurrentObservableHashSet
()
{
ConcurrentHashSet
=
new
ConcurrentHashSet
<
T
>();
}
public
event
NotifyCollectionChangedEventHandler
CollectionChanged
;
private
void
OnCollectionChanged
()
{
CollectionChanged
?.
Invoke
(
this
,
new
NotifyCollectionChangedEventArgs
(
NotifyCollectionChangedAction
.
Reset
));
}
IEnumerator
IEnumerable
.
GetEnumerator
()
=>
GetEnumerator
();
public
IEnumerator
<
T
>
GetEnumerator
()
=>
ConcurrentHashSet
.
GetEnumerator
();
public
bool
TryAdd
(
T
item
)
{
lock
(
Lock
)
{
if
(
ConcurrentHashSet
.
Add
(
item
))
{
OnCollectionChanged
();
return
true
;
}
return
false
;
}
}
public
void
Clear
()
{
lock
(
Lock
)
{
if
(
ConcurrentHashSet
.
Count
>
0
)
{
ConcurrentHashSet
.
Clear
();
OnCollectionChanged
();
}
}
}
public
bool
Contains
(
T
item
)
=>
ConcurrentHashSet
.
Contains
(
item
);
public
bool
TryRemove
(
T
item
)
{
lock
(
Lock
)
{
if
(
ConcurrentHashSet
.
TryRemove
(
item
))
{
OnCollectionChanged
();
return
true
;
}
return
false
;
}
}
public
int
Count
=>
ConcurrentHashSet
.
Count
;
}
}
Breeze/src/Breeze.Wallet/Temp/Height.cs
deleted
100644 → 0
View file @
7822b524
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading.Tasks
;
namespace
HBitcoin.Models
{
public
struct
Height
:
IEquatable
<
Height
>,
IEquatable
<
int
>,
IComparable
<
Height
>,
IComparable
<
int
>
{
public
HeightType
Type
{
get
;
}
private
readonly
int
_value
;
public
int
Value
{
get
{
if
(
Type
==
HeightType
.
Chain
)
return
_value
;
if
(
Type
==
HeightType
.
MemPool
)
return
int
.
MaxValue
-
1
;
//if(Type == HeightType.Unknown)
return
int
.
MaxValue
;
}
}
public
static
Height
MemPool
=>
new
Height
(
HeightType
.
MemPool
);
public
static
Height
Unknown
=>
new
Height
(
HeightType
.
Unknown
);
public
Height
(
int
height
)
{
if
(
height
<
0
)
throw
new
ArgumentException
(
$"
{
nameof
(
height
)}
:
{
height
}
cannot be < 0"
);
if
(
height
==
int
.
MaxValue
)
Type
=
HeightType
.
Unknown
;
else
if
(
height
==
int
.
MaxValue
-
1
)
Type
=
HeightType
.
MemPool
;
else
Type
=
HeightType
.
Chain
;
_value
=
height
;
}
public
Height
(
string
heightOrHeightType
)
{
var
trimmed
=
heightOrHeightType
.
Trim
();
if
(
trimmed
==
HeightType
.
MemPool
.
ToString
())
this
=
MemPool
;
else
if
(
trimmed
==
HeightType
.
Unknown
.
ToString
())
this
=
Unknown
;
else
this
=
new
Height
(
int
.
Parse
(
trimmed
));
}
public
Height
(
HeightType
type
)
{
if
(
type
==
HeightType
.
Chain
)
throw
new
NotSupportedException
(
$"For
{
type
}
height must be specified"
);
Type
=
type
;
if
(
Type
==
HeightType
.
MemPool
)
_value
=
int
.
MaxValue
-
1
;
else
_value
=
int
.
MaxValue
;
// HeightType.Unknown
}
public
override
string
ToString
()
{
if
(
Type
==
HeightType
.
Chain
)
return
Value
.
ToString
();
else
return
Type
.
ToString
();
}
#
region
EqualityAndComparison
public
override
bool
Equals
(
object
obj
)
=>
obj
is
Height
&&
this
==
(
Height
)
obj
;
public
bool
Equals
(
Height
other
)
=>
this
==
other
;
public
override
int
GetHashCode
()
=>
Value
.
GetHashCode
();
public
static
bool
operator
==(
Height
x
,
Height
y
)
=>
x
.
Value
==
y
.
Value
;
public
static
bool
operator
!=(
Height
x
,
Height
y
)
=>
!(
x
==
y
);
public
bool
Equals
(
int
other
)
=>
Value
==
other
;
public
static
bool
operator
==(
int
x
,
Height
y
)
=>
x
==
y
.
Value
;
public
static
bool
operator
==(
Height
x
,
int
y
)
=>
x
.
Value
==
y
;
public
static
bool
operator
!=(
int
x
,
Height
y
)
=>
!(
x
==
y
);
public
static
bool
operator
!=(
Height
x
,
int
y
)
=>
!(
x
==
y
);
public
int
CompareTo
(
Height
other
)
=>
Value
.
CompareTo
(
other
.
Value
);
public
int
CompareTo
(
int
other
)
{
if
(
Value
>
other
)
return
-
1
;
if
(
Value
==
other
)
return
0
;
return
1
;
}
public
static
bool
operator
>(
Height
x
,
Height
y
)
=>
x
.
Value
>
y
.
Value
;
public
static
bool
operator
<(
Height
x
,
Height
y
)
=>
x
.
Value
<
y
.
Value
;
public
static
bool
operator
>=(
Height
x
,
Height
y
)
=>
x
.
Value
>=
y
.
Value
;
public
static
bool
operator
<=(
Height
x
,
Height
y
)
=>
x
.
Value
<=
y
.
Value
;
public
static
bool
operator
>(
int
x
,
Height
y
)
=>
x
>
y
.
Value
;
public
static
bool
operator
>(
Height
x
,
int
y
)
=>
x
.
Value
>
y
;
public
static
bool
operator
<(
int
x
,
Height
y
)
=>
x
<
y
.
Value
;
public
static
bool
operator
<(
Height
x
,
int
y
)
=>
x
.
Value
<
y
;
public
static
bool
operator
>=(
int
x
,
Height
y
)
=>
x
>=
y
.
Value
;
public
static
bool
operator
<=(
int
x
,
Height
y
)
=>
x
<=
y
.
Value
;
public
static
bool
operator
>=(
Height
x
,
int
y
)
=>
x
.
Value
>=
y
;
public
static
bool
operator
<=(
Height
x
,
int
y
)
=>
x
.
Value
<=
y
;
#
endregion
}
public
enum
HeightType
{
Chain
,
MemPool
,
Unknown
}
}
Breeze/src/Breeze.Wallet/Temp/SmartMerkleBlock.cs
deleted
100644 → 0
View file @
7822b524
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
ConcurrentCollections
;
using
HBitcoin.Models
;
using
NBitcoin
;
namespace
HBitcoin.Models
{
public
class
SmartMerkleBlock
:
IEquatable
<
SmartMerkleBlock
>,
IComparable
<
SmartMerkleBlock
>
{
#
region
Members
public
Height
Height
{
get
;
}
public
MerkleBlock
MerkleBlock
{
get
;
}
public
IEnumerable
<
uint256
>
GetMatchedTransactions
()
=>
MerkleBlock
.
PartialMerkleTree
.
GetMatchedTransactions
();
public
uint
TransactionCount
=>
MerkleBlock
.
PartialMerkleTree
.
TransactionCount
;
#
endregion
#
region
Constructors
public
SmartMerkleBlock
()
{
}
public
SmartMerkleBlock
(
Height
height
,
Block
block
,
params
uint256
[]
interestedTransactionIds
)
{
Height
=
height
;
MerkleBlock
=
interestedTransactionIds
==
null
||
interestedTransactionIds
.
Length
==
0
?
block
.
Filter
()
:
block
.
Filter
(
interestedTransactionIds
);
}
public
SmartMerkleBlock
(
int
height
,
Block
block
,
params
uint256
[]
interestedTransactionIds
)
{
Height
=
new
Height
(
height
);
MerkleBlock
=
interestedTransactionIds
==
null
||
interestedTransactionIds
.
Length
==
0
?
block
.
Filter
()
:
block
.
Filter
(
interestedTransactionIds
);
}
public
SmartMerkleBlock
(
Height
height
,
MerkleBlock
merkleBlock
)
{
Height
=
height
;
MerkleBlock
=
merkleBlock
;
}
#
endregion
#
region
Formatting
public
static
byte
[]
ToBytes
(
SmartMerkleBlock
smartMerkleBlock
)
=>
BitConverter
.
GetBytes
(
smartMerkleBlock
.
Height
.
Value
)
// 4bytes
.
Concat
(
smartMerkleBlock
.
MerkleBlock
.
ToBytes
())
.
ToArray
();
public
byte
[]
ToBytes
()
=>
ToBytes
(
this
);
public
static
SmartMerkleBlock
FromBytes
(
byte
[]
bytes
)
{
var
heightBytes
=
bytes
.
Take
(
4
).
ToArray
();
var
merkleBlockBytes
=
bytes
.
Skip
(
4
).
ToArray
();
var
height
=
new
Height
(
BitConverter
.
ToInt32
(
heightBytes
,
startIndex
:
0
));
// Bypass NBitcoin bug
var
merkleBlock
=
new
MerkleBlock
();
if
(!
merkleBlock
.
ToBytes
().
SequenceEqual
(
merkleBlockBytes
))
// if not default MerkleBlock
{
merkleBlock
.
FromBytes
(
merkleBlockBytes
);
}
return
new
SmartMerkleBlock
(
height
,
merkleBlock
);
}
#
endregion
#
region
EqualityAndComparison
public
override
bool
Equals
(
object
obj
)
=>
obj
is
SmartMerkleBlock
&&
this
==
(
SmartMerkleBlock
)
obj
;
public
bool
Equals
(
SmartMerkleBlock
other
)
=>
this
==
other
;
public
override
int
GetHashCode
()
{
var
hash
=
Height
.
GetHashCode
();
hash
=
hash
^
MerkleBlock
.
Header
.
GetHash
().
GetHashCode
();
hash
=
hash
^
MerkleBlock
.
Header
.
HashPrevBlock
.
GetHashCode
();
hash
=
hash
^
MerkleBlock
.
Header
.
HashMerkleRoot
.
GetHashCode
();
foreach
(
uint256
txhash
in
GetMatchedTransactions
())
hash
=
hash
^
txhash
.
GetHashCode
();
return
hash
;
}
public
static
bool
operator
==(
SmartMerkleBlock
x
,
SmartMerkleBlock
y
)
{
if
(
x
.
Height
!=
y
.
Height
)
return
false
;
if
(
x
.
MerkleBlock
.
Header
.
GetHash
()
!=
y
.
MerkleBlock
.
Header
.
GetHash
())
return
false
;
if
(
x
.
MerkleBlock
.
Header
.
HashPrevBlock
!=
y
.
MerkleBlock
.
Header
.
HashPrevBlock
)
return
false
;
if
(
x
.
MerkleBlock
.
Header
.
HashMerkleRoot
!=
y
.
MerkleBlock
.
Header
.
HashMerkleRoot
)
return
false
;
if
(
x
.
TransactionCount
!=
y
.
TransactionCount
)
return
false
;
if
(
x
.
TransactionCount
==
0
)
return
true
;
if
(!
x
.
GetMatchedTransactions
().
SequenceEqual
(
y
.
GetMatchedTransactions
()))
return
false
;
return
true
;
}
public
static
bool
operator
!=(
SmartMerkleBlock
x
,
SmartMerkleBlock
y
)
=>
!(
x
==
y
);
public
int
CompareTo
(
SmartMerkleBlock
other
)
=>
Height
.
CompareTo
(
other
.
Height
);
public
static
bool
operator
>(
SmartMerkleBlock
x
,
SmartMerkleBlock
y
)
=>
x
.
Height
>
y
.
Height
;
public
static
bool
operator
<(
SmartMerkleBlock
x
,
SmartMerkleBlock
y
)
=>
x
.
Height
<
y
.
Height
;
public
static
bool
operator
>=(
SmartMerkleBlock
x
,
SmartMerkleBlock
y
)
=>
x
.
Height
>=
y
.
Height
;
public
static
bool
operator
<=(
SmartMerkleBlock
x
,
SmartMerkleBlock
y
)
=>
x
.
Height
<=
y
.
Height
;
#
endregion
}
}
Breeze/src/Breeze.Wallet/Temp/SmartTransaction.cs
deleted
100644 → 0
View file @
7822b524
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading.Tasks
;
using
HBitcoin.Models
;
using
NBitcoin
;
namespace
HBitcoin.Models
{
public
class
SmartTransaction
:
IEquatable
<
SmartTransaction
>
{
#
region
Members
public
Height
Height
{
get
;
}
public
Transaction
Transaction
{
get
;
}
public
bool
Confirmed
=>
Height
.
Type
==
HeightType
.
Chain
;
public
uint256
GetHash
()
=>
Transaction
.
GetHash
();
#
endregion
#
region
Constructors
public
SmartTransaction
()
{
}
public
SmartTransaction
(
Transaction
transaction
,
Height
height
)
{
Height
=
height
;
Transaction
=
transaction
;
}
#
endregion
#
region
Equality
public
bool
Equals
(
SmartTransaction
other
)
=>
GetHash
().
Equals
(
other
.
GetHash
());
public
bool
Equals
(
Transaction
other
)
=>
GetHash
().
Equals
(
other
.
GetHash
());
public
override
bool
Equals
(
object
obj
)
{
bool
rc
=
false
;
if
(
obj
is
SmartTransaction
)
{
var
transaction
=
(
SmartTransaction
)
obj
;
rc
=
GetHash
().
Equals
(
transaction
.
GetHash
());
}
else
if
(
obj
is
Transaction
)
{
var
transaction
=
(
Transaction
)
obj
;
rc
=
GetHash
().
Equals
(
transaction
.
GetHash
());
}
return
rc
;
}
public
override
int
GetHashCode
()
{
return
GetHash
().
GetHashCode
();
}
public
static
bool
operator
!=(
SmartTransaction
tx1
,
SmartTransaction
tx2
)
{
return
!(
tx1
==
tx2
);
}
public
static
bool
operator
==(
SmartTransaction
tx1
,
SmartTransaction
tx2
)
{
bool
rc
;
if
(
ReferenceEquals
(
tx1
,
tx2
))
rc
=
true
;
else
if
((
object
)
tx1
==
null
||
(
object
)
tx2
==
null
)
{
rc
=
false
;
}
else
{
rc
=
tx1
.
GetHash
().
Equals
(
tx2
.
GetHash
());
}
return
rc
;
}
public
static
bool
operator
==(
Transaction
tx1
,
SmartTransaction
tx2
)
{
bool
rc
;
if
((
object
)
tx1
==
null
||
(
object
)
tx2
==
null
)
{
rc
=
false
;
}
else
{
rc
=
tx1
.
GetHash
().
Equals
(
tx2
.
GetHash
());
}
return
rc
;
}
public
static
bool
operator
!=(
Transaction
tx1
,
SmartTransaction
tx2
)
{
return
!(
tx1
==
tx2
);
}
public
static
bool
operator
==(
SmartTransaction
tx1
,
Transaction
tx2
)
{
bool
rc
;
if
((
object
)
tx1
==
null
||
(
object
)
tx2
==
null
)
{
rc
=
false
;
}
else
{
rc
=
tx1
.
GetHash
().
Equals
(
tx2
.
GetHash
());
}
return
rc
;
}
public
static
bool
operator
!=(
SmartTransaction
tx1
,
Transaction
tx2
)
{
return
!(
tx1
==
tx2
);
}
#
endregion
}
}
Breeze/src/Breeze.Wallet/Temp/Tracker.cs
deleted
100644 → 0
View file @
7822b524
using
System
;
using
System.Collections.Concurrent
;
using
System.Collections.Generic
;
using
System.Collections.ObjectModel
;
using
System.Diagnostics
;
using
System.IO
;
using
System.Linq
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
ConcurrentCollections
;
using
HBitcoin.Models
;
using
NBitcoin
;
namespace
HBitcoin.FullBlockSpv
{
public
class
Tracker
{
#
region
Members
public
Network
Network
{
get
;
private
set
;
}
public
ConcurrentHashSet
<
SmartMerkleBlock
>
MerkleChain
{
get
;
}
=
new
ConcurrentHashSet
<
SmartMerkleBlock
>();
/// <summary>
///
/// </summary>
/// <param name="scriptPubKey"></param>
/// <param name="receivedTransactions">int: block height</param>
/// <param name="spentTransactions">int: block height</param>
/// <returns></returns>
public
bool
TryFindConfirmedTransactions
(
Script
scriptPubKey
,
out
ConcurrentHashSet
<
SmartTransaction
>
receivedTransactions
,
out
ConcurrentHashSet
<
SmartTransaction
>
spentTransactions
)
{
var
found
=
false
;
receivedTransactions
=
new
ConcurrentHashSet
<
SmartTransaction
>();
spentTransactions
=
new
ConcurrentHashSet
<
SmartTransaction
>();
foreach
(
var
tx
in
TrackedTransactions
.
Where
(
x
=>
x
.
Confirmed
))
{
// if already has that tx continue
if
(
receivedTransactions
.
Any
(
x
=>
x
.
GetHash
()
==
tx
.
GetHash
()))
continue
;
foreach
(
var
output
in
tx
.
Transaction
.
Outputs
)
{
if
(
output
.
ScriptPubKey
.
Equals
(
scriptPubKey
))
{
receivedTransactions
.
Add
(
tx
);
found
=
true
;
}
}
}
if
(
found
)
{
foreach
(
var
tx
in
TrackedTransactions
.
Where
(
x
=>
x
.
Confirmed
))
{
// if already has that tx continue
if
(
spentTransactions
.
Any
(
x
=>
x
.
GetHash
()
==
tx
.
GetHash
()))
continue
;
foreach
(
var
input
in
tx
.
Transaction
.
Inputs
)
{
if
(
receivedTransactions
.
Select
(
x
=>
x
.
GetHash
()).
Contains
(
input
.
PrevOut
.
Hash
))
{
spentTransactions
.
Add
(
tx
);
found
=
true
;
}
}
}
}
return
found
;
}
/// <summary>
///
/// </summary>
/// <param name="scriptPubKey"></param>
/// <returns>if never had any money on it</returns>
public
bool
IsClean
(
Script
scriptPubKey
)
=>
TrackedTransactions
.
All
(
tx
=>
!
tx
.
Transaction
.
Outputs
.
Any
(
output
=>
output
.
ScriptPubKey
.
Equals
(
scriptPubKey
)));
public
ConcurrentObservableHashSet
<
SmartTransaction
>
TrackedTransactions
{
get
;
}
=
new
ConcurrentObservableHashSet
<
SmartTransaction
>();
public
ConcurrentHashSet
<
Script
>
TrackedScriptPubKeys
{
get
;
}
=
new
ConcurrentHashSet
<
Script
>();
public
readonly
UnprocessedBlockBuffer
UnprocessedBlockBuffer
=
new
UnprocessedBlockBuffer
();
private
Height
_bestHeight
=
Height
.
Unknown
;
public
Height
BestHeight
{
get
{
return
_bestHeight
;
}
private
set
{
if
(
_bestHeight
==
value
)
return
;
_bestHeight
=
value
;
OnBestHeightChanged
();
}
}
public
event
EventHandler
BestHeightChanged
;
private
void
OnBestHeightChanged
()
=>
BestHeightChanged
?.
Invoke
(
this
,
EventArgs
.
Empty
);
public
int
BlockCount
=>
MerkleChain
.
Count
;
#
endregion
#
region
Constructors
private
Tracker
()
{
}
public
Tracker
(
Network
network
)
{
Network
=
network
;
UnprocessedBlockBuffer
.
HaveBlocks
+=
UnprocessedBlockBuffer_HaveBlocks
;
}
#
endregion
#
region
Tracking
private
IEnumerable
<
SmartTransaction
>
GetNotYetFoundTrackedTransactions
()
{
var
notFound
=
new
HashSet
<
SmartTransaction
>();
foreach
(
var
tx
in
TrackedTransactions
.
Where
(
x
=>
!
x
.
Confirmed
))
{
notFound
.
Add
(
tx
);
}
return
notFound
;
}
#
endregion
public
void
ReorgOne
()
{
// remove the last block
if
(
MerkleChain
.
Count
!=
0
)
{
if
(
MerkleChain
.
TryRemove
(
MerkleChain
.
Max
()))
{
BestHeight
=
MerkleChain
.
Max
().
Height
;
}
}
}
public
void
AddOrReplaceBlock
(
Height
height
,
Block
block
)
{
UnprocessedBlockBuffer
.
TryAddOrReplace
(
height
,
block
);
}
#
region
TransactionProcessing
/// <returns>if processed it transaction</returns>
public
bool
ProcessTransaction
(
SmartTransaction
transaction
)
{
// 1. If already tracking can we update it?
var
found
=
TrackedTransactions
.
FirstOrDefault
(
x
=>
x
==
transaction
);
if
(
found
!=
default
(
SmartTransaction
))
{
// if in a lower level don't track
if
(
found
.
Height
.
Type
<=
transaction
.
Height
.
Type
)
return
false
;
else
{
// else update
TrackedTransactions
.
TryRemove
(
transaction
);
TrackedTransactions
.
TryAdd
(
transaction
);
return
true
;
}
}
// 2. If this transaction arrived to any of our scriptpubkey track it!
if
(
transaction
.
Transaction
.
Outputs
.
Any
(
output
=>
TrackedScriptPubKeys
.
Contains
(
output
.
ScriptPubKey
)))
{
TrackedTransactions
.
TryAdd
(
transaction
);
return
true
;
}
// 3. If this transaction spends any of our scriptpubkeys track it!
if
(
transaction
.
Transaction
.
Inputs
.
Any
(
input
=>
TrackedTransactions
.
Where
(
ttx
=>
ttx
.
GetHash
()
==
input
.
PrevOut
.
Hash
)
.
Any
(
ttx
=>
TrackedScriptPubKeys
.
Contains
(
ttx
.
Transaction
.
Outputs
[
input
.
PrevOut
.
N
].
ScriptPubKey
))))
{
TrackedTransactions
.
TryAdd
(
transaction
);
return
true
;
}
// if got so far we are not interested
return
false
;
}
/// <returns>transactions it processed, empty if not processed any</returns>
private
HashSet
<
SmartTransaction
>
ProcessTransactions
(
IEnumerable
<
Transaction
>
transactions
,
Height
height
)
{
var
processedTransactions
=
new
HashSet
<
SmartTransaction
>();
try
{
// Process all transactions
foreach
(
var
tx
in
transactions
)
{
var
smartTx
=
new
SmartTransaction
(
tx
,
height
);
if
(
ProcessTransaction
(
smartTx
))
{
processedTransactions
.
Add
(
smartTx
);
}
}
// If processed any then do it again recursively until zero new is processed
if
(
processedTransactions
.
Count
>
0
)
{
var
newlyProcessedTransactions
=
ProcessTransactions
(
transactions
,
height
);
foreach
(
var
ptx
in
newlyProcessedTransactions
)
{
processedTransactions
.
Add
(
ptx
);
}
}
}
catch
(
Exception
ex
)
{
Debug
.
WriteLine
(
$"Ignoring
{
nameof
(
ProcessBlock
)}
exception at height
{
height
}
:"
);
Debug
.
WriteLine
(
ex
);
}
return
processedTransactions
;
}
/// <returns>transactions it processed, empty if not processed any</returns>
private
HashSet
<
SmartTransaction
>
ProcessBlock
(
Height
height
,
Block
block
)
{
var
foundTransactions
=
ProcessTransactions
(
block
.
Transactions
,
height
);
var
smartMerkleBlock
=
new
SmartMerkleBlock
(
height
,
block
,
foundTransactions
.
Select
(
x
=>
x
.
GetHash
()).
ToArray
());
var
sameHeights
=
MerkleChain
.
Where
(
x
=>
x
.
Height
==
height
);
foreach
(
var
elem
in
sameHeights
)
{
MerkleChain
.
TryRemove
(
elem
);
}
MerkleChain
.
Add
(
smartMerkleBlock
);
BestHeight
=
height
;
return
foundTransactions
;
}
#
endregion
private
void
UnprocessedBlockBuffer_HaveBlocks
(
object
sender
,
EventArgs
e
)
{
Height
height
;
Block
block
;
while
(
UnprocessedBlockBuffer
.
TryGetAndRemoveOldest
(
out
height
,
out
block
))
{
ProcessBlock
(
height
,
block
);
}
}
#
region
Saving
private
readonly
SemaphoreSlim
Saving
=
new
SemaphoreSlim
(
1
,
1
);
private
const
string
TrackedScriptPubKeysFileName
=
"TrackedScriptPubKeys.dat"
;
private
const
string
TrackedTransactionsFileName
=
"TrackedTransactions.dat"
;
private
const
string
MerkleChainFileName
=
"MerkleChain.dat"
;
private
static
readonly
byte
[]
blockSep
=
new
byte
[]
{
0x10
,
0x1A
,
0x7B
,
0x23
,
0x5D
,
0x12
,
0x7D
};
public
async
Task
SaveAsync
(
string
trackerFolderPath
)
{
await
Saving
.
WaitAsync
().
ConfigureAwait
(
false
);
try
{
if
(
TrackedScriptPubKeys
.
Count
>
0
||
TrackedTransactions
.
Count
>
0
||
MerkleChain
.
Count
>
0
)
{
Directory
.
CreateDirectory
(
trackerFolderPath
);
}
if
(
TrackedScriptPubKeys
.
Count
>
0
)
{
File
.
WriteAllLines
(
Path
.
Combine
(
trackerFolderPath
,
TrackedScriptPubKeysFileName
),
TrackedScriptPubKeys
.
Select
(
x
=>
x
.
ToString
()));
}
if
(
TrackedTransactions
.
Count
>
0
)
{
File
.
WriteAllLines
(
Path
.
Combine
(
trackerFolderPath
,
TrackedTransactionsFileName
),
TrackedTransactions
.
Select
(
x
=>
$"
{
x
.
Transaction
.
ToHex
()}
:
{
x
.
Height
}
"
));
}
if
(
MerkleChain
.
Count
>
0
)
{
var
path
=
Path
.
Combine
(
trackerFolderPath
,
MerkleChainFileName
);
if
(
File
.
Exists
(
path
))
{
const
string
backupName
=
MerkleChainFileName
+
"_backup"
;
var
backupPath
=
Path
.
Combine
(
trackerFolderPath
,
backupName
);
File
.
Copy
(
path
,
backupPath
,
overwrite
:
true
);
File
.
Delete
(
path
);
}
using
(
FileStream
stream
=
File
.
OpenWrite
(
path
))
{
var
toFile
=
MerkleChain
.
First
().
ToBytes
();
await
stream
.
WriteAsync
(
toFile
,
0
,
toFile
.
Length
).
ConfigureAwait
(
false
);
foreach
(
var
block
in
MerkleChain
.
Skip
(
1
))
{
await
stream
.
WriteAsync
(
blockSep
,
0
,
blockSep
.
Length
).
ConfigureAwait
(
false
);
var
blockBytes
=
block
.
ToBytes
();
await
stream
.
WriteAsync
(
blockBytes
,
0
,
blockBytes
.
Length
).
ConfigureAwait
(
false
);
}
}
}
}
finally
{
Saving
.
Release
();
}
}
public
async
Task
LoadAsync
(
string
trackerFolderPath
)
{
await
Saving
.
WaitAsync
().
ConfigureAwait
(
false
);
try
{
if
(!
Directory
.
Exists
(
trackerFolderPath
))
throw
new
DirectoryNotFoundException
(
$"No Blockchain found at
{
trackerFolderPath
}
"
);
var
tspb
=
Path
.
Combine
(
trackerFolderPath
,
TrackedScriptPubKeysFileName
);
if
(
File
.
Exists
(
tspb
)
&&
new
FileInfo
(
tspb
).
Length
!=
0
)
{
foreach
(
var
line
in
File
.
ReadAllLines
(
tspb
))
{
TrackedScriptPubKeys
.
Add
(
new
Script
(
line
));
}
}
var
tt
=
Path
.
Combine
(
trackerFolderPath
,
TrackedTransactionsFileName
);
if
(
File
.
Exists
(
tt
)
&&
new
FileInfo
(
tt
).
Length
!=
0
)
{
foreach
(
var
line
in
File
.
ReadAllLines
(
tt
))
{
var
pieces
=
line
.
Split
(
':'
);
ProcessTransaction
(
new
SmartTransaction
(
new
Transaction
(
pieces
[
0
]),
new
Height
(
pieces
[
1
])));
}
}
var
pbc
=
Path
.
Combine
(
trackerFolderPath
,
MerkleChainFileName
);
if
(
File
.
Exists
(
pbc
)
&&
new
FileInfo
(
pbc
).
Length
!=
0
)
{
foreach
(
var
block
in
Util
.
Separate
(
File
.
ReadAllBytes
(
pbc
),
blockSep
))
{
SmartMerkleBlock
smartMerkleBlock
=
SmartMerkleBlock
.
FromBytes
(
block
);
MerkleChain
.
Add
(
smartMerkleBlock
);
}
BestHeight
=
MerkleChain
.
Max
().
Height
;
}
}
finally
{
Saving
.
Release
();
}
}
#
endregion
}
}
Breeze/src/Breeze.Wallet/Temp/UnprocessedBlockBuffer.cs
deleted
100644 → 0
View file @
7822b524
using
System
;
using
System.Collections.Concurrent
;
using
System.Collections.Generic
;
using
System.Collections.ObjectModel
;
using
System.Linq
;
using
System.Threading.Tasks
;
using
HBitcoin.Models
;
using
NBitcoin
;
namespace
HBitcoin.FullBlockSpv
{
public
class
UnprocessedBlockBuffer
{
public
const
int
Capacity
=
50
;
private
readonly
ConcurrentObservableDictionary
<
Height
,
Block
>
_blocks
=
new
ConcurrentObservableDictionary
<
Height
,
Block
>();
public
event
EventHandler
HaveBlocks
;
private
void
OnHaveBlocks
()
=>
HaveBlocks
?.
Invoke
(
this
,
EventArgs
.
Empty
);
/// <summary>
///
/// </summary>
/// <param name="height"></param>
/// <param name="block"></param>
/// <returns>false if we have more than UnprocessedBlockBuffer.Capacity blocks in memory already</returns>
public
bool
TryAddOrReplace
(
Height
height
,
Block
block
)
{
if
(
_blocks
.
Count
>
Capacity
)
return
false
;
_blocks
.
AddOrReplace
(
height
,
block
);
if
(
_blocks
.
Count
==
1
)
OnHaveBlocks
();
return
true
;
}
public
bool
Full
=>
_blocks
.
Count
==
Capacity
;
public
Height
BestHeight
=>
_blocks
.
Count
==
0
?
Height
.
Unknown
:
_blocks
.
Keys
.
Max
();
/// <summary>
///
/// </summary>
/// <returns>false if empty</returns>
public
bool
TryGetAndRemoveOldest
(
out
Height
height
,
out
Block
block
)
{
height
=
Height
.
Unknown
;
block
=
default
(
Block
);
if
(
_blocks
.
Count
==
0
)
return
false
;
height
=
_blocks
.
Keys
.
Min
();
block
=
_blocks
[
height
];
_blocks
.
Remove
(
height
);
return
true
;
}
}
}
Breeze/src/Breeze.Wallet/Temp/Util.cs
deleted
100644 → 0
View file @
7822b524
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading.Tasks
;
namespace
HBitcoin
{
internal
static
class
Util
{
internal
static
byte
[][]
Separate
(
byte
[]
source
,
byte
[]
separator
)
{
var
Parts
=
new
List
<
byte
[
]>
();
var
Index
=
0
;
byte
[]
Part
;
for
(
var
I
=
0
;
I
<
source
.
Length
;
++
I
)
{
if
(
Equals
(
source
,
separator
,
I
))
{
Part
=
new
byte
[
I
-
Index
];
Array
.
Copy
(
source
,
Index
,
Part
,
0
,
Part
.
Length
);
Parts
.
Add
(
Part
);
Index
=
I
+
separator
.
Length
;
I
+=
separator
.
Length
-
1
;
}
}
Part
=
new
byte
[
source
.
Length
-
Index
];
Array
.
Copy
(
source
,
Index
,
Part
,
0
,
Part
.
Length
);
Parts
.
Add
(
Part
);
return
Parts
.
ToArray
();
}
private
static
bool
Equals
(
byte
[]
source
,
byte
[]
separator
,
int
index
)
{
for
(
int
i
=
0
;
i
<
separator
.
Length
;
++
i
)
if
(
index
+
i
>=
source
.
Length
||
source
[
index
+
i
]
!=
separator
[
i
])
return
false
;
return
true
;
}
/// <summary>
/// Splits an array into several smaller arrays.
/// </summary>
/// <typeparam name="T">The type of the array.</typeparam>
/// <param name="array">The array to split.</param>
/// <param name="size">The size of the smaller arrays.</param>
/// <returns>An array containing smaller arrays.</returns>
public
static
IEnumerable
<
IEnumerable
<
T
>>
Split
<
T
>(
T
[]
array
,
int
size
)
{
for
(
var
i
=
0
;
i
<
(
float
)
array
.
Length
/
size
;
i
++)
{
yield
return
array
.
Skip
(
i
*
size
).
Take
(
size
);
}
}
}
}
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