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