From 62c9d56fe85f8fb42e2c27eac452242511313a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rich=CE=9Brd?= Date: Mon, 14 Sep 2020 09:39:24 -0400 Subject: [PATCH] Add API functions to store pending transaction data (#2037) * Add API functions to store pending transaction data * fix: code review --- appdatabase/migrations/bindata.go | 323 +++++++++--------- .../sql/0012_pending_transactions.down.sql | 1 + .../sql/0012_pending_transactions.up.sql | 11 + services/wallet/api.go | 28 ++ services/wallet/database.go | 76 +++++ services/wallet/database_test.go | 51 +++ 6 files changed, 332 insertions(+), 158 deletions(-) create mode 100644 appdatabase/migrations/sql/0012_pending_transactions.down.sql create mode 100644 appdatabase/migrations/sql/0012_pending_transactions.up.sql diff --git a/appdatabase/migrations/bindata.go b/appdatabase/migrations/bindata.go index d99c36237..f4ddbdacf 100644 --- a/appdatabase/migrations/bindata.go +++ b/appdatabase/migrations/bindata.go @@ -1,32 +1,34 @@ -// Code generated by go-bindata. DO NOT EDIT. +// Code generated by go-bindata. // sources: -// 0001_app.down.sql (356B) -// 0001_app.up.sql (2.967kB) -// 0002_tokens.down.sql (19B) -// 0002_tokens.up.sql (248B) -// 0003_settings.down.sql (118B) -// 0003_settings.up.sql (1.311kB) -// 0004_pending_stickers.down.sql (0) -// 0004_pending_stickers.up.sql (61B) -// 0005_waku_mode.down.sql (0) -// 0005_waku_mode.up.sql (146B) -// 0006_appearance.up.sql (67B) -// 0007_enable_waku_default.up.sql (38B) -// 0008_add_push_notifications.up.sql (349B) -// 0009_enable_sending_push_notifications.down.sql (49B) -// 0009_enable_sending_push_notifications.up.sql (49B) -// 0010_add_block_mentions.down.sql (83B) -// 0010_add_block_mentions.up.sql (89B) -// 0011_allow_webview_permission_requests.down.sql (0) -// 0011_allow_webview_permission_requests.up.sql (88B) -// doc.go (74B) +// 0001_app.down.sql +// 0001_app.up.sql +// 0002_tokens.down.sql +// 0002_tokens.up.sql +// 0003_settings.down.sql +// 0003_settings.up.sql +// 0004_pending_stickers.down.sql +// 0004_pending_stickers.up.sql +// 0005_waku_mode.down.sql +// 0005_waku_mode.up.sql +// 0006_appearance.up.sql +// 0007_enable_waku_default.up.sql +// 0008_add_push_notifications.up.sql +// 0009_enable_sending_push_notifications.down.sql +// 0009_enable_sending_push_notifications.up.sql +// 0010_add_block_mentions.down.sql +// 0010_add_block_mentions.up.sql +// 0011_allow_webview_permission_requests.down.sql +// 0011_allow_webview_permission_requests.up.sql +// 0012_pending_transactions.down.sql +// 0012_pending_transactions.up.sql +// doc.go +// DO NOT EDIT! package migrations import ( "bytes" "compress/gzip" - "crypto/sha256" "fmt" "io" "io/ioutil" @@ -39,7 +41,7 @@ import ( func bindataRead(data []byte, name string) ([]byte, error) { gz, err := gzip.NewReader(bytes.NewBuffer(data)) if err != nil { - return nil, fmt.Errorf("read %q: %w", name, err) + return nil, fmt.Errorf("Read %q: %v", name, err) } var buf bytes.Buffer @@ -47,7 +49,7 @@ func bindataRead(data []byte, name string) ([]byte, error) { clErr := gz.Close() if err != nil { - return nil, fmt.Errorf("read %q: %w", name, err) + return nil, fmt.Errorf("Read %q: %v", name, err) } if clErr != nil { return nil, err @@ -57,9 +59,8 @@ func bindataRead(data []byte, name string) ([]byte, error) { } type asset struct { - bytes []byte - info os.FileInfo - digest [sha256.Size]byte + bytes []byte + info os.FileInfo } type bindataFileInfo struct { @@ -103,8 +104,8 @@ func _0001_appDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_app.down.sql", size: 356, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb5, 0x25, 0xa0, 0xf8, 0x7d, 0x2d, 0xd, 0xcf, 0x18, 0xe4, 0x73, 0xc3, 0x95, 0xf5, 0x24, 0x20, 0xa9, 0xe6, 0x9e, 0x1d, 0x93, 0xe5, 0xc5, 0xad, 0x93, 0x8f, 0x5e, 0x40, 0xb5, 0x30, 0xaa, 0x25}} + info := bindataFileInfo{name: "0001_app.down.sql", size: 356, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -123,8 +124,8 @@ func _0001_appUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0001_app.up.sql", size: 2967, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf7, 0x3a, 0xa7, 0xf2, 0x8f, 0xfa, 0x82, 0x7c, 0xc5, 0x49, 0xac, 0xac, 0xf, 0xc, 0x77, 0xe2, 0xba, 0xe8, 0x4d, 0xe, 0x6f, 0x5d, 0x2c, 0x2c, 0x18, 0x80, 0xc2, 0x1d, 0xe, 0x25, 0xe, 0x18}} + info := bindataFileInfo{name: "0001_app.up.sql", size: 2967, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -143,8 +144,8 @@ func _0002_tokensDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0002_tokens.down.sql", size: 19, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd1, 0x31, 0x2, 0xcc, 0x2f, 0x38, 0x90, 0xf7, 0x58, 0x37, 0x47, 0xf4, 0x18, 0xf7, 0x72, 0x74, 0x67, 0x14, 0x7e, 0xf3, 0xb1, 0xd6, 0x5f, 0xb0, 0xd5, 0xe7, 0x91, 0xf4, 0x26, 0x77, 0x8e, 0x68}} + info := bindataFileInfo{name: "0002_tokens.down.sql", size: 19, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -163,8 +164,8 @@ func _0002_tokensUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0002_tokens.up.sql", size: 248, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xcc, 0xd6, 0xde, 0xd3, 0x7b, 0xee, 0x92, 0x11, 0x38, 0xa4, 0xeb, 0x84, 0xca, 0xcb, 0x37, 0x75, 0x5, 0x77, 0x7f, 0x14, 0x39, 0xee, 0xa1, 0x8b, 0xd4, 0x5c, 0x6e, 0x55, 0x6, 0x50, 0x16, 0xd4}} + info := bindataFileInfo{name: "0002_tokens.up.sql", size: 248, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -183,8 +184,8 @@ func _0003_settingsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0003_settings.down.sql", size: 118, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe5, 0xa6, 0xf5, 0xc0, 0x60, 0x64, 0x77, 0xe2, 0xe7, 0x3c, 0x9b, 0xb1, 0x52, 0xa9, 0x95, 0x16, 0xf8, 0x60, 0x2f, 0xa5, 0xeb, 0x46, 0xb9, 0xb9, 0x8f, 0x4c, 0xf4, 0xfd, 0xbb, 0xe7, 0xe5, 0xe5}} + info := bindataFileInfo{name: "0003_settings.down.sql", size: 118, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -203,8 +204,8 @@ func _0003_settingsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0003_settings.up.sql", size: 1311, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x35, 0x0, 0xeb, 0xe2, 0x33, 0x68, 0xb9, 0xf4, 0xf6, 0x8e, 0x9e, 0x10, 0xe9, 0x58, 0x68, 0x28, 0xb, 0xcd, 0xec, 0x74, 0x71, 0xa7, 0x9a, 0x5a, 0x77, 0x59, 0xb1, 0x13, 0x1c, 0xa1, 0x5b}} + info := bindataFileInfo{name: "0003_settings.up.sql", size: 1311, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -223,8 +224,8 @@ func _0004_pending_stickersDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0004_pending_stickers.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} + info := bindataFileInfo{name: "0004_pending_stickers.down.sql", size: 0, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -243,8 +244,8 @@ func _0004_pending_stickersUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0004_pending_stickers.up.sql", size: 61, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x3c, 0xed, 0x25, 0xdf, 0x75, 0x2, 0x6c, 0xf0, 0xa2, 0xa8, 0x37, 0x62, 0x65, 0xad, 0xfd, 0x98, 0xa0, 0x9d, 0x63, 0x94, 0xdf, 0x6b, 0x46, 0xe0, 0x68, 0xec, 0x9c, 0x7f, 0x77, 0xdd, 0xb3, 0x6}} + info := bindataFileInfo{name: "0004_pending_stickers.up.sql", size: 61, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -263,8 +264,8 @@ func _0005_waku_modeDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0005_waku_mode.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} + info := bindataFileInfo{name: "0005_waku_mode.down.sql", size: 0, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -283,8 +284,8 @@ func _0005_waku_modeUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0005_waku_mode.up.sql", size: 146, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa6, 0x91, 0xc, 0xd7, 0x89, 0x61, 0x2e, 0x4c, 0x5a, 0xb6, 0x67, 0xd1, 0xc1, 0x42, 0x24, 0x38, 0xd6, 0x1b, 0x75, 0x41, 0x9c, 0x23, 0xb0, 0xca, 0x5c, 0xf1, 0x5c, 0xd0, 0x13, 0x92, 0x3e, 0xe1}} + info := bindataFileInfo{name: "0005_waku_mode.up.sql", size: 146, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -303,8 +304,8 @@ func _0006_appearanceUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0006_appearance.up.sql", size: 67, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xae, 0x6, 0x25, 0x6c, 0xe4, 0x9d, 0xa7, 0x72, 0xe8, 0xbc, 0xe4, 0x1f, 0x1e, 0x2d, 0x7c, 0xb7, 0xf6, 0xa3, 0xec, 0x3b, 0x4e, 0x93, 0x2e, 0xa4, 0xec, 0x6f, 0xe5, 0x95, 0x94, 0xe8, 0x4, 0xfb}} + info := bindataFileInfo{name: "0006_appearance.up.sql", size: 67, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -323,8 +324,8 @@ func _0007_enable_waku_defaultUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0007_enable_waku_default.up.sql", size: 38, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd4, 0x42, 0xb6, 0xe5, 0x48, 0x41, 0xeb, 0xc0, 0x7e, 0x3b, 0xe6, 0x8e, 0x96, 0x33, 0x20, 0x92, 0x24, 0x5a, 0x60, 0xfa, 0xa0, 0x3, 0x5e, 0x76, 0x4b, 0x89, 0xaa, 0x37, 0x66, 0xbc, 0x26, 0x11}} + info := bindataFileInfo{name: "0007_enable_waku_default.up.sql", size: 38, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -343,8 +344,8 @@ func _0008_add_push_notificationsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0008_add_push_notifications.up.sql", size: 349, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5a, 0x0, 0xbf, 0xd0, 0xdd, 0xcd, 0x73, 0xe0, 0x7c, 0x56, 0xef, 0xdc, 0x57, 0x61, 0x94, 0x64, 0x70, 0xb9, 0xfa, 0xa1, 0x2a, 0x36, 0xc, 0x2f, 0xf8, 0x95, 0xa, 0x57, 0x3e, 0x7a, 0xd7, 0x12}} + info := bindataFileInfo{name: "0008_add_push_notifications.up.sql", size: 349, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -363,8 +364,8 @@ func _0009_enable_sending_push_notificationsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0009_enable_sending_push_notifications.down.sql", size: 49, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe9, 0xae, 0x1b, 0x41, 0xcb, 0x9c, 0x2c, 0x93, 0xc6, 0x2a, 0x77, 0x3, 0xb9, 0x51, 0xe0, 0x68, 0x68, 0x0, 0xf7, 0x5b, 0xb3, 0x1e, 0x94, 0x44, 0xba, 0x9c, 0xd0, 0x3b, 0x80, 0x21, 0x6f, 0xb5}} + info := bindataFileInfo{name: "0009_enable_sending_push_notifications.down.sql", size: 49, mode: os.FileMode(436), modTime: time.Unix(1599666593, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -383,8 +384,8 @@ func _0009_enable_sending_push_notificationsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0009_enable_sending_push_notifications.up.sql", size: 49, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1b, 0x80, 0xe4, 0x9c, 0xc8, 0xb8, 0xd5, 0xef, 0xce, 0x74, 0x9b, 0x7b, 0xdd, 0xa, 0x99, 0x1e, 0xef, 0x7f, 0xb8, 0x99, 0x84, 0x4, 0x0, 0x6b, 0x1d, 0x2c, 0xa, 0xf8, 0x2c, 0x4f, 0xb5, 0x44}} + info := bindataFileInfo{name: "0009_enable_sending_push_notifications.up.sql", size: 49, mode: os.FileMode(436), modTime: time.Unix(1599666593, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -403,8 +404,8 @@ func _0010_add_block_mentionsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0010_add_block_mentions.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1599718102, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x6d, 0x9e, 0x27, 0x1e, 0xba, 0x9f, 0xca, 0xae, 0x98, 0x2e, 0x6e, 0xe3, 0xdd, 0xac, 0x73, 0x34, 0x4e, 0x69, 0x92, 0xb5, 0xf6, 0x9, 0xab, 0x50, 0x35, 0xd, 0xee, 0xeb, 0x3e, 0xcc, 0x7e, 0xce}} + info := bindataFileInfo{name: "0010_add_block_mentions.down.sql", size: 83, mode: os.FileMode(436), modTime: time.Unix(1599742167, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -423,8 +424,8 @@ func _0010_add_block_mentionsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0010_add_block_mentions.up.sql", size: 89, mode: os.FileMode(0644), modTime: time.Unix(1599718102, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd7, 0x23, 0x85, 0xa2, 0xb5, 0xb6, 0xb4, 0x3f, 0xdc, 0x4e, 0xff, 0xe2, 0x6b, 0x66, 0x68, 0x5e, 0xb2, 0xb4, 0x14, 0xb2, 0x1b, 0x4d, 0xb1, 0xce, 0xf7, 0x6, 0x58, 0xa7, 0xaf, 0x93, 0x3f, 0x25}} + info := bindataFileInfo{name: "0010_add_block_mentions.up.sql", size: 89, mode: os.FileMode(436), modTime: time.Unix(1599742167, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -443,8 +444,8 @@ func _0011_allow_webview_permission_requestsDownSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0011_allow_webview_permission_requests.down.sql", size: 0, mode: os.FileMode(0644), modTime: time.Unix(1599718858, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}} + info := bindataFileInfo{name: "0011_allow_webview_permission_requests.down.sql", size: 0, mode: os.FileMode(436), modTime: time.Unix(1599742167, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -463,8 +464,48 @@ func _0011_allow_webview_permission_requestsUpSql() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "0011_allow_webview_permission_requests.up.sql", size: 88, mode: os.FileMode(0644), modTime: time.Unix(1599718851, 0)} - a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x43, 0x5f, 0x22, 0x4c, 0x98, 0x1d, 0xc6, 0xf4, 0x89, 0xaf, 0xf4, 0x44, 0xba, 0xf8, 0x28, 0xa7, 0xb5, 0xb9, 0xf0, 0xf2, 0xcb, 0x5, 0x59, 0x7a, 0xc, 0xdf, 0xd3, 0x38, 0xa4, 0xb8, 0x98, 0xc2}} + info := bindataFileInfo{name: "0011_allow_webview_permission_requests.up.sql", size: 88, mode: os.FileMode(436), modTime: time.Unix(1599742167, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var __0012_pending_transactionsDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x28\x48\xcd\x4b\xc9\xcc\x4b\x8f\x2f\x29\x4a\xcc\x2b\x4e\x4c\x2e\xc9\xcc\xcf\x2b\xb6\xe6\x02\x04\x00\x00\xff\xff\x62\x4b\x2a\x6c\x21\x00\x00\x00") + +func _0012_pending_transactionsDownSqlBytes() ([]byte, error) { + return bindataRead( + __0012_pending_transactionsDownSql, + "0012_pending_transactions.down.sql", + ) +} + +func _0012_pending_transactionsDownSql() (*asset, error) { + bytes, err := _0012_pending_transactionsDownSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "0012_pending_transactions.down.sql", size: 33, mode: os.FileMode(436), modTime: time.Unix(1599742460, 0)} + a := &asset{bytes: bytes, info: info} + return a, nil +} + +var __0012_pending_transactionsUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x7c\x8f\xc1\x4e\x02\x31\x14\x45\xf7\xfd\x8a\xbb\x84\x84\x3f\x70\x55\xa0\xc2\x8b\x63\xc7\x74\xde\x08\xac\x9a\x62\xab\x4c\x90\x76\xd2\xd6\x18\xff\xde\xe8\x46\x8d\x13\x96\x2f\xe7\x9d\x9b\x9c\x95\x51\x92\x15\x58\x2e\x1b\x05\xba\x85\x6e\x19\x6a\x4f\x1d\x77\x18\x43\xf4\x43\x7c\xb1\x35\xbb\x58\xdc\x53\x1d\x52\x2c\x98\x09\x20\x86\xfa\x9e\xf2\xd9\x0e\x1e\xbd\xee\x68\xa3\xd5\x1a\x4b\xda\x90\xe6\x6f\x5d\xf7\x4d\xb3\x10\xc0\x2f\xcf\x9e\x5c\x39\xe1\x51\x9a\xd5\x56\x9a\x3f\x4f\xc7\xd7\xb3\x8d\x6f\x97\x63\xc8\x53\x13\xcf\x39\x5d\xac\xf3\x3e\x87\x52\x26\xf5\x9a\xae\xe3\x8f\x31\x4c\x02\xef\xaa\x03\xab\x3d\x7f\x1d\x0f\x86\xee\xa5\x39\xe0\x4e\x1d\x30\xfb\x89\x5b\xfc\x2b\x98\x8b\x39\x76\xc4\xdb\xb6\x67\x98\x76\x47\xeb\x1b\x21\x3e\x03\x00\x00\xff\xff\x9c\xbd\x6e\xaa\x41\x01\x00\x00") + +func _0012_pending_transactionsUpSqlBytes() ([]byte, error) { + return bindataRead( + __0012_pending_transactionsUpSql, + "0012_pending_transactions.up.sql", + ) +} + +func _0012_pending_transactionsUpSql() (*asset, error) { + bytes, err := _0012_pending_transactionsUpSqlBytes() + if err != nil { + return nil, err + } + + info := bindataFileInfo{name: "0012_pending_transactions.up.sql", size: 321, mode: os.FileMode(436), modTime: time.Unix(1599767791, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -483,8 +524,8 @@ func docGo() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(0644), modTime: time.Unix(1599559256, 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}} + info := bindataFileInfo{name: "doc.go", size: 74, mode: os.FileMode(436), modTime: time.Unix(1599505269, 0)} + a := &asset{bytes: bytes, info: info} return a, nil } @@ -492,8 +533,8 @@ func docGo() (*asset, error) { // It returns an error if the asset could not be found or // could not be loaded. func Asset(name string) ([]byte, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err) @@ -503,12 +544,6 @@ func Asset(name string) ([]byte, error) { return nil, fmt.Errorf("Asset %s not found", name) } -// AssetString returns the asset contents as a string (instead of a []byte). -func AssetString(name string) (string, error) { - data, err := Asset(name) - return string(data), err -} - // MustAsset is like Asset but panics when Asset would return an error. // It simplifies safe initialization of global variables. func MustAsset(name string) []byte { @@ -520,18 +555,12 @@ func MustAsset(name string) []byte { return a } -// MustAssetString is like AssetString but panics when Asset would return an -// error. It simplifies safe initialization of global variables. -func MustAssetString(name string) string { - return string(MustAsset(name)) -} - // AssetInfo loads and returns the asset info for the given name. // It returns an error if the asset could not be found or // could not be loaded. func AssetInfo(name string) (os.FileInfo, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { + cannonicalName := strings.Replace(name, "\\", "/", -1) + if f, ok := _bindata[cannonicalName]; ok { a, err := f() if err != nil { return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err) @@ -541,33 +570,6 @@ func AssetInfo(name string) (os.FileInfo, error) { return nil, fmt.Errorf("AssetInfo %s not found", name) } -// AssetDigest returns the digest of the file with the given name. It returns an -// error if the asset could not be found or the digest could not be loaded. -func AssetDigest(name string) ([sha256.Size]byte, error) { - canonicalName := strings.Replace(name, "\\", "/", -1) - if f, ok := _bindata[canonicalName]; ok { - a, err := f() - if err != nil { - return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s can't read by error: %v", name, err) - } - return a.digest, nil - } - return [sha256.Size]byte{}, fmt.Errorf("AssetDigest %s not found", name) -} - -// Digests returns a map of all known files and their checksums. -func Digests() (map[string][sha256.Size]byte, error) { - mp := make(map[string][sha256.Size]byte, len(_bindata)) - for name := range _bindata { - a, err := _bindata[name]() - if err != nil { - return nil, err - } - mp[name] = a.digest - } - return mp, nil -} - // AssetNames returns the names of the assets. func AssetNames() []string { names := make([]string, 0, len(_bindata)) @@ -579,31 +581,30 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "0001_app.down.sql": _0001_appDownSql, - "0001_app.up.sql": _0001_appUpSql, - "0002_tokens.down.sql": _0002_tokensDownSql, - "0002_tokens.up.sql": _0002_tokensUpSql, - "0003_settings.down.sql": _0003_settingsDownSql, - "0003_settings.up.sql": _0003_settingsUpSql, - "0004_pending_stickers.down.sql": _0004_pending_stickersDownSql, - "0004_pending_stickers.up.sql": _0004_pending_stickersUpSql, - "0005_waku_mode.down.sql": _0005_waku_modeDownSql, - "0005_waku_mode.up.sql": _0005_waku_modeUpSql, - "0006_appearance.up.sql": _0006_appearanceUpSql, - "0007_enable_waku_default.up.sql": _0007_enable_waku_defaultUpSql, - "0008_add_push_notifications.up.sql": _0008_add_push_notificationsUpSql, + "0001_app.down.sql": _0001_appDownSql, + "0001_app.up.sql": _0001_appUpSql, + "0002_tokens.down.sql": _0002_tokensDownSql, + "0002_tokens.up.sql": _0002_tokensUpSql, + "0003_settings.down.sql": _0003_settingsDownSql, + "0003_settings.up.sql": _0003_settingsUpSql, + "0004_pending_stickers.down.sql": _0004_pending_stickersDownSql, + "0004_pending_stickers.up.sql": _0004_pending_stickersUpSql, + "0005_waku_mode.down.sql": _0005_waku_modeDownSql, + "0005_waku_mode.up.sql": _0005_waku_modeUpSql, + "0006_appearance.up.sql": _0006_appearanceUpSql, + "0007_enable_waku_default.up.sql": _0007_enable_waku_defaultUpSql, + "0008_add_push_notifications.up.sql": _0008_add_push_notificationsUpSql, "0009_enable_sending_push_notifications.down.sql": _0009_enable_sending_push_notificationsDownSql, - "0009_enable_sending_push_notifications.up.sql": _0009_enable_sending_push_notificationsUpSql, - "0010_add_block_mentions.down.sql": _0010_add_block_mentionsDownSql, - "0010_add_block_mentions.up.sql": _0010_add_block_mentionsUpSql, + "0009_enable_sending_push_notifications.up.sql": _0009_enable_sending_push_notificationsUpSql, + "0010_add_block_mentions.down.sql": _0010_add_block_mentionsDownSql, + "0010_add_block_mentions.up.sql": _0010_add_block_mentionsUpSql, "0011_allow_webview_permission_requests.down.sql": _0011_allow_webview_permission_requestsDownSql, - "0011_allow_webview_permission_requests.up.sql": _0011_allow_webview_permission_requestsUpSql, + "0011_allow_webview_permission_requests.up.sql": _0011_allow_webview_permission_requestsUpSql, + "0012_pending_transactions.down.sql": _0012_pending_transactionsDownSql, + "0012_pending_transactions.up.sql": _0012_pending_transactionsUpSql, "doc.go": docGo, } -// AssetDebug is true if the assets were built with the debug flag enabled. -const AssetDebug = false - // AssetDir returns the file names below a certain // directory embedded in the file by go-bindata. // For example if you run go-bindata on data/... and data contains the @@ -613,15 +614,15 @@ const AssetDebug = false // img/ // a.png // b.png -// then AssetDir("data") would return []string{"foo.txt", "img"}, -// AssetDir("data/img") would return []string{"a.png", "b.png"}, -// AssetDir("foo.txt") and AssetDir("notexist") would return an error, and +// then AssetDir("data") would return []string{"foo.txt", "img"} +// AssetDir("data/img") would return []string{"a.png", "b.png"} +// AssetDir("foo.txt") and AssetDir("notexist") would return an error // AssetDir("") will return []string{"data"}. func AssetDir(name string) ([]string, error) { node := _bintree if len(name) != 0 { - canonicalName := strings.Replace(name, "\\", "/", -1) - pathList := strings.Split(canonicalName, "/") + cannonicalName := strings.Replace(name, "\\", "/", -1) + pathList := strings.Split(cannonicalName, "/") for _, p := range pathList { node = node.Children[p] if node == nil { @@ -643,31 +644,32 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } - var _bintree = &bintree{nil, map[string]*bintree{ - "0001_app.down.sql": &bintree{_0001_appDownSql, map[string]*bintree{}}, - "0001_app.up.sql": &bintree{_0001_appUpSql, map[string]*bintree{}}, - "0002_tokens.down.sql": &bintree{_0002_tokensDownSql, map[string]*bintree{}}, - "0002_tokens.up.sql": &bintree{_0002_tokensUpSql, map[string]*bintree{}}, - "0003_settings.down.sql": &bintree{_0003_settingsDownSql, map[string]*bintree{}}, - "0003_settings.up.sql": &bintree{_0003_settingsUpSql, map[string]*bintree{}}, - "0004_pending_stickers.down.sql": &bintree{_0004_pending_stickersDownSql, map[string]*bintree{}}, - "0004_pending_stickers.up.sql": &bintree{_0004_pending_stickersUpSql, map[string]*bintree{}}, - "0005_waku_mode.down.sql": &bintree{_0005_waku_modeDownSql, map[string]*bintree{}}, - "0005_waku_mode.up.sql": &bintree{_0005_waku_modeUpSql, map[string]*bintree{}}, - "0006_appearance.up.sql": &bintree{_0006_appearanceUpSql, map[string]*bintree{}}, - "0007_enable_waku_default.up.sql": &bintree{_0007_enable_waku_defaultUpSql, map[string]*bintree{}}, - "0008_add_push_notifications.up.sql": &bintree{_0008_add_push_notificationsUpSql, map[string]*bintree{}}, + "0001_app.down.sql": &bintree{_0001_appDownSql, map[string]*bintree{}}, + "0001_app.up.sql": &bintree{_0001_appUpSql, map[string]*bintree{}}, + "0002_tokens.down.sql": &bintree{_0002_tokensDownSql, map[string]*bintree{}}, + "0002_tokens.up.sql": &bintree{_0002_tokensUpSql, map[string]*bintree{}}, + "0003_settings.down.sql": &bintree{_0003_settingsDownSql, map[string]*bintree{}}, + "0003_settings.up.sql": &bintree{_0003_settingsUpSql, map[string]*bintree{}}, + "0004_pending_stickers.down.sql": &bintree{_0004_pending_stickersDownSql, map[string]*bintree{}}, + "0004_pending_stickers.up.sql": &bintree{_0004_pending_stickersUpSql, map[string]*bintree{}}, + "0005_waku_mode.down.sql": &bintree{_0005_waku_modeDownSql, map[string]*bintree{}}, + "0005_waku_mode.up.sql": &bintree{_0005_waku_modeUpSql, map[string]*bintree{}}, + "0006_appearance.up.sql": &bintree{_0006_appearanceUpSql, map[string]*bintree{}}, + "0007_enable_waku_default.up.sql": &bintree{_0007_enable_waku_defaultUpSql, map[string]*bintree{}}, + "0008_add_push_notifications.up.sql": &bintree{_0008_add_push_notificationsUpSql, map[string]*bintree{}}, "0009_enable_sending_push_notifications.down.sql": &bintree{_0009_enable_sending_push_notificationsDownSql, map[string]*bintree{}}, - "0009_enable_sending_push_notifications.up.sql": &bintree{_0009_enable_sending_push_notificationsUpSql, map[string]*bintree{}}, - "0010_add_block_mentions.down.sql": &bintree{_0010_add_block_mentionsDownSql, map[string]*bintree{}}, - "0010_add_block_mentions.up.sql": &bintree{_0010_add_block_mentionsUpSql, map[string]*bintree{}}, + "0009_enable_sending_push_notifications.up.sql": &bintree{_0009_enable_sending_push_notificationsUpSql, map[string]*bintree{}}, + "0010_add_block_mentions.down.sql": &bintree{_0010_add_block_mentionsDownSql, map[string]*bintree{}}, + "0010_add_block_mentions.up.sql": &bintree{_0010_add_block_mentionsUpSql, map[string]*bintree{}}, "0011_allow_webview_permission_requests.down.sql": &bintree{_0011_allow_webview_permission_requestsDownSql, map[string]*bintree{}}, - "0011_allow_webview_permission_requests.up.sql": &bintree{_0011_allow_webview_permission_requestsUpSql, map[string]*bintree{}}, + "0011_allow_webview_permission_requests.up.sql": &bintree{_0011_allow_webview_permission_requestsUpSql, map[string]*bintree{}}, + "0012_pending_transactions.down.sql": &bintree{_0012_pending_transactionsDownSql, map[string]*bintree{}}, + "0012_pending_transactions.up.sql": &bintree{_0012_pending_transactionsUpSql, map[string]*bintree{}}, "doc.go": &bintree{docGo, map[string]*bintree{}}, }} -// RestoreAsset restores an asset under the given directory. +// RestoreAsset restores an asset under the given directory func RestoreAsset(dir, name string) error { data, err := Asset(name) if err != nil { @@ -685,10 +687,14 @@ func RestoreAsset(dir, name string) error { if err != nil { return err } - return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime()) + if err != nil { + return err + } + return nil } -// RestoreAssets restores an asset under the given directory recursively. +// RestoreAssets restores an asset under the given directory recursively func RestoreAssets(dir, name string) error { children, err := AssetDir(name) // File @@ -706,6 +712,7 @@ func RestoreAssets(dir, name string) error { } func _filePath(dir, name string) string { - canonicalName := strings.Replace(name, "\\", "/", -1) - return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...) + cannonicalName := strings.Replace(name, "\\", "/", -1) + return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } + diff --git a/appdatabase/migrations/sql/0012_pending_transactions.down.sql b/appdatabase/migrations/sql/0012_pending_transactions.down.sql new file mode 100644 index 000000000..d74ce843b --- /dev/null +++ b/appdatabase/migrations/sql/0012_pending_transactions.down.sql @@ -0,0 +1 @@ +DROP TABLE pending_transactions; diff --git a/appdatabase/migrations/sql/0012_pending_transactions.up.sql b/appdatabase/migrations/sql/0012_pending_transactions.up.sql new file mode 100644 index 000000000..49501862a --- /dev/null +++ b/appdatabase/migrations/sql/0012_pending_transactions.up.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS pending_transactions ( + network_id UNSIGNED BIGINT NOT NULL, + transaction_hash VARCHAR NOT NULL, + blk_number BIGINT NOT NULL, + from_address VARCHAR NOT NULL, + to_address VARCHAR NOT NULL, + type VARCHAR NOT NULL, + data TEXT, + PRIMARY KEY (network_id, transaction_hash) +) WITHOUT ROWID; + diff --git a/services/wallet/api.go b/services/wallet/api.go index 2e5287ac6..0713e4183 100644 --- a/services/wallet/api.go +++ b/services/wallet/api.go @@ -133,3 +133,31 @@ func (api *API) DeleteCustomToken(ctx context.Context, address common.Address) e log.Debug("result from database for remove custom token", "err", err) return err } + +func (api *API) GetPendingTransactions(ctx context.Context) ([]*PendingTransaction, error) { + log.Debug("call to get pending transactions") + rst, err := api.s.db.GetPendingTransactions() + log.Debug("result from database for pending transactions", "len", len(rst)) + return rst, err +} + +func (api *API) GetPendingOutboundTransactionsByAddress(ctx context.Context, address common.Address) ([]*PendingTransaction, error) { + log.Debug("call to get pending transactions by address") + rst, err := api.s.db.GetPendingOutboundTransactionsByAddress(address) + log.Debug("result from database for pending transactions by address", "len", len(rst)) + return rst, err +} + +func (api *API) StorePendingTransaction(ctx context.Context, trx PendingTransaction) error { + log.Debug("call to create or edit pending transaction") + err := api.s.db.StorePendingTransaction(trx) + log.Debug("result from database for creating or editing a pending transaction", "err", err) + return err +} + +func (api *API) DeletePendingTransaction(ctx context.Context, transactionHash common.Hash) error { + log.Debug("call to remove pending transaction") + err := api.s.db.DeletePendingTransaction(transactionHash) + log.Debug("result from database for remove pending transaction", "err", err) + return err +} diff --git a/services/wallet/database.go b/services/wallet/database.go index e78f78351..a990af7ba 100644 --- a/services/wallet/database.go +++ b/services/wallet/database.go @@ -583,6 +583,82 @@ func (db *Database) DeleteCustomToken(address common.Address) error { return err } +type PendingTrxType string + +const ( + RegisterENS PendingTrxType = "RegisterENS" + ReleaseENS PendingTrxType = "ReleaseENS" + SetPubKey PendingTrxType = "SetPubKey" + BuyStickerPack PendingTrxType = "BuyStickerPack" + WalletTransfer PendingTrxType = "WalletTransfer" +) + +type PendingTransaction struct { + TransactionHash common.Hash `json:"transactionHash"` + BlockNumber *big.Int `json:"blockNumber"` + From common.Address `json:"from_address"` + To common.Address `json:"to_address"` + Type PendingTrxType `json:"type"` + Data string `json:"data"` +} + +func (db *Database) GetPendingTransactions() ([]*PendingTransaction, error) { + rows, err := db.db.Query(`SELECT transaction_hash, blk_number, from_address, to_address, type, data FROM pending_transactions WHERE network_id = ?`, db.network) + if err != nil { + return nil, err + } + defer rows.Close() + + var rst []*PendingTransaction + for rows.Next() { + trx := &PendingTransaction{BlockNumber: new(big.Int)} + err := rows.Scan(&trx.TransactionHash, (*SQLBigInt)(trx.BlockNumber), &trx.From, &trx.To, &trx.Type, &trx.Data) + if err != nil { + return nil, err + } + + rst = append(rst, trx) + } + + return rst, nil +} + +func (db *Database) GetPendingOutboundTransactionsByAddress(address common.Address) ([]*PendingTransaction, error) { + rows, err := db.db.Query(`SELECT transaction_hash, blk_number, from_address, to_address, type, data FROM pending_transactions WHERE network_id = ? AND from_address = ?`, db.network, address) + if err != nil { + return nil, err + } + defer rows.Close() + + var rst []*PendingTransaction + for rows.Next() { + trx := &PendingTransaction{BlockNumber: new(big.Int)} + err := rows.Scan(&trx.TransactionHash, (*SQLBigInt)(trx.BlockNumber), &trx.From, &trx.To, &trx.Type, &trx.Data) + + if err != nil { + return nil, err + } + + rst = append(rst, trx) + } + + return rst, nil +} + +func (db *Database) StorePendingTransaction(trx PendingTransaction) error { + insert, err := db.db.Prepare("INSERT OR REPLACE INTO pending_transactions (network_id, transaction_hash, blk_number, from_address, to_address, type, data) VALUES (?, ?, ?, ?, ?, ?, ?)") + if err != nil { + return err + } + _, err = insert.Exec(db.network, trx.TransactionHash, (*SQLBigInt)(trx.BlockNumber), trx.From, trx.To, trx.Type, trx.Data) + return err +} + +func (db *Database) DeletePendingTransaction(transactionHash common.Hash) error { + _, err := db.db.Exec(`DELETE FROM pending_transactions WHERE transaction_hash = ?`, transactionHash) + return err +} + // statementCreator allows to pass transaction or database to use in consumer. type statementCreator interface { Prepare(query string) (*sql.Stmt, error) diff --git a/services/wallet/database_test.go b/services/wallet/database_test.go index 9df805c0c..30720458d 100644 --- a/services/wallet/database_test.go +++ b/services/wallet/database_test.go @@ -204,3 +204,54 @@ func TestCustomTokens(t *testing.T) { require.NoError(t, err) require.Equal(t, 0, len(rst)) } + +func TestPendingTransactions(t *testing.T) { + db, stop := setupTestDB(t) + defer stop() + + trx := PendingTransaction{ + TransactionHash: common.Hash{1}, + BlockNumber: big.NewInt(1), + From: common.Address{1}, + To: common.Address{2}, + Type: RegisterENS, + Data: "someuser.stateofus.eth", + } + + rst, err := db.GetPendingTransactions() + require.NoError(t, err) + require.Nil(t, rst) + + rst, err = db.GetPendingOutboundTransactionsByAddress(trx.From) + require.NoError(t, err) + require.Nil(t, rst) + + err = db.StorePendingTransaction(trx) + require.NoError(t, err) + + rst, err = db.GetPendingOutboundTransactionsByAddress(trx.From) + require.NoError(t, err) + require.Equal(t, 1, len(rst)) + require.Equal(t, trx, *rst[0]) + + rst, err = db.GetPendingTransactions() + require.NoError(t, err) + require.Equal(t, 1, len(rst)) + require.Equal(t, trx, *rst[0]) + + rst, err = db.GetPendingOutboundTransactionsByAddress(common.Address{2}) + require.NoError(t, err) + require.Nil(t, rst) + + err = db.DeletePendingTransaction(trx.TransactionHash) + require.NoError(t, err) + + rst, err = db.GetPendingOutboundTransactionsByAddress(trx.From) + require.NoError(t, err) + require.Equal(t, 0, len(rst)) + + rst, err = db.GetPendingTransactions() + require.NoError(t, err) + require.Equal(t, 0, len(rst)) + +}