Line data Source code
1 : #ifndef HEADER_fd_src_discof_genesis_genesis_hash_h 2 : #define HEADER_fd_src_discof_genesis_genesis_hash_h 3 : 4 : #include "../../ballet/sha256/fd_sha256.h" 5 : 6 : #include <errno.h> 7 : #include <fcntl.h> 8 : #include <unistd.h> 9 : 10 : static inline ushort 11 : compute_shred_version( uchar const genesis_hash[ 32 ], 12 : fd_hard_fork_t const * hard_forks, 13 0 : ulong hard_fork_cnt ) { 14 0 : union { 15 0 : uchar c[ 32 ]; 16 0 : ushort s[ 16 ]; 17 0 : } running_hash; 18 0 : fd_memcpy( running_hash.c, genesis_hash, 32UL ); 19 : 20 0 : for( ulong i=0UL; i<hard_fork_cnt; i++ ) { 21 0 : ulong slot = hard_forks[ i ].slot; 22 0 : ulong count = hard_forks[ i ].cnt; 23 : 24 0 : uchar data[ 48UL ]; 25 0 : fd_memcpy( data, running_hash.c, 32UL ); 26 0 : fd_memcpy( data+32UL, &slot, sizeof(ulong) ); 27 0 : fd_memcpy( data+40UL, &count, sizeof(ulong) ); 28 0 : FD_TEST( fd_sha256_hash( data, 48UL, running_hash.c ) ); 29 0 : } 30 : 31 0 : ushort xor = 0; 32 0 : for( ulong i=0UL; i<16UL; i++ ) xor ^= running_hash.s[ i ]; 33 : 34 0 : xor = fd_ushort_bswap( xor ); 35 0 : xor = fd_ushort_if( xor<USHORT_MAX, (ushort)(xor + 1), USHORT_MAX ); 36 : 37 0 : return xor; 38 0 : } 39 : 40 : static inline int 41 : read_genesis_bin( char const * genesis_path, 42 : ushort * opt_shred_version, 43 0 : uchar * opt_gen_hash ) { 44 : 45 0 : fd_sha256_t _sha[ 1 ]; fd_sha256_t * sha = fd_sha256_join( fd_sha256_new( _sha ) ); 46 0 : fd_sha256_init( sha ); 47 0 : uchar buffer[ 4096 ]; 48 : 49 0 : int fd = open( genesis_path, O_RDONLY ); 50 0 : if( FD_UNLIKELY( -1==fd ) ) return -1; 51 : 52 0 : for(;;) { 53 0 : long result = read( fd, buffer, sizeof(buffer) ); 54 0 : if( FD_UNLIKELY( -1==result ) ) { 55 0 : if( FD_UNLIKELY( -1==close( fd ) ) ) FD_LOG_ERR(( "close failed `%s` (%i-%s)", genesis_path, errno, fd_io_strerror( errno ) )); 56 0 : return -1; 57 0 : } else if( FD_UNLIKELY( !result ) ) break; 58 : 59 0 : fd_sha256_append( sha, buffer, (ulong)result ); 60 0 : } 61 : 62 0 : if( FD_UNLIKELY( -1==close( fd ) ) ) FD_LOG_ERR(( "close failed `%s` (%i-%s)", genesis_path, errno, fd_io_strerror( errno ) )); 63 : 64 0 : union { 65 0 : uchar c[ 32 ]; 66 0 : ushort s[ 16 ]; 67 0 : } hash; 68 : 69 0 : fd_sha256_fini( sha, hash.c ); 70 0 : fd_sha256_delete( fd_sha256_leave( sha ) ); 71 : 72 0 : if( FD_LIKELY( opt_gen_hash ) ) memcpy( opt_gen_hash, hash.c, 32UL ); 73 0 : if( FD_LIKELY( opt_shred_version ) ) *opt_shred_version = compute_shred_version( hash.c, NULL, 0UL ); 74 : 75 0 : return 0; 76 0 : } 77 : 78 : #endif /* HEADER_fd_src_discof_genesis_genesis_hash_h */