Compute emojiHash on-the-fly

This commit is contained in:
Vitaliy Vlasov 2023-03-06 10:51:09 +02:00
parent 8a296407f3
commit 27a76f43ba
9 changed files with 99 additions and 51 deletions

View File

@ -1 +1 @@
0.136.2
0.136.3

View File

@ -6,7 +6,7 @@ import (
"encoding/json"
"time"
"github.com/status-im/status-go/api/multiformat"
accountJson "github.com/status-im/status-go/account/json"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/extkeys"
@ -69,20 +69,11 @@ type AccountInfo struct {
func (a AccountInfo) MarshalJSON() ([]byte, error) {
type Alias AccountInfo
item := struct {
Alias
CompressedKey string `json:"compressedKey"`
}{
Alias: (Alias)(a),
}
compressedKey, err := multiformat.SerializeLegacyKey(item.PublicKey)
ext, err := accountJson.ExtendStructWithPubKeyData(a.PublicKey, Alias(a))
if err != nil {
return nil, err
}
item.CompressedKey = compressedKey
return json.Marshal(item)
return json.Marshal(ext)
}
// IdentifiedAccountInfo contains AccountInfo and the ID of an account.

58
account/json/utils.go Normal file
View File

@ -0,0 +1,58 @@
package json
import (
"reflect"
"github.com/status-im/status-go/api/multiformat"
"github.com/status-im/status-go/protocol/identity/emojihash"
)
type PublicKeyData struct {
CompressedKey string `json:"compressedKey"`
EmojiHash []string `json:"emojiHash"`
}
func getPubKeyData(publicKey string) (*PublicKeyData, error) {
compressedKey, err := multiformat.SerializeLegacyKey(publicKey)
if err != nil {
return nil, err
}
emojiHash, err := emojihash.GenerateFor(publicKey)
if err != nil {
return nil, err
}
return &PublicKeyData{compressedKey, emojiHash}, nil
}
func ExtendStructWithPubKeyData(publicKey string, item any) (any, error) {
pkd, err := getPubKeyData(publicKey)
if err != nil {
return nil, err
}
// Create a struct with 2 embedded substruct fields in order to circumvent
// "embedded field type cannot be a (pointer to a) type parameter"
// compiler error that arises if we were to use a generic function instead
typ := reflect.StructOf([]reflect.StructField{
{
Name: "Item",
Anonymous: true,
Type: reflect.TypeOf(item),
},
{
Name: "Pkd",
Anonymous: true,
Type: reflect.TypeOf(pkd),
},
})
v := reflect.New(typ).Elem()
v.Field(0).Set(reflect.ValueOf(item))
v.Field(1).Set(reflect.ValueOf(pkd))
s := v.Addr().Interface()
return s, nil
}

View File

@ -52,7 +52,8 @@ func TestJSONEncoding(t *testing.T) {
encoded, err := json.Marshal(settings)
require.NoError(t, err)
require.True(t, strings.Contains(string(encoded), "\"compressed-key\":\"zQ3shudJrBctPznsRLvbsCtvZFTdi3b34uzYDuqE9Wq9m9T1C\""))
require.True(t, strings.Contains(string(encoded), "\"compressedKey\":\"zQ3shudJrBctPznsRLvbsCtvZFTdi3b34uzYDuqE9Wq9m9T1C\""))
require.True(t, strings.Contains(string(encoded), "\"emojiHash\""))
}
// TestGetFieldFromProtobufType checks if all the protobuf.SyncSetting_Type_value are assigned to a SettingField

View File

@ -3,7 +3,7 @@ package settings
import (
"encoding/json"
"github.com/status-im/status-go/api/multiformat"
accountJson "github.com/status-im/status-go/account/json"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf"
@ -190,19 +190,13 @@ type Settings struct {
}
func (s Settings) MarshalJSON() ([]byte, error) {
// We need this typedef in order to overcome stack overflow
// when marshaling JSON
type Alias Settings
item := struct {
Alias
CompressedKey string `json:"compressed-key"`
}{
Alias: (Alias)(s),
}
compressedKey, err := multiformat.SerializeLegacyKey(item.PublicKey)
ext, err := accountJson.ExtendStructWithPubKeyData(s.PublicKey, Alias(s))
if err != nil {
return nil, err
}
item.CompressedKey = compressedKey
return json.Marshal(item)
return json.Marshal(ext)
}

View File

@ -18,7 +18,7 @@ import (
"github.com/status-im/markdown"
"github.com/status-im/markdown/ast"
"github.com/status-im/status-go/api/multiformat"
accountJson "github.com/status-im/status-go/account/json"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/images"
"github.com/status-im/status-go/protocol/audio"
@ -222,11 +222,11 @@ func (m *Message) MarshalJSON() ([]byte, error) {
Pack int32 `json:"pack"`
URL string `json:"url"`
}
item := struct {
type MessageStructType struct {
ID string `json:"id"`
WhisperTimestamp uint64 `json:"whisperTimestamp"`
From string `json:"from"`
CompressedKey string `json:"compressedKey"`
Alias string `json:"alias"`
Identicon string `json:"identicon"`
Seen bool `json:"seen"`
@ -268,7 +268,8 @@ func (m *Message) MarshalJSON() ([]byte, error) {
ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"`
ContactVerificationState ContactVerificationState `json:"contactVerificationState,omitempty"`
DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"`
}{
}
item := MessageStructType{
ID: m.ID,
WhisperTimestamp: m.WhisperTimestamp,
From: m.From,
@ -308,13 +309,6 @@ func (m *Message) MarshalJSON() ([]byte, error) {
ContactRequestState: m.ContactRequestState,
ContactVerificationState: m.ContactVerificationState,
}
if item.From != "" {
compressedKey, err := multiformat.SerializeLegacyKey(item.From)
if err != nil {
return nil, err
}
item.CompressedKey = compressedKey
}
if sticker := m.GetSticker(); sticker != nil {
item.Sticker = &StickerAlias{
@ -337,6 +331,14 @@ func (m *Message) MarshalJSON() ([]byte, error) {
if discordMessage := m.GetDiscordMessage(); discordMessage != nil {
item.DiscordMessage = discordMessage
}
if item.From != "" {
ext, err := accountJson.ExtendStructWithPubKeyData(item.From, item)
if err != nil {
return nil, err
}
return json.Marshal(ext)
}
return json.Marshal(item)
}

View File

@ -3,6 +3,7 @@ package common
import (
"encoding/json"
"io/ioutil"
"log"
"os"
"strings"
"testing"
@ -140,5 +141,8 @@ func TestMarshalMessageJSON(t *testing.T) {
encodedMessage, err := json.Marshal(message)
require.NoError(t, err)
log.Println("### encodedMessage", string(encodedMessage))
require.True(t, strings.Contains(string(encodedMessage), "compressedKey\":\"zQ"))
require.True(t, strings.Contains(string(encodedMessage), "emojiHash"))
}

View File

@ -4,7 +4,7 @@ import (
"crypto/ecdsa"
"encoding/json"
"github.com/status-im/status-go/api/multiformat"
accountJson "github.com/status-im/status-go/account/json"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/images"
@ -401,34 +401,27 @@ func (c *Contact) ProcessSyncContactRequestState(remoteState ContactRequestState
func (c *Contact) MarshalJSON() ([]byte, error) {
type Alias Contact
item := struct {
type ContactType struct {
*Alias
CompressedKey string `json:"compressedKey"`
Added bool `json:"added"`
ContactRequestState ContactRequestState `json:"contactRequestState"`
HasAddedUs bool `json:"hasAddedUs"`
Mutual bool `json:"mutual"`
Active bool `json:"active"`
PrimaryName string `json:"primaryName"`
SecondaryName string `json:"secondaryName,omitempty"`
}
Active bool `json:"active"`
PrimaryName string `json:"primaryName"`
SecondaryName string `json:"secondaryName,omitempty"`
}{
item := ContactType{
Alias: (*Alias)(c),
}
compressedKey, err := multiformat.SerializeLegacyKey(item.ID)
if err != nil {
return nil, err
}
item.CompressedKey = compressedKey
item.Added = c.added()
item.HasAddedUs = c.hasAddedUs()
item.Mutual = c.mutual()
item.Active = c.active()
item.PrimaryName = c.PrimaryName()
item.SecondaryName = c.SecondaryName()
item.Active = c.active()
if c.mutual() {
item.ContactRequestState = ContactRequestStateMutual
@ -437,8 +430,12 @@ func (c *Contact) MarshalJSON() ([]byte, error) {
} else if c.hasAddedUs() {
item.ContactRequestState = ContactRequestStateReceived
}
ext, err := accountJson.ExtendStructWithPubKeyData(item.ID, item)
if err != nil {
return nil, err
}
return json.Marshal(item)
return json.Marshal(ext)
}
// ContactRequestPropagatedStateReceived handles the propagation of state from

View File

@ -570,6 +570,7 @@ func TestMarshalContactJSON(t *testing.T) {
require.True(t, strings.Contains(string(encodedContact), "active\":true"))
require.True(t, strings.Contains(string(encodedContact), "primaryName\":\"primary-name"))
require.True(t, strings.Contains(string(encodedContact), "secondaryName\":\"secondary-name"))
require.True(t, strings.Contains(string(encodedContact), "emojiHash"))
}
func TestContactContactRequestPropagatedStateReceivedOutOfDateLocalStateOnTheirSide(t *testing.T) {