@@ -1756,24 +1756,105 @@ fd_new_target_program_data_account( fd_exec_slot_ctx_t * slot_ctx,
1756
1756
} FD_SPAD_FRAME_END ;
1757
1757
}
1758
1758
1759
- /* Mimics migrate_builtin_to_core_bpf(). The arguments map as follows:
1760
- - builtin_program_id: builtin_program_id
1761
- - config
1762
- - source_buffer_address: source_buffer_address
1763
- - migration_target
1764
- - Builtin: !stateless
1765
- - Stateless: stateless
1766
- - upgrade_authority_address: upgrade_authority_address
1759
+ /* Initializes a source buffer account from funk. Returns 1 if the
1760
+ buffer account does not exist or is not owned by the upgradeable
1761
+ loader. Returns 0 on success.
1762
+
1763
+ https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L22-L49 */
1764
+ static int
1765
+ fd_source_buffer_account_new ( fd_exec_slot_ctx_t * slot_ctx ,
1766
+ fd_txn_account_t * buffer_account ,
1767
+ fd_pubkey_t const * buffer_address ,
1768
+ fd_funk_rec_prepare_t * prepare ) {
1769
+ /* The buffer account should exist.
1770
+ https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L27-L29 */
1771
+ if ( FD_UNLIKELY ( fd_txn_account_init_from_funk_mutable ( buffer_account , buffer_address , slot_ctx -> funk , slot_ctx -> funk_txn , 0 , 0UL , prepare )!= FD_ACC_MGR_SUCCESS ) ) {
1772
+ FD_LOG_WARNING (( "Buffer account %s does not exist, skipping migration..." , FD_BASE58_ENC_32_ALLOCA ( buffer_address ) ));
1773
+ return 1 ;
1774
+ }
1775
+
1776
+ /* The buffer account should be owned by the upgradeable loader.
1777
+ https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L31-L34 */
1778
+ if ( FD_UNLIKELY ( memcmp ( fd_txn_account_get_owner ( buffer_account ), fd_solana_bpf_loader_upgradeable_program_id .uc , sizeof (fd_pubkey_t ) ) ) ) {
1779
+ FD_LOG_WARNING (( "Buffer account %s is not owned by the upgradeable loader, skipping migration..." , FD_BASE58_ENC_32_ALLOCA ( buffer_address ) ));
1780
+ return 1 ;
1781
+ }
1782
+
1783
+ /* The buffer account should have the correct state. We already check
1784
+ the buffer account state in fd_new_target_program_data_account(),
1785
+ so we can skip the checks here.
1786
+ https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L37-L47 */
1787
+
1788
+ return 0 ;
1789
+ }
1790
+
1791
+ /* Similar to fd_source_buffer_account_new() but also checks the build
1792
+ hash of the buffer account for verification. verified_build_hash must
1793
+ be valid and non-NULL. Returns 1 if fd_source_buffer_account_new()
1794
+ fails, the buffer dlen is too small, or if the build hash mismatches.
1795
+ Returns 0 on success.
1796
+
1797
+ https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L51-L75 */
1798
+ static int
1799
+ fd_source_buffer_account_new_with_hash ( fd_exec_slot_ctx_t * slot_ctx ,
1800
+ fd_txn_account_t * buffer_account ,
1801
+ fd_pubkey_t const * buffer_address ,
1802
+ fd_hash_t const * verified_build_hash ,
1803
+ fd_funk_rec_prepare_t * prepare ) {
1804
+ /* https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L58 */
1805
+ int err = fd_source_buffer_account_new ( slot_ctx , buffer_account , buffer_address , prepare );
1806
+ if ( FD_UNLIKELY ( err ) ) {
1807
+ return err ;
1808
+ }
1809
+
1810
+ /* https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L59 */
1811
+ uchar const * data = fd_txn_account_get_data ( buffer_account );
1812
+ ulong data_len = fd_txn_account_get_data_len ( buffer_account );
1813
+
1814
+ /* https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L61 */
1815
+ ulong offset = BUFFER_METADATA_SIZE ;
1816
+ if ( FD_UNLIKELY ( data_len < offset ) ) {
1817
+ return 1 ;
1818
+ }
1819
+
1820
+ /* Search for the first nonzero byte in the buffer account data starting
1821
+ from the right.
1822
+ https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L62 */
1823
+ ulong end_offset = offset ;
1824
+ for ( ulong i = data_len - 1UL ; i >=offset ; i -- ) {
1825
+ if ( data [i ]!= 0 ) {
1826
+ end_offset = i + 1UL ;
1827
+ break ;
1828
+ }
1829
+ }
1830
+
1831
+ /* Compute and verify the hash.
1832
+ https://github.com/anza-xyz/agave/blob/v2.3.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L64-L71 */
1833
+ fd_hash_t hash [1 ];
1834
+ fd_sha256_hash ( data + offset , end_offset - offset , hash );
1835
+ if ( FD_UNLIKELY ( memcmp ( verified_build_hash , hash , sizeof (fd_hash_t ) ) ) ) {
1836
+ FD_LOG_WARNING (( "Mismatching build hash for Buffer account %s (expected=%s, actual=%s). Skipping migration..." , FD_BASE58_ENC_32_ALLOCA ( buffer_address ), FD_BASE58_ENC_32_ALLOCA ( verified_build_hash ), FD_BASE58_ENC_32_ALLOCA ( hash ) ));
1837
+ return 1 ;
1838
+ }
1839
+
1840
+ return 0 ;
1841
+ }
1842
+
1843
+ /* Mimics migrate_builtin_to_core_bpf().
1767
1844
https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L235-L318 */
1768
1845
static void
1769
- fd_migrate_builtin_to_core_bpf ( fd_exec_slot_ctx_t * slot_ctx ,
1770
- fd_pubkey_t * upgrade_authority_address ,
1771
- fd_pubkey_t const * builtin_program_id ,
1772
- fd_pubkey_t const * source_buffer_address ,
1773
- uchar stateless ,
1774
- fd_spad_t * runtime_spad ) {
1846
+ fd_migrate_builtin_to_core_bpf ( fd_exec_slot_ctx_t * slot_ctx ,
1847
+ fd_core_bpf_migration_config_t const * config ,
1848
+ fd_spad_t * runtime_spad ) {
1775
1849
int err ;
1776
1850
1851
+ /* Initialize local variables from the config */
1852
+ fd_pubkey_t const * source_buffer_address = config -> source_buffer_address ;
1853
+ fd_pubkey_t * upgrade_authority_address = config -> upgrade_authority_address ;
1854
+ uchar stateless = !!( config -> migration_target == FD_CORE_BPF_MIGRATION_TARGET_STATELESS );
1855
+ fd_pubkey_t const * builtin_program_id = config -> builtin_program_id ;
1856
+ fd_hash_t const * verified_build_hash = config -> verified_build_hash ;
1857
+
1777
1858
/* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L242-L243
1778
1859
1779
1860
The below logic is used to obtain a TargetBuiltin account. There
@@ -1836,19 +1917,22 @@ fd_migrate_builtin_to_core_bpf( fd_exec_slot_ctx_t * slot_ctx,
1836
1917
return ;
1837
1918
}
1838
1919
1839
- /* https://github.com/anza-xyz/agave/blob/v2.1 .0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L244
1920
+ /* https://github.com/anza-xyz/agave/blob/v2.3 .0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L221-L229
1840
1921
1841
1922
Obtains a SourceBuffer account. There are two fields returned:
1842
1923
- source.buffer_address: source_buffer_address
1843
- - source.buffer_account: the existing buffer account */
1844
-
1845
- /* The buffer account should exist.
1846
- https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L26-L29 */
1924
+ - source.buffer_account: the existing buffer account
1925
+ Depending on if the verified build hash is provided, */
1847
1926
FD_TXN_ACCOUNT_DECL ( source_buffer_account );
1848
1927
fd_funk_rec_prepare_t source_buffer_prepare = {0 };
1849
- if ( FD_UNLIKELY ( fd_txn_account_init_from_funk_mutable ( source_buffer_account , source_buffer_address , slot_ctx -> funk , slot_ctx -> funk_txn , 0 , 0UL , & source_buffer_prepare )!= FD_ACC_MGR_SUCCESS ) ) {
1850
- FD_LOG_NOTICE (( "Buffer account %s does not exist, skipping migration..." , FD_BASE58_ENC_32_ALLOCA ( source_buffer_address ) ));
1851
- return ;
1928
+ if ( verified_build_hash != NULL ) {
1929
+ if ( FD_UNLIKELY ( fd_source_buffer_account_new_with_hash ( slot_ctx , source_buffer_account , source_buffer_address , verified_build_hash , & source_buffer_prepare ) ) ) {
1930
+ return ;
1931
+ }
1932
+ } else {
1933
+ if ( FD_UNLIKELY ( fd_source_buffer_account_new ( slot_ctx , source_buffer_account , source_buffer_address , & source_buffer_prepare ) ) ) {
1934
+ return ;
1935
+ }
1852
1936
}
1853
1937
1854
1938
fd_lthash_value_t prev_source_buffer_hash [1 ];
@@ -1858,19 +1942,8 @@ fd_migrate_builtin_to_core_bpf( fd_exec_slot_ctx_t * slot_ctx,
1858
1942
fd_txn_account_get_data ( source_buffer_account ),
1859
1943
prev_source_buffer_hash );
1860
1944
1861
- /* The buffer account should be owned by the upgradeable loader.
1862
- https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L31-L34 */
1863
- if ( FD_UNLIKELY ( memcmp ( fd_txn_account_get_owner ( source_buffer_account ), fd_solana_bpf_loader_upgradeable_program_id .uc , sizeof (fd_pubkey_t ) ) ) ) {
1864
- FD_LOG_WARNING (( "Buffer account %s is not owned by the upgradeable loader, skipping migration..." , FD_BASE58_ENC_32_ALLOCA ( source_buffer_address ) ));
1865
- return ;
1866
- }
1867
-
1868
- /* The buffer account should have the correct state. We already check
1869
- the buffer account state in fd_new_target_program_data_account, so
1870
- we can skip the checks here.
1871
- https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/source_buffer.rs#L37-L47 */
1872
-
1873
- /* This check is done a bit prematurely because we calculate the previous account state's lamports. We use 0 for starting lamports
1945
+ /* This check is done a bit prematurely because we calculate the
1946
+ previous account state's lamports. We use 0 for starting lamports
1874
1947
for stateless accounts because they don't yet exist.
1875
1948
1876
1949
https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L277-L280 */
@@ -1883,8 +1956,9 @@ fd_migrate_builtin_to_core_bpf( fd_exec_slot_ctx_t * slot_ctx,
1883
1956
slot_ctx -> funk_txn = fd_funk_txn_prepare ( slot_ctx -> funk , slot_ctx -> funk_txn , & migration_xid , 0UL );
1884
1957
fd_funk_txn_end_write ( slot_ctx -> funk );
1885
1958
1886
- /* Attempt serialization of program account. If the program is stateless, we want to create the account. Otherwise,
1887
- we want a writable handle to modify the existing account.
1959
+ /* Attempt serialization of program account. If the program is
1960
+ stateless, we want to create the account. Otherwise, we want a
1961
+ writable handle to modify the existing account.
1888
1962
https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank/builtins/core_bpf_migration/mod.rs#L246-L249 */
1889
1963
FD_TXN_ACCOUNT_DECL ( new_target_program_account );
1890
1964
fd_funk_rec_prepare_t new_target_program_prepare = {0 };
@@ -2037,12 +2111,7 @@ fd_apply_builtin_program_feature_transitions( fd_exec_slot_ctx_t * slot_ctx,
2037
2111
/* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank.rs#L6732-L6751 */
2038
2112
if ( builtins [i ].core_bpf_migration_config && FD_FEATURE_ACTIVE_OFFSET ( fd_bank_slot_get ( slot_ctx -> bank ), fd_bank_features_get ( slot_ctx -> bank ), builtins [i ].core_bpf_migration_config -> enable_feature_offset ) ) {
2039
2113
FD_LOG_NOTICE (( "Migrating builtin program %s to core BPF" , FD_BASE58_ENC_32_ALLOCA ( builtins [i ].pubkey -> key ) ));
2040
- fd_migrate_builtin_to_core_bpf ( slot_ctx ,
2041
- builtins [i ].core_bpf_migration_config -> upgrade_authority_address ,
2042
- builtins [i ].core_bpf_migration_config -> builtin_program_id ,
2043
- builtins [i ].core_bpf_migration_config -> source_buffer_address ,
2044
- 0 ,
2045
- runtime_spad );
2114
+ fd_migrate_builtin_to_core_bpf ( slot_ctx , builtins [i ].core_bpf_migration_config , runtime_spad );
2046
2115
}
2047
2116
/* https://github.com/anza-xyz/agave/blob/v2.1.0/runtime/src/bank.rs#L6753-L6774 */
2048
2117
if ( builtins [i ].enable_feature_offset != NO_ENABLE_FEATURE_ID && FD_FEATURE_JUST_ACTIVATED_OFFSET ( slot_ctx , builtins [i ].enable_feature_offset ) ) {
@@ -2056,12 +2125,7 @@ fd_apply_builtin_program_feature_transitions( fd_exec_slot_ctx_t * slot_ctx,
2056
2125
for ( ulong i = 0UL ; i < fd_num_stateless_builtins (); i ++ ) {
2057
2126
if ( stateless_builtins [i ].core_bpf_migration_config && FD_FEATURE_ACTIVE_OFFSET ( fd_bank_slot_get ( slot_ctx -> bank ), fd_bank_features_get ( slot_ctx -> bank ), stateless_builtins [i ].core_bpf_migration_config -> enable_feature_offset ) ) {
2058
2127
FD_LOG_NOTICE (( "Migrating stateless builtin program %s to core BPF" , FD_BASE58_ENC_32_ALLOCA ( stateless_builtins [i ].pubkey -> key ) ));
2059
- fd_migrate_builtin_to_core_bpf ( slot_ctx ,
2060
- stateless_builtins [i ].core_bpf_migration_config -> upgrade_authority_address ,
2061
- stateless_builtins [i ].core_bpf_migration_config -> builtin_program_id ,
2062
- stateless_builtins [i ].core_bpf_migration_config -> source_buffer_address ,
2063
- 1 ,
2064
- runtime_spad );
2128
+ fd_migrate_builtin_to_core_bpf ( slot_ctx , stateless_builtins [i ].core_bpf_migration_config , runtime_spad );
2065
2129
}
2066
2130
}
2067
2131
0 commit comments