diff --git a/appdatabase/migrations/bindata.go b/appdatabase/migrations/bindata.go index dd82fccf3..b3c94b7a9 100644 --- a/appdatabase/migrations/bindata.go +++ b/appdatabase/migrations/bindata.go @@ -105,6 +105,7 @@ // 1704281285_tokens_advanced_settings.up.sql (743B) // 1705338819_collectible_preferences.up.sql (590B) // 1706097653_migration_order_fix.up.sql (9.484kB) +// 1706955596_community_storenodes.up.sql (515B) // doc.go (74B) package migrations @@ -188,7 +189,7 @@ func _1640111208_dummyUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1640111208_dummy.up.sql", size: 258, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1640111208_dummy.up.sql", size: 258, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xf0, 0xae, 0x20, 0x6e, 0x75, 0xd1, 0x36, 0x14, 0xf2, 0x40, 0xe5, 0xd6, 0x7a, 0xc4, 0xa5, 0x72, 0xaa, 0xb5, 0x4d, 0x71, 0x97, 0xb8, 0xe8, 0x95, 0x22, 0x95, 0xa2, 0xac, 0xaf, 0x48, 0x58}} return a, nil } @@ -208,7 +209,7 @@ func _1642666031_add_removed_clock_to_bookmarksUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1642666031_add_removed_clock_to_bookmarks.up.sql", size: 117, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1642666031_add_removed_clock_to_bookmarks.up.sql", size: 117, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x84, 0x4e, 0x38, 0x99, 0x7a, 0xc, 0x90, 0x13, 0xec, 0xfe, 0x2f, 0x55, 0xff, 0xb7, 0xb6, 0xaa, 0x96, 0xc6, 0x92, 0x79, 0xcc, 0xee, 0x4e, 0x99, 0x53, 0xfe, 0x1c, 0xbb, 0x32, 0x2, 0xa4, 0x27}} return a, nil } @@ -228,7 +229,7 @@ func _1643644541_gif_api_key_settingUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1643644541_gif_api_key_setting.up.sql", size: 108, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1643644541_gif_api_key_setting.up.sql", size: 108, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1b, 0x94, 0x28, 0xfb, 0x66, 0xd1, 0x7c, 0xb8, 0x89, 0xe2, 0xb4, 0x71, 0x65, 0x24, 0x57, 0x22, 0x95, 0x38, 0x97, 0x3, 0x9b, 0xc6, 0xa4, 0x41, 0x7b, 0xba, 0xf7, 0xdb, 0x70, 0xf7, 0x20, 0x3a}} return a, nil } @@ -248,7 +249,7 @@ func _1644188994_recent_stickersUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1644188994_recent_stickers.up.sql", size: 79, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1644188994_recent_stickers.up.sql", size: 79, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1e, 0xad, 0xaa, 0x30, 0xbf, 0x4, 0x7, 0xf8, 0xc3, 0x3, 0xb8, 0x97, 0x23, 0x2b, 0xbd, 0x1c, 0x60, 0x69, 0xb0, 0x42, 0x5e, 0x6b, 0xd, 0xa7, 0xa3, 0x6b, 0x2e, 0xdc, 0x70, 0x13, 0x72, 0x7}} return a, nil } @@ -268,7 +269,7 @@ func _1646659233_add_address_to_dapp_permisssionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1646659233_add_address_to_dapp_permisssion.up.sql", size: 700, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1646659233_add_address_to_dapp_permisssion.up.sql", size: 700, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xed, 0xb0, 0x35, 0xcc, 0x2e, 0x16, 0xe6, 0x15, 0x86, 0x2c, 0x37, 0x80, 0xae, 0xa3, 0xc5, 0x31, 0x78, 0x5, 0x9d, 0xcd, 0x7b, 0xeb, 0x5f, 0xf2, 0xb3, 0x74, 0x72, 0xdf, 0xcf, 0x88, 0xb, 0x40}} return a, nil } @@ -288,7 +289,7 @@ func _1646841105_add_emoji_accountUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1646841105_add_emoji_account.up.sql", size: 96, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1646841105_add_emoji_account.up.sql", size: 96, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe6, 0x77, 0x29, 0x95, 0x18, 0x64, 0x82, 0x63, 0xe7, 0xaf, 0x6c, 0xa9, 0x15, 0x7d, 0x46, 0xa6, 0xbc, 0xdf, 0xa7, 0xd, 0x2b, 0xd2, 0x2d, 0x97, 0x4d, 0xa, 0x6b, 0xd, 0x6e, 0x90, 0x42, 0x5c}} return a, nil } @@ -308,7 +309,7 @@ func _1647278782_display_nameUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1647278782_display_name.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1647278782_display_name.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf4, 0xa1, 0x1f, 0x3e, 0x61, 0x65, 0x8d, 0xff, 0xee, 0xde, 0xc5, 0x91, 0xd9, 0x5c, 0xb5, 0xe2, 0xf0, 0xb7, 0xe7, 0x5c, 0x5c, 0x16, 0x25, 0x89, 0xee, 0x78, 0x12, 0xea, 0x3e, 0x48, 0x41, 0xa6}} return a, nil } @@ -328,7 +329,7 @@ func _1647862838_reset_last_backupUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1647862838_reset_last_backup.up.sql", size: 37, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1647862838_reset_last_backup.up.sql", size: 37, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x21, 0xe3, 0xd5, 0xf6, 0x5f, 0xfe, 0x65, 0xfa, 0x1d, 0x88, 0xf8, 0x5f, 0x24, 0x71, 0x34, 0x68, 0x96, 0x2a, 0x60, 0x87, 0x15, 0x82, 0x4d, 0x8a, 0x59, 0x3d, 0x1f, 0xd8, 0x56, 0xd4, 0xfb, 0xda}} return a, nil } @@ -348,7 +349,7 @@ func _1647871652_add_settings_sync_clock_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1647871652_add_settings_sync_clock_table.up.sql", size: 1044, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1647871652_add_settings_sync_clock_table.up.sql", size: 1044, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd8, 0x58, 0xec, 0x85, 0x90, 0xfa, 0x30, 0x98, 0x98, 0x9a, 0xa6, 0xa8, 0x96, 0x2b, 0x38, 0x93, 0xf3, 0xae, 0x46, 0x74, 0xa4, 0x41, 0x62, 0x9b, 0x2, 0x86, 0xbf, 0xe5, 0x2a, 0xce, 0xe2, 0xc0}} return a, nil } @@ -368,7 +369,7 @@ func _1647880168_add_torrent_configUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1647880168_add_torrent_config.up.sql", size: 211, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1647880168_add_torrent_config.up.sql", size: 211, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0x92, 0x22, 0x37, 0x96, 0xf3, 0xb5, 0x5b, 0x27, 0xd0, 0x7d, 0x43, 0x5, 0x4e, 0x9d, 0xe2, 0x49, 0xbe, 0x86, 0x31, 0xa1, 0x89, 0xff, 0xd6, 0x51, 0xe0, 0x9c, 0xb, 0xda, 0xfc, 0xf2, 0x93}} return a, nil } @@ -388,7 +389,7 @@ func _1647882837_add_communities_settings_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1647882837_add_communities_settings_table.up.sql", size: 206, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1647882837_add_communities_settings_table.up.sql", size: 206, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xbd, 0x87, 0x78, 0x99, 0xd9, 0x5d, 0xbd, 0xf7, 0x57, 0x9c, 0xca, 0x97, 0xbd, 0xb3, 0xe9, 0xb5, 0x89, 0x31, 0x3f, 0xf6, 0x5c, 0x13, 0xb, 0xc3, 0x54, 0x93, 0x18, 0x40, 0x7, 0x82, 0xfe, 0x7e}} return a, nil } @@ -408,7 +409,7 @@ func _1647956635_add_waku_messages_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1647956635_add_waku_messages_table.up.sql", size: 266, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1647956635_add_waku_messages_table.up.sql", size: 266, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd1, 0xe, 0xe1, 0xdc, 0xda, 0x2e, 0x89, 0x8d, 0xdc, 0x2a, 0x1c, 0x13, 0xa1, 0xfc, 0xfe, 0xf, 0xb2, 0xb9, 0x85, 0xc8, 0x45, 0xd6, 0xd1, 0x7, 0x5c, 0xa3, 0x8, 0x47, 0x44, 0x6d, 0x96, 0xe0}} return a, nil } @@ -428,7 +429,7 @@ func _1648554928_network_testUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1648554928_network_test.up.sql", size: 132, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1648554928_network_test.up.sql", size: 132, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9a, 0xc5, 0x7f, 0x87, 0xf3, 0x2c, 0xf7, 0xbb, 0xd3, 0x3a, 0x4e, 0x76, 0x88, 0xca, 0xaf, 0x73, 0xce, 0x8f, 0xa1, 0xf6, 0x3d, 0x4d, 0xed, 0x6f, 0x49, 0xf2, 0xfe, 0x56, 0x2a, 0x60, 0x68, 0xca}} return a, nil } @@ -448,7 +449,7 @@ func _1649174829_add_visitble_tokenUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1649174829_add_visitble_token.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1649174829_add_visitble_token.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa3, 0x22, 0xc0, 0x2b, 0x3f, 0x4f, 0x3d, 0x5e, 0x4c, 0x68, 0x7c, 0xd0, 0x15, 0x36, 0x9f, 0xec, 0xa1, 0x2a, 0x7b, 0xb4, 0xe3, 0xc6, 0xc9, 0xb4, 0x81, 0x50, 0x4a, 0x11, 0x3b, 0x35, 0x7, 0xcf}} return a, nil } @@ -468,7 +469,7 @@ func _1649882262_add_derived_from_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1649882262_add_derived_from_accounts.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1649882262_add_derived_from_accounts.up.sql", size: 110, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x11, 0xb9, 0x44, 0x4d, 0x85, 0x8d, 0x7f, 0xb4, 0xae, 0x4f, 0x5c, 0x66, 0x64, 0xb6, 0xe2, 0xe, 0x3d, 0xad, 0x9d, 0x8, 0x4f, 0xab, 0x6e, 0xa8, 0x7d, 0x76, 0x3, 0xad, 0x96, 0x1, 0xee, 0x5c}} return a, nil } @@ -488,7 +489,7 @@ func _1650612625_add_community_message_archive_hashes_tableUpSql() (*asset, erro return nil, err } - info := bindataFileInfo{name: "1650612625_add_community_message_archive_hashes_table.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1650612625_add_community_message_archive_hashes_table.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x48, 0x31, 0xb3, 0x75, 0x23, 0xe2, 0x45, 0xe, 0x47, 0x1b, 0x35, 0xa5, 0x6e, 0x83, 0x4e, 0x64, 0x7d, 0xd7, 0xa2, 0xda, 0xe9, 0x53, 0xf1, 0x16, 0x86, 0x2c, 0x57, 0xad, 0xfa, 0xca, 0x39, 0xde}} return a, nil } @@ -508,7 +509,7 @@ func _1650616788_add_communities_archives_info_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1650616788_add_communities_archives_info_table.up.sql", size: 208, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1650616788_add_communities_archives_info_table.up.sql", size: 208, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd1, 0x4f, 0x80, 0x45, 0xb9, 0xd9, 0x15, 0xe2, 0x78, 0xd0, 0xcb, 0x71, 0xc1, 0x1b, 0xb7, 0x1b, 0x1b, 0x97, 0xfe, 0x47, 0x53, 0x3c, 0x62, 0xbc, 0xdd, 0x3a, 0x94, 0x1a, 0xc, 0x48, 0x76, 0xe}} return a, nil } @@ -528,7 +529,7 @@ func _1652715604_add_clock_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1652715604_add_clock_accounts.up.sql", size: 62, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1652715604_add_clock_accounts.up.sql", size: 62, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb6, 0xd9, 0x8d, 0x73, 0xc9, 0xef, 0xfa, 0xb1, 0x4b, 0xa5, 0xf3, 0x5, 0x19, 0x26, 0x46, 0xf8, 0x47, 0x93, 0xdb, 0xac, 0x2, 0xef, 0xf9, 0x71, 0x56, 0x83, 0xe6, 0x2d, 0xb0, 0xd7, 0x83, 0x5c}} return a, nil } @@ -548,7 +549,7 @@ func _1653037334_add_notifications_settings_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1653037334_add_notifications_settings_table.up.sql", size: 1276, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1653037334_add_notifications_settings_table.up.sql", size: 1276, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4b, 0xc4, 0x65, 0xac, 0xa, 0xf2, 0xef, 0xb6, 0x39, 0x3c, 0xc5, 0xb1, 0xb2, 0x9c, 0x86, 0x58, 0xe0, 0x38, 0xcb, 0x57, 0x3c, 0x76, 0x73, 0x87, 0x79, 0x4e, 0xf6, 0xed, 0xb0, 0x8e, 0x9e, 0xa}} return a, nil } @@ -568,7 +569,7 @@ func _1654702119_add_mutual_contact_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1654702119_add_mutual_contact_settings.up.sql", size: 78, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1654702119_add_mutual_contact_settings.up.sql", size: 78, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x26, 0x66, 0x67, 0x50, 0xfe, 0xd7, 0xe3, 0x29, 0x8b, 0xff, 0x9d, 0x5a, 0x87, 0xa7, 0x99, 0x6e, 0xd6, 0xcd, 0x2e, 0xbb, 0x17, 0xdf, 0x7f, 0xf7, 0xa3, 0xfa, 0x32, 0x7c, 0x2d, 0x92, 0xc8, 0x74}} return a, nil } @@ -588,7 +589,7 @@ func _1655375270_add_clock_field_to_communities_settings_tableUpSql() (*asset, e return nil, err } - info := bindataFileInfo{name: "1655375270_add_clock_field_to_communities_settings_table.up.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1655375270_add_clock_field_to_communities_settings_table.up.sql", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x19, 0xc5, 0xc0, 0xf9, 0x84, 0x53, 0xdf, 0x83, 0xcf, 0xb6, 0x40, 0x6d, 0xf5, 0xdc, 0x77, 0x37, 0xb7, 0xe3, 0xa, 0x75, 0xe7, 0x6, 0x11, 0xca, 0x2b, 0x51, 0x92, 0xdd, 0x7d, 0xdb, 0xc3, 0xf5}} return a, nil } @@ -608,7 +609,7 @@ func _1655385721_drop_networks_configUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1655385721_drop_networks_config.up.sql", size: 27, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1655385721_drop_networks_config.up.sql", size: 27, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfc, 0xa7, 0x20, 0xbb, 0x67, 0x21, 0xe, 0xc6, 0xc8, 0x21, 0x74, 0xe0, 0xce, 0xc8, 0xe2, 0x2, 0xb4, 0xea, 0xf0, 0xe5, 0xc4, 0x4d, 0xdd, 0xd4, 0x52, 0x31, 0xa9, 0x3d, 0xcd, 0xd8, 0x9b, 0xab}} return a, nil } @@ -628,7 +629,7 @@ func _1655385724_networks_chaincolor_shortnameUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1655385724_networks_chainColor_shortName.up.sql", size: 220, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1655385724_networks_chainColor_shortName.up.sql", size: 220, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd9, 0xe7, 0x84, 0xbb, 0x5f, 0xd2, 0x2c, 0x42, 0x88, 0x62, 0x52, 0xb6, 0x58, 0x31, 0xac, 0xc, 0x96, 0x2b, 0x1b, 0xe5, 0x4e, 0x9a, 0x3a, 0xf6, 0xf6, 0xfc, 0xa9, 0x1a, 0x35, 0x62, 0x28, 0x88}} return a, nil } @@ -648,7 +649,7 @@ func _1655456688_add_deleted_at_field_to_bookmarks_tableUpSql() (*asset, error) return nil, err } - info := bindataFileInfo{name: "1655456688_add_deleted_at_field_to_bookmarks_table.up.sql", size: 69, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1655456688_add_deleted_at_field_to_bookmarks_table.up.sql", size: 69, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe7, 0x9a, 0xbd, 0x9a, 0xc9, 0xf, 0xdf, 0x90, 0x0, 0x5d, 0xea, 0x6e, 0x7d, 0x51, 0x95, 0xcd, 0x90, 0xd3, 0x1a, 0x36, 0x6c, 0xf4, 0xbd, 0xa7, 0x6b, 0xbf, 0xe5, 0xdb, 0xa3, 0x88, 0xe3, 0x50}} return a, nil } @@ -668,7 +669,7 @@ func _1655462032_create_bookmarks_deleted_at_indexUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1655462032_create_bookmarks_deleted_at_index.up.sql", size: 81, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1655462032_create_bookmarks_deleted_at_index.up.sql", size: 81, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf, 0x8e, 0x20, 0x6b, 0x14, 0x9e, 0xcd, 0x97, 0xd3, 0xfe, 0x62, 0x3, 0x26, 0x59, 0x1, 0x6c, 0x99, 0xef, 0x6d, 0x21, 0xd4, 0xb5, 0xa3, 0xf4, 0x39, 0x40, 0x54, 0x6, 0xd, 0x60, 0x13, 0x38}} return a, nil } @@ -688,7 +689,7 @@ func _1657617291_add_multi_transactions_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1657617291_add_multi_transactions_table.up.sql", size: 412, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1657617291_add_multi_transactions_table.up.sql", size: 412, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x86, 0xb0, 0x4e, 0x8c, 0x4, 0x82, 0xb4, 0x43, 0xaa, 0xd0, 0x16, 0xdd, 0xcb, 0x88, 0x81, 0xac, 0x4, 0x34, 0x1a, 0x8f, 0x2e, 0xc5, 0x69, 0xb, 0xf0, 0x17, 0xf7, 0xe3, 0x9, 0xe, 0x54, 0xe0}} return a, nil } @@ -708,7 +709,7 @@ func _1660134042_add_social_links_settings_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1660134042_add_social_links_settings_table.up.sql", size: 334, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1660134042_add_social_links_settings_table.up.sql", size: 334, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x84, 0x73, 0xb6, 0xe7, 0x3f, 0xaa, 0x39, 0x9a, 0x56, 0x56, 0x31, 0xf1, 0x8e, 0x26, 0x23, 0x1, 0xe4, 0xfa, 0x98, 0xfe, 0x78, 0x87, 0x20, 0xcb, 0x52, 0xf4, 0x38, 0x7f, 0xc4, 0x1c, 0x4, 0x22}} return a, nil } @@ -728,7 +729,7 @@ func _1660134060_settings_bioUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1660134060_settings_bio.up.sql", size: 91, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1660134060_settings_bio.up.sql", size: 91, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x46, 0x25, 0xa0, 0xa6, 0x47, 0xff, 0xbc, 0x2a, 0x0, 0xff, 0x59, 0x4b, 0xb0, 0xc9, 0x4e, 0x15, 0xe4, 0xd9, 0xda, 0xeb, 0xfe, 0x55, 0x98, 0xc3, 0x9d, 0x96, 0xe7, 0xf, 0xd1, 0x5c, 0x93, 0x73}} return a, nil } @@ -748,7 +749,7 @@ func _1660134070_add_wakuv2_storeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1660134070_add_wakuv2_store.up.sql", size: 269, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1660134070_add_wakuv2_store.up.sql", size: 269, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1d, 0xe6, 0xc3, 0x9, 0xef, 0xdc, 0xae, 0x49, 0x30, 0x78, 0x54, 0xd6, 0xdb, 0xbf, 0xc0, 0x8e, 0x25, 0x8f, 0xfc, 0x67, 0x80, 0x39, 0x37, 0xd4, 0x86, 0xc1, 0x85, 0xc8, 0x99, 0xc4, 0x59, 0xd4}} return a, nil } @@ -768,7 +769,7 @@ func _1660134072_waku2_store_messagesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1660134072_waku2_store_messages.up.sql", size: 497, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1660134072_waku2_store_messages.up.sql", size: 497, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xeb, 0xb4, 0xa0, 0xa1, 0x2b, 0xcb, 0x4c, 0x3c, 0xc6, 0xd0, 0xe8, 0x96, 0xe3, 0x96, 0xf1, 0x4f, 0x1f, 0xe0, 0xe7, 0x1f, 0x85, 0xa3, 0xe, 0xf7, 0x52, 0x56, 0x63, 0x2b, 0xb0, 0x87, 0x7b}} return a, nil } @@ -788,7 +789,7 @@ func _1662365868_add_key_uid_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1662365868_add_key_uid_accounts.up.sql", size: 68, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1662365868_add_key_uid_accounts.up.sql", size: 68, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc6, 0xd8, 0x2f, 0x2f, 0x3b, 0xa8, 0xbd, 0x6d, 0xf6, 0x87, 0x7e, 0xd2, 0xf1, 0xa2, 0xf7, 0x81, 0x6a, 0x23, 0x10, 0xbc, 0xbf, 0x5b, 0xe7, 0x2b, 0x9c, 0xa9, 0x8a, 0x18, 0xbb, 0xd0, 0x86, 0x91}} return a, nil } @@ -808,7 +809,7 @@ func _1662447680_add_keypairs_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1662447680_add_keypairs_table.up.sql", size: 218, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1662447680_add_keypairs_table.up.sql", size: 218, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdc, 0x25, 0xa9, 0xc7, 0x63, 0x27, 0x97, 0x35, 0x5f, 0x6b, 0xab, 0x26, 0xcb, 0xf9, 0xbd, 0x5e, 0xac, 0x3, 0xa0, 0x5e, 0xb9, 0x71, 0xa3, 0x1f, 0xb3, 0x4f, 0x7f, 0x79, 0x28, 0x48, 0xbe, 0xc}} return a, nil } @@ -828,7 +829,7 @@ func _1662460056_move_favourites_to_saved_addressesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1662460056_move_favourites_to_saved_addresses.up.sql", size: 233, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1662460056_move_favourites_to_saved_addresses.up.sql", size: 233, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x10, 0xa2, 0x8c, 0xa3, 0xec, 0xad, 0xdf, 0xc3, 0x48, 0x5, 0x9b, 0x50, 0x25, 0x59, 0xae, 0x7d, 0xee, 0x58, 0xd2, 0x41, 0x27, 0xf2, 0x22, 0x2e, 0x9a, 0xb9, 0x4a, 0xcc, 0x38, 0x6e, 0x3a, 0xb2}} return a, nil } @@ -848,7 +849,7 @@ func _1662738097_add_base_fee_transactionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1662738097_add_base_fee_transaction.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1662738097_add_base_fee_transaction.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6b, 0xfb, 0x10, 0xae, 0xfc, 0x77, 0x70, 0x98, 0x6f, 0xec, 0xaa, 0xcd, 0x7, 0xc7, 0x74, 0x23, 0xc, 0xd5, 0x1e, 0x82, 0xdd, 0xfe, 0xff, 0x3b, 0xd2, 0x49, 0x10, 0x5b, 0x30, 0xc, 0x2d, 0xb0}} return a, nil } @@ -868,7 +869,7 @@ func _1662972194_add_keypairs_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1662972194_add_keypairs_table.up.sql", size: 345, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1662972194_add_keypairs_table.up.sql", size: 345, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xab, 0x76, 0xf2, 0x86, 0xe1, 0x7e, 0xe9, 0x47, 0x32, 0x48, 0xd5, 0x6b, 0xe5, 0xd, 0xab, 0xb7, 0xf1, 0xd4, 0xf1, 0xad, 0x38, 0xa6, 0x11, 0xe7, 0xce, 0x5c, 0x11, 0x11, 0xf, 0x47, 0xb2, 0x4}} return a, nil } @@ -888,7 +889,7 @@ func _1664392661_add_third_party_id_to_waku_messagesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1664392661_add_third_party_id_to_waku_messages.up.sql", size: 70, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1664392661_add_third_party_id_to_waku_messages.up.sql", size: 70, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfd, 0x67, 0x66, 0x9e, 0x66, 0x74, 0xce, 0x1c, 0xb, 0x1b, 0x9d, 0xd5, 0xfc, 0x65, 0xe, 0x83, 0x90, 0x4c, 0x61, 0x4e, 0x6b, 0xe7, 0x86, 0xbe, 0x36, 0x4f, 0x91, 0x36, 0x4, 0x47, 0x7b, 0x82}} return a, nil } @@ -908,7 +909,7 @@ func _1664783660_add_sync_info_to_saved_addressesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1664783660_add_sync_info_to_saved_addresses.up.sql", size: 388, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1664783660_add_sync_info_to_saved_addresses.up.sql", size: 388, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x67, 0x7c, 0x3a, 0x95, 0x4e, 0x55, 0xb2, 0xbd, 0xb4, 0x18, 0x93, 0xc1, 0xcf, 0x9f, 0x12, 0xbb, 0x49, 0x8a, 0x2a, 0x6a, 0x2a, 0x7f, 0xad, 0x44, 0xc3, 0xf, 0x3a, 0x79, 0x18, 0xb9, 0x4c, 0x64}} return a, nil } @@ -928,7 +929,7 @@ func _1668109917_wakunodesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1668109917_wakunodes.up.sql", size: 99, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1668109917_wakunodes.up.sql", size: 99, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x29, 0xaa, 0x9e, 0x2, 0x66, 0x85, 0x69, 0xa8, 0xd9, 0xe2, 0x4b, 0x8d, 0x2a, 0x9c, 0xdf, 0xd2, 0xef, 0x64, 0x58, 0xe3, 0xa6, 0xe7, 0xc1, 0xd1, 0xc8, 0x9c, 0xc0, 0x2c, 0x1, 0xa8, 0x7b, 0x81}} return a, nil } @@ -948,7 +949,7 @@ func _1670249678_display_name_to_settings_sync_clock_tableUpSql() (*asset, error return nil, err } - info := bindataFileInfo{name: "1670249678_display_name_to_settings_sync_clock_table.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1670249678_display_name_to_settings_sync_clock_table.up.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x39, 0x18, 0xdc, 0xc4, 0x1f, 0x79, 0x22, 0x16, 0x4d, 0xdf, 0x6c, 0x66, 0xd5, 0xa4, 0x88, 0x5d, 0x5, 0x37, 0xa7, 0x41, 0x5, 0x50, 0xae, 0x12, 0xfa, 0x7e, 0x89, 0x24, 0x5c, 0xae, 0x30, 0xfc}} return a, nil } @@ -968,7 +969,7 @@ func _1670836810_add_imported_flag_to_community_archive_hashesUpSql() (*asset, e return nil, err } - info := bindataFileInfo{name: "1670836810_add_imported_flag_to_community_archive_hashes.up.sql", size: 144, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1670836810_add_imported_flag_to_community_archive_hashes.up.sql", size: 144, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6f, 0xf, 0xf0, 0xbd, 0xfe, 0x63, 0x25, 0x8f, 0x5e, 0x46, 0x4b, 0x45, 0x31, 0x8b, 0x3e, 0xd8, 0x6b, 0x5d, 0x9d, 0x6d, 0x10, 0x9a, 0x87, 0x4b, 0x18, 0xc6, 0x39, 0x81, 0x6e, 0xe4, 0x75, 0xfb}} return a, nil } @@ -988,7 +989,7 @@ func _1671438731_add_magnetlink_uri_to_communities_archive_infoUpSql() (*asset, return nil, err } - info := bindataFileInfo{name: "1671438731_add_magnetlink_uri_to_communities_archive_info.up.sql", size: 86, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1671438731_add_magnetlink_uri_to_communities_archive_info.up.sql", size: 86, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xda, 0x8b, 0x4b, 0xd6, 0xd8, 0xe2, 0x3d, 0xf7, 0x6b, 0xcd, 0x1e, 0x70, 0x9, 0x2e, 0x35, 0x4, 0x61, 0xc3, 0xb5, 0x9d, 0xc5, 0x27, 0x21, 0xa, 0x5a, 0xd6, 0x3e, 0xa6, 0x24, 0xa2, 0x12, 0xdf}} return a, nil } @@ -1008,7 +1009,7 @@ func _1672933930_switcher_cardUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1672933930_switcher_card.up.sql", size: 162, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1672933930_switcher_card.up.sql", size: 162, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x39, 0xba, 0xdc, 0xbb, 0x40, 0x4, 0xf2, 0x10, 0xdf, 0xb4, 0xd2, 0x80, 0x8a, 0x74, 0x4d, 0xf6, 0xbc, 0x50, 0x7, 0xd, 0x22, 0x7f, 0xc4, 0xaf, 0xaa, 0xde, 0xdc, 0x71, 0xe9, 0x42, 0x98, 0x36}} return a, nil } @@ -1028,7 +1029,7 @@ func _1674056187_add_price_cacheUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1674056187_add_price_cache.up.sql", size: 255, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1674056187_add_price_cache.up.sql", size: 255, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb7, 0x79, 0x6a, 0x9b, 0x28, 0xd1, 0x22, 0xf0, 0x84, 0x76, 0x40, 0x39, 0x49, 0x15, 0x5d, 0xaa, 0xfd, 0x11, 0xff, 0x13, 0x27, 0x42, 0x12, 0xfa, 0x82, 0xe6, 0x7a, 0xf0, 0x5e, 0x1f, 0xe3, 0xba}} return a, nil } @@ -1048,7 +1049,7 @@ func _1674136690_ens_usernamesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1674136690_ens_usernames.up.sql", size: 98, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1674136690_ens_usernames.up.sql", size: 98, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x81, 0x7a, 0xf3, 0xa8, 0x88, 0x99, 0xd6, 0x9c, 0x69, 0x48, 0x3c, 0x10, 0xda, 0x72, 0xdc, 0x14, 0xd, 0x6e, 0x8c, 0x82, 0x92, 0x2d, 0x2c, 0xee, 0x4c, 0x70, 0xa4, 0xdc, 0x5c, 0x5, 0x2, 0xc3}} return a, nil } @@ -1068,7 +1069,7 @@ func _1674232431_add_balance_historyUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1674232431_add_balance_history.up.sql", size: 698, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1674232431_add_balance_history.up.sql", size: 698, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf7, 0xb5, 0x18, 0xca, 0x4a, 0x93, 0xbb, 0x6f, 0xa4, 0xee, 0xe4, 0x3e, 0xff, 0x6a, 0x4b, 0xe2, 0xe1, 0x61, 0x28, 0xee, 0xc5, 0x26, 0x57, 0x61, 0x5e, 0x6d, 0x44, 0x1e, 0x85, 0x43, 0x70, 0xa2}} return a, nil } @@ -1088,7 +1089,7 @@ func _1676368933_keypairs_to_keycardsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1676368933_keypairs_to_keycards.up.sql", size: 639, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1676368933_keypairs_to_keycards.up.sql", size: 639, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x81, 0x93, 0x27, 0x2, 0xf0, 0x37, 0x81, 0x65, 0xa4, 0xb3, 0x5b, 0x60, 0x36, 0x95, 0xfc, 0x81, 0xf0, 0x3b, 0x7c, 0xc3, 0x2c, 0x85, 0xbd, 0x38, 0x46, 0xa4, 0x95, 0x4a, 0x6, 0x3e, 0x74, 0xd5}} return a, nil } @@ -1108,7 +1109,7 @@ func _1676951398_add_currency_format_cacheUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1676951398_add_currency_format_cache.up.sql", size: 291, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1676951398_add_currency_format_cache.up.sql", size: 291, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf9, 0xa3, 0x76, 0x35, 0xca, 0xf, 0xe8, 0xdf, 0xd9, 0x61, 0xf9, 0xed, 0xfc, 0x6d, 0xf5, 0xe, 0x11, 0x88, 0xbd, 0x14, 0x92, 0xc6, 0x57, 0x53, 0xe, 0xcd, 0x52, 0xf4, 0xa9, 0xb1, 0xdd, 0xfd}} return a, nil } @@ -1128,7 +1129,7 @@ func _1676968196_keycards_add_clock_columnUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1676968196_keycards_add_clock_column.up.sql", size: 73, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1676968196_keycards_add_clock_column.up.sql", size: 73, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4c, 0xf, 0x1c, 0x28, 0x41, 0x57, 0x57, 0x6c, 0xe, 0x75, 0x6b, 0x75, 0x12, 0x0, 0x18, 0x1e, 0x88, 0x1e, 0x45, 0xe0, 0x32, 0xb9, 0xd4, 0xd9, 0x2e, 0xc8, 0xb, 0x80, 0x6, 0x51, 0x3d, 0x28}} return a, nil } @@ -1148,7 +1149,7 @@ func _1676968197_add_fallback_rpc_to_networksUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1676968197_add_fallback_rpc_to_networks.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1676968197_add_fallback_rpc_to_networks.up.sql", size: 112, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x77, 0x6a, 0xc6, 0x45, 0xfa, 0x62, 0x84, 0x74, 0x6d, 0x7c, 0xd7, 0x1d, 0x79, 0xb6, 0x38, 0x43, 0xa8, 0x8, 0x6b, 0x75, 0x3d, 0x9, 0x2, 0xc5, 0x9f, 0xbb, 0x45, 0x56, 0x4c, 0x4e, 0x17, 0x89}} return a, nil } @@ -1168,7 +1169,7 @@ func _1677674090_add_chains_ens_istest_to_saved_addressesUpSql() (*asset, error) return nil, err } - info := bindataFileInfo{name: "1677674090_add_chains_ens_istest_to_saved_addresses.up.sql", size: 638, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1677674090_add_chains_ens_istest_to_saved_addresses.up.sql", size: 638, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0x2d, 0xa4, 0x1b, 0xf6, 0x6a, 0x13, 0x7b, 0xe, 0x59, 0xcd, 0xe2, 0x4e, 0x81, 0x99, 0xc4, 0x33, 0x84, 0xde, 0x66, 0xca, 0xac, 0x2f, 0x5, 0x90, 0xac, 0xfd, 0x4e, 0xfc, 0x55, 0x44, 0xe5}} return a, nil } @@ -1188,7 +1189,7 @@ func _1677681143_accounts_table_type_column_updateUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1677681143_accounts_table_type_column_update.up.sql", size: 135, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1677681143_accounts_table_type_column_update.up.sql", size: 135, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd2, 0xc4, 0x6, 0x42, 0x50, 0x1d, 0xf4, 0x48, 0x55, 0xbc, 0xa2, 0x19, 0xdd, 0xad, 0xc8, 0xc, 0xa7, 0x30, 0xb6, 0xaf, 0xe, 0x2b, 0xaa, 0x2a, 0xa4, 0xe1, 0xb9, 0x41, 0x23, 0x66, 0xd3, 0x3}} return a, nil } @@ -1208,7 +1209,7 @@ func _1678264207_accounts_table_new_columns_addedUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1678264207_accounts_table_new_columns_added.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1678264207_accounts_table_new_columns_added.up.sql", size: 130, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf4, 0xd4, 0xf3, 0x35, 0xef, 0x5c, 0x19, 0x3c, 0x15, 0x90, 0x60, 0xbd, 0x1f, 0x81, 0xf0, 0x86, 0x73, 0x89, 0xa0, 0x70, 0xf2, 0x46, 0xae, 0xea, 0xd0, 0xc6, 0x9e, 0x55, 0x4a, 0x54, 0x62, 0xbb}} return a, nil } @@ -1228,7 +1229,7 @@ func _1680770368_add_bio_to_settings_sync_clock_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1680770368_add_bio_to_settings_sync_clock_table.up.sql", size: 75, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1680770368_add_bio_to_settings_sync_clock_table.up.sql", size: 75, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4a, 0x52, 0xf6, 0x3f, 0xaa, 0xd, 0xa0, 0xee, 0xe8, 0xe6, 0x16, 0x21, 0x80, 0x61, 0xe4, 0x7a, 0x4e, 0x37, 0x8d, 0x30, 0x51, 0x20, 0x4d, 0x15, 0x47, 0xfb, 0x6, 0xa1, 0xce, 0xc8, 0x27, 0x5a}} return a, nil } @@ -1248,7 +1249,7 @@ func _1681110436_add_mnemonic_to_settings_sync_clock_tableUpSql() (*asset, error return nil, err } - info := bindataFileInfo{name: "1681110436_add_mnemonic_to_settings_sync_clock_table.up.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1681110436_add_mnemonic_to_settings_sync_clock_table.up.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3d, 0x74, 0x81, 0x7d, 0x9e, 0x77, 0xb6, 0xfe, 0xe3, 0xcb, 0x48, 0xe5, 0x5f, 0x39, 0x23, 0xa1, 0x7d, 0x53, 0x22, 0xe8, 0x96, 0x15, 0x8a, 0x1e, 0x8e, 0xbc, 0xe2, 0x1d, 0xc4, 0xc2, 0x56, 0x34}} return a, nil } @@ -1268,7 +1269,7 @@ func _1681392602_9d_sync_periodUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1681392602_9d_sync_period.up.sql", size: 60, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1681392602_9d_sync_period.up.sql", size: 60, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc9, 0xa, 0x90, 0x29, 0x7f, 0x76, 0x98, 0xa7, 0x71, 0x80, 0x5a, 0x2f, 0xbe, 0x23, 0x9a, 0xd4, 0xf4, 0x39, 0x19, 0xd3, 0xa5, 0x34, 0x6e, 0x67, 0x6a, 0xbe, 0x8a, 0xad, 0x21, 0xc7, 0xba, 0x88}} return a, nil } @@ -1288,7 +1289,7 @@ func _1681762078_default_sync_period_9dUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1681762078_default_sync_period_9d.up.sql", size: 3002, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1681762078_default_sync_period_9d.up.sql", size: 3002, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3e, 0xd9, 0x26, 0xfc, 0xa9, 0x45, 0xc1, 0x81, 0xa8, 0xe2, 0x2c, 0xe9, 0x3c, 0xea, 0x1d, 0x37, 0x11, 0x45, 0x8c, 0x6c, 0xbc, 0xc2, 0x6, 0x69, 0x2, 0x75, 0x29, 0x40, 0x9f, 0xc5, 0xbb, 0x36}} return a, nil } @@ -1308,7 +1309,7 @@ func _1681780680_add_clock_to_social_links_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1681780680_add_clock_to_social_links_settings.up.sql", size: 137, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1681780680_add_clock_to_social_links_settings.up.sql", size: 137, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x63, 0x11, 0xf5, 0x41, 0xe5, 0x5a, 0xf4, 0xe3, 0xf3, 0x14, 0x87, 0x28, 0xd8, 0xf0, 0x52, 0x31, 0x8, 0xd5, 0xbb, 0xf4, 0xff, 0x55, 0x5f, 0x42, 0x90, 0xcb, 0xf7, 0x46, 0x2, 0x6, 0xbe, 0x42}} return a, nil } @@ -1328,7 +1329,7 @@ func _1682073779_settings_table_remove_latest_derived_path_columnUpSql() (*asset return nil, err } - info := bindataFileInfo{name: "1682073779_settings_table_remove_latest_derived_path_column.up.sql", size: 4470, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1682073779_settings_table_remove_latest_derived_path_column.up.sql", size: 4470, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7a, 0x36, 0x2, 0x41, 0xd, 0x5c, 0xd1, 0x92, 0x85, 0x6d, 0x84, 0xff, 0x67, 0xa7, 0x4c, 0x67, 0xa4, 0xef, 0x52, 0x69, 0x1f, 0x22, 0x25, 0x92, 0xc, 0xb3, 0x89, 0x50, 0x91, 0xc, 0x49, 0xf9}} return a, nil } @@ -1348,7 +1349,7 @@ func _1682146075_add_created_at_to_saved_addressesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1682146075_add_created_at_to_saved_addresses.up.sql", size: 107, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1682146075_add_created_at_to_saved_addresses.up.sql", size: 107, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x88, 0xfe, 0x35, 0x9c, 0x6b, 0xdf, 0x67, 0x18, 0x16, 0xe4, 0xc9, 0xd4, 0x77, 0x7c, 0x4, 0xe2, 0x6c, 0x41, 0xd9, 0x53, 0x97, 0xfe, 0x5, 0xa3, 0x23, 0xce, 0x82, 0xad, 0x92, 0x5e, 0xd7, 0x7d}} return a, nil } @@ -1368,7 +1369,7 @@ func _1682393575_sync_ens_nameUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1682393575_sync_ens_name.up.sql", size: 713, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1682393575_sync_ens_name.up.sql", size: 713, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfb, 0xea, 0xcb, 0x4d, 0x71, 0x5a, 0x49, 0x19, 0x8b, 0xef, 0x66, 0x27, 0x33, 0x89, 0xb0, 0xe, 0x37, 0x1b, 0x41, 0x8, 0x12, 0xcc, 0x56, 0xd8, 0x1b, 0xf, 0xf8, 0x50, 0x4b, 0x93, 0xf1, 0x29}} return a, nil } @@ -1388,7 +1389,7 @@ func _1683457503_add_blocks_ranges_sequential_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1683457503_add_blocks_ranges_sequential_table.up.sql", size: 263, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1683457503_add_blocks_ranges_sequential_table.up.sql", size: 263, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfe, 0x57, 0x2e, 0x0, 0x6a, 0x6e, 0xd7, 0xeb, 0xe6, 0x66, 0x79, 0x32, 0x22, 0x82, 0x92, 0xf4, 0xc9, 0xf1, 0x58, 0x1a, 0x45, 0x60, 0x77, 0x50, 0xe7, 0x54, 0x4a, 0xc0, 0x42, 0x3a, 0x4f, 0x35}} return a, nil } @@ -1408,7 +1409,7 @@ func _1683627613_accounts_and_keycards_improvementsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1683627613_accounts_and_keycards_improvements.up.sql", size: 3640, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1683627613_accounts_and_keycards_improvements.up.sql", size: 3640, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8e, 0xbe, 0x62, 0xf5, 0x9, 0x42, 0x8c, 0x8f, 0xa8, 0x45, 0xe7, 0x36, 0xc9, 0xde, 0xf4, 0xe2, 0xfd, 0xc4, 0x8, 0xd0, 0xa3, 0x8, 0x64, 0xe2, 0x56, 0xcc, 0xa7, 0x6d, 0xc5, 0xcc, 0x82, 0x2c}} return a, nil } @@ -1428,7 +1429,7 @@ func _1685041348_settings_table_add_latest_derived_path_columnUpSql() (*asset, e return nil, err } - info := bindataFileInfo{name: "1685041348_settings_table_add_latest_derived_path_column.up.sql", size: 115, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1685041348_settings_table_add_latest_derived_path_column.up.sql", size: 115, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x21, 0xd4, 0x1b, 0xbf, 0x8, 0xf9, 0xd4, 0xb0, 0xa0, 0x6, 0x5b, 0xfb, 0x7e, 0xff, 0xfa, 0xbf, 0xcc, 0x64, 0x47, 0x81, 0x8b, 0x5e, 0x17, 0x6a, 0xa7, 0xa4, 0x35, 0x8f, 0x30, 0x4f, 0xd9, 0xd}} return a, nil } @@ -1448,7 +1449,7 @@ func _1685440989_update_color_id_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1685440989_update_color_id_accounts.up.sql", size: 918, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1685440989_update_color_id_accounts.up.sql", size: 918, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x10, 0x2e, 0x51, 0x1d, 0x2d, 0x16, 0x84, 0xd6, 0xe8, 0xbc, 0x20, 0x53, 0x47, 0xb8, 0x40, 0x21, 0x52, 0x5c, 0xd9, 0xbb, 0xea, 0xe2, 0xa5, 0x77, 0xc8, 0x35, 0x4c, 0xe0, 0x9d, 0x42, 0x44, 0x50}} return a, nil } @@ -1468,7 +1469,7 @@ func _1685463947_add_to_asset_to_multitransactionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1685463947_add_to_asset_to_multitransaction.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1685463947_add_to_asset_to_multitransaction.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd3, 0x66, 0x15, 0x10, 0xfa, 0x66, 0x81, 0x68, 0xd9, 0xb4, 0x93, 0x9e, 0x11, 0xed, 0x1d, 0x16, 0x9d, 0x5a, 0xf8, 0xd7, 0x8, 0xea, 0x7a, 0xaf, 0xe4, 0xb3, 0x22, 0x19, 0xca, 0xff, 0x75, 0x7c}} return a, nil } @@ -1488,7 +1489,7 @@ func _1685880973_add_profile_links_settings_tableUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1685880973_add_profile_links_settings_table.up.sql", size: 1656, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1685880973_add_profile_links_settings_table.up.sql", size: 1656, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x13, 0x23, 0x7b, 0x1e, 0x82, 0x61, 0xcc, 0x76, 0xd6, 0xc7, 0x42, 0x6e, 0x69, 0x21, 0x1b, 0xfd, 0x7d, 0xda, 0xd7, 0xb7, 0xc7, 0xd3, 0x22, 0x63, 0xfe, 0xc6, 0xd3, 0xdf, 0xc8, 0x5f, 0x50, 0xcc}} return a, nil } @@ -1508,7 +1509,7 @@ func _1686041510_add_idx_transfers_blkno_loadedUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1686041510_add_idx_transfers_blkno_loaded.up.sql", size: 71, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1686041510_add_idx_transfers_blkno_loaded.up.sql", size: 71, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe2, 0x5d, 0x7e, 0x43, 0x14, 0x3c, 0x50, 0x44, 0x25, 0xd0, 0xe1, 0x75, 0xba, 0x61, 0x7b, 0x68, 0x2e, 0x43, 0x74, 0x1d, 0x10, 0x61, 0x8e, 0x45, 0xe6, 0x25, 0x78, 0x81, 0x68, 0x6, 0x24, 0x5b}} return a, nil } @@ -1528,7 +1529,7 @@ func _1686048341_transfers_receipt_json_blob_outUpSqlDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.down.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.down.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9f, 0x6c, 0xd9, 0x76, 0x83, 0x64, 0xf0, 0xf2, 0x74, 0x97, 0xca, 0xd7, 0xaa, 0x4, 0x74, 0x7c, 0x34, 0x56, 0x88, 0x10, 0xa9, 0x4d, 0x1d, 0x8e, 0x85, 0xc3, 0x66, 0x1, 0x2b, 0x30, 0x90, 0xf4}} return a, nil } @@ -1548,7 +1549,7 @@ func _1686048341_transfers_receipt_json_blob_outUpSqlUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.up.sql", size: 1500, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1686048341_transfers_receipt_json_blob_out.up.sql.up.sql", size: 1500, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xcd, 0xe3, 0xa6, 0x8c, 0x53, 0x51, 0xe6, 0x3c, 0x64, 0xcb, 0x3, 0x3, 0xb, 0x4d, 0x52, 0xa5, 0x1c, 0xcc, 0xe1, 0x23, 0x94, 0x14, 0x79, 0xd7, 0x56, 0x58, 0xef, 0xcc, 0x1a, 0x6, 0xa4}} return a, nil } @@ -1568,7 +1569,7 @@ func _1686825075_cleanup_token_addressUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1686825075_cleanup_token_address.up.sql", size: 273, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1686825075_cleanup_token_address.up.sql", size: 273, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x14, 0x72, 0x10, 0xec, 0x97, 0xc9, 0x3a, 0xdb, 0x39, 0x33, 0xc9, 0x6, 0x92, 0xbe, 0xe4, 0xc2, 0x5c, 0xb6, 0xaa, 0xe5, 0x25, 0x21, 0x4d, 0x74, 0x18, 0x94, 0xc, 0x33, 0x2f, 0xa4, 0x9, 0x99}} return a, nil } @@ -1588,7 +1589,7 @@ func _1687193315_transfers_extract_from_to_addressDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1687193315_transfers_extract_from_to_address.down.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1687193315_transfers_extract_from_to_address.down.sql", size: 104, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9f, 0x6c, 0xd9, 0x76, 0x83, 0x64, 0xf0, 0xf2, 0x74, 0x97, 0xca, 0xd7, 0xaa, 0x4, 0x74, 0x7c, 0x34, 0x56, 0x88, 0x10, 0xa9, 0x4d, 0x1d, 0x8e, 0x85, 0xc3, 0x66, 0x1, 0x2b, 0x30, 0x90, 0xf4}} return a, nil } @@ -1608,7 +1609,7 @@ func _1687193315_transfers_extract_from_to_addressUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1687193315_transfers_extract_from_to_address.up.sql", size: 499, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1687193315_transfers_extract_from_to_address.up.sql", size: 499, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x4c, 0xef, 0xf4, 0x66, 0xac, 0x3a, 0xa6, 0xe3, 0x26, 0x43, 0x53, 0xe, 0xd8, 0xfe, 0xf2, 0xaa, 0x20, 0x8, 0x4e, 0x52, 0x49, 0x37, 0xbf, 0x46, 0xbf, 0x53, 0xa7, 0xcf, 0x27, 0x23, 0xab, 0x99}} return a, nil } @@ -1628,7 +1629,7 @@ func _1687249080_add_position_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1687249080_add_position_accounts.up..sql", size: 2053, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1687249080_add_position_accounts.up..sql", size: 2053, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf3, 0x47, 0x9f, 0xb4, 0xe3, 0xc, 0x35, 0x15, 0x74, 0xc3, 0x72, 0x57, 0x9f, 0x3b, 0xc9, 0xd5, 0x9b, 0x31, 0xef, 0xd6, 0x21, 0xc4, 0x27, 0x8e, 0x37, 0xd5, 0x5, 0xdb, 0x3d, 0xcf, 0x37, 0xbb}} return a, nil } @@ -1648,7 +1649,7 @@ func _1687269871_add_device_nameUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1687269871_add_device_name.up.sql", size: 108, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1687269871_add_device_name.up.sql", size: 108, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xed, 0x61, 0xf2, 0xf9, 0x78, 0x57, 0xc3, 0x57, 0xdb, 0x37, 0xe, 0x7, 0x15, 0xde, 0x5a, 0x2a, 0xb5, 0x86, 0xb8, 0x5, 0x48, 0x68, 0x2a, 0xb, 0x7c, 0xd, 0x60, 0xba, 0x67, 0x30, 0x2d, 0xa3}} return a, nil } @@ -1668,7 +1669,7 @@ func _1687506642_include_watch_only_account_settingUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1687506642_include_watch_only_account_setting.up.sql", size: 81, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1687506642_include_watch_only_account_setting.up.sql", size: 81, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xaa, 0xa0, 0x61, 0xf8, 0xb9, 0x15, 0x22, 0x9a, 0xca, 0x9b, 0x89, 0x96, 0x90, 0x47, 0x56, 0xf3, 0x21, 0xf6, 0xbd, 0xd1, 0xa1, 0x8f, 0xa8, 0x34, 0xc3, 0x54, 0x86, 0x69, 0x14, 0x96, 0xdb, 0xbb}} return a, nil } @@ -1688,7 +1689,7 @@ func _1688022264_add_include_watch_only_account_to_settings_sync_clockUpSql() (* return nil, err } - info := bindataFileInfo{name: "1688022264_add_include_watch_only_account_to_settings_sync_clock.up.sql", size: 98, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1688022264_add_include_watch_only_account_to_settings_sync_clock.up.sql", size: 98, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xab, 0xa2, 0x31, 0xcc, 0x3d, 0x59, 0x1b, 0x26, 0x5b, 0x78, 0xd, 0x6a, 0x75, 0x2a, 0xe0, 0x2, 0x21, 0x28, 0x8c, 0x92, 0x24, 0x98, 0x86, 0xdd, 0x2, 0x53, 0xe8, 0xf6, 0xc2, 0x7d, 0x57, 0x13}} return a, nil } @@ -1708,7 +1709,7 @@ func _1688054680_add_columns_to_multitransactionUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1688054680_add_columns_to_multitransaction.up.sql", size: 342, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1688054680_add_columns_to_multitransaction.up.sql", size: 342, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0xbb, 0x88, 0xde, 0x98, 0x9e, 0xa8, 0xc0, 0xf7, 0x2b, 0xc4, 0x33, 0x77, 0xf5, 0x58, 0x46, 0x52, 0xc6, 0xc2, 0x27, 0x1d, 0x8, 0xc9, 0x83, 0xb6, 0x16, 0x31, 0x99, 0x15, 0xcb, 0xb1, 0x40}} return a, nil } @@ -1728,7 +1729,7 @@ func _1688636552_keycards_table_columns_updateUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1688636552_keycards_table_columns_update.up.sql", size: 1051, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1688636552_keycards_table_columns_update.up.sql", size: 1051, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2f, 0x82, 0x37, 0x82, 0xae, 0x44, 0x7f, 0x4d, 0xb5, 0x50, 0x1b, 0x5f, 0x2b, 0xaa, 0xb1, 0x3, 0x97, 0xba, 0x8b, 0xea, 0x30, 0x5, 0xa4, 0x1a, 0x2c, 0x7, 0x63, 0x89, 0x43, 0x12, 0xb6, 0xb7}} return a, nil } @@ -1748,7 +1749,7 @@ func _1689248269_add_related_chain_id_networksUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1689248269_add_related_chain_id_networks.up.sql", size: 66, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1689248269_add_related_chain_id_networks.up.sql", size: 66, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x76, 0xad, 0xde, 0xb5, 0xc7, 0x60, 0x1a, 0x99, 0x7d, 0x51, 0x74, 0x43, 0x60, 0x17, 0x54, 0x82, 0xb6, 0xc6, 0x96, 0x1c, 0x43, 0x74, 0x6, 0x15, 0xd6, 0xa4, 0x2a, 0xd2, 0x1c, 0xeb, 0xdc, 0xb4}} return a, nil } @@ -1768,7 +1769,7 @@ func _1689340211_index_filter_columnsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1689340211_index_filter_columns.up.sql", size: 633, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1689340211_index_filter_columns.up.sql", size: 633, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x83, 0xc8, 0x1, 0x8b, 0x85, 0x2b, 0xa7, 0x46, 0xfe, 0xe9, 0x9c, 0xaf, 0xec, 0x10, 0xe5, 0xec, 0x23, 0xd3, 0xf, 0xee, 0xad, 0xfb, 0xf1, 0xc7, 0xc, 0xbc, 0x14, 0xac, 0xf8, 0x3b, 0x5a, 0x9e}} return a, nil } @@ -1788,7 +1789,7 @@ func _1689498471_make_wallet_accounts_positions_non_negativeUpSql() (*asset, err return nil, err } - info := bindataFileInfo{name: "1689498471_make_wallet_accounts_positions_non_negative.up.sql", size: 1617, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1689498471_make_wallet_accounts_positions_non_negative.up.sql", size: 1617, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xfe, 0x8d, 0xfc, 0x64, 0x78, 0x7a, 0x55, 0x38, 0xc9, 0x1e, 0x71, 0x25, 0xe2, 0x81, 0xc8, 0x3b, 0x1d, 0xf, 0xe7, 0x1f, 0x67, 0xbf, 0x6, 0xf1, 0x6a, 0x56, 0xf, 0x30, 0xb1, 0xc5, 0xca, 0x19}} return a, nil } @@ -1808,7 +1809,7 @@ func _1689856991_add_soft_remove_column_for_keypairs_and_accountsUpSql() (*asset return nil, err } - info := bindataFileInfo{name: "1689856991_add_soft_remove_column_for_keypairs_and_accounts.up.sql", size: 284, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1689856991_add_soft_remove_column_for_keypairs_and_accounts.up.sql", size: 284, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd4, 0xfb, 0x7b, 0x9a, 0xee, 0xa4, 0x1f, 0x54, 0x81, 0x9c, 0x66, 0xd1, 0xde, 0x2d, 0xee, 0x8f, 0xb0, 0xc, 0x8, 0xb7, 0x1f, 0x5f, 0x28, 0x42, 0x75, 0x3, 0x19, 0xfb, 0xb5, 0x53, 0xa2, 0xcc}} return a, nil } @@ -1828,7 +1829,7 @@ func _1690225863_add_collectibles_ownership_cacheUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1690225863_add_collectibles_ownership_cache.up.sql", size: 327, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1690225863_add_collectibles_ownership_cache.up.sql", size: 327, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x70, 0x2d, 0xfa, 0x52, 0x54, 0x3e, 0x6e, 0x50, 0x7a, 0xe0, 0x4d, 0xd1, 0x5b, 0x3a, 0xc7, 0xb6, 0x67, 0xe8, 0x82, 0xf0, 0xc4, 0xb5, 0xcc, 0x3b, 0xbf, 0x89, 0xe0, 0x1b, 0xbc, 0xa4, 0xa9, 0x68}} return a, nil } @@ -1848,7 +1849,7 @@ func _1690734354_add_preferred_chain_idsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1690734354_add_preferred_chain_ids.up.sql", size: 189, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1690734354_add_preferred_chain_ids.up.sql", size: 189, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x90, 0xb4, 0x32, 0x89, 0xa1, 0xed, 0x19, 0x61, 0x1a, 0xdf, 0x72, 0x4c, 0x28, 0x5f, 0x87, 0x72, 0x33, 0xad, 0x9a, 0xc6, 0xaf, 0x6b, 0xaf, 0xa9, 0x70, 0xc7, 0x8a, 0x42, 0xe2, 0xac, 0x15, 0x2a}} return a, nil } @@ -1868,7 +1869,7 @@ func _1691173699_add_collectibles_and_collections_data_cacheUpSql() (*asset, err return nil, err } - info := bindataFileInfo{name: "1691173699_add_collectibles_and_collections_data_cache.up.sql", size: 1811, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1691173699_add_collectibles_and_collections_data_cache.up.sql", size: 1811, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x0, 0xf2, 0xaa, 0xa9, 0x56, 0x92, 0xb7, 0x3c, 0xd8, 0xbf, 0x4c, 0x42, 0x90, 0xdd, 0xb3, 0xb8, 0xca, 0x4a, 0xa1, 0x91, 0x29, 0x5, 0xf6, 0xb0, 0x75, 0x82, 0x98, 0x7e, 0x6d, 0x74, 0x15, 0xc3}} return a, nil } @@ -1888,7 +1889,7 @@ func _1691753758_move_wallet_tables_to_wallet_dbUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1691753758_move_wallet_tables_to_wallet_db.up.sql", size: 603, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1691753758_move_wallet_tables_to_wallet_db.up.sql", size: 603, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2c, 0x7f, 0xd9, 0x6f, 0x91, 0x37, 0x7a, 0x8f, 0xf4, 0xd6, 0xec, 0xd4, 0xb9, 0x8e, 0xc5, 0xeb, 0x1a, 0xfa, 0xd1, 0x4, 0x1, 0xff, 0x51, 0x23, 0xc, 0x96, 0xf2, 0x3c, 0x12, 0xa7, 0xf7, 0x33}} return a, nil } @@ -1908,7 +1909,7 @@ func _1691753800_pubsubtopic_keyUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1691753800_pubsubtopic_key.up.sql", size: 767, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1691753800_pubsubtopic_key.up.sql", size: 767, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xdf, 0x42, 0x78, 0x4, 0x20, 0xa5, 0x62, 0xa1, 0xa5, 0x82, 0xa1, 0x41, 0x14, 0xaf, 0x5e, 0xe2, 0xc9, 0xcf, 0xad, 0x4b, 0x32, 0x6e, 0xc7, 0xac, 0x9f, 0xe0, 0xf, 0xe0, 0x3a, 0xa0, 0x67, 0x2d}} return a, nil } @@ -1928,7 +1929,7 @@ func _1693900971_add_profile_migration_needed_column_to_settings_tableUpSql() (* return nil, err } - info := bindataFileInfo{name: "1693900971_add_profile_migration_needed_column_to_settings_table.up.sql", size: 88, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1693900971_add_profile_migration_needed_column_to_settings_table.up.sql", size: 88, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf7, 0x89, 0x89, 0x81, 0xf1, 0x1, 0x2d, 0xa6, 0x24, 0xba, 0x48, 0x1, 0x9a, 0x7a, 0xcf, 0xe0, 0xfd, 0x3f, 0xc6, 0xc2, 0xd9, 0xe2, 0xfc, 0x6f, 0x2f, 0x83, 0x16, 0x61, 0x8e, 0x89, 0x64, 0xef}} return a, nil } @@ -1948,7 +1949,7 @@ func _1694764094_add_original_to_networksUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1694764094_add_original_to_networks.up.sql", size: 120, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1694764094_add_original_to_networks.up.sql", size: 120, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x64, 0xa0, 0xef, 0x4e, 0xf3, 0x1, 0xd5, 0x61, 0xcb, 0x83, 0xd2, 0xdf, 0x6a, 0x69, 0xee, 0x36, 0x0, 0x13, 0x94, 0x57, 0xb2, 0xa, 0x12, 0x28, 0x5c, 0x5, 0x69, 0x1a, 0xfd, 0xa0, 0x31, 0x6c}} return a, nil } @@ -1968,7 +1969,7 @@ func _1695974515_add_is_sepolia_enabled_to_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1695974515_add_is_sepolia_enabled_to_settings.up.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1695974515_add_is_sepolia_enabled_to_settings.up.sql", size: 82, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x42, 0x95, 0xa7, 0xbb, 0x64, 0x91, 0x4e, 0x66, 0x9c, 0xbd, 0x96, 0xbb, 0x79, 0x3d, 0xc4, 0x2d, 0x3a, 0x36, 0xb5, 0x35, 0xdb, 0x53, 0x45, 0xf2, 0xf3, 0x61, 0xac, 0xe3, 0x38, 0xe6, 0x73, 0x54}} return a, nil } @@ -1988,7 +1989,7 @@ func _1696259336_settings_add_url_unfurling_modeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1696259336_settings_add_url_unfurling_mode.up.sql", size: 160, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1696259336_settings_add_url_unfurling_mode.up.sql", size: 160, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x62, 0xf4, 0x5, 0x31, 0x4e, 0x35, 0xb5, 0xcd, 0x1a, 0xad, 0xdc, 0xcb, 0x4, 0x94, 0x16, 0x67, 0xc4, 0x8d, 0x6f, 0x63, 0xa6, 0x8f, 0xbf, 0xa5, 0x6, 0xfd, 0xbe, 0xb1, 0x7c, 0xe8, 0xa7}} return a, nil } @@ -2008,7 +2009,7 @@ func _1697123140_drop_include_watch_only_accountsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1697123140_drop_include_watch_only_accounts.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1697123140_drop_include_watch_only_accounts.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x77, 0xc9, 0xc7, 0xaf, 0x7b, 0xe4, 0x83, 0x5, 0xe1, 0xde, 0x83, 0xd9, 0xdd, 0xbe, 0xb6, 0x1d, 0x24, 0x5c, 0x19, 0x88, 0xad, 0xc1, 0x5c, 0xd1, 0x26, 0x84, 0x61, 0xce, 0x3a, 0x74, 0x3c, 0x8c}} return a, nil } @@ -2028,7 +2029,7 @@ func _1697123233_drop_include_watch_only_account_to_settings_sync_clockUpSql() ( return nil, err } - info := bindataFileInfo{name: "1697123233_drop_include_watch_only_account_to_settings_sync_clock.up.sql", size: 72, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1697123233_drop_include_watch_only_account_to_settings_sync_clock.up.sql", size: 72, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xcd, 0xe9, 0x5b, 0xc9, 0xd2, 0x96, 0x18, 0x8e, 0x97, 0x13, 0x3b, 0x72, 0x2d, 0x8a, 0xa9, 0xa3, 0x32, 0x6, 0x17, 0xb, 0xd1, 0xd8, 0x44, 0x13, 0xde, 0xb6, 0xa3, 0xbf, 0xef, 0xf4, 0xf9, 0xff}} return a, nil } @@ -2048,7 +2049,7 @@ func _1697623289_add_omit_transfers_history_scan_to_settingsUpSql() (*asset, err return nil, err } - info := bindataFileInfo{name: "1697623289_add_omit_transfers_history_scan_to_settings.up.sql", size: 92, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1697623289_add_omit_transfers_history_scan_to_settings.up.sql", size: 92, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc9, 0xf, 0x2e, 0x73, 0x46, 0xee, 0x96, 0x1d, 0xa6, 0x75, 0xde, 0x46, 0x19, 0xbd, 0x13, 0x3f, 0x41, 0xf3, 0x6a, 0xb4, 0x93, 0x85, 0x8b, 0xed, 0x19, 0xa1, 0x4f, 0x91, 0xa1, 0x8, 0x88, 0xe2}} return a, nil } @@ -2068,7 +2069,7 @@ func _1699577175_use_shardsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1699577175_use_shards.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1699577175_use_shards.up.sql", size: 84, mode: os.FileMode(0644), modTime: time.Unix(1699855131, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3c, 0xc9, 0x51, 0x6d, 0x40, 0xb9, 0x96, 0xd2, 0xe3, 0xfc, 0xd8, 0xb1, 0xdf, 0xc7, 0x55, 0xf6, 0x63, 0xb4, 0xec, 0xc1, 0xe5, 0xb9, 0xcc, 0xa, 0xaa, 0xac, 0x49, 0x20, 0x7f, 0xdd, 0xa2, 0x71}} return a, nil } @@ -2088,7 +2089,7 @@ func _1700741911_clusteridUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1700741911_clusterID.up.sql", size: 75, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1700741911_clusterID.up.sql", size: 75, mode: os.FileMode(0644), modTime: time.Unix(1700838822, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x38, 0x60, 0x13, 0x88, 0x61, 0x66, 0xe0, 0xf3, 0x38, 0x91, 0x1a, 0x91, 0xa7, 0x0, 0x7b, 0x32, 0x5e, 0x8, 0xa9, 0xb3, 0x76, 0x5, 0xeb, 0xf, 0x37, 0x85, 0xdf, 0x5c, 0xed, 0x34, 0x50, 0x9e}} return a, nil } @@ -2108,7 +2109,7 @@ func _1701084316_add_wallet_was_not_shown_to_keypairs_accountsUpSql() (*asset, e return nil, err } - info := bindataFileInfo{name: "1701084316_add_wallet_was_not_shown_to_keypairs_accounts.up.sql", size: 95, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1701084316_add_wallet_was_not_shown_to_keypairs_accounts.up.sql", size: 95, mode: os.FileMode(0644), modTime: time.Unix(1701443413, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0xe, 0x28, 0xdd, 0x95, 0xfb, 0xf4, 0xd2, 0xf4, 0xed, 0xd4, 0xdf, 0x14, 0xde, 0xa, 0x53, 0x60, 0x3, 0xa5, 0xbc, 0xd6, 0xdb, 0x7b, 0xd5, 0x62, 0x1c, 0xc3, 0xc6, 0xae, 0x8e, 0x4d, 0x85}} return a, nil } @@ -2128,7 +2129,7 @@ func _1701084317_add_mnemonic_was_not_shown_to_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1701084317_add_mnemonic_was_not_shown_to_settings.up.sql", size: 87, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1701084317_add_mnemonic_was_not_shown_to_settings.up.sql", size: 87, mode: os.FileMode(0644), modTime: time.Unix(1701443413, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x90, 0xcd, 0xc9, 0x6b, 0x4, 0x7, 0xec, 0x71, 0x55, 0x7a, 0xce, 0x2f, 0xa4, 0xd3, 0xfb, 0x58, 0xcc, 0x5a, 0xa0, 0x19, 0xb1, 0x85, 0xb8, 0xa6, 0xcd, 0xcd, 0x5a, 0x5c, 0xa3, 0x39, 0xe5, 0x8e}} return a, nil } @@ -2148,7 +2149,7 @@ func _1701444172_token_preferencesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1701444172_token_preferences.up.sql", size: 511, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1701444172_token_preferences.up.sql", size: 511, mode: os.FileMode(0644), modTime: time.Unix(1702641016, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xe, 0x76, 0xb9, 0x1d, 0xd4, 0xf0, 0xa, 0x12, 0xd3, 0x3, 0x42, 0x1, 0x4, 0x25, 0x93, 0xab, 0xb8, 0x30, 0xff, 0x12, 0x91, 0x1e, 0xc1, 0x1a, 0x7a, 0xf8, 0xc5, 0xbc, 0x3e, 0x29, 0x5a}} return a, nil } @@ -2168,7 +2169,7 @@ func _1701961850_shards_testUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1701961850_shards_test.up.sql", size: 1276, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1701961850_shards_test.up.sql", size: 1276, mode: os.FileMode(0644), modTime: time.Unix(1702641016, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x72, 0x86, 0x27, 0x90, 0xff, 0x69, 0x70, 0xe4, 0xe3, 0x38, 0x57, 0x4b, 0x47, 0x33, 0xfb, 0xcd, 0xe2, 0xc9, 0x87, 0xd9, 0x6c, 0x92, 0xc3, 0x90, 0xf1, 0x4c, 0x41, 0xdc, 0x39, 0x16, 0x2a, 0x69}} return a, nil } @@ -2188,7 +2189,7 @@ func _1702395750_fix_enr_shards_testUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1702395750_fix_enr_shards_test.up.sql", size: 1234, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1702395750_fix_enr_shards_test.up.sql", size: 1234, mode: os.FileMode(0644), modTime: time.Unix(1702641016, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x9b, 0x99, 0xd8, 0xc9, 0xe0, 0xf0, 0xe1, 0xf1, 0x77, 0xf, 0x5f, 0x97, 0xfc, 0x54, 0xd4, 0x8d, 0xc1, 0xa4, 0xbb, 0x4f, 0x5c, 0x50, 0x5d, 0xef, 0xb2, 0xa3, 0xc1, 0x13, 0x2, 0xbd, 0x9, 0x30}} return a, nil } @@ -2208,7 +2209,7 @@ func _1702999401_add_dns_discovery_urlUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1702999401_add_dns_discovery_url.up.sql", size: 284, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1702999401_add_dns_discovery_url.up.sql", size: 284, mode: os.FileMode(0644), modTime: time.Unix(1703943409, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xec, 0x31, 0xf8, 0x99, 0xf5, 0xe2, 0xd1, 0xae, 0x95, 0x13, 0xbf, 0x73, 0x84, 0xd3, 0xd1, 0x90, 0x25, 0x9b, 0x3d, 0x9e, 0xd7, 0x55, 0x2, 0x7a, 0x61, 0x68, 0x6f, 0xca, 0x1e, 0x9d, 0x8f, 0x42}} return a, nil } @@ -2228,7 +2229,7 @@ func _1704281285_tokens_advanced_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1704281285_tokens_advanced_settings.up.sql", size: 743, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1704281285_tokens_advanced_settings.up.sql", size: 743, mode: os.FileMode(0644), modTime: time.Unix(1704466806, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x45, 0xa7, 0x62, 0x1f, 0x62, 0x24, 0x5c, 0x66, 0x97, 0x6, 0x49, 0xb7, 0x5d, 0x44, 0x9f, 0x13, 0xab, 0x64, 0x35, 0xc4, 0xfb, 0xa8, 0x3f, 0xee, 0x2f, 0x3f, 0x3e, 0x65, 0x33, 0xf6, 0x7b, 0xdc}} return a, nil } @@ -2248,7 +2249,7 @@ func _1705338819_collectible_preferencesUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1705338819_collectible_preferences.up.sql", size: 590, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1705338819_collectible_preferences.up.sql", size: 590, mode: os.FileMode(0644), modTime: time.Unix(1706955294, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb3, 0x9d, 0xd9, 0x5e, 0x8c, 0x57, 0x8e, 0x53, 0x1a, 0x7b, 0xc8, 0x7f, 0x1a, 0x1f, 0x61, 0x79, 0x67, 0x72, 0x77, 0x8d, 0x24, 0xe1, 0xe6, 0x2d, 0x78, 0xac, 0xa1, 0x97, 0x67, 0x5b, 0xb, 0xa4}} return a, nil } @@ -2268,11 +2269,31 @@ func _1706097653_migration_order_fixUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "1706097653_migration_order_fix.up.sql", size: 9484, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "1706097653_migration_order_fix.up.sql", size: 9484, mode: os.FileMode(0644), modTime: time.Unix(1706955294, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x5b, 0x3, 0x9c, 0xaf, 0xa5, 0xb0, 0x3f, 0x8e, 0xe3, 0x67, 0x86, 0xed, 0x92, 0xbc, 0x2d, 0xb3, 0xc8, 0x6e, 0x31, 0xf, 0x74, 0xdf, 0xf7, 0x2f, 0x26, 0x67, 0xf1, 0xe7, 0x35, 0x25, 0xb7}} return a, nil } +var __1706955596_community_storenodesUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x91\x4d\x4f\x32\x31\x14\x85\xf7\xfc\x8a\xb3\x84\x04\x92\x77\xfd\xba\xea\x40\x09\x13\xeb\xd4\x94\x22\xb2\x22\x95\x5e\xa5\xb1\x1f\x64\x5a\x30\xfc\x7b\x23\x24\x7c\x19\xdc\xde\xe7\x39\x67\x71\xee\x50\x71\xa6\x39\x34\xab\x04\x47\x3d\x46\x23\x35\xf8\x6b\x3d\xd5\x53\xac\x52\x08\xdb\xe8\xca\x7e\x99\x4b\x6a\x29\x26\x4b\x19\xdd\x0e\x80\x0b\xe4\x2c\x2a\x21\xab\x43\xae\x99\x09\xd1\x3f\xf0\x53\xe0\x87\xbf\x30\x35\x9c\x30\x75\xa3\x44\x13\xe8\x0e\x32\xd6\xb6\x94\xf3\x1d\xfa\xee\x89\xca\x1d\xb6\xa3\x36\xbb\x14\x51\x37\xfa\x86\xac\x7c\x5a\x7d\x5e\xdd\x31\xe2\x63\x36\x13\x1a\xff\x8e\x46\x4b\x21\xed\xc8\xa2\x92\x52\x70\xd6\xfc\xf6\xc6\x4c\x4c\xf9\xd1\xb5\xe4\xa9\x90\x5d\x9a\xf2\x67\xe5\xb3\xaa\x9f\x98\x5a\xe0\x91\x2f\xd0\xbd\xdc\xac\x7f\xb5\x50\x0f\x83\x01\x64\x24\x94\x84\x60\xe2\x1e\x2d\x79\x53\x5c\x8a\x79\xed\x36\x78\xa3\xf2\x45\x14\x4f\x9b\x3b\xca\x30\xd1\x9e\x1b\xf2\x7f\xa4\x48\xe7\x9f\x20\xb8\x8f\x75\xc1\xda\xec\x08\x61\xeb\x8b\xdb\x78\xba\xb0\x3b\x3d\xcc\x6b\x3d\x91\x33\x0d\x25\xe7\xf5\xe8\xe1\x3b\x00\x00\xff\xff\x88\x8f\xd5\xa1\x03\x02\x00\x00") + +func _1706955596_community_storenodesUpSqlBytes() ([]byte, error) { + return bindataRead( + __1706955596_community_storenodesUpSql, + "1706955596_community_storenodes.up.sql", + ) +} + +func _1706955596_community_storenodesUpSql() (*asset, error) { + bytes, err := _1706955596_community_storenodesUpSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "1706955596_community_storenodes.up.sql", size: 515, mode: os.FileMode(0644), modTime: time.Unix(1708412524, 0)} + a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x52, 0x79, 0xe, 0xb1, 0xd3, 0xc6, 0x63, 0x2d, 0x21, 0xb, 0x70, 0xbd, 0x51, 0xc, 0x7, 0xd6, 0x57, 0xbc, 0x75, 0xc6, 0x2e, 0x8f, 0x53, 0xbd, 0x8f, 0xff, 0xb1, 0xe1, 0xde, 0x5e, 0xa6, 0x18}} + return a, nil +} + var _docGo = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x2c\xc9\xb1\x0d\xc4\x20\x0c\x05\xd0\x9e\x29\xfe\x02\xd8\xfd\x6d\xe3\x4b\xac\x2f\x44\x82\x09\x78\x7f\xa5\x49\xfd\xa6\x1d\xdd\xe8\xd8\xcf\x55\x8a\x2a\xe3\x47\x1f\xbe\x2c\x1d\x8c\xfa\x6f\xe3\xb4\x34\xd4\xd9\x89\xbb\x71\x59\xb6\x18\x1b\x35\x20\xa2\x9f\x0a\x03\xa2\xe5\x0d\x00\x00\xff\xff\x60\xcd\x06\xbe\x4a\x00\x00\x00") func docGoBytes() ([]byte, error) { @@ -2288,7 +2309,7 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1707305567, 0)} + info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1699261304, 0)} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x7c, 0x28, 0xcd, 0x47, 0xf2, 0xfa, 0x7c, 0x51, 0x2d, 0xd8, 0x38, 0xb, 0xb0, 0x34, 0x9d, 0x4c, 0x62, 0xa, 0x9e, 0x28, 0xc3, 0x31, 0x23, 0xd9, 0xbb, 0x89, 0x9f, 0xa0, 0x89, 0x1f, 0xe8}} return a, nil } @@ -2489,6 +2510,7 @@ var _bindata = map[string]func() (*asset, error){ "1704281285_tokens_advanced_settings.up.sql": _1704281285_tokens_advanced_settingsUpSql, "1705338819_collectible_preferences.up.sql": _1705338819_collectible_preferencesUpSql, "1706097653_migration_order_fix.up.sql": _1706097653_migration_order_fixUpSql, + "1706955596_community_storenodes.up.sql": _1706955596_community_storenodesUpSql, "doc.go": docGo, } @@ -2643,6 +2665,7 @@ var _bintree = &bintree{nil, map[string]*bintree{ "1704281285_tokens_advanced_settings.up.sql": {_1704281285_tokens_advanced_settingsUpSql, map[string]*bintree{}}, "1705338819_collectible_preferences.up.sql": {_1705338819_collectible_preferencesUpSql, map[string]*bintree{}}, "1706097653_migration_order_fix.up.sql": {_1706097653_migration_order_fixUpSql, map[string]*bintree{}}, + "1706955596_community_storenodes.up.sql": {_1706955596_community_storenodesUpSql, map[string]*bintree{}}, "doc.go": {docGo, map[string]*bintree{}}, }} diff --git a/appdatabase/migrations/sql/1706955596_community_storenodes.up.sql b/appdatabase/migrations/sql/1706955596_community_storenodes.up.sql new file mode 100644 index 000000000..9561029c4 --- /dev/null +++ b/appdatabase/migrations/sql/1706955596_community_storenodes.up.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS community_storenodes ( + community_id BLOB NOT NULL, + storenode_id VARCHAR NOT NULL, + name VARCHAR NOT NULL, + address VARCHAR NOT NULL, + fleet VARCHAR NOT NULL, + version INT NOT NULL, + clock INT NOT NULL DEFAULT 0, + removed BOOLEAN NOT NULL DEFAULT FALSE, + deleted_at INT NOT NULL DEFAULT 0, + PRIMARY KEY (community_id, storenode_id) -- One to many relationship between communities and storenodes: one community might have multiple storenodes +) WITHOUT ROWID; \ No newline at end of file diff --git a/protocol/messenger.go b/protocol/messenger.go index ad3a50cd7..bfaf13cf4 100644 --- a/protocol/messenger.go +++ b/protocol/messenger.go @@ -55,6 +55,7 @@ import ( "github.com/status-im/status-go/protocol/pushnotificationserver" "github.com/status-im/status-go/protocol/requests" "github.com/status-im/status-go/protocol/sqlite" + "github.com/status-im/status-go/protocol/storenodes" "github.com/status-im/status-go/protocol/transport" v1protocol "github.com/status-im/status-go/protocol/v1" "github.com/status-im/status-go/protocol/verification" @@ -134,6 +135,7 @@ type Messenger struct { modifiedInstallations *stringBoolMap installationID string mailserverCycle mailserverCycle + communityStorenodes *storenodes.CommunityStorenodes database *sql.DB multiAccounts *multiaccounts.Database settings *accounts.Database @@ -164,7 +166,7 @@ type Messenger struct { // TODO(samyoul) Determine if/how the remaining usage of this mutex can be removed mutex sync.Mutex - mailPeersMutex sync.Mutex + mailPeersMutex sync.RWMutex handleMessagesMutex sync.Mutex handleImportMessagesMutex sync.Mutex @@ -544,6 +546,7 @@ func NewMessenger( availabilitySubscriptions: make([]chan struct{}, 0), }, mailserversDatabase: c.mailserversDatabase, + communityStorenodes: storenodes.NewCommunityStorenodes(storenodes.NewDB(database), logger), account: c.account, quit: make(chan struct{}), ctx: ctx, @@ -847,6 +850,10 @@ func (m *Messenger) Start() (*MessengerResponse, error) { return nil, err } + if err := m.communityStorenodes.ReloadFromDB(); err != nil { + return nil, err + } + controlledCommunities, err := m.communitiesManager.Controlled() if err != nil { return nil, err @@ -2206,7 +2213,6 @@ func (m *Messenger) dispatchMessage(ctx context.Context, rawMessage common.RawMe return rawMessage, err } case ChatTypeCommunityChat: - community, err := m.communitiesManager.GetByIDString(chat.CommunityID) if err != nil { return rawMessage, err diff --git a/protocol/messenger_communities.go b/protocol/messenger_communities.go index 34819fa49..34e0e7ce4 100644 --- a/protocol/messenger_communities.go +++ b/protocol/messenger_communities.go @@ -2216,6 +2216,51 @@ func (m *Messenger) RemovePubsubTopicPrivateKey(topic string) error { return m.transport.RemovePubsubTopicKey(topic) } +func (m *Messenger) SetCommunityStorenodes(request *requests.SetCommunityStorenodes) (*MessengerResponse, error) { + if err := request.Validate(); err != nil { + return nil, err + } + community, err := m.communitiesManager.GetByID(request.CommunityID) + if err != nil { + return nil, err + } + if !community.IsControlNode() { + return nil, errors.New("not admin or owner") + } + + if err := m.communityStorenodes.UpdateStorenodesInDB(request.CommunityID, request.Storenodes, 0); err != nil { + return nil, err + } + err = m.sendCommunityPublicStorenodesInfo(community, request.Storenodes) + if err != nil { + return nil, err + } + response := &MessengerResponse{ + CommunityStorenodes: request.Storenodes, + } + return response, nil +} + +func (m *Messenger) GetCommunityStorenodes(communityID types.HexBytes) (*MessengerResponse, error) { + community, err := m.communitiesManager.GetByID(communityID) + if err != nil { + return nil, err + } + if community == nil { + return nil, communities.ErrOrgNotFound + } + + snodes, err := m.communityStorenodes.GetStorenodesFromDB(communityID) + if err != nil { + return nil, err + } + + response := &MessengerResponse{ + CommunityStorenodes: snodes, + } + return response, nil +} + func (m *Messenger) UpdateCommunityFilters(community *communities.Community) error { defaultFilters := m.DefaultFilters(community) publicFiltersToInit := make([]transport.FiltersToInitialize, 0, len(defaultFilters)+len(community.Chats())) @@ -3377,7 +3422,8 @@ func (m *Messenger) InitHistoryArchiveTasks(communities []*communities.Community } // Request possibly missed waku messages for community - _, err = m.syncFiltersFrom(filters, uint32(latestWakuMessageTimestamp)) + ms := m.getActiveMailserver(c.ID().String()) + _, err = m.syncFiltersFrom(*ms, filters, uint32(latestWakuMessageTimestamp)) if err != nil { m.communitiesManager.LogStdout("failed to request missing messages", zap.Error(err)) continue diff --git a/protocol/messenger_community_shard.go b/protocol/messenger_community_shard.go index e23de4d6c..097c3ea8a 100644 --- a/protocol/messenger_community_shard.go +++ b/protocol/messenger_community_shard.go @@ -2,7 +2,6 @@ package protocol import ( "context" - "crypto/ecdsa" "errors" "github.com/golang/protobuf/proto" @@ -75,13 +74,7 @@ func (m *Messenger) HandleCommunityPublicShardInfo(state *ReceivedMessageState, m.logger.Error("HandleCommunityPublicShardInfo failed: ", zap.Error(err), zap.String("communityID", types.EncodeHex(publicShardInfo.CommunityId))) } - signer, err := recoverCommunityShardInfoSignature(a) - if err != nil { - logError(err) - return err - } - - err = m.verifyCommunityPublicShardInfo(publicShardInfo, signer) + err = m.verifyCommunitySignature(a.Payload, a.Signature, publicShardInfo.CommunityId, publicShardInfo.ChainId) if err != nil { logError(err) return err @@ -95,26 +88,25 @@ func (m *Messenger) HandleCommunityPublicShardInfo(state *ReceivedMessageState, return nil } -func recoverCommunityShardInfoSignature(rawShardInfo *protobuf.CommunityPublicShardInfo) (*ecdsa.PublicKey, error) { - if rawShardInfo.Signature == nil || len(rawShardInfo.Signature) == 0 { - return nil, errors.New("missing shard info signature") +func (m *Messenger) verifyCommunitySignature(payload, signature, communityID []byte, chainID uint64) error { + if len(signature) == 0 { + return errors.New("missing signature") } - - return crypto.SigToPub(crypto.Keccak256(rawShardInfo.Payload), rawShardInfo.Signature) -} - -func (m *Messenger) verifyCommunityPublicShardInfo(publicShardInfo *protobuf.PublicShardInfo, signer *ecdsa.PublicKey) error { - pubKeyStr := common.PubkeyToHex(signer) + pubKey, err := crypto.SigToPub(crypto.Keccak256(payload), signature) + if err != nil { + return err + } + pubKeyStr := common.PubkeyToHex(pubKey) var ownerPublicKey string - if publicShardInfo.ChainId > 0 { - owner, err := m.communitiesManager.SafeGetSignerPubKey(publicShardInfo.ChainId, types.EncodeHex(publicShardInfo.CommunityId)) + if chainID > 0 { + owner, err := m.communitiesManager.SafeGetSignerPubKey(chainID, types.EncodeHex(communityID)) if err != nil { return err } ownerPublicKey = owner } else { - communityPubkey, err := crypto.DecompressPubkey(publicShardInfo.CommunityId) + communityPubkey, err := crypto.DecompressPubkey(communityID) if err != nil { return err } diff --git a/protocol/messenger_community_storenodes.go b/protocol/messenger_community_storenodes.go new file mode 100644 index 000000000..e2374085d --- /dev/null +++ b/protocol/messenger_community_storenodes.go @@ -0,0 +1,92 @@ +package protocol + +import ( + "context" + "errors" + + "github.com/golang/protobuf/proto" + "go.uber.org/zap" + + "github.com/status-im/status-go/eth-node/crypto" + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/protocol/common" + "github.com/status-im/status-go/protocol/communities" + "github.com/status-im/status-go/protocol/protobuf" + "github.com/status-im/status-go/protocol/storenodes" + v1protocol "github.com/status-im/status-go/protocol/v1" +) + +func (m *Messenger) sendCommunityPublicStorenodesInfo(community *communities.Community, snodes storenodes.Storenodes) error { + if !community.IsControlNode() { + return communities.ErrNotControlNode + } + + clock, _ := m.getLastClockWithRelatedChat() + pb := &protobuf.CommunityStorenodes{ + Clock: clock, + CommunityId: community.ID(), + Storenodes: snodes.ToProtobuf(), + ChainId: communities.CommunityDescriptionTokenOwnerChainID(community.Description()), + } + snPayload, err := proto.Marshal(pb) + if err != nil { + return err + } + signature, err := crypto.Sign(crypto.Keccak256(snPayload), community.PrivateKey()) + if err != nil { + return err + } + signedStorenodesInfo := &protobuf.CommunityPublicStorenodesInfo{ + Signature: signature, + Payload: snPayload, + } + signedPayload, err := proto.Marshal(signedStorenodesInfo) + if err != nil { + return err + } + + rawMessage := common.RawMessage{ + Payload: signedPayload, + Sender: community.PrivateKey(), + SkipEncryptionLayer: true, + MessageType: protobuf.ApplicationMetadataMessage_COMMUNITY_PUBLIC_STORENODES_INFO, + PubsubTopic: community.PubsubTopic(), + } + + _, err = m.sender.SendPublic(context.Background(), community.IDString(), rawMessage) + return err +} + +// HandleCommunityPublicStorenodesInfo will process the control message sent by the community owner on updating the community storenodes for his community (sendCommunityPublicStorenodesInfo). +// The message will be received by many peers that are not interested on that community, so if we don't have this community in our DB we just ignore this message. +func (m *Messenger) HandleCommunityPublicStorenodesInfo(state *ReceivedMessageState, a *protobuf.CommunityPublicStorenodesInfo, statusMessage *v1protocol.StatusMessage) error { + sn := &protobuf.CommunityStorenodes{} + err := proto.Unmarshal(a.Payload, sn) + if err != nil { + return err + } + logger := m.logger.Named("HandleCommunityPublicStorenodesInfo").With(zap.String("communityID", types.EncodeHex(sn.CommunityId))) + + err = m.verifyCommunitySignature(a.Payload, a.Signature, sn.CommunityId, sn.ChainId) + if err != nil { + logger.Error("failed to verify community signature", zap.Error(err)) + return err + } + + // verify if we are interested in this control message + _, err = m.communitiesManager.GetByID(sn.CommunityId) + if err != nil { + if errors.Is(err, communities.ErrOrgNotFound) { + logger.Debug("ignoring control message, community not found") + return nil + } + logger.Error("failed get community by id", zap.Error(err)) + return err + } + + if err := m.communityStorenodes.UpdateStorenodesInDB(sn.CommunityId, storenodes.FromProtobuf(sn.Storenodes, sn.Clock), sn.Clock); err != nil { + logger.Error("failed to update storenodes for community", zap.Error(err)) + return err + } + return nil +} diff --git a/protocol/messenger_handlers.go b/protocol/messenger_handlers.go index 266988957..4ca4dad49 100644 --- a/protocol/messenger_handlers.go +++ b/protocol/messenger_handlers.go @@ -243,6 +243,9 @@ func (m *Messenger) dispatchToHandler(messageState *ReceivedMessageState, protoB case protobuf.ApplicationMetadataMessage_COMMUNITY_USER_KICKED: return m.handleCommunityUserKickedProtobuf(messageState, protoBytes, msg, filter) + + case protobuf.ApplicationMetadataMessage_COMMUNITY_PUBLIC_STORENODES_INFO: + return m.handleCommunityPublicStorenodesInfoProtobuf(messageState, protoBytes, msg, filter) case protobuf.ApplicationMetadataMessage_SYNC_PROFILE_SHOWCASE_PREFERENCES: return m.handleSyncProfileShowcasePreferencesProtobuf(messageState, protoBytes, msg, filter) @@ -251,7 +254,6 @@ func (m *Messenger) dispatchToHandler(messageState *ReceivedMessageState, protoB m.logger.Info("protobuf type not found", zap.String("type", string(msg.ApplicationLayer.Type))) return errors.New("protobuf type not found") } - return nil } @@ -1710,6 +1712,20 @@ func (m *Messenger) handleCommunityPublicShardInfoProtobuf(messageState *Receive } +func (m *Messenger) handleCommunityPublicStorenodesInfoProtobuf(messageState *ReceivedMessageState, protoBytes []byte, msg *v1protocol.StatusMessage, filter transport.Filter) error { + m.logger.Info("handling CommunityPublicStorenodesInfo") + + p := &protobuf.CommunityPublicStorenodesInfo{} + err := proto.Unmarshal(protoBytes, p) + if err != nil { + return err + } + + m.outputToCSV(msg.TransportLayer.Message.Timestamp, msg.ApplicationLayer.ID, messageState.CurrentMessageState.Contact.ID, filter.ContentTopic, filter.ChatID, msg.ApplicationLayer.Type, p) + + return m.HandleCommunityPublicStorenodesInfo(messageState, p, msg) + +} func (m *Messenger) handleSyncCollectiblePreferencesProtobuf(messageState *ReceivedMessageState, protoBytes []byte, msg *v1protocol.StatusMessage, filter transport.Filter) error { m.logger.Info("handling SyncCollectiblePreferences") diff --git a/protocol/messenger_mailserver.go b/protocol/messenger_mailserver.go index 2992fd91b..eab644f5a 100644 --- a/protocol/messenger_mailserver.go +++ b/protocol/messenger_mailserver.go @@ -41,6 +41,7 @@ var maxTopicsPerRequest int = 10 var ErrNoFiltersForChat = errors.New("no filter registered for given chat") func (m *Messenger) shouldSync() (bool, error) { + // TODO (pablo) support community store node as well if m.mailserverCycle.activeMailserver == nil || !m.Online() { return false, nil } @@ -66,8 +67,9 @@ func (m *Messenger) scheduleSyncChat(chat *Chat) (bool, error) { } go func() { - _, err := m.performMailserverRequest(func() (*MessengerResponse, error) { - response, err := m.syncChatWithFilters(chat.ID) + ms := m.getActiveMailserver(chat.CommunityID) + _, err = m.performMailserverRequest(ms, func(mailServer mailservers.Mailserver) (*MessengerResponse, error) { + response, err := m.syncChatWithFilters(mailServer, chat.ID) if err != nil { m.logger.Error("failed to sync chat", zap.Error(err)) @@ -102,45 +104,42 @@ func (m *Messenger) connectToNewMailserverAndWait() error { return m.findNewMailserver() } -func (m *Messenger) performMailserverRequest(fn func() (*MessengerResponse, error)) (*MessengerResponse, error) { +func (m *Messenger) performMailserverRequest(ms *mailservers.Mailserver, fn func(mailServer mailservers.Mailserver) (*MessengerResponse, error)) (*MessengerResponse, error) { + if ms == nil { + return nil, errors.New("mailserver not available") + } m.mailserverCycle.RLock() defer m.mailserverCycle.RUnlock() var tries uint = 0 for tries < mailserverMaxTries { - if !m.isActiveMailserverAvailable() { - return nil, errors.New("mailserver not available") - } - - m.logger.Info("trying performing mailserver requests", zap.Uint("try", tries)) - activeMailserver := m.getActiveMailserver() - // Make sure we are connected to a mailserver - if activeMailserver == nil { + if !m.communityStorenodes.IsCommunityStoreNode(ms.ID) && !m.isMailserverAvailable(ms.ID) { return nil, errors.New("mailserver not available") } + m.logger.Info("trying performing mailserver requests", zap.Uint("try", tries), zap.String("mailserverID", ms.ID)) // Peform request - response, err := fn() + response, err := fn(*ms) // pass by value because we don't want the fn to modify the mailserver if err == nil { // Reset failed requests m.logger.Debug("mailserver request performed successfully", - zap.String("mailserverID", activeMailserver.ID)) - activeMailserver.FailedRequests = 0 + zap.String("mailserverID", ms.ID)) + ms.FailedRequests = 0 return response, nil } m.logger.Error("failed to perform mailserver request", - zap.String("mailserverID", activeMailserver.ID), + zap.String("mailserverID", ms.ID), zap.Uint("tries", tries), zap.Error(err), ) tries++ // Increment failed requests - activeMailserver.FailedRequests++ + ms.FailedRequests++ // Change mailserver - if activeMailserver.FailedRequests >= mailserverMaxFailedRequests { + if ms.FailedRequests >= mailserverMaxFailedRequests { return nil, errors.New("too many failed requests") } // Wait a couple of second not to spam @@ -162,21 +161,26 @@ func (m *Messenger) scheduleSyncFilters(filters []*transport.Filter) (bool, erro } go func() { - _, err := m.performMailserverRequest(func() (*MessengerResponse, error) { - response, err := m.syncFilters(filters) + // split filters by community store node so we can request the filters to the correct mailserver + filtersByMs := m.SplitFiltersByStoreNode(filters) + for communityID, filtersForMs := range filtersByMs { + ms := m.getActiveMailserver(communityID) + _, err := m.performMailserverRequest(ms, func(ms mailservers.Mailserver) (*MessengerResponse, error) { + response, err := m.syncFilters(ms, filtersForMs) + if err != nil { + m.logger.Error("failed to sync filter", zap.Error(err)) + return nil, err + } + + if m.config.messengerSignalsHandler != nil { + m.config.messengerSignalsHandler.MessengerResponse(response) + } + return response, nil + }) if err != nil { - m.logger.Error("failed to sync filter", zap.Error(err)) - return nil, err + m.logger.Error("failed to perform mailserver request", zap.Error(err)) } - - if m.config.messengerSignalsHandler != nil { - m.config.messengerSignalsHandler.MessengerResponse(response) - } - return response, nil - }) - if err != nil { - m.logger.Error("failed to perform mailserver request", zap.Error(err)) } }() @@ -242,12 +246,13 @@ func (m *Messenger) topicsForChat(chatID string) (string, []types.TopicType, err return filters[0].PubsubTopic, contentTopics, nil } -func (m *Messenger) syncChatWithFilters(chatID string) (*MessengerResponse, error) { +func (m *Messenger) syncChatWithFilters(ms mailservers.Mailserver, chatID string) (*MessengerResponse, error) { filters, err := m.filtersForChat(chatID) if err != nil { return nil, err } - return m.syncFilters(filters) + + return m.syncFilters(ms, filters) } func (m *Messenger) syncBackup() error { @@ -260,7 +265,8 @@ func (m *Messenger) syncBackup() error { from, to := m.calculateMailserverTimeBounds(oneMonthDuration) batch := MailserverBatch{From: from, To: to, Topics: []types.TopicType{filter.ContentTopic}} - err := m.processMailserverBatch(batch) + ms := m.getActiveMailserver(filter.ChatID) + err := m.processMailserverBatch(*ms, batch) if err != nil { return err } @@ -303,14 +309,24 @@ func (m *Messenger) resetFiltersPriority(filters []*transport.Filter) { } } -func (m *Messenger) RequestAllHistoricMessagesWithRetries(forceFetchingBackup bool) (*MessengerResponse, error) { - return m.performMailserverRequest(func() (*MessengerResponse, error) { - return m.RequestAllHistoricMessages(forceFetchingBackup) - }) +func (m *Messenger) SplitFiltersByStoreNode(filters []*transport.Filter) map[string][]*transport.Filter { + // split filters by community store node so we can request the filters to the correct mailserver + filtersByMs := make(map[string][]*transport.Filter, len(filters)) + for _, f := range filters { + communityID := "" // none by default + if chat, ok := m.allChats.Load(f.ChatID); ok && chat.CommunityChat() && m.communityStorenodes.HasStorenodeSetup(chat.CommunityID) { + communityID = chat.CommunityID + } + if _, exists := filtersByMs[communityID]; !exists { + filtersByMs[communityID] = make([]*transport.Filter, 0, len(filters)) + } + filtersByMs[communityID] = append(filtersByMs[communityID], f) + } + return filtersByMs } // RequestAllHistoricMessages requests all the historic messages for any topic -func (m *Messenger) RequestAllHistoricMessages(forceFetchingBackup bool) (*MessengerResponse, error) { +func (m *Messenger) RequestAllHistoricMessages(forceFetchingBackup, withRetries bool) (*MessengerResponse, error) { shouldSync, err := m.shouldSync() if err != nil { return nil, err @@ -337,18 +353,37 @@ func (m *Messenger) RequestAllHistoricMessages(forceFetchingBackup bool) (*Messe filters := m.transport.Filters() m.updateFiltersPriority(filters) defer m.resetFiltersPriority(filters) - response, err := m.syncFilters(filters) - if err != nil { - return nil, err + + filtersByMs := m.SplitFiltersByStoreNode(filters) + allResponses := &MessengerResponse{} + for communityID, filtersForMs := range filtersByMs { + ms := m.getActiveMailserver(communityID) + if withRetries { + response, err := m.performMailserverRequest(ms, func(ms mailservers.Mailserver) (*MessengerResponse, error) { + return m.syncFilters(ms, filtersForMs) + }) + if err != nil { + return nil, err + } + allResponses.AddChats(response.Chats()) + allResponses.AddMessages(response.Messages()) + continue + } + response, err := m.syncFilters(*ms, filtersForMs) + if err != nil { + return nil, err + } + allResponses.AddChats(response.Chats()) + allResponses.AddMessages(response.Messages()) } - return response, nil + return allResponses, nil } func getPrioritizedBatches() []int { return []int{1, 5, 10} } -func (m *Messenger) syncFiltersFrom(filters []*transport.Filter, lastRequest uint32) (*MessengerResponse, error) { +func (m *Messenger) syncFiltersFrom(ms mailservers.Mailserver, filters []*transport.Filter, lastRequest uint32) (*MessengerResponse, error) { response := &MessengerResponse{} topicInfo, err := m.mailserversDatabase.Topics() if err != nil { @@ -519,10 +554,8 @@ func (m *Messenger) syncFiltersFrom(filters []*transport.Filter, lastRequest uin } } - i := 0 for _, batch := range batches24h { - i++ - err := m.processMailserverBatch(batch) + err := m.processMailserverBatch(ms, batch) if err != nil { m.logger.Error("error syncing topics", zap.Error(err)) return nil, err @@ -580,8 +613,8 @@ func (m *Messenger) syncFiltersFrom(filters []*transport.Filter, lastRequest uin return response, nil } -func (m *Messenger) syncFilters(filters []*transport.Filter) (*MessengerResponse, error) { - return m.syncFiltersFrom(filters, 0) +func (m *Messenger) syncFilters(ms mailservers.Mailserver, filters []*transport.Filter) (*MessengerResponse, error) { + return m.syncFiltersFrom(ms, filters, 0) } func (m *Messenger) calculateGapForChat(chat *Chat, from uint32) (*common.Message, error) { @@ -802,30 +835,30 @@ loop: return result } -func (m *Messenger) processMailserverBatch(batch MailserverBatch) error { +func (m *Messenger) processMailserverBatch(ms mailservers.Mailserver, batch MailserverBatch) error { if m.featureFlags.StoreNodesDisabled { return nil } - mailserverID, err := m.activeMailserverID() + mailserverID, err := ms.IDBytes() if err != nil { return err } - - return processMailserverBatch(m.ctx, m.transport, batch, mailserverID, m.logger, defaultStoreNodeRequestPageSize, nil, false) + logger := m.logger.With(zap.String("mailserverID", ms.ID)) + return processMailserverBatch(m.ctx, m.transport, batch, mailserverID, logger, defaultStoreNodeRequestPageSize, nil, false) } -func (m *Messenger) processMailserverBatchWithOptions(batch MailserverBatch, pageLimit uint32, shouldProcessNextPage func(int) (bool, uint32), processEnvelopes bool) error { +func (m *Messenger) processMailserverBatchWithOptions(ms mailservers.Mailserver, batch MailserverBatch, pageLimit uint32, shouldProcessNextPage func(int) (bool, uint32), processEnvelopes bool) error { if m.featureFlags.StoreNodesDisabled { return nil } - mailserverID, err := m.activeMailserverID() + mailserverID, err := ms.IDBytes() if err != nil { return err } - - return processMailserverBatch(m.ctx, m.transport, batch, mailserverID, m.logger, pageLimit, shouldProcessNextPage, processEnvelopes) + logger := m.logger.With(zap.String("mailserverID", ms.ID)) + return processMailserverBatch(m.ctx, m.transport, batch, mailserverID, logger, pageLimit, shouldProcessNextPage, processEnvelopes) } type MailserverBatch struct { @@ -838,18 +871,19 @@ type MailserverBatch struct { } func (m *Messenger) SyncChatFromSyncedFrom(chatID string) (uint32, error) { + chat, ok := m.allChats.Load(chatID) + if !ok { + return 0, ErrChatNotFound + } + + ms := m.getActiveMailserver(chat.CommunityID) var from uint32 - _, err := m.performMailserverRequest(func() (*MessengerResponse, error) { + _, err := m.performMailserverRequest(ms, func(ms mailservers.Mailserver) (*MessengerResponse, error) { pubsubTopic, topics, err := m.topicsForChat(chatID) if err != nil { return nil, nil } - chat, ok := m.allChats.Load(chatID) - if !ok { - return nil, ErrChatNotFound - } - defaultSyncPeriod, err := m.settings.GetDefaultSyncPeriod() if err != nil { return nil, err @@ -866,7 +900,7 @@ func (m *Messenger) SyncChatFromSyncedFrom(chatID string) (uint32, error) { m.config.messengerSignalsHandler.HistoryRequestStarted(1) } - err = m.processMailserverBatch(batch) + err = m.processMailserverBatch(ms, batch) if err != nil { return nil, err } @@ -897,7 +931,7 @@ func (m *Messenger) FillGaps(chatID string, messageIDs []string) error { return err } - _, ok := m.allChats.Load(chatID) + chat, ok := m.allChats.Load(chatID) if !ok { return errors.New("chat not existing") } @@ -935,7 +969,8 @@ func (m *Messenger) FillGaps(chatID string, messageIDs []string) error { m.config.messengerSignalsHandler.HistoryRequestStarted(1) } - err = m.processMailserverBatch(batch) + ms := m.getActiveMailserver(chat.CommunityID) + err = m.processMailserverBatch(*ms, batch) if err != nil { return err } @@ -1017,17 +1052,19 @@ func (m *Messenger) ConnectionChanged(state connection.State) { func (m *Messenger) fetchMessages(chatID string, duration time.Duration) (uint32, error) { from, to := m.calculateMailserverTimeBounds(duration) - _, err := m.performMailserverRequest(func() (*MessengerResponse, error) { + chat, ok := m.allChats.Load(chatID) + if !ok { + return 0, ErrChatNotFound + } + + ms := m.getActiveMailserver(chat.CommunityID) + _, err := m.performMailserverRequest(ms, func(ms mailservers.Mailserver) (*MessengerResponse, error) { + m.logger.Debug("fetching messages", zap.String("chatID", chatID), zap.String("mailserver", ms.Name)) pubsubTopic, topics, err := m.topicsForChat(chatID) if err != nil { return nil, nil } - chat, ok := m.allChats.Load(chatID) - if !ok { - return nil, ErrChatNotFound - } - batch := MailserverBatch{ ChatIDs: []string{chatID}, From: from, @@ -1039,7 +1076,7 @@ func (m *Messenger) fetchMessages(chatID string, duration time.Duration) (uint32 m.config.messengerSignalsHandler.HistoryRequestStarted(1) } - err = m.processMailserverBatch(batch) + err = m.processMailserverBatch(ms, batch) if err != nil { return nil, err } diff --git a/protocol/messenger_mailserver_cycle.go b/protocol/messenger_mailserver_cycle.go index 1ac813ba7..6eef05b3e 100644 --- a/protocol/messenger_mailserver_cycle.go +++ b/protocol/messenger_mailserver_cycle.go @@ -18,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/status-im/status-go/params" + "github.com/status-im/status-go/protocol/storenodes" "github.com/status-im/status-go/services/mailservers" "github.com/status-im/status-go/signal" ) @@ -50,14 +51,6 @@ func (s byRTTMsAndCanConnectBefore) Less(i, j int) bool { return s[i].CanConnectAfter.Before(s[j].CanConnectAfter) } -func (m *Messenger) activeMailserverID() ([]byte, error) { - if m.mailserverCycle.activeMailserver == nil { - return nil, nil - } - - return m.mailserverCycle.activeMailserver.IDBytes() -} - func (m *Messenger) StartMailserverCycle(mailservers []mailservers.Mailserver) error { m.mailserverCycle.allMailservers = mailservers @@ -353,19 +346,14 @@ func (m *Messenger) findNewMailserver() error { } -func (m *Messenger) activeMailserverStatus() (connStatus, error) { - if m.mailserverCycle.activeMailserver == nil { - return disconnected, errors.New("Active mailserver is not set") +func (m *Messenger) mailserverStatus(mailserverID string) connStatus { + m.mailPeersMutex.RLock() + defer m.mailPeersMutex.RUnlock() + peer, ok := m.mailserverCycle.peers[mailserverID] + if !ok { + return disconnected } - - mailserverID := m.mailserverCycle.activeMailserver.ID - - m.mailPeersMutex.Lock() - status := m.mailserverCycle.peers[mailserverID].status - m.mailPeersMutex.Unlock() - - return status, nil - + return peer.status } func (m *Messenger) connectToMailserver(ms mailservers.Mailserver) error { @@ -380,11 +368,7 @@ func (m *Messenger) connectToMailserver(ms mailservers.Mailserver) error { // received after the peer was added. So we first set the peer status as // Connecting and once a peerConnected signal is received, we mark it as // Connected - activeMailserverStatus, err := m.activeMailserverStatus() - if err != nil { - return err - } - + activeMailserverStatus := m.mailserverStatus(ms.ID) if ms.Version != m.transport.WakuVersion() { return errors.New("mailserver waku version doesn't match") } @@ -426,27 +410,52 @@ func (m *Messenger) connectToMailserver(ms mailservers.Mailserver) error { // Query mailserver if m.config.featureFlags.AutoRequestHistoricMessages { - m.asyncRequestAllHistoricMessages() + go func() { + _, err := m.performMailserverRequest(&ms, func(_ mailservers.Mailserver) (*MessengerResponse, error) { + return m.RequestAllHistoricMessages(false, false) + }) + if err != nil { + m.logger.Error("could not perform mailserver request", zap.Error(err)) + } + }() } } } return nil } -func (m *Messenger) getActiveMailserver() *mailservers.Mailserver { - return m.mailserverCycle.activeMailserver -} - -func (m *Messenger) isActiveMailserverAvailable() bool { - mailserverStatus, err := m.activeMailserverStatus() - if err != nil { - return false +// getActiveMailserver returns the active mailserver if a communityID is present then it'll return the mailserver +// for that community if it has a mailserver setup otherwise it'll return the global mailserver +func (m *Messenger) getActiveMailserver(communityID ...string) *mailservers.Mailserver { + if len(communityID) == 0 || communityID[0] == "" { + return m.mailserverCycle.activeMailserver } - - return mailserverStatus == connected + ms, err := m.communityStorenodes.GetStorenodeByCommunnityID(communityID[0]) + if err != nil { + if errors.Is(err, storenodes.ErrNotFound) { + m.logger.Debug("not found specific mailserver for community, using global", zap.String("communityID", communityID[0])) + } else { + m.logger.Error("not found specific mailserver for community, using global", zap.String("communityID", communityID[0]), zap.Error(err)) + } + // if we don't find a specific mailserver for the community, we use the global one + return m.mailserverCycle.activeMailserver + } + return &ms } -func (m *Messenger) mailserverAddressToID(uniqueID string, allMailservers []mailservers.Mailserver) (string, error) { +func (m *Messenger) getActiveMailserverID(communityID ...string) string { + ms := m.getActiveMailserver(communityID...) + if ms == nil { + return "" + } + return ms.ID +} + +func (m *Messenger) isMailserverAvailable(mailserverID string) bool { + return m.mailserverStatus(mailserverID) == connected +} + +func mailserverAddressToID(uniqueID string, allMailservers []mailservers.Mailserver) (string, error) { for _, ms := range allMailservers { if uniqueID == ms.UniqueID() { return ms.ID, nil @@ -485,6 +494,7 @@ func (m *Messenger) penalizeMailserver(id string) { m.mailserverCycle.peers[id] = pInfo } +// handleMailserverCycleEvent runs every 1 second or when updating peers to keep the data of the active mailserver updated func (m *Messenger) handleMailserverCycleEvent(connectedPeers []ConnectedPeer) error { m.logger.Debug("mailserver cycle event", zap.Any("connected", connectedPeers), @@ -501,7 +511,7 @@ func (m *Messenger) handleMailserverCycleEvent(connectedPeers []ConnectedPeer) e found := false for _, connectedPeer := range connectedPeers { - id, err := m.mailserverAddressToID(connectedPeer.UniqueID, m.mailserverCycle.allMailservers) + id, err := mailserverAddressToID(connectedPeer.UniqueID, m.mailserverCycle.allMailservers) if err != nil { m.logger.Error("failed to convert id to hex", zap.Error(err)) return err @@ -527,7 +537,7 @@ func (m *Messenger) handleMailserverCycleEvent(connectedPeers []ConnectedPeer) e // not available error if m.mailserverCycle.activeMailserver != nil { for _, connectedPeer := range connectedPeers { - id, err := m.mailserverAddressToID(connectedPeer.UniqueID, m.mailserverCycle.allMailservers) + id, err := mailserverAddressToID(connectedPeer.UniqueID, m.mailserverCycle.allMailservers) if err != nil { m.logger.Error("failed to convert id to hex", zap.Error(err)) return err @@ -555,7 +565,12 @@ func (m *Messenger) handleMailserverCycleEvent(connectedPeers []ConnectedPeer) e } // Query mailserver if m.config.featureFlags.AutoRequestHistoricMessages { - m.asyncRequestAllHistoricMessages() + go func() { + _, err := m.RequestAllHistoricMessages(false, true) + if err != nil { + m.logger.Error("failed to request historic messages", zap.Error(err)) + } + }() } } else { m.mailPeersMutex.Unlock() @@ -600,7 +615,7 @@ func (m *Messenger) handleMailserverCycleEvent(connectedPeers []ConnectedPeer) e func (m *Messenger) asyncRequestAllHistoricMessages() { m.logger.Debug("asyncRequestAllHistoricMessages") go func() { - _, err := m.RequestAllHistoricMessagesWithRetries(false) + _, err := m.RequestAllHistoricMessages(false, true) if err != nil { m.logger.Error("failed to request historic messages", zap.Error(err)) } @@ -760,7 +775,7 @@ func (m *Messenger) waitForAvailableStoreNode(timeout time.Duration) bool { defer func() { wg.Done() }() - for !m.isActiveMailserverAvailable() { + for !m.isMailserverAvailable(m.getActiveMailserverID()) { select { case <-m.SubscribeMailserverAvailable(): case <-cancel: @@ -784,5 +799,5 @@ func (m *Messenger) waitForAvailableStoreNode(timeout time.Duration) bool { close(cancel) } - return m.isActiveMailserverAvailable() + return m.isMailserverAvailable(m.getActiveMailserverID()) } diff --git a/protocol/messenger_response.go b/protocol/messenger_response.go index adb4c645e..49d935853 100644 --- a/protocol/messenger_response.go +++ b/protocol/messenger_response.go @@ -21,6 +21,7 @@ import ( "github.com/status-im/status-go/protocol/encryption/multidevice" "github.com/status-im/status-go/protocol/identity" "github.com/status-im/status-go/protocol/protobuf" + "github.com/status-im/status-go/protocol/storenodes" "github.com/status-im/status-go/protocol/verification" localnotifications "github.com/status-im/status-go/services/local-notifications" "github.com/status-im/status-go/services/mailservers" @@ -51,6 +52,7 @@ type MessengerResponse struct { CommunityChanges []*communities.CommunityChanges AnonymousMetrics []*appmetrics.AppMetric Mailservers []mailservers.Mailserver + CommunityStorenodes []storenodes.Storenode Bookmarks []*browsers.Bookmark Settings []*settings.SyncSettingField IdentityImages []images.IdentityImage @@ -108,6 +110,7 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) { CommunityChanges []*communities.CommunityChanges `json:"communityChanges,omitempty"` RequestsToJoinCommunity []*communities.RequestToJoin `json:"requestsToJoinCommunity,omitempty"` Mailservers []mailservers.Mailserver `json:"mailservers,omitempty"` + CommunityStorenodes []storenodes.Storenode `json:"communityStorenodes,omitempty"` Bookmarks []*browsers.Bookmark `json:"bookmarks,omitempty"` ClearedHistories []*ClearedHistory `json:"clearedHistories,omitempty"` VerificationRequests []*verification.Request `json:"verificationRequests,omitempty"` @@ -146,6 +149,7 @@ func (r *MessengerResponse) MarshalJSON() ([]byte, error) { CommunityChanges: r.CommunityChanges, RequestsToJoinCommunity: r.RequestsToJoinCommunity(), Mailservers: r.Mailservers, + CommunityStorenodes: r.CommunityStorenodes, Bookmarks: r.Bookmarks, CurrentStatus: r.currentStatus, Settings: r.Settings, @@ -294,6 +298,7 @@ func (r *MessengerResponse) IsEmpty() bool { len(r.removedChats)+ len(r.removedMessages)+ len(r.Mailservers)+ + len(r.CommunityStorenodes)+ len(r.IdentityImages)+ len(r.WatchOnlyAccounts)+ len(r.Keypairs)+ diff --git a/protocol/messenger_store_node_request_manager.go b/protocol/messenger_store_node_request_manager.go index 75f9cfd84..05927011f 100644 --- a/protocol/messenger_store_node_request_manager.go +++ b/protocol/messenger_store_node_request_manager.go @@ -15,6 +15,7 @@ import ( "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/communities" "github.com/status-im/status-go/protocol/transport" + "github.com/status-im/status-go/services/mailservers" ) const ( @@ -225,9 +226,7 @@ func (m *StoreNodeRequestManager) getFilter(requestType storeNodeRequestType, da } switch requestType { - case storeNodeShardRequest: - fallthrough - case storeNodeCommunityRequest: + case storeNodeShardRequest, storeNodeCommunityRequest: // If filter wasn't installed we create it and // remember for uninstalling after response is received filters, err := m.messenger.transport.InitPublicFilters([]transport.FiltersToInitialize{{ @@ -503,11 +502,12 @@ func (r *storeNodeRequest) routine() { r.finalize() }() - if !r.manager.messenger.waitForAvailableStoreNode(storeNodeAvailableTimeout) { + communityIDStr := strings.TrimSuffix(r.requestID.DataID, transport.CommunityShardInfoTopicPrefix()) + if !r.manager.messenger.communityStorenodes.HasStorenodeSetup(communityIDStr) && !r.manager.messenger.waitForAvailableStoreNode(storeNodeAvailableTimeout) { r.result.err = fmt.Errorf("store node is not available") return } - + ms := r.manager.messenger.getActiveMailserver(communityIDStr) // Check if community already exists locally and get Clock. localCommunity, _ := r.manager.messenger.communitiesManager.GetByIDString(r.requestID.DataID) @@ -519,7 +519,7 @@ func (r *storeNodeRequest) routine() { // Start store node request from, to := r.manager.messenger.calculateMailserverTimeBounds(oneMonthDuration) - _, err := r.manager.messenger.performMailserverRequest(func() (*MessengerResponse, error) { + _, err := r.manager.messenger.performMailserverRequest(ms, func(ms mailservers.Mailserver) (*MessengerResponse, error) { batch := MailserverBatch{ From: from, To: to, @@ -531,7 +531,7 @@ func (r *storeNodeRequest) routine() { r.manager.onPerformingBatch(batch) } - return nil, r.manager.messenger.processMailserverBatchWithOptions(batch, r.config.InitialPageSize, r.shouldFetchNextPage, true) + return nil, r.manager.messenger.processMailserverBatchWithOptions(ms, batch, r.config.InitialPageSize, r.shouldFetchNextPage, true) }) r.result.err = err diff --git a/protocol/messenger_storenode_comunity_test.go b/protocol/messenger_storenode_comunity_test.go new file mode 100644 index 000000000..1f2ef9756 --- /dev/null +++ b/protocol/messenger_storenode_comunity_test.go @@ -0,0 +1,344 @@ +package protocol + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/status-im/status-go/protocol/storenodes" + + gethbridge "github.com/status-im/status-go/eth-node/bridge/geth" + "github.com/status-im/status-go/protocol/common/shard" + "github.com/status-im/status-go/protocol/communities" + "github.com/status-im/status-go/protocol/tt" + + "github.com/stretchr/testify/suite" + "go.uber.org/zap" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/status-im/status-go/appdatabase" + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/protocol/protobuf" + "github.com/status-im/status-go/protocol/requests" + "github.com/status-im/status-go/protocol/sqlite" + "github.com/status-im/status-go/t/helpers" + + mailserversDB "github.com/status-im/status-go/services/mailservers" + waku2 "github.com/status-im/status-go/wakuv2" + wakuV2common "github.com/status-im/status-go/wakuv2/common" +) + +func TestMessengerStoreNodeCommunitySuite(t *testing.T) { + suite.Run(t, new(MessengerStoreNodeCommunitySuite)) +} + +type MessengerStoreNodeCommunitySuite struct { + suite.Suite + + cancel chan struct{} + + owner *Messenger + ownerWaku types.Waku + + bob *Messenger + bobWaku types.Waku + + storeNode *waku2.Waku + storeNodeAddress string + communityStoreNode *waku2.Waku + communityStoreNodeAddress string + + collectiblesServiceMock *CollectiblesServiceMock + + logger *zap.Logger +} + +func (s *MessengerStoreNodeCommunitySuite) SetupTest() { + s.logger = tt.MustCreateTestLogger() + + s.cancel = make(chan struct{}, 10) + + s.collectiblesServiceMock = &CollectiblesServiceMock{} + + s.storeNode, s.storeNodeAddress = s.createStore("store-1") + s.communityStoreNode, s.communityStoreNodeAddress = s.createStore("store-community") + + s.owner, s.ownerWaku = s.newMessenger("owner", s.storeNodeAddress) + s.bob, s.bobWaku = s.newMessenger("bob", s.storeNodeAddress) +} + +func (s *MessengerStoreNodeCommunitySuite) TearDown() { + close(s.cancel) + if s.storeNode != nil { + s.Require().NoError(s.storeNode.Stop()) + } + if s.communityStoreNode != nil { + s.Require().NoError(s.communityStoreNode.Stop()) + } + if s.owner != nil { + TearDownMessenger(&s.Suite, s.owner) + } + if s.bob != nil { + TearDownMessenger(&s.Suite, s.bob) + } +} + +func (s *MessengerStoreNodeCommunitySuite) createStore(name string) (*waku2.Waku, string) { + cfg := testWakuV2Config{ + logger: s.logger.Named(name), + enableStore: true, + useShardAsDefaultTopic: false, + clusterID: shard.UndefinedShardValue, + } + + storeNode := NewTestWakuV2(&s.Suite, cfg) + addresses := storeNode.ListenAddresses() + s.Require().GreaterOrEqual(len(addresses), 1, "no storenode listen address") + return storeNode, addresses[0] +} + +func (s *MessengerStoreNodeCommunitySuite) newMessenger(name, storenodeAddress string) (*Messenger, types.Waku) { + localMailserverID := "local-mailserver-007" + localFleet := "local-fleet-007" + + logger := s.logger.Named(name) + cfg := testWakuV2Config{ + logger: logger, + enableStore: false, + useShardAsDefaultTopic: false, + clusterID: shard.UndefinedShardValue, + } + wakuV2 := NewTestWakuV2(&s.Suite, cfg) + wakuV2Wrapper := gethbridge.NewGethWakuV2Wrapper(wakuV2) + + privateKey, err := crypto.GenerateKey() + s.Require().NoError(err) + + mailserversSQLDb, err := helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{}) + s.Require().NoError(err) + err = sqlite.Migrate(mailserversSQLDb) // migrate default + s.Require().NoError(err) + + mailserversDatabase := mailserversDB.NewDB(mailserversSQLDb) + err = mailserversDatabase.Add(mailserversDB.Mailserver{ + ID: localMailserverID, + Name: localMailserverID, + Address: storenodeAddress, + Fleet: localFleet, + }) + s.Require().NoError(err) + + options := []Option{ + WithAutoRequestHistoricMessages(false), + } + + if storenodeAddress != "" { + options = append(options, + WithTestStoreNode(&s.Suite, localMailserverID, storenodeAddress, localFleet, s.collectiblesServiceMock), + ) + } + + messenger, err := newMessengerWithKey(wakuV2Wrapper, privateKey, logger, options) + + s.Require().NoError(err) + return messenger, wakuV2Wrapper +} + +func (s *MessengerStoreNodeCommunitySuite) createCommunityWithChat(m *Messenger) (*communities.Community, *Chat) { + WaitForAvailableStoreNode(&s.Suite, m, 500*time.Millisecond) + + storeNodeSubscription := s.setupStoreNodeEnvelopesWatcher(nil) + + createCommunityRequest := &requests.CreateCommunity{ + Name: RandomLettersString(10), + Description: RandomLettersString(20), + Color: RandomColor(), + Tags: RandomCommunityTags(3), + Membership: protobuf.CommunityPermissions_AUTO_ACCEPT, + } + + response, err := m.CreateCommunity(createCommunityRequest, true) + s.Require().NoError(err) + s.Require().NotNil(response) + s.Require().Len(response.Communities(), 1) + s.Require().Len(response.Chats(), 1) + s.Require().True(response.Communities()[0].Joined()) + s.Require().True(response.Communities()[0].IsControlNode()) + s.Require().True(response.Communities()[0].IsMemberOwner(&m.identity.PublicKey)) + + s.waitForEnvelopes(storeNodeSubscription, 1) + + return response.Communities()[0], response.Chats()[0] +} + +func (s *MessengerStoreNodeCommunitySuite) requireCommunitiesEqual(c *communities.Community, expected *communities.Community) { + if expected == nil { + s.Require().Nil(c) + return + } + s.Require().NotNil(c) + s.Require().Equal(expected.IDString(), c.IDString()) + s.Require().Equal(expected.Clock(), c.Clock()) + s.Require().Equal(expected.Name(), c.Name()) + s.Require().Equal(expected.Identity().Description, c.Identity().Description) + s.Require().Equal(expected.Color(), c.Color()) + s.Require().Equal(expected.Tags(), c.Tags()) + s.Require().Equal(expected.Shard(), c.Shard()) + s.Require().Equal(expected.TokenPermissions(), c.TokenPermissions()) + s.Require().Equal(expected.CommunityTokensMetadata(), c.CommunityTokensMetadata()) +} + +func (s *MessengerStoreNodeCommunitySuite) fetchCommunity(m *Messenger, communityShard communities.CommunityShard, expectedCommunity *communities.Community) StoreNodeRequestStats { + options := []StoreNodeRequestOption{ + WithWaitForResponseOption(true), + } + + fetchedCommunity, stats, err := m.storeNodeRequestsManager.FetchCommunity(communityShard, options) + + s.Require().NoError(err) + s.requireCommunitiesEqual(fetchedCommunity, expectedCommunity) + + return stats +} + +func (s *MessengerStoreNodeCommunitySuite) setupEnvelopesWatcher(wakuNode *waku2.Waku, topic *wakuV2common.TopicType, cb func(envelope *wakuV2common.ReceivedMessage)) { + envelopesWatcher := make(chan wakuV2common.EnvelopeEvent, 100) + envelopesSub := wakuNode.SubscribeEnvelopeEvents(envelopesWatcher) + + go func() { + defer envelopesSub.Unsubscribe() + for { + select { + case <-s.cancel: + return + + case envelopeEvent := <-envelopesWatcher: + if envelopeEvent.Event != wakuV2common.EventEnvelopeAvailable { + continue + } + if topic != nil && *topic != envelopeEvent.Topic { + continue + } + envelope := wakuNode.GetEnvelope(envelopeEvent.Hash) + cb(envelope) + s.logger.Debug("envelope available event for fetched content topic", + zap.Any("envelopeEvent", envelopeEvent), + zap.Any("envelope", envelope), + ) + } + + } + }() +} + +func (s *MessengerStoreNodeCommunitySuite) setupStoreNodeEnvelopesWatcher(topic *wakuV2common.TopicType) <-chan string { + storeNodeSubscription := make(chan string, 100) + s.setupEnvelopesWatcher(s.storeNode, topic, func(envelope *wakuV2common.ReceivedMessage) { + storeNodeSubscription <- envelope.Hash().String() + }) + return storeNodeSubscription +} + +func (s *MessengerStoreNodeCommunitySuite) waitForEnvelopes(subscription <-chan string, expectedEnvelopesCount int) { + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + for i := 0; i < expectedEnvelopesCount; i++ { + select { + case <-subscription: + case <-ctx.Done(): + err := fmt.Sprintf("timeout waiting for store node to receive envelopes, received: %d, expected: %d", i, expectedEnvelopesCount) + s.Require().Fail(err) + } + } +} + +func (s *MessengerStoreNodeCommunitySuite) TestSetCommunityStorenodesAndFetch() { + err := s.owner.DialPeer(s.storeNodeAddress) + s.Require().NoError(err) + err = s.bob.DialPeer(s.storeNodeAddress) + s.Require().NoError(err) + + // Create a community + community, _ := s.createCommunityWithChat(s.owner) + + // Set the storenode for the community + _, err = s.owner.SetCommunityStorenodes(&requests.SetCommunityStorenodes{ + CommunityID: community.ID(), + Storenodes: []storenodes.Storenode{ + { + StorenodeID: "community-store-node", + Name: "community-store-node", + CommunityID: community.ID(), + Version: 2, + Address: s.communityStoreNodeAddress, + Fleet: "aaa", + }, + }, + }) + s.Require().NoError(err) + + // Bob tetches the community + s.fetchCommunity(s.bob, community.CommunityShard(), community) +} + +func (s *MessengerStoreNodeCommunitySuite) TestSetStorenodeForCommunity_fetchMessagesFromNewStorenode() { + err := s.owner.DialPeer(s.storeNodeAddress) + s.Require().NoError(err) + err = s.bob.DialPeer(s.storeNodeAddress) + s.Require().NoError(err) + + ownerPeerID := gethbridge.GetGethWakuV2From(s.ownerWaku).PeerID().String() + bobPeerID := gethbridge.GetGethWakuV2From(s.bobWaku).PeerID().String() + + // 1. Owner creates a community + community, chat := s.createCommunityWithChat(s.owner) + + // waits for onwer and bob to connect to the store node + WaitForPeersConnected(&s.Suite, s.storeNode, func() []string { + return []string{ownerPeerID, bobPeerID} + }) + + // 2. Bob joins the community + advertiseCommunityTo(&s.Suite, community, s.owner, s.bob) + request := &requests.RequestToJoinCommunity{CommunityID: community.ID()} + joinCommunity(&s.Suite, community, s.owner, s.bob, request, "") + + // waits for onwer and bob to connect to the community store node + WaitForPeersConnected(&s.Suite, s.communityStoreNode, func() []string { + err := s.bob.DialPeer(s.communityStoreNodeAddress) + s.Require().NoError(err) + err = s.owner.DialPeer(s.communityStoreNodeAddress) + s.Require().NoError(err) + + return []string{ownerPeerID, bobPeerID} + }) + + // 3. Owner sets the storenode for the community + _, err = s.owner.SetCommunityStorenodes(&requests.SetCommunityStorenodes{ + CommunityID: community.ID(), + Storenodes: []storenodes.Storenode{ + { + StorenodeID: "community-store-node", + Name: "community-store-node", + CommunityID: community.ID(), + Version: 2, + Address: s.communityStoreNodeAddress, + Fleet: "aaa", + }, + }, + }) + s.Require().NoError(err) + + // 5. Bob sends a message to the community chat + inputMessage := buildTestMessage(*chat) + _, err = s.bob.SendChatMessage(context.Background(), inputMessage) + s.Require().NoError(err) + + // 6. Owner fetches the message from the new storenode + err = s.owner.FetchMessages(&requests.FetchMessages{ + ID: chat.ID, + }) + s.Require().NoError(err) +} diff --git a/protocol/messenger_storenode_request_test.go b/protocol/messenger_storenode_request_test.go index 4ae07a93a..393c20836 100644 --- a/protocol/messenger_storenode_request_test.go +++ b/protocol/messenger_storenode_request_test.go @@ -141,6 +141,7 @@ func (s *MessengerStoreNodeRequestSuite) SetupTest() { s.logger = tt.MustCreateTestLogger() s.cancel = make(chan struct{}, 10) + s.collectiblesServiceMock = &CollectiblesServiceMock{} s.createStore() @@ -1136,10 +1137,10 @@ func (s *MessengerStoreNodeRequestSuite) TestFetchingHistoryWhenOnline() { // Connect to store node to force "online" status { - WaitForPeerConnected(&s.Suite, gethbridge.GetGethWakuV2From(s.bobWaku), func() string { + WaitForPeersConnected(&s.Suite, gethbridge.GetGethWakuV2From(s.bobWaku), func() []string { err := s.bob.DialPeer(storeAddress) s.Require().NoError(err) - return storePeerID + return []string{storePeerID} }) s.Require().True(s.bob.Online()) @@ -1193,10 +1194,10 @@ func (s *MessengerStoreNodeRequestSuite) TestFetchingHistoryWhenOnline() { // We don't enable it earlier to control when we connect to the store node. s.bob.config.featureFlags.AutoRequestHistoricMessages = true - WaitForPeerConnected(&s.Suite, gethbridge.GetGethWakuV2From(s.bobWaku), func() string { + WaitForPeersConnected(&s.Suite, gethbridge.GetGethWakuV2From(s.bobWaku), func() []string { err := s.bob.DialPeer(storeAddress) s.Require().NoError(err) - return storePeerID + return []string{storePeerID} }) s.Require().True(s.bob.Online()) diff --git a/protocol/messenger_testing_utils.go b/protocol/messenger_testing_utils.go index 1ec4b5244..ddeed71ca 100644 --- a/protocol/messenger_testing_utils.go +++ b/protocol/messenger_testing_utils.go @@ -11,6 +11,7 @@ import ( "github.com/status-im/status-go/protocol/identity" + "github.com/status-im/status-go/eth-node/types" waku2 "github.com/status-im/status-go/wakuv2" "golang.org/x/exp/maps" @@ -166,7 +167,16 @@ func WaitForConnectionStatus(s *suite.Suite, waku *waku2.Waku, action func() boo } } -func WaitForPeerConnected(s *suite.Suite, waku *waku2.Waku, action func() string) { +func hasAllPeers(m map[string]types.WakuV2Peer, checkSlice []string) bool { + for _, check := range checkSlice { + if _, ok := m[check]; !ok { + return false + } + } + return true +} + +func WaitForPeersConnected(s *suite.Suite, waku *waku2.Waku, action func() []string) { subscription := waku.SubscribeToConnStatusChanges() defer subscription.Unsubscribe() @@ -174,20 +184,19 @@ func WaitForPeerConnected(s *suite.Suite, waku *waku2.Waku, action func() string defer cancel() // Action should return the desired peer ID - peerID := action() - - if _, ok := waku.Peers()[peerID]; ok { + peerIDs := action() + if hasAllPeers(waku.Peers(), peerIDs) { return } for { select { case status := <-subscription.C: - if _, ok := status.Peers[peerID]; ok { + if hasAllPeers(status.Peers, peerIDs) { return } case <-ctx.Done(): - s.Require().Fail(fmt.Sprintf("timeout waiting for peer connected '%s'", peerID)) + s.Require().Fail(fmt.Sprintf("timeout waiting for peers connected '%+v'", peerIDs)) return } } diff --git a/protocol/protobuf/application_metadata_message.pb.go b/protocol/protobuf/application_metadata_message.pb.go index 5ca941c42..5608fd7c6 100644 --- a/protocol/protobuf/application_metadata_message.pb.go +++ b/protocol/protobuf/application_metadata_message.pb.go @@ -104,6 +104,7 @@ const ( ApplicationMetadataMessage_SYNC_COLLECTIBLE_PREFERENCES ApplicationMetadataMessage_Type = 80 ApplicationMetadataMessage_COMMUNITY_USER_KICKED ApplicationMetadataMessage_Type = 81 ApplicationMetadataMessage_SYNC_PROFILE_SHOWCASE_PREFERENCES ApplicationMetadataMessage_Type = 82 + ApplicationMetadataMessage_COMMUNITY_PUBLIC_STORENODES_INFO ApplicationMetadataMessage_Type = 83 ) // Enum value maps for ApplicationMetadataMessage_Type. @@ -188,6 +189,7 @@ var ( 80: "SYNC_COLLECTIBLE_PREFERENCES", 81: "COMMUNITY_USER_KICKED", 82: "SYNC_PROFILE_SHOWCASE_PREFERENCES", + 83: "COMMUNITY_PUBLIC_STORENODES_INFO", } ApplicationMetadataMessage_Type_value = map[string]int32{ "UNKNOWN": 0, @@ -269,6 +271,7 @@ var ( "SYNC_COLLECTIBLE_PREFERENCES": 80, "COMMUNITY_USER_KICKED": 81, "SYNC_PROFILE_SHOWCASE_PREFERENCES": 82, + "COMMUNITY_PUBLIC_STORENODES_INFO": 83, } ) @@ -370,7 +373,7 @@ var File_application_metadata_message_proto protoreflect.FileDescriptor var file_application_metadata_message_proto_rawDesc = []byte{ 0x0a, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0xc7, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x22, 0xed, 0x14, 0x0a, 0x1a, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, @@ -380,7 +383,7 @@ var file_application_metadata_message_proto_rawDesc = []byte{ 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, - 0x74, 0x79, 0x70, 0x65, 0x22, 0xb1, 0x13, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, + 0x74, 0x79, 0x70, 0x65, 0x22, 0xd7, 0x13, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x48, 0x41, 0x54, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x43, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x02, @@ -527,16 +530,19 @@ var file_application_metadata_message_proto_rawDesc = []byte{ 0x55, 0x4e, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x53, 0x45, 0x52, 0x5f, 0x4b, 0x49, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x51, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x50, 0x52, 0x4f, 0x46, 0x49, 0x4c, 0x45, 0x5f, 0x53, 0x48, 0x4f, 0x57, 0x43, 0x41, 0x53, 0x45, 0x5f, 0x50, 0x52, 0x45, - 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x10, 0x52, 0x22, 0x04, 0x08, 0x0e, 0x10, 0x0e, - 0x22, 0x04, 0x08, 0x41, 0x10, 0x41, 0x22, 0x04, 0x08, 0x42, 0x10, 0x42, 0x2a, 0x1d, 0x53, 0x59, - 0x4e, 0x43, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x43, 0x48, 0x41, 0x54, 0x2a, 0x22, 0x53, 0x59, 0x4e, - 0x43, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x49, 0x54, 0x59, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, - 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x2a, - 0x27, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x49, 0x54, 0x59, 0x5f, 0x43, - 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x53, 0x10, 0x52, 0x12, 0x24, 0x0a, 0x20, 0x43, 0x4f, + 0x4d, 0x4d, 0x55, 0x4e, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x53, + 0x54, 0x4f, 0x52, 0x45, 0x4e, 0x4f, 0x44, 0x45, 0x53, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x53, + 0x22, 0x04, 0x08, 0x0e, 0x10, 0x0e, 0x22, 0x04, 0x08, 0x41, 0x10, 0x41, 0x22, 0x04, 0x08, 0x42, + 0x10, 0x42, 0x2a, 0x1d, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x49, 0x4e, 0x53, 0x54, 0x41, 0x4c, 0x4c, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x43, 0x48, 0x41, + 0x54, 0x2a, 0x22, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, 0x49, 0x54, 0x59, + 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x53, 0x2a, 0x27, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x41, 0x43, 0x54, 0x49, + 0x56, 0x49, 0x54, 0x59, 0x5f, 0x43, 0x45, 0x4e, 0x54, 0x45, 0x52, 0x5f, 0x4e, 0x4f, 0x54, 0x49, + 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x42, 0x0d, + 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/protobuf/application_metadata_message.proto b/protocol/protobuf/application_metadata_message.proto index 5fc725796..86e5e3270 100644 --- a/protocol/protobuf/application_metadata_message.proto +++ b/protocol/protobuf/application_metadata_message.proto @@ -100,5 +100,6 @@ message ApplicationMetadataMessage { SYNC_COLLECTIBLE_PREFERENCES = 80; COMMUNITY_USER_KICKED = 81; SYNC_PROFILE_SHOWCASE_PREFERENCES = 82; + COMMUNITY_PUBLIC_STORENODES_INFO = 83; } } diff --git a/protocol/protobuf/communities.pb.go b/protocol/protobuf/communities.pb.go index 24019ded4..b84b668da 100644 --- a/protocol/protobuf/communities.pb.go +++ b/protocol/protobuf/communities.pb.go @@ -1961,6 +1961,237 @@ func (x *WakuMessageArchiveIndex) GetArchives() map[string]*WakuMessageArchiveIn return nil } +type CommunityPublicStorenodesInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Signature of the payload field + Signature []byte `protobuf:"bytes,1,opt,name=signature,proto3" json:"signature,omitempty"` + // Marshaled CommunityStorenodes + Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` +} + +func (x *CommunityPublicStorenodesInfo) Reset() { + *x = CommunityPublicStorenodesInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_communities_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommunityPublicStorenodesInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommunityPublicStorenodesInfo) ProtoMessage() {} + +func (x *CommunityPublicStorenodesInfo) ProtoReflect() protoreflect.Message { + mi := &file_communities_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommunityPublicStorenodesInfo.ProtoReflect.Descriptor instead. +func (*CommunityPublicStorenodesInfo) Descriptor() ([]byte, []int) { + return file_communities_proto_rawDescGZIP(), []int{23} +} + +func (x *CommunityPublicStorenodesInfo) GetSignature() []byte { + if x != nil { + return x.Signature + } + return nil +} + +func (x *CommunityPublicStorenodesInfo) GetPayload() []byte { + if x != nil { + return x.Payload + } + return nil +} + +type CommunityStorenodes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"` + CommunityId []byte `protobuf:"bytes,2,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"` + Storenodes []*Storenode `protobuf:"bytes,3,rep,name=storenodes,proto3" json:"storenodes,omitempty"` + ChainId uint64 `protobuf:"varint,4,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` +} + +func (x *CommunityStorenodes) Reset() { + *x = CommunityStorenodes{} + if protoimpl.UnsafeEnabled { + mi := &file_communities_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommunityStorenodes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommunityStorenodes) ProtoMessage() {} + +func (x *CommunityStorenodes) ProtoReflect() protoreflect.Message { + mi := &file_communities_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommunityStorenodes.ProtoReflect.Descriptor instead. +func (*CommunityStorenodes) Descriptor() ([]byte, []int) { + return file_communities_proto_rawDescGZIP(), []int{24} +} + +func (x *CommunityStorenodes) GetClock() uint64 { + if x != nil { + return x.Clock + } + return 0 +} + +func (x *CommunityStorenodes) GetCommunityId() []byte { + if x != nil { + return x.CommunityId + } + return nil +} + +func (x *CommunityStorenodes) GetStorenodes() []*Storenode { + if x != nil { + return x.Storenodes + } + return nil +} + +func (x *CommunityStorenodes) GetChainId() uint64 { + if x != nil { + return x.ChainId + } + return 0 +} + +type Storenode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CommunityId []byte `protobuf:"bytes,1,opt,name=community_id,json=communityId,proto3" json:"community_id,omitempty"` + StorenodeId string `protobuf:"bytes,2,opt,name=storenode_id,json=storenodeId,proto3" json:"storenode_id,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Address string `protobuf:"bytes,4,opt,name=address,proto3" json:"address,omitempty"` + Fleet string `protobuf:"bytes,5,opt,name=fleet,proto3" json:"fleet,omitempty"` + Version uint32 `protobuf:"varint,6,opt,name=version,proto3" json:"version,omitempty"` + Removed bool `protobuf:"varint,7,opt,name=removed,proto3" json:"removed,omitempty"` + DeletedAt int64 `protobuf:"varint,8,opt,name=deleted_at,json=deletedAt,proto3" json:"deleted_at,omitempty"` +} + +func (x *Storenode) Reset() { + *x = Storenode{} + if protoimpl.UnsafeEnabled { + mi := &file_communities_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Storenode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Storenode) ProtoMessage() {} + +func (x *Storenode) ProtoReflect() protoreflect.Message { + mi := &file_communities_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Storenode.ProtoReflect.Descriptor instead. +func (*Storenode) Descriptor() ([]byte, []int) { + return file_communities_proto_rawDescGZIP(), []int{25} +} + +func (x *Storenode) GetCommunityId() []byte { + if x != nil { + return x.CommunityId + } + return nil +} + +func (x *Storenode) GetStorenodeId() string { + if x != nil { + return x.StorenodeId + } + return "" +} + +func (x *Storenode) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *Storenode) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *Storenode) GetFleet() string { + if x != nil { + return x.Fleet + } + return "" +} + +func (x *Storenode) GetVersion() uint32 { + if x != nil { + return x.Version + } + return 0 +} + +func (x *Storenode) GetRemoved() bool { + if x != nil { + return x.Removed + } + return false +} + +func (x *Storenode) GetDeletedAt() int64 { + if x != nil { + return x.DeletedAt + } + return 0 +} + var File_communities_proto protoreflect.FileDescriptor var file_communities_proto_rawDesc = []byte{ @@ -2348,8 +2579,38 @@ var file_communities_proto_rawDesc = []byte{ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x57, 0x61, 0x6b, 0x75, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x38, 0x01, 0x22, 0x57, 0x0a, 0x1d, 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x9e, 0x01, 0x0a, 0x13, + 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x6e, 0x6f, + 0x64, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x05, 0x63, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, + 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x0a, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x6e, 0x6f, 0x64, 0x65, + 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0xe8, 0x01, 0x0a, + 0x09, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, + 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x21, 0x0a, + 0x0c, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x6e, 0x6f, 0x64, 0x65, 0x49, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, + 0x6c, 0x65, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, + 0x0a, 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x41, 0x74, 0x42, 0x0d, 0x5a, 0x0b, 0x2e, 0x2f, 0x3b, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2365,7 +2626,7 @@ func file_communities_proto_rawDescGZIP() []byte { } var file_communities_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_communities_proto_msgTypes = make([]protoimpl.MessageInfo, 32) +var file_communities_proto_msgTypes = make([]protoimpl.MessageInfo, 35) var file_communities_proto_goTypes = []interface{}{ (CommunityMember_Roles)(0), // 0: protobuf.CommunityMember.Roles (CommunityPermissions_Access)(0), // 1: protobuf.CommunityPermissions.Access @@ -2393,60 +2654,64 @@ var file_communities_proto_goTypes = []interface{}{ (*WakuMessageArchive)(nil), // 23: protobuf.WakuMessageArchive (*WakuMessageArchiveIndexMetadata)(nil), // 24: protobuf.WakuMessageArchiveIndexMetadata (*WakuMessageArchiveIndex)(nil), // 25: protobuf.WakuMessageArchiveIndex - nil, // 26: protobuf.CommunityTokenMetadata.ContractAddressesEntry - nil, // 27: protobuf.TokenCriteria.ContractAddressesEntry - nil, // 28: protobuf.CommunityDescription.MembersEntry - nil, // 29: protobuf.CommunityDescription.ChatsEntry - nil, // 30: protobuf.CommunityDescription.CategoriesEntry - nil, // 31: protobuf.CommunityDescription.TokenPermissionsEntry - nil, // 32: protobuf.CommunityDescription.PrivateDataEntry - nil, // 33: protobuf.CommunityChat.MembersEntry - nil, // 34: protobuf.WakuMessageArchiveIndex.ArchivesEntry - (CommunityTokenType)(0), // 35: protobuf.CommunityTokenType - (*ChatIdentity)(nil), // 36: protobuf.ChatIdentity - (*Shard)(nil), // 37: protobuf.Shard + (*CommunityPublicStorenodesInfo)(nil), // 26: protobuf.CommunityPublicStorenodesInfo + (*CommunityStorenodes)(nil), // 27: protobuf.CommunityStorenodes + (*Storenode)(nil), // 28: protobuf.Storenode + nil, // 29: protobuf.CommunityTokenMetadata.ContractAddressesEntry + nil, // 30: protobuf.TokenCriteria.ContractAddressesEntry + nil, // 31: protobuf.CommunityDescription.MembersEntry + nil, // 32: protobuf.CommunityDescription.ChatsEntry + nil, // 33: protobuf.CommunityDescription.CategoriesEntry + nil, // 34: protobuf.CommunityDescription.TokenPermissionsEntry + nil, // 35: protobuf.CommunityDescription.PrivateDataEntry + nil, // 36: protobuf.CommunityChat.MembersEntry + nil, // 37: protobuf.WakuMessageArchiveIndex.ArchivesEntry + (CommunityTokenType)(0), // 38: protobuf.CommunityTokenType + (*ChatIdentity)(nil), // 39: protobuf.ChatIdentity + (*Shard)(nil), // 40: protobuf.Shard } var file_communities_proto_depIdxs = []int32{ 0, // 0: protobuf.CommunityMember.roles:type_name -> protobuf.CommunityMember.Roles 13, // 1: protobuf.CommunityMember.revealed_accounts:type_name -> protobuf.RevealedAccount - 26, // 2: protobuf.CommunityTokenMetadata.contract_addresses:type_name -> protobuf.CommunityTokenMetadata.ContractAddressesEntry - 35, // 3: protobuf.CommunityTokenMetadata.tokenType:type_name -> protobuf.CommunityTokenType + 29, // 2: protobuf.CommunityTokenMetadata.contract_addresses:type_name -> protobuf.CommunityTokenMetadata.ContractAddressesEntry + 38, // 3: protobuf.CommunityTokenMetadata.tokenType:type_name -> protobuf.CommunityTokenType 1, // 4: protobuf.CommunityPermissions.access:type_name -> protobuf.CommunityPermissions.Access - 27, // 5: protobuf.TokenCriteria.contract_addresses:type_name -> protobuf.TokenCriteria.ContractAddressesEntry - 35, // 6: protobuf.TokenCriteria.type:type_name -> protobuf.CommunityTokenType + 30, // 5: protobuf.TokenCriteria.contract_addresses:type_name -> protobuf.TokenCriteria.ContractAddressesEntry + 38, // 6: protobuf.TokenCriteria.type:type_name -> protobuf.CommunityTokenType 2, // 7: protobuf.CommunityTokenPermission.type:type_name -> protobuf.CommunityTokenPermission.Type 7, // 8: protobuf.CommunityTokenPermission.token_criteria:type_name -> protobuf.TokenCriteria - 28, // 9: protobuf.CommunityDescription.members:type_name -> protobuf.CommunityDescription.MembersEntry + 31, // 9: protobuf.CommunityDescription.members:type_name -> protobuf.CommunityDescription.MembersEntry 6, // 10: protobuf.CommunityDescription.permissions:type_name -> protobuf.CommunityPermissions - 36, // 11: protobuf.CommunityDescription.identity:type_name -> protobuf.ChatIdentity - 29, // 12: protobuf.CommunityDescription.chats:type_name -> protobuf.CommunityDescription.ChatsEntry - 30, // 13: protobuf.CommunityDescription.categories:type_name -> protobuf.CommunityDescription.CategoriesEntry + 39, // 11: protobuf.CommunityDescription.identity:type_name -> protobuf.ChatIdentity + 32, // 12: protobuf.CommunityDescription.chats:type_name -> protobuf.CommunityDescription.ChatsEntry + 33, // 13: protobuf.CommunityDescription.categories:type_name -> protobuf.CommunityDescription.CategoriesEntry 10, // 14: protobuf.CommunityDescription.admin_settings:type_name -> protobuf.CommunityAdminSettings - 31, // 15: protobuf.CommunityDescription.token_permissions:type_name -> protobuf.CommunityDescription.TokenPermissionsEntry + 34, // 15: protobuf.CommunityDescription.token_permissions:type_name -> protobuf.CommunityDescription.TokenPermissionsEntry 5, // 16: protobuf.CommunityDescription.community_tokens_metadata:type_name -> protobuf.CommunityTokenMetadata - 32, // 17: protobuf.CommunityDescription.privateData:type_name -> protobuf.CommunityDescription.PrivateDataEntry - 33, // 18: protobuf.CommunityChat.members:type_name -> protobuf.CommunityChat.MembersEntry + 35, // 17: protobuf.CommunityDescription.privateData:type_name -> protobuf.CommunityDescription.PrivateDataEntry + 36, // 18: protobuf.CommunityChat.members:type_name -> protobuf.CommunityChat.MembersEntry 6, // 19: protobuf.CommunityChat.permissions:type_name -> protobuf.CommunityPermissions - 36, // 20: protobuf.CommunityChat.identity:type_name -> protobuf.ChatIdentity + 39, // 20: protobuf.CommunityChat.identity:type_name -> protobuf.ChatIdentity 13, // 21: protobuf.CommunityRequestToJoin.revealed_accounts:type_name -> protobuf.RevealedAccount 13, // 22: protobuf.CommunityEditSharedAddresses.revealed_accounts:type_name -> protobuf.RevealedAccount 9, // 23: protobuf.CommunityRequestToJoinResponse.community:type_name -> protobuf.CommunityDescription - 37, // 24: protobuf.CommunityRequestToJoinResponse.shard:type_name -> protobuf.Shard + 40, // 24: protobuf.CommunityRequestToJoinResponse.shard:type_name -> protobuf.Shard 22, // 25: protobuf.WakuMessageArchive.metadata:type_name -> protobuf.WakuMessageArchiveMetadata 21, // 26: protobuf.WakuMessageArchive.messages:type_name -> protobuf.WakuMessage 22, // 27: protobuf.WakuMessageArchiveIndexMetadata.metadata:type_name -> protobuf.WakuMessageArchiveMetadata - 34, // 28: protobuf.WakuMessageArchiveIndex.archives:type_name -> protobuf.WakuMessageArchiveIndex.ArchivesEntry - 4, // 29: protobuf.CommunityDescription.MembersEntry.value:type_name -> protobuf.CommunityMember - 11, // 30: protobuf.CommunityDescription.ChatsEntry.value:type_name -> protobuf.CommunityChat - 12, // 31: protobuf.CommunityDescription.CategoriesEntry.value:type_name -> protobuf.CommunityCategory - 8, // 32: protobuf.CommunityDescription.TokenPermissionsEntry.value:type_name -> protobuf.CommunityTokenPermission - 4, // 33: protobuf.CommunityChat.MembersEntry.value:type_name -> protobuf.CommunityMember - 24, // 34: protobuf.WakuMessageArchiveIndex.ArchivesEntry.value:type_name -> protobuf.WakuMessageArchiveIndexMetadata - 35, // [35:35] is the sub-list for method output_type - 35, // [35:35] is the sub-list for method input_type - 35, // [35:35] is the sub-list for extension type_name - 35, // [35:35] is the sub-list for extension extendee - 0, // [0:35] is the sub-list for field type_name + 37, // 28: protobuf.WakuMessageArchiveIndex.archives:type_name -> protobuf.WakuMessageArchiveIndex.ArchivesEntry + 28, // 29: protobuf.CommunityStorenodes.storenodes:type_name -> protobuf.Storenode + 4, // 30: protobuf.CommunityDescription.MembersEntry.value:type_name -> protobuf.CommunityMember + 11, // 31: protobuf.CommunityDescription.ChatsEntry.value:type_name -> protobuf.CommunityChat + 12, // 32: protobuf.CommunityDescription.CategoriesEntry.value:type_name -> protobuf.CommunityCategory + 8, // 33: protobuf.CommunityDescription.TokenPermissionsEntry.value:type_name -> protobuf.CommunityTokenPermission + 4, // 34: protobuf.CommunityChat.MembersEntry.value:type_name -> protobuf.CommunityMember + 24, // 35: protobuf.WakuMessageArchiveIndex.ArchivesEntry.value:type_name -> protobuf.WakuMessageArchiveIndexMetadata + 36, // [36:36] is the sub-list for method output_type + 36, // [36:36] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_communities_proto_init() } @@ -2734,6 +2999,42 @@ func file_communities_proto_init() { return nil } } + file_communities_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommunityPublicStorenodesInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_communities_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommunityStorenodes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_communities_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Storenode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -2741,7 +3042,7 @@ func file_communities_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_communities_proto_rawDesc, NumEnums: 3, - NumMessages: 32, + NumMessages: 35, NumExtensions: 0, NumServices: 0, }, diff --git a/protocol/protobuf/communities.proto b/protocol/protobuf/communities.proto index c69154fe2..f64490844 100644 --- a/protocol/protobuf/communities.proto +++ b/protocol/protobuf/communities.proto @@ -213,3 +213,29 @@ message WakuMessageArchiveIndexMetadata { message WakuMessageArchiveIndex { map archives = 1; } + +message CommunityPublicStorenodesInfo { + // Signature of the payload field + bytes signature = 1; + // Marshaled CommunityStorenodes + bytes payload = 2; +} + +message CommunityStorenodes { + uint64 clock = 1; + bytes community_id = 2; + repeated Storenode storenodes = 3; + uint64 chain_id = 4; +} + +message Storenode { + bytes community_id = 1; + string storenode_id = 2; + string name = 3; + string address = 4; + string fleet = 5; + uint32 version = 6; + bool removed = 7; + int64 deleted_at = 8; +} + diff --git a/protocol/requests/set_community_storenodes.go b/protocol/requests/set_community_storenodes.go new file mode 100644 index 000000000..6a8e09101 --- /dev/null +++ b/protocol/requests/set_community_storenodes.go @@ -0,0 +1,45 @@ +package requests + +import ( + "bytes" + "errors" + + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/protocol/storenodes" +) + +var ( + ErrSetCommunityStorenodesEmpty = errors.New("set-community-storenodes: empty payload") + ErrSetCommunityStorenodesTooMany = errors.New("set-community-storenodes: too many") + ErrSetCommunityStorenodesMismatch = errors.New("set-community-storenodes: communityId mismatch") + ErrSetCommunityStorenodesMissingCommunity = errors.New("set-community-storenodes: missing community") + ErrSetCommunityStorenodesBadVersion = errors.New("set-community-storenodes: bad version") +) + +type SetCommunityStorenodes struct { + CommunityID types.HexBytes `json:"communityId"` + Storenodes []storenodes.Storenode `json:"storenodes"` +} + +func (s *SetCommunityStorenodes) Validate() error { + if s == nil || len(s.Storenodes) == 0 { + return ErrSetCommunityStorenodesEmpty + } + if len(s.Storenodes) > 1 { + // TODO for now only allow one + return ErrSetCommunityStorenodesTooMany + } + if len(s.CommunityID) == 0 { + return ErrSetCommunityStorenodesMissingCommunity + } + for _, sn := range s.Storenodes { + if !bytes.Equal(sn.CommunityID, s.CommunityID) { + return ErrSetCommunityStorenodesMismatch + } + if sn.Version == 0 { + return ErrSetCommunityStorenodesBadVersion + } + // TODO validate address and other fields + } + return nil +} diff --git a/protocol/storenodes/database.go b/protocol/storenodes/database.go new file mode 100644 index 000000000..baa70957c --- /dev/null +++ b/protocol/storenodes/database.go @@ -0,0 +1,191 @@ +package storenodes + +import ( + "bytes" + "database/sql" + "fmt" + "time" + + "github.com/status-im/status-go/eth-node/types" +) + +type Database struct { + db *sql.DB +} + +func NewDB(db *sql.DB) *Database { + return &Database{db: db} +} + +// syncSave will sync the storenodes in the DB from the snode slice +// - if a storenode is not in the provided list, it will be soft-deleted +// - if a storenode is in the provided list, it will be inserted or updated +func (d *Database) syncSave(communityID types.HexBytes, snode []Storenode, clock uint64) (err error) { + var tx *sql.Tx + tx, err = d.db.Begin() + if err != nil { + return err + } + defer func() { + if err == nil { + err = tx.Commit() + return + } + _ = tx.Rollback() + }() + + now := time.Now().Unix() + dbNodes, err := d.getByCommunityID(communityID, tx) + if err != nil { + return fmt.Errorf("getting storenodes by community id: %w", err) + } + // Soft-delete db nodes that are not in the provided list + for _, dbN := range dbNodes { + if find(dbN, snode) != nil { + continue + } + if clock != 0 && dbN.Clock >= clock { + continue + } + if err := d.softDelete(communityID, dbN.StorenodeID, now, tx); err != nil { + return fmt.Errorf("soft deleting existing storenodes: %w", err) + } + + } + // Insert or update the nodes in the provided list + for _, n := range snode { + // defensively validate the communityID + if len(n.CommunityID) == 0 || !bytes.Equal(communityID, n.CommunityID) { + err = fmt.Errorf("communityID mismatch %v != %v", communityID, n.CommunityID) + return err + } + dbN := find(n, dbNodes) + if dbN != nil && n.Clock != 0 && dbN.Clock >= n.Clock { + continue + } + if err := d.upsert(n, tx); err != nil { + return fmt.Errorf("upserting storenodes: %w", err) + } + } + // TODO for now only allow one storenode per community + count, err := d.countByCommunity(communityID, tx) + if err != nil { + return err + } + if count > 1 { + err = fmt.Errorf("only one storenode per community is allowed") + return err + } + return nil +} + +func (d *Database) getAll() ([]Storenode, error) { + rows, err := d.db.Query(` + SELECT community_id, storenode_id, name, address, fleet, version, clock, removed, deleted_at + FROM community_storenodes + WHERE removed = 0 + `) + if err != nil { + return nil, err + } + defer rows.Close() + return toStorenodes(rows) +} + +func (d *Database) getByCommunityID(communityID types.HexBytes, tx ...*sql.Tx) ([]Storenode, error) { + var rows *sql.Rows + var err error + q := ` + SELECT community_id, storenode_id, name, address, fleet, version, clock, removed, deleted_at + FROM community_storenodes + WHERE community_id = ? AND removed = 0 +` + if len(tx) > 0 { + rows, err = tx[0].Query(q, communityID) + } else { + rows, err = d.db.Query(q, communityID) + } + if err != nil { + return nil, err + } + defer rows.Close() + return toStorenodes(rows) +} + +func (d *Database) softDelete(communityID types.HexBytes, storenodeID string, deletedAt int64, tx *sql.Tx) error { + _, err := tx.Exec("UPDATE community_storenodes SET removed = 1, deleted_at = ? WHERE community_id = ? AND storenode_id = ?", deletedAt, communityID, storenodeID) + if err != nil { + return err + } + return nil +} + +func (d *Database) upsert(n Storenode, tx *sql.Tx) error { + _, err := tx.Exec(`INSERT OR REPLACE INTO community_storenodes( + community_id, + storenode_id, + name, + address, + fleet, + version, + clock, + removed, + deleted_at + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, + n.CommunityID, + n.StorenodeID, + n.Name, + n.Address, + n.Fleet, + n.Version, + n.Clock, + n.Removed, + n.DeletedAt, + ) + if err != nil { + return err + } + return nil +} + +func (d *Database) countByCommunity(communityID types.HexBytes, tx *sql.Tx) (int, error) { + var count int + err := tx.QueryRow(`SELECT COUNT(*) FROM community_storenodes WHERE community_id = ? AND removed = 0`, communityID).Scan(&count) + if err != nil { + return 0, err + } + return count, nil +} + +func toStorenodes(rows *sql.Rows) ([]Storenode, error) { + var result []Storenode + + for rows.Next() { + var m Storenode + if err := rows.Scan( + &m.CommunityID, + &m.StorenodeID, + &m.Name, + &m.Address, + &m.Fleet, + &m.Version, + &m.Clock, + &m.Removed, + &m.DeletedAt, + ); err != nil { + return nil, err + } + result = append(result, m) + } + + return result, nil +} + +func find(n Storenode, nodes []Storenode) *Storenode { + for i, node := range nodes { + if node.StorenodeID == n.StorenodeID && bytes.Equal(node.CommunityID, n.CommunityID) { + return &nodes[i] + } + } + return nil +} diff --git a/protocol/storenodes/database_test.go b/protocol/storenodes/database_test.go new file mode 100644 index 000000000..4b9075d07 --- /dev/null +++ b/protocol/storenodes/database_test.go @@ -0,0 +1,74 @@ +package storenodes + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/status-im/status-go/eth-node/types" +) + +var ( + communityID1 = types.HexBytes("community001") + communityID2 = types.HexBytes("community002") +) + +func TestSyncSave(t *testing.T) { + db, close := setupTestDB(t, communityID1) + defer close() + snodes := []Storenode{ + { + CommunityID: communityID1, + StorenodeID: "storenode001", + Name: "My Mailserver", + Address: "enode://...", + Fleet: "prod", + Version: 2, + }, + } + + // ======== + // Save + + err := db.syncSave(communityID1, snodes, 0) + require.NoError(t, err) + + dbNodes, err := db.getByCommunityID(communityID1) + require.NoError(t, err) + + require.Len(t, dbNodes, 1) + require.ElementsMatch(t, dbNodes, snodes) + + // ======== + // Update + + updated := []Storenode{ + { + CommunityID: communityID1, + StorenodeID: "storenode001", + Name: "My Mailserver 2", + Address: "enode://...", + Fleet: "prod", + Version: 2, + }, + } + err = db.syncSave(communityID1, updated, 0) + require.NoError(t, err) + + dbNodes, err = db.getByCommunityID(communityID1) + require.NoError(t, err) + + require.Len(t, dbNodes, 1) + require.ElementsMatch(t, dbNodes, updated) + + // ======== + // Remove + + err = db.syncSave(communityID1, []Storenode{}, 0) + require.NoError(t, err) + + dbNodes, err = db.getByCommunityID(communityID1) + require.NoError(t, err) + + require.Len(t, dbNodes, 0) +} diff --git a/protocol/storenodes/dbhelper_test.go b/protocol/storenodes/dbhelper_test.go new file mode 100644 index 000000000..3e5730a95 --- /dev/null +++ b/protocol/storenodes/dbhelper_test.go @@ -0,0 +1,42 @@ +package storenodes + +import ( + "database/sql" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/status-im/status-go/appdatabase" + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/protocol/sqlite" + "github.com/status-im/status-go/t/helpers" +) + +func setupTestDB(t *testing.T, communityIDs ...types.HexBytes) (*Database, func()) { + db, cleanup, err := helpers.SetupTestSQLDB(appdatabase.DbInitializer{}, "storenodes-tests-") + require.NoError(t, err) + + err = sqlite.Migrate(db) + require.NoError(t, err) + + for _, communityID := range communityIDs { + err = saveTestCommunity(db, communityID) + require.NoError(t, err) + } + + return NewDB(db), func() { require.NoError(t, cleanup()) } +} + +func saveTestCommunity(db *sql.DB, communityID types.HexBytes) error { + _, err := db.Exec( + `INSERT INTO communities_communities ("id", "private_key", "description", "joined", "verified", "synced_at", "muted") VALUES (?, ?, ?, ?, ?, ?, ?)`, + communityID, + []byte("private_key"), + []byte("description"), + true, + true, + 0, + false, + ) + return err +} diff --git a/protocol/storenodes/doc.go b/protocol/storenodes/doc.go new file mode 100644 index 000000000..bb70b553b --- /dev/null +++ b/protocol/storenodes/doc.go @@ -0,0 +1,6 @@ +// package storenodes provides functionality to work with community specific storenodes +// Current limitations: +// - we support only one storenode per community +// - we assume that the storenode is always active +// - we don't support a way to regularly check connection similar to the `messenger_mailserver_cycle.go` +package storenodes diff --git a/protocol/storenodes/models.go b/protocol/storenodes/models.go new file mode 100644 index 000000000..d072aad4e --- /dev/null +++ b/protocol/storenodes/models.go @@ -0,0 +1,69 @@ +package storenodes + +import ( + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/protocol/protobuf" + "github.com/status-im/status-go/services/mailservers" +) + +// Storenode is a struct that represents a storenode, it is very closely related to `mailservers.Mailserver` +type Storenode struct { + CommunityID types.HexBytes `json:"community_id"` + StorenodeID string `json:"storenode_id"` + Name string `json:"name"` + Address string `json:"address"` + Fleet string `json:"fleet"` + Version uint `json:"version"` + Clock uint64 `json:"-"` // used to sync + Removed bool `json:"-"` + DeletedAt int64 `json:"-"` +} + +type Storenodes []Storenode + +func (m Storenodes) ToProtobuf() []*protobuf.Storenode { + result := make([]*protobuf.Storenode, 0, len(m)) + for _, n := range m { + + result = append(result, &protobuf.Storenode{ + CommunityId: n.CommunityID, + StorenodeId: n.StorenodeID, + Name: n.Name, + Address: n.Address, + Fleet: n.Fleet, + Version: uint32(n.Version), + Removed: n.Removed, + DeletedAt: n.DeletedAt, + }) + } + return result +} + +func FromProtobuf(storenodes []*protobuf.Storenode, clock uint64) Storenodes { + result := make(Storenodes, 0, len(storenodes)) + for _, s := range storenodes { + result = append(result, Storenode{ + CommunityID: s.CommunityId, + StorenodeID: s.StorenodeId, + Name: s.Name, + Address: s.Address, + Fleet: s.Fleet, + Version: uint(s.Version), + Removed: s.Removed, + DeletedAt: s.DeletedAt, + Clock: clock, + }) + } + return result +} + +func toMailserver(m Storenode) mailservers.Mailserver { + return mailservers.Mailserver{ + ID: m.StorenodeID, + Name: m.Name, + Custom: true, + Address: m.Address, + Fleet: m.Fleet, + Version: m.Version, + } +} diff --git a/protocol/storenodes/storenodes.go b/protocol/storenodes/storenodes.go new file mode 100644 index 000000000..db4c1bbde --- /dev/null +++ b/protocol/storenodes/storenodes.go @@ -0,0 +1,114 @@ +package storenodes + +import ( + "errors" + "sync" + + "go.uber.org/zap" + + "github.com/status-im/status-go/eth-node/types" + "github.com/status-im/status-go/services/mailservers" +) + +var ( + ErrNotFound = errors.New("not found") +) + +// CommunityStorenodes has methods to handle the storenodes for a community +type CommunityStorenodes struct { + storenodesByCommunityIDMutex *sync.RWMutex + storenodesByCommunityID map[string]storenodesData + + storenodesDB *Database + logger *zap.Logger +} + +func NewCommunityStorenodes(storenodesDB *Database, logger *zap.Logger) *CommunityStorenodes { + if logger == nil { + logger = zap.NewNop() + } + return &CommunityStorenodes{ + storenodesByCommunityIDMutex: &sync.RWMutex{}, + storenodesByCommunityID: make(map[string]storenodesData), + storenodesDB: storenodesDB, + logger: logger.With(zap.Namespace("CommunityStorenodes")), + } +} + +type storenodesData struct { + storenodes []Storenode +} + +// GetStorenodeByCommunnityID returns the active storenode for a community +func (m *CommunityStorenodes) GetStorenodeByCommunnityID(communityID string) (mailservers.Mailserver, error) { + m.storenodesByCommunityIDMutex.RLock() + defer m.storenodesByCommunityIDMutex.RUnlock() + + msData, ok := m.storenodesByCommunityID[communityID] + if !ok || len(msData.storenodes) == 0 { + return mailservers.Mailserver{}, ErrNotFound + } + return toMailserver(msData.storenodes[0]), nil +} + +func (m *CommunityStorenodes) IsCommunityStoreNode(id string) bool { + m.storenodesByCommunityIDMutex.RLock() + defer m.storenodesByCommunityIDMutex.RUnlock() + + for _, data := range m.storenodesByCommunityID { + for _, snode := range data.storenodes { + if snode.StorenodeID == id { + return true + } + } + } + return false +} + +func (m *CommunityStorenodes) HasStorenodeSetup(communityID string) bool { + m.storenodesByCommunityIDMutex.RLock() + defer m.storenodesByCommunityIDMutex.RUnlock() + + msData, ok := m.storenodesByCommunityID[communityID] + return ok && len(msData.storenodes) > 0 +} + +// ReloadFromDB loads or reloads the mailservers from the database (on adding/deleting mailservers) +func (m *CommunityStorenodes) ReloadFromDB() error { + if m.storenodesDB == nil { + return nil + } + m.storenodesByCommunityIDMutex.Lock() + defer m.storenodesByCommunityIDMutex.Unlock() + dbNodes, err := m.storenodesDB.getAll() + if err != nil { + return err + } + // overwrite the in-memory storenodes + m.storenodesByCommunityID = make(map[string]storenodesData) + for _, node := range dbNodes { + communityID := node.CommunityID.String() + if _, ok := m.storenodesByCommunityID[communityID]; !ok { + m.storenodesByCommunityID[communityID] = storenodesData{} + } + data := m.storenodesByCommunityID[communityID] + data.storenodes = append(data.storenodes, node) + m.storenodesByCommunityID[communityID] = data + } + m.logger.Debug("loaded communities storenodes", zap.Int("count", len(dbNodes))) + return nil +} + +func (m *CommunityStorenodes) UpdateStorenodesInDB(communityID types.HexBytes, snodes []Storenode, clock uint64) error { + if err := m.storenodesDB.syncSave(communityID, snodes, clock); err != nil { + return err + } + if err := m.ReloadFromDB(); err != nil { + return err + } + return nil +} + +func (m *CommunityStorenodes) GetStorenodesFromDB(communityID types.HexBytes) ([]Storenode, error) { + return m.storenodesDB.getByCommunityID(communityID) +} diff --git a/protocol/storenodes/storenodes_test.go b/protocol/storenodes/storenodes_test.go new file mode 100644 index 000000000..d8e439e0a --- /dev/null +++ b/protocol/storenodes/storenodes_test.go @@ -0,0 +1,57 @@ +package storenodes + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/status-im/status-go/services/mailservers" +) + +func TestUpdateStorenodesInDB(t *testing.T) { + db, close := setupTestDB(t, communityID1, communityID2) + defer close() + csn := NewCommunityStorenodes(db, nil) + snodes1 := []Storenode{ + { + CommunityID: communityID1, + StorenodeID: "storenode001", + Name: "My Mailserver", + Address: "enode://...", + Fleet: "prod", + Version: 2, + }, + } + snodes2 := []Storenode{ + { + CommunityID: communityID2, + StorenodeID: "storenode002", + Name: "My Mailserver", + Address: "enode://...", + Fleet: "prod", + Version: 2, + }, + } + // populate db + err := csn.UpdateStorenodesInDB(communityID1, snodes1, 0) + require.NoError(t, err) + err = csn.UpdateStorenodesInDB(communityID2, snodes2, 0) + require.NoError(t, err) + + // check if storenodes are loaded + ms1, err := csn.GetStorenodeByCommunnityID(communityID1.String()) + require.NoError(t, err) + matchStoreNode(t, snodes1[0], ms1) + + ms2, err := csn.GetStorenodeByCommunnityID(communityID2.String()) + require.NoError(t, err) + matchStoreNode(t, snodes2[0], ms2) +} + +func matchStoreNode(t *testing.T, sn Storenode, ms mailservers.Mailserver) { + require.Equal(t, sn.StorenodeID, ms.ID) + require.Equal(t, sn.Name, ms.Name) + require.Equal(t, sn.Address, ms.Address) + require.Equal(t, sn.Fleet, ms.Fleet) + require.Equal(t, sn.Version, ms.Version) +} diff --git a/services/ext/api.go b/services/ext/api.go index bc6827ec1..50936c10d 100644 --- a/services/ext/api.go +++ b/services/ext/api.go @@ -449,6 +449,16 @@ func (api *PublicAPI) SetCommunityShard(request *requests.SetCommunityShard) (*p return api.service.messenger.SetCommunityShard(request) } +// Sets the community storenodes for a community +func (api *PublicAPI) SetCommunityStorenodes(request *requests.SetCommunityStorenodes) (*protocol.MessengerResponse, error) { + return api.service.messenger.SetCommunityStorenodes(request) +} + +// Gets the community storenodes for a community +func (api *PublicAPI) GetCommunityStorenodes(id types.HexBytes) (*protocol.MessengerResponse, error) { + return api.service.messenger.GetCommunityStorenodes(id) +} + // ExportCommunity exports the private key of the community with given ID func (api *PublicAPI) ExportCommunity(id types.HexBytes) (types.HexBytes, error) { key, err := api.service.messenger.ExportCommunity(id) @@ -1349,11 +1359,11 @@ func (api *PublicAPI) DeleteActivityCenterNotifications(ctx context.Context, ids } func (api *PublicAPI) RequestAllHistoricMessages(forceFetchingBackup bool) (*protocol.MessengerResponse, error) { - return api.service.messenger.RequestAllHistoricMessages(forceFetchingBackup) + return api.service.messenger.RequestAllHistoricMessages(forceFetchingBackup, false) } func (api *PublicAPI) RequestAllHistoricMessagesWithRetries(forceFetchingBackup bool) (*protocol.MessengerResponse, error) { - return api.service.messenger.RequestAllHistoricMessagesWithRetries(forceFetchingBackup) + return api.service.messenger.RequestAllHistoricMessages(forceFetchingBackup, true) } func (api *PublicAPI) DisconnectActiveMailserver() { diff --git a/services/mailservers/api_test.go b/services/mailservers/api_test.go index 640edd441..503eaf26c 100644 --- a/services/mailservers/api_test.go +++ b/services/mailservers/api_test.go @@ -9,6 +9,7 @@ import ( "github.com/status-im/status-go/appdatabase" "github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/protocol/common/shard" + "github.com/status-im/status-go/protocol/sqlite" "github.com/status-im/status-go/protocol/transport" "github.com/status-im/status-go/t/helpers" ) @@ -16,6 +17,8 @@ import ( func setupTestDB(t *testing.T) (*Database, func()) { db, cleanup, err := helpers.SetupTestSQLDB(appdatabase.DbInitializer{}, "maliservers-tests-") require.NoError(t, err) + err = sqlite.Migrate(db) // migrate default + require.NoError(t, err) return NewDB(db), func() { require.NoError(t, cleanup()) } } diff --git a/services/mailservers/database.go b/services/mailservers/database.go index 0a9e2e6a0..383e8c8b0 100644 --- a/services/mailservers/database.go +++ b/services/mailservers/database.go @@ -146,13 +146,16 @@ func (d *Database) Add(mailserver Mailserver) error { } func (d *Database) Mailservers() ([]Mailserver, error) { - var result []Mailserver - rows, err := d.db.Query(`SELECT id, name, address, password, fleet FROM mailservers`) if err != nil { return nil, err } defer rows.Close() + return toMailservers(rows) +} + +func toMailservers(rows *sql.Rows) ([]Mailserver, error) { + var result []Mailserver for rows.Next() { var ( @@ -198,7 +201,7 @@ func (d *Database) AddGaps(gaps []MailserverRequestGap) error { for _, gap := range gaps { - _, err := tx.Exec(`INSERT OR REPLACE INTO mailserver_request_gaps( + _, err = tx.Exec(`INSERT OR REPLACE INTO mailserver_request_gaps( id, chat_id, gap_from,