From 75479405231a17e9dc75f4b4aaa76284d19c4249 Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Fri, 8 Nov 2024 07:34:41 +0000 Subject: [PATCH] WIP investigate gw bug (#2130) * investigate gw bug * fix * fix * fix * fix --- lib/gethfork/node/extract_params_handler.go | 6 ++---- lib/gethfork/rpc/handler.go | 3 ++- tools/walletextension/common/types.go | 9 +++------ tools/walletextension/httpapi/utils.go | 2 +- tools/walletextension/rpcapi/filter_api.go | 10 +++++----- tools/walletextension/rpcapi/from_tx_args.go | 12 ++++++------ tools/walletextension/rpcapi/utils.go | 5 ++++- .../storage/database/common/db_types.go | 12 ++++++------ .../storage/database/sqlite/sqlite.go | 19 ++++++++++++++++--- 9 files changed, 45 insertions(+), 33 deletions(-) diff --git a/lib/gethfork/node/extract_params_handler.go b/lib/gethfork/node/extract_params_handler.go index 02a92babc0..e0234b63ab 100644 --- a/lib/gethfork/node/extract_params_handler.go +++ b/lib/gethfork/node/extract_params_handler.go @@ -24,9 +24,7 @@ func newHTTPParamsHandler(exposedParam string, next http.Handler) http.Handler { func (handler *httpParamsHandler) ServeHTTP(out http.ResponseWriter, r *http.Request) { q := r.URL.Query() val := q.Get(handler.exposedParam) - if len(val) > 0 { - ctx := context.WithValue(r.Context(), rpc.GWTokenKey{}, val) - handler.next.ServeHTTP(out, r.WithContext(ctx)) - } + ctx := context.WithValue(r.Context(), rpc.GWTokenKey{}, val) + handler.next.ServeHTTP(out, r.WithContext(ctx)) handler.next.ServeHTTP(out, r) } diff --git a/lib/gethfork/rpc/handler.go b/lib/gethfork/rpc/handler.go index 8836f3c6b5..6d5cc533e0 100644 --- a/lib/gethfork/rpc/handler.go +++ b/lib/gethfork/rpc/handler.go @@ -389,7 +389,8 @@ func (h *handler) startCallProc(fn func(*callProc)) { defer h.callWG.Done() defer cancel() // handle the case when normal rpc calls are made over a ws connection - if ctx.Value(GWTokenKey{}) == nil { + v, ok := ctx.Value(GWTokenKey{}).(string) + if !ok || len(v) == 0 { ctx = context.WithValue(ctx, GWTokenKey{}, hexutils.BytesToHex(h.UserID)) } fn(&callProc{ctx: ctx}) diff --git a/tools/walletextension/common/types.go b/tools/walletextension/common/types.go index 4d793bbf86..1326e26203 100644 --- a/tools/walletextension/common/types.go +++ b/tools/walletextension/common/types.go @@ -2,6 +2,7 @@ package common import ( "github.com/ten-protocol/go-ten/go/common/viewingkey" + "golang.org/x/exp/maps" "github.com/ethereum/go-ethereum/common" ) @@ -19,10 +20,6 @@ type GWUser struct { UserKey []byte } -func (u GWUser) GetAllAddresses() []*common.Address { - accts := make([]*common.Address, 0) - for _, acc := range u.Accounts { - accts = append(accts, acc.Address) - } - return accts +func (u GWUser) GetAllAddresses() []common.Address { + return maps.Keys(u.Accounts) } diff --git a/tools/walletextension/httpapi/utils.go b/tools/walletextension/httpapi/utils.go index e367856abc..2acbc9fdf5 100644 --- a/tools/walletextension/httpapi/utils.go +++ b/tools/walletextension/httpapi/utils.go @@ -31,7 +31,7 @@ func getUserID(conn UserConn) ([]byte, error) { return hexutils.HexToBytes(userID), nil } - return nil, fmt.Errorf(fmt.Sprintf("wrong length of userID from URL. Got: %d, Expected: %d od %d", len(userID), common.MessageUserIDLenWithPrefix, common.MessageUserIDLen)) + return nil, fmt.Errorf("wrong length of userID from URL. Got: %d, Expected: %d od %d", len(userID), common.MessageUserIDLenWithPrefix, common.MessageUserIDLen) } return nil, fmt.Errorf("missing token field") diff --git a/tools/walletextension/rpcapi/filter_api.go b/tools/walletextension/rpcapi/filter_api.go index 15e6ec63a8..202e864cd2 100644 --- a/tools/walletextension/rpcapi/filter_api.go +++ b/tools/walletextension/rpcapi/filter_api.go @@ -85,7 +85,7 @@ func (api *FilterAPI) Logs(ctx context.Context, crit common.FilterCriteria) (*rp errorChannels := make([]<-chan error, 0) backendSubscriptions := make([]*rpc.ClientSubscription, 0) for _, address := range candidateAddresses { - rpcWSClient, err := api.we.BackendRPC.ConnectWS(ctx, user.Accounts[*address]) + rpcWSClient, err := api.we.BackendRPC.ConnectWS(ctx, user.Accounts[address]) if err != nil { return nil, err } @@ -174,14 +174,14 @@ func getUserAndNotifier(ctx context.Context, api *FilterAPI) (*rpc.Notifier, *we return subNotifier, user, nil } -func searchForAddressInFilterCriteria(filterCriteria common.FilterCriteria, possibleAddresses []*gethcommon.Address) []*gethcommon.Address { - result := make([]*gethcommon.Address, 0) +func searchForAddressInFilterCriteria(filterCriteria common.FilterCriteria, possibleAddresses []gethcommon.Address) []gethcommon.Address { + result := make([]gethcommon.Address, 0) addrMap := toMap(possibleAddresses) for _, topicCondition := range filterCriteria.Topics { for _, topic := range topicCondition { potentialAddr := common.ExtractPotentialAddress(topic) - if potentialAddr != nil && addrMap[*potentialAddr] != nil { - result = append(result, potentialAddr) + if potentialAddr != nil && addrMap[*potentialAddr] { + result = append(result, *potentialAddr) } } } diff --git a/tools/walletextension/rpcapi/from_tx_args.go b/tools/walletextension/rpcapi/from_tx_args.go index 996e0b667d..37bf41a166 100644 --- a/tools/walletextension/rpcapi/from_tx_args.go +++ b/tools/walletextension/rpcapi/from_tx_args.go @@ -8,8 +8,8 @@ import ( "github.com/ten-protocol/go-ten/go/common/gethapi" ) -func searchFromAndData(possibleAddresses []*common.Address, args gethapi.TransactionArgs) *common.Address { - if args.From != nil { +func searchFromAndData(possibleAddresses []common.Address, args gethapi.TransactionArgs) *common.Address { + if args.From != nil && (*args.From != common.Address{}) { return args.From } @@ -22,7 +22,7 @@ func searchFromAndData(possibleAddresses []*common.Address, args gethapi.Transac return searchDataFieldForAccount(addressesMap, *args.Data) } -func searchDataFieldForAccount(addressesMap map[common.Address]*common.Address, data []byte) *common.Address { +func searchDataFieldForAccount(addressesMap map[common.Address]bool, data []byte) *common.Address { hexEncodedData := hexutils.BytesToHex(data) // We check that the data field is long enough before removing the leading "0x" (1 bytes/2 chars) and the method ID @@ -57,10 +57,10 @@ func searchDataFieldForAccount(addressesMap map[common.Address]*common.Address, return nil } -func toMap(possibleAddresses []*common.Address) map[common.Address]*common.Address { - addresses := map[common.Address]*common.Address{} +func toMap(possibleAddresses []common.Address) map[common.Address]bool { + addresses := map[common.Address]bool{} for i := range possibleAddresses { - addresses[*possibleAddresses[i]] = possibleAddresses[i] + addresses[possibleAddresses[i]] = true } return addresses } diff --git a/tools/walletextension/rpcapi/utils.go b/tools/walletextension/rpcapi/utils.go index 6ee345b9b3..9012f3217e 100644 --- a/tools/walletextension/rpcapi/utils.go +++ b/tools/walletextension/rpcapi/utils.go @@ -153,7 +153,7 @@ func ExecAuthRPC[R any](ctx context.Context, w *services.Services, cfg *ExecCfg, return res, err } -func getCandidateAccounts(user *common.GWUser, _ *services.Services, cfg *ExecCfg) ([]*common.GWAccount, error) { +func getCandidateAccounts(user *common.GWUser, we *services.Services, cfg *ExecCfg) ([]*common.GWAccount, error) { candidateAccts := make([]*common.GWAccount, 0) // for users with multiple accounts try to determine a candidate account based on the available information switch { @@ -171,6 +171,9 @@ func getCandidateAccounts(user *common.GWUser, _ *services.Services, cfg *ExecCf if acc != nil { candidateAccts = append(candidateAccts, acc) return candidateAccts, nil + } else { + // this should not happen, because the suggestedAddress is one of the addresses + return nil, fmt.Errorf("should not happen. From: %s . UserId: %s", suggestedAddress.Hex(), hexutils.BytesToHex(user.UserID)) } } } diff --git a/tools/walletextension/storage/database/common/db_types.go b/tools/walletextension/storage/database/common/db_types.go index 06e4433864..af84deed2d 100644 --- a/tools/walletextension/storage/database/common/db_types.go +++ b/tools/walletextension/storage/database/common/db_types.go @@ -3,7 +3,7 @@ package common import ( "github.com/ethereum/go-ethereum/common" "github.com/ten-protocol/go-ten/go/common/viewingkey" - common2 "github.com/ten-protocol/go-ten/tools/walletextension/common" + wecommon "github.com/ten-protocol/go-ten/tools/walletextension/common" ) type GWUserDB struct { @@ -18,22 +18,22 @@ type GWAccountDB struct { SignatureType int `json:"signatureType"` } -func (userDB *GWUserDB) ToGWUser() *common2.GWUser { - result := &common2.GWUser{ +func (userDB *GWUserDB) ToGWUser() *wecommon.GWUser { + result := &wecommon.GWUser{ UserID: userDB.UserId, - Accounts: make(map[common.Address]*common2.GWAccount), + Accounts: make(map[common.Address]*wecommon.GWAccount), UserKey: userDB.PrivateKey, } for _, accountDB := range userDB.Accounts { address := common.BytesToAddress(accountDB.AccountAddress) - gwAccount := &common2.GWAccount{ + gwAccount := wecommon.GWAccount{ User: result, Address: &address, Signature: accountDB.Signature, SignatureType: viewingkey.SignatureType(accountDB.SignatureType), } - result.Accounts[address] = gwAccount + result.Accounts[address] = &gwAccount } return result diff --git a/tools/walletextension/storage/database/sqlite/sqlite.go b/tools/walletextension/storage/database/sqlite/sqlite.go index e58926a104..57ce320a92 100644 --- a/tools/walletextension/storage/database/sqlite/sqlite.go +++ b/tools/walletextension/storage/database/sqlite/sqlite.go @@ -28,6 +28,8 @@ type SqliteDB struct { db *sql.DB } +const sqliteCfg = "_foreign_keys=on&_journal_mode=wal&_txlock=immediate&_synchronous=normal" + func NewSqliteDatabase(dbPath string) (*SqliteDB, error) { // load the db file dbFilePath, err := createOrLoad(dbPath) @@ -36,7 +38,8 @@ func NewSqliteDatabase(dbPath string) (*SqliteDB, error) { } // open the db - db, err := sql.Open("sqlite3", dbFilePath) + path := fmt.Sprintf("file:%s?%s", dbFilePath, sqliteCfg) + db, err := sql.Open("sqlite3", path) if err != nil { fmt.Println("Error opening database: ", err) return nil, err @@ -104,7 +107,13 @@ func (s *SqliteDB) DeleteUser(userID []byte) error { func (s *SqliteDB) AddAccount(userID []byte, accountAddress []byte, signature []byte, signatureType viewingkey.SignatureType) error { var userDataJSON string - err := s.db.QueryRow("SELECT user_data FROM users WHERE id = ?", string(userID)).Scan(&userDataJSON) + tx, err := s.db.Begin() + if err != nil { + return err + } + defer tx.Rollback() + + err = tx.QueryRow("SELECT user_data FROM users WHERE id = ?", string(userID)).Scan(&userDataJSON) if err != nil { return fmt.Errorf("failed to get user: %w", err) } @@ -128,7 +137,7 @@ func (s *SqliteDB) AddAccount(userID []byte, accountAddress []byte, signature [] return fmt.Errorf("error marshaling updated user: %w", err) } - stmt, err := s.db.Prepare("UPDATE users SET user_data = ? WHERE id = ?") + stmt, err := tx.Prepare("UPDATE users SET user_data = ? WHERE id = ?") if err != nil { return err } @@ -138,6 +147,10 @@ func (s *SqliteDB) AddAccount(userID []byte, accountAddress []byte, signature [] if err != nil { return fmt.Errorf("failed to update user with new account: %w", err) } + err = tx.Commit() + if err != nil { + return err + } return nil }