@@ -314,3 +314,70 @@ impl Store {
314314 Ok ( changeset)
315315 }
316316}
317+
318+ #[ cfg( test) ]
319+ mod test {
320+ use super :: * ;
321+
322+ use bitcoin:: hashes:: Hash ;
323+
324+ #[ tokio:: test]
325+ async fn block_table_height_is_unique ( ) -> anyhow:: Result < ( ) > {
326+ let mut cs = local_chain:: ChangeSet :: default ( ) ;
327+ cs. blocks . insert ( 0 , Some ( Hash :: hash ( b"0" ) ) ) ;
328+ cs. blocks . insert ( 1 , Some ( Hash :: hash ( b"1" ) ) ) ;
329+
330+ let store = Store :: new_memory ( ) . await ?;
331+ store. migrate ( ) . await ?;
332+ store
333+ . write_local_chain ( & cs)
334+ . await
335+ . expect ( "failed to write `local_chain`" ) ;
336+
337+ // Trying to replace the value of existing height should be ignored.
338+ cs. blocks . insert ( 1 , Some ( Hash :: hash ( b"1a" ) ) ) ;
339+
340+ store
341+ . write_local_chain ( & cs)
342+ . await
343+ . expect ( "failed to write `local_chain`" ) ;
344+
345+ let rows = sqlx:: query ( "SELECT height, hash FROM block WHERE height = 1" )
346+ . fetch_all ( & store. pool )
347+ . await ?;
348+
349+ assert_eq ! ( rows. len( ) , 1 , "Expected 1 block row" ) ;
350+
351+ let row = rows. first ( ) . unwrap ( ) ;
352+ let row_hash: String = row. get ( "hash" ) ;
353+ let expected_hash: BlockHash = Hash :: hash ( b"1" ) ;
354+ assert_eq ! ( row_hash, expected_hash. to_string( ) ) ;
355+
356+ // Delete row 1 and insert hash "1a" again.
357+ let mut cs = local_chain:: ChangeSet :: default ( ) ;
358+ cs. blocks . insert ( 1 , None ) ;
359+ store
360+ . write_local_chain ( & cs)
361+ . await
362+ . expect ( "failed to write `local_chain`" ) ;
363+
364+ cs. blocks . insert ( 1 , Some ( Hash :: hash ( b"1a" ) ) ) ;
365+ store
366+ . write_local_chain ( & cs)
367+ . await
368+ . expect ( "failed to write `local_chain`" ) ;
369+
370+ let rows = sqlx:: query ( "SELECT height, hash FROM block WHERE height = 1" )
371+ . fetch_all ( & store. pool )
372+ . await ?;
373+
374+ // Row hash should change to "1a".
375+ assert_eq ! ( rows. len( ) , 1 , "Expected 1 block row" ) ;
376+ let row = rows. first ( ) . unwrap ( ) ;
377+ let row_hash: String = row. get ( "hash" ) ;
378+ let expected_hash: BlockHash = Hash :: hash ( b"1a" ) ;
379+ assert_eq ! ( row_hash, expected_hash. to_string( ) ) ;
380+
381+ Ok ( ( ) )
382+ }
383+ }
0 commit comments