1
1
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited
2
2
// SPDX-License-Identifier: LGPL-3.0-only
3
3
4
-
5
4
using System ;
6
5
using System . Buffers ;
7
6
using System . Collections . Generic ;
@@ -18,11 +17,11 @@ public static class ExecutionRequestExtensions
18
17
public const int DepositRequestsBytesSize = PublicKeySize /*pubkey: Bytes48 */ + Hash256 . Size /*withdrawal_credentials: Bytes32 */ + sizeof ( ulong ) /*amount: uint64*/ + 96 /*signature: Bytes96*/ + sizeof ( ulong ) /*index: uint64*/ ;
19
18
public const int WithdrawalRequestsBytesSize = Address . Size + PublicKeySize /*validator_pubkey: Bytes48*/ + sizeof ( ulong ) /*amount: uint64*/ ;
20
19
public const int ConsolidationRequestsBytesSize = Address . Size + PublicKeySize /*source_pubkey: Bytes48*/ + PublicKeySize /*target_pubkey: Bytes48*/ ;
21
- public const int RequestPartsCount = 3 ;
20
+ public const int MaxRequestsCount = 3 ;
22
21
private const int PublicKeySize = 48 ;
23
22
24
- public static readonly byte [ ] [ ] EmptyRequests = [ [ ] , [ ] , [ ] ] ;
25
- public static readonly Hash256 EmptyRequestsHash = CalculateHashFromFlatEncodedRequests ( EmptyRequests ) ;
23
+ public static byte [ ] [ ] EmptyRequests = [ ] ;
24
+ public static Hash256 EmptyRequestsHash = CalculateHashFromFlatEncodedRequests ( EmptyRequests ) ;
26
25
27
26
public static int GetRequestsByteSize ( this IEnumerable < ExecutionRequest > requests )
28
27
{
@@ -37,29 +36,22 @@ public static int GetRequestsByteSize(this IEnumerable<ExecutionRequest> request
37
36
[ SkipLocalsInit ]
38
37
public static Hash256 CalculateHashFromFlatEncodedRequests ( byte [ ] [ ] ? flatEncodedRequests )
39
38
{
40
- // make sure that length is exactly 3
41
- if ( flatEncodedRequests is null || flatEncodedRequests . Length != RequestPartsCount )
39
+ // make sure that length is 3 or less elements
40
+ if ( flatEncodedRequests is null || flatEncodedRequests . Length > MaxRequestsCount )
42
41
{
43
- throw new ArgumentException ( "Flat encoded requests must be an array of 3 elements" ) ;
42
+ throw new ArgumentException ( "Flat encoded requests must be an array of 3 or less elements" ) ;
44
43
}
45
44
46
- byte [ ] concatenatedHashes = new byte [ Hash256 . Size * RequestPartsCount ] ;
47
- int currentPosition = 0 ;
48
- byte type = 0 ;
49
- // Allocate the buffer once outside the loop
50
- Span < byte > requestBuffer = stackalloc byte [ Math . Max ( Math . Max ( flatEncodedRequests [ 0 ] . Length , flatEncodedRequests [ 1 ] . Length ) , flatEncodedRequests [ 2 ] . Length ) + 1 ] ;
51
- // Compute sha256 for each request and concatenate them
45
+ using SHA256 sha256 = SHA256 . Create ( ) ;
46
+ using ArrayPoolList < byte > concatenatedHashes = new ( Hash256 . Size * MaxRequestsCount ) ;
52
47
foreach ( byte [ ] requests in flatEncodedRequests )
53
48
{
54
- requestBuffer [ 0 ] = type ;
55
- requests . CopyTo ( requestBuffer . Slice ( 1 , requests . Length ) ) ;
56
- SHA256 . HashData ( requestBuffer [ ..( requests . Length + 1 ) ] ) . CopyTo ( concatenatedHashes . AsSpan ( currentPosition , Hash256 . Size ) ) ;
57
- currentPosition += Hash256 . Size ;
58
- type ++ ;
49
+ if ( requests . Length <= 1 ) continue ;
50
+ concatenatedHashes . AddRange ( sha256 . ComputeHash ( requests ) ) ;
59
51
}
60
52
61
53
// Compute sha256 of the concatenated hashes
62
- return new Hash256 ( SHA256 . HashData ( concatenatedHashes ) ) ;
54
+ return new Hash256 ( sha256 . ComputeHash ( concatenatedHashes . ToArray ( ) ) ) ;
63
55
}
64
56
65
57
@@ -70,16 +62,28 @@ public static ArrayPoolList<byte[]> GetFlatEncodedRequests(
70
62
ExecutionRequest [ ] consolidationRequests
71
63
)
72
64
{
73
- return new ( RequestPartsCount )
65
+ var result = new ArrayPoolList < byte [ ] > ( MaxRequestsCount ) ;
66
+
67
+ if ( depositRequests . Length > 0 )
68
+ {
69
+ result . Add ( FlatEncodeRequests ( depositRequests , depositRequests . Length * DepositRequestsBytesSize , ( byte ) ExecutionRequestType . Deposit ) ) ;
70
+ }
71
+
72
+ if ( withdrawalRequests . Length > 0 )
74
73
{
75
- FlatEncodeRequests ( depositRequests , depositRequests . Length * DepositRequestsBytesSize ) ,
76
- FlatEncodeRequests ( withdrawalRequests , withdrawalRequests . Length * WithdrawalRequestsBytesSize ) ,
77
- FlatEncodeRequests ( consolidationRequests , consolidationRequests . Length * ConsolidationRequestsBytesSize )
78
- } ;
74
+ result . Add ( FlatEncodeRequests ( withdrawalRequests , withdrawalRequests . Length * WithdrawalRequestsBytesSize , ( byte ) ExecutionRequestType . WithdrawalRequest ) ) ;
75
+ }
76
+
77
+ if ( consolidationRequests . Length > 0 )
78
+ {
79
+ result . Add ( FlatEncodeRequests ( consolidationRequests , consolidationRequests . Length * ConsolidationRequestsBytesSize , ( byte ) ExecutionRequestType . ConsolidationRequest ) ) ;
80
+ }
81
+
82
+ return result ;
79
83
80
- static byte [ ] FlatEncodeRequests ( ExecutionRequest [ ] requests , int bufferSize )
84
+ static byte [ ] FlatEncodeRequests ( ExecutionRequest [ ] requests , int bufferSize , byte type )
81
85
{
82
- using ArrayPoolList < byte > buffer = new ( bufferSize ) ;
86
+ using ArrayPoolList < byte > buffer = new ( bufferSize + 1 ) { type } ;
83
87
84
88
foreach ( ExecutionRequest request in requests )
85
89
{
0 commit comments