From c6bb2fc7e7c5837ab981140dd06509e462584aea Mon Sep 17 00:00:00 2001 From: Jason Chavannes Date: Sat, 15 Jun 2024 13:12:06 -0700 Subject: [PATCH 1/5] Save memo link requests. --- db/item/db/main.go | 4 ++ db/item/memo/addr_link_request.go | 46 +++++++++++++++++++ db/item/memo/addr_link_requested.go | 46 +++++++++++++++++++ db/item/memo/link_request.go | 51 +++++++++++++++++++++ db/item/memo/main.go | 3 ++ node/obj/op_return/main.go | 1 + node/obj/op_return/memo_link_request.go | 61 +++++++++++++++++++++++++ 7 files changed, 212 insertions(+) create mode 100644 db/item/memo/addr_link_request.go create mode 100644 db/item/memo/addr_link_requested.go create mode 100644 db/item/memo/link_request.go create mode 100644 node/obj/op_return/memo_link_request.go diff --git a/db/item/db/main.go b/db/item/db/main.go index 7b3b38b2..391f239b 100644 --- a/db/item/db/main.go +++ b/db/item/db/main.go @@ -41,6 +41,10 @@ const ( TopicMemoRoomPost = "memo_room_post" TopicMemoSeenPost = "memo_seen_post" + TopicMemoAddrLinkRequest = "memo_addr_link_request" + TopicMemoAddrLinkRequested = "memo_addr_link_requested" + TopicMemoLinkRequest = "memo_link_request" + TopicChainBlock = "chain_block" TopicChainBlockHeight = "chain_block_height" TopicChainHeightBlock = "chain_height_block" diff --git a/db/item/memo/addr_link_request.go b/db/item/memo/addr_link_request.go new file mode 100644 index 00000000..7a91282d --- /dev/null +++ b/db/item/memo/addr_link_request.go @@ -0,0 +1,46 @@ +package memo + +import ( + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/client" + "github.com/memocash/index/db/item/db" + "github.com/memocash/index/ref/bitcoin/memo" + "time" +) + +type AddrLinkRequest struct { + Addr [25]byte + Seen time.Time + TxHash [32]byte +} + +func (r *AddrLinkRequest) GetTopic() string { + return db.TopicMemoAddrLinkRequest +} + +func (r *AddrLinkRequest) GetShardSource() uint { + return client.GenShardSource(r.Addr[:]) +} + +func (r *AddrLinkRequest) GetUid() []byte { + return jutil.CombineBytes( + r.Addr[:], + jutil.GetTimeByteNanoBig(r.Seen), + jutil.ByteReverse(r.TxHash[:]), + ) +} + +func (r *AddrLinkRequest) SetUid(uid []byte) { + if len(uid) != memo.AddressLength+memo.Int8Size+memo.TxHashLength { + return + } + copy(r.Addr[:], uid[:25]) + r.Seen = jutil.GetByteTimeNanoBig(uid[25:33]) + copy(r.TxHash[:], jutil.ByteReverse(uid[33:65])) +} + +func (r *AddrLinkRequest) Serialize() []byte { + return nil +} + +func (r *AddrLinkRequest) Deserialize([]byte) {} diff --git a/db/item/memo/addr_link_requested.go b/db/item/memo/addr_link_requested.go new file mode 100644 index 00000000..19f6c5c5 --- /dev/null +++ b/db/item/memo/addr_link_requested.go @@ -0,0 +1,46 @@ +package memo + +import ( + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/client" + "github.com/memocash/index/db/item/db" + "github.com/memocash/index/ref/bitcoin/memo" + "time" +) + +type AddrLinkRequested struct { + Addr [25]byte + Seen time.Time + TxHash [32]byte +} + +func (r *AddrLinkRequested) GetTopic() string { + return db.TopicMemoAddrLinkRequested +} + +func (r *AddrLinkRequested) GetShardSource() uint { + return client.GenShardSource(r.Addr[:]) +} + +func (r *AddrLinkRequested) GetUid() []byte { + return jutil.CombineBytes( + r.Addr[:], + jutil.GetTimeByteNanoBig(r.Seen), + jutil.ByteReverse(r.TxHash[:]), + ) +} + +func (r *AddrLinkRequested) SetUid(uid []byte) { + if len(uid) != memo.AddressLength+memo.Int8Size+memo.TxHashLength { + return + } + copy(r.Addr[:], uid[:25]) + r.Seen = jutil.GetByteTimeNanoBig(uid[25:33]) + copy(r.TxHash[:], jutil.ByteReverse(uid[33:65])) +} + +func (r *AddrLinkRequested) Serialize() []byte { + return nil +} + +func (r *AddrLinkRequested) Deserialize([]byte) {} diff --git a/db/item/memo/link_request.go b/db/item/memo/link_request.go new file mode 100644 index 00000000..062546f5 --- /dev/null +++ b/db/item/memo/link_request.go @@ -0,0 +1,51 @@ +package memo + +import ( + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/client" + "github.com/memocash/index/db/item/db" + "github.com/memocash/index/ref/bitcoin/memo" +) + +type LinkRequest struct { + TxHash [32]byte + ChildAddr [25]byte + ParentAddr [25]byte + Message string +} + +func (r *LinkRequest) GetTopic() string { + return db.TopicMemoLinkRequest +} + +func (r *LinkRequest) GetShardSource() uint { + return client.GenShardSource(r.TxHash[:]) +} + +func (r *LinkRequest) GetUid() []byte { + return jutil.ByteReverse(r.TxHash[:]) +} + +func (r *LinkRequest) SetUid(uid []byte) { + if len(uid) != memo.TxHashLength { + panic("invalid uid size for link request") + } + copy(r.TxHash[:], jutil.ByteReverse(uid)) +} + +func (r *LinkRequest) Serialize() []byte { + return jutil.CombineBytes( + r.ChildAddr[:], + r.ParentAddr[:], + []byte(r.Message), + ) +} + +func (r *LinkRequest) Deserialize(data []byte) { + if len(data) < memo.AddressLength*2 { + panic("invalid data size for link request") + } + copy(r.ChildAddr[:], data[:25]) + copy(r.ParentAddr[:], data[25:50]) + r.Message = string(data[50:]) +} diff --git a/db/item/memo/main.go b/db/item/memo/main.go index d1463b90..20e3e533 100644 --- a/db/item/memo/main.go +++ b/db/item/memo/main.go @@ -20,5 +20,8 @@ func GetTopics() []db.Object { &PostRoom{}, &RoomFollow{}, &RoomPost{}, + &LinkRequest{}, + &AddrLinkRequest{}, + &AddrLinkRequested{}, } } diff --git a/node/obj/op_return/main.go b/node/obj/op_return/main.go index 1a5310cd..df07cabc 100644 --- a/node/obj/op_return/main.go +++ b/node/obj/op_return/main.go @@ -42,6 +42,7 @@ func GetHandlers() ([]*Handler, error) { memoRoomPostHandler, memoRoomFollowHandler, memoRoomUnfollowHandler, + memoLinkRequestHandler, slpTokenHandler, } for _, opReturn := range handlers { diff --git a/node/obj/op_return/memo_link_request.go b/node/obj/op_return/memo_link_request.go new file mode 100644 index 00000000..27c66911 --- /dev/null +++ b/node/obj/op_return/memo_link_request.go @@ -0,0 +1,61 @@ +package op_return + +import ( + "context" + "fmt" + "github.com/memocash/index/db/item" + "github.com/memocash/index/db/item/db" + dbMemo "github.com/memocash/index/db/item/memo" + "github.com/memocash/index/ref/bitcoin/memo" + "github.com/memocash/index/ref/bitcoin/tx/parse" + "github.com/memocash/index/ref/bitcoin/wallet" +) + +var memoLinkRequestHandler = &Handler{ + prefix: memo.PrefixLinkRequest, + handle: func(ctx context.Context, info parse.OpReturn) error { + if len(info.PushData) < 2 { + if err := item.LogProcessError(&item.ProcessError{ + TxHash: info.TxHash, + Error: fmt.Sprintf("invalid set link request, incorrect push data (%d)", len(info.PushData)), + }); err != nil { + return fmt.Errorf("error saving process error memo link request incorrect push data; %w", err) + } + return nil + } + if len(info.PushData[1]) != memo.PkHashLength { + if err := item.LogProcessError(&item.ProcessError{ + TxHash: info.TxHash, + Error: fmt.Sprintf("error link request address incorrect length: %d", len(info.PushData[1])), + }); err != nil { + return fmt.Errorf("error saving process error memo link request address; %w", err) + } + return nil + } + parentAddr := *wallet.GetAddrFromPkHash(info.PushData[1]) + var message string + if len(info.PushData) > 2 { + message = string(info.PushData[2]) + } + var linkRequest = &dbMemo.LinkRequest{ + TxHash: info.TxHash, + ChildAddr: info.Addr, + ParentAddr: parentAddr, + Message: message, + } + var addrLinkRequest = &dbMemo.AddrLinkRequest{ + Addr: info.Addr, + Seen: info.Seen, + TxHash: info.TxHash, + } + var addrLinkRequested = &dbMemo.AddrLinkRequested{ + Addr: parentAddr, + Seen: info.Seen, + TxHash: info.TxHash, + } + if err := db.Save([]db.Object{linkRequest, addrLinkRequest, addrLinkRequested}); err != nil { + return fmt.Errorf("error saving db lock memo link request object; %w", err) + } + return nil + }, +} From 2a3608bb15a427a2f7e12d003e64c1b8866eeb3d Mon Sep 17 00:00:00 2001 From: Jason Chavannes Date: Sat, 15 Jun 2024 14:03:39 -0700 Subject: [PATCH 2/5] Save memo link accepts. --- db/item/db/main.go | 2 + db/item/memo/link_accept.go | 51 ++++++++++++++++++++++ db/item/memo/link_accepted.go | 43 +++++++++++++++++++ db/item/memo/main.go | 2 + node/obj/op_return/main.go | 1 + node/obj/op_return/memo_link_accept.go | 57 +++++++++++++++++++++++++ node/obj/op_return/memo_link_request.go | 6 +-- 7 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 db/item/memo/link_accept.go create mode 100644 db/item/memo/link_accepted.go create mode 100644 node/obj/op_return/memo_link_accept.go diff --git a/db/item/db/main.go b/db/item/db/main.go index 391f239b..39e37e8a 100644 --- a/db/item/db/main.go +++ b/db/item/db/main.go @@ -43,6 +43,8 @@ const ( TopicMemoAddrLinkRequest = "memo_addr_link_request" TopicMemoAddrLinkRequested = "memo_addr_link_requested" + TopicMemoLinkAccept = "memo_link_accept" + TopicMemoLinkAccepted = "memo_link_accepted" TopicMemoLinkRequest = "memo_link_request" TopicChainBlock = "chain_block" diff --git a/db/item/memo/link_accept.go b/db/item/memo/link_accept.go new file mode 100644 index 00000000..b3ee4939 --- /dev/null +++ b/db/item/memo/link_accept.go @@ -0,0 +1,51 @@ +package memo + +import ( + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/client" + "github.com/memocash/index/db/item/db" + "github.com/memocash/index/ref/bitcoin/memo" +) + +type LinkAccept struct { + TxHash [32]byte + Addr [25]byte + RequestTxHash [32]byte + Message string +} + +func (r *LinkAccept) GetTopic() string { + return db.TopicMemoLinkAccept +} + +func (r *LinkAccept) GetShardSource() uint { + return client.GenShardSource(r.TxHash[:]) +} + +func (r *LinkAccept) GetUid() []byte { + return jutil.ByteReverse(r.TxHash[:]) +} + +func (r *LinkAccept) SetUid(uid []byte) { + if len(uid) != memo.TxHashLength { + panic("invalid uid size for link accept") + } + copy(r.TxHash[:], jutil.ByteReverse(uid)) +} + +func (r *LinkAccept) Serialize() []byte { + return jutil.CombineBytes( + r.Addr[:], + jutil.ByteReverse(r.RequestTxHash[:]), + []byte(r.Message), + ) +} + +func (r *LinkAccept) Deserialize(data []byte) { + if len(data) < memo.AddressLength+memo.TxHashLength { + panic("invalid data size for link accept") + } + copy(r.Addr[:], data[:25]) + copy(r.RequestTxHash[:], jutil.ByteReverse(data[25:57])) + r.Message = string(data[57:]) +} diff --git a/db/item/memo/link_accepted.go b/db/item/memo/link_accepted.go new file mode 100644 index 00000000..3e04e1dc --- /dev/null +++ b/db/item/memo/link_accepted.go @@ -0,0 +1,43 @@ +package memo + +import ( + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/client" + "github.com/memocash/index/db/item/db" + "github.com/memocash/index/ref/bitcoin/memo" +) + +type LinkAccepted struct { + RequestTxHash [32]byte + TxHash [32]byte +} + +func (r *LinkAccepted) GetTopic() string { + return db.TopicMemoLinkAccepted +} + +func (r *LinkAccepted) GetShardSource() uint { + return client.GenShardSource(r.RequestTxHash[:]) +} + +func (r *LinkAccepted) GetUid() []byte { + return jutil.ByteReverse(r.RequestTxHash[:]) +} + +func (r *LinkAccepted) SetUid(uid []byte) { + if len(uid) != memo.TxHashLength { + panic("invalid uid size for link accepted") + } + copy(r.RequestTxHash[:], jutil.ByteReverse(uid)) +} + +func (r *LinkAccepted) Serialize() []byte { + return jutil.ByteReverse(r.TxHash[:]) +} + +func (r *LinkAccepted) Deserialize(data []byte) { + if len(data) != memo.TxHashLength { + panic("invalid data size for link accepted") + } + copy(r.TxHash[:], jutil.ByteReverse(data)) +} diff --git a/db/item/memo/main.go b/db/item/memo/main.go index 20e3e533..7f2db49e 100644 --- a/db/item/memo/main.go +++ b/db/item/memo/main.go @@ -23,5 +23,7 @@ func GetTopics() []db.Object { &LinkRequest{}, &AddrLinkRequest{}, &AddrLinkRequested{}, + &LinkAccept{}, + &LinkAccepted{}, } } diff --git a/node/obj/op_return/main.go b/node/obj/op_return/main.go index df07cabc..53539ab2 100644 --- a/node/obj/op_return/main.go +++ b/node/obj/op_return/main.go @@ -43,6 +43,7 @@ func GetHandlers() ([]*Handler, error) { memoRoomFollowHandler, memoRoomUnfollowHandler, memoLinkRequestHandler, + memoLinkAcceptHandler, slpTokenHandler, } for _, opReturn := range handlers { diff --git a/node/obj/op_return/memo_link_accept.go b/node/obj/op_return/memo_link_accept.go new file mode 100644 index 00000000..53c78bba --- /dev/null +++ b/node/obj/op_return/memo_link_accept.go @@ -0,0 +1,57 @@ +package op_return + +import ( + "context" + "fmt" + "github.com/jchavannes/btcd/chaincfg/chainhash" + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/item" + "github.com/memocash/index/db/item/db" + dbMemo "github.com/memocash/index/db/item/memo" + "github.com/memocash/index/ref/bitcoin/memo" + "github.com/memocash/index/ref/bitcoin/tx/parse" +) + +var memoLinkAcceptHandler = &Handler{ + prefix: memo.PrefixLinkAccept, + handle: func(ctx context.Context, info parse.OpReturn) error { + if len(info.PushData) < 2 { + if err := item.LogProcessError(&item.ProcessError{ + TxHash: info.TxHash, + Error: fmt.Sprintf("invalid set link accept, incorrect push data (%d)", len(info.PushData)), + }); err != nil { + return fmt.Errorf("error saving process error memo link accept incorrect push data; %w", err) + } + return nil + } + if len(info.PushData[1]) != memo.TxHashLength { + if err := item.LogProcessError(&item.ProcessError{ + TxHash: info.TxHash, + Error: fmt.Sprintf("error link accept request tx hash incorrect length: %d", len(info.PushData[1])), + }); err != nil { + return fmt.Errorf("error saving process error memo link accept request tx hash; %w", err) + } + return nil + } + var acceptTxHash chainhash.Hash + copy(acceptTxHash[:], jutil.ByteReverse(info.PushData[1])) + var message string + if len(info.PushData) > 2 { + message = string(info.PushData[2]) + } + var linkAccept = &dbMemo.LinkAccept{ + TxHash: info.TxHash, + Addr: info.Addr, + RequestTxHash: acceptTxHash, + Message: message, + } + var linkAccepted = &dbMemo.LinkAccepted{ + TxHash: info.TxHash, + RequestTxHash: acceptTxHash, + } + if err := db.Save([]db.Object{linkAccept, linkAccepted}); err != nil { + return fmt.Errorf("error saving db lock memo link accept object; %w", err) + } + return nil + }, +} diff --git a/node/obj/op_return/memo_link_request.go b/node/obj/op_return/memo_link_request.go index 27c66911..79c07e9b 100644 --- a/node/obj/op_return/memo_link_request.go +++ b/node/obj/op_return/memo_link_request.go @@ -32,7 +32,7 @@ var memoLinkRequestHandler = &Handler{ } return nil } - parentAddr := *wallet.GetAddrFromPkHash(info.PushData[1]) + parentAddr := wallet.GetAddrFromPkHash(info.PushData[1]) var message string if len(info.PushData) > 2 { message = string(info.PushData[2]) @@ -40,7 +40,7 @@ var memoLinkRequestHandler = &Handler{ var linkRequest = &dbMemo.LinkRequest{ TxHash: info.TxHash, ChildAddr: info.Addr, - ParentAddr: parentAddr, + ParentAddr: *parentAddr, Message: message, } var addrLinkRequest = &dbMemo.AddrLinkRequest{ @@ -49,7 +49,7 @@ var memoLinkRequestHandler = &Handler{ TxHash: info.TxHash, } var addrLinkRequested = &dbMemo.AddrLinkRequested{ - Addr: parentAddr, + Addr: *parentAddr, Seen: info.Seen, TxHash: info.TxHash, } From 657dd5d360aa3f269fbd01bc807633648719cf15 Mon Sep 17 00:00:00 2001 From: Jason Chavannes Date: Sat, 15 Jun 2024 14:43:51 -0700 Subject: [PATCH 3/5] Save memo link revokes. --- db/item/db/main.go | 2 + db/item/memo/link_revoke.go | 51 +++++++++++++++++++++++ db/item/memo/link_revoked.go | 43 +++++++++++++++++++ db/item/memo/main.go | 2 + node/obj/op_return/main.go | 1 + node/obj/op_return/memo_link_revoke.go | 57 ++++++++++++++++++++++++++ 6 files changed, 156 insertions(+) create mode 100644 db/item/memo/link_revoke.go create mode 100644 db/item/memo/link_revoked.go create mode 100644 node/obj/op_return/memo_link_revoke.go diff --git a/db/item/db/main.go b/db/item/db/main.go index 39e37e8a..c694acd0 100644 --- a/db/item/db/main.go +++ b/db/item/db/main.go @@ -46,6 +46,8 @@ const ( TopicMemoLinkAccept = "memo_link_accept" TopicMemoLinkAccepted = "memo_link_accepted" TopicMemoLinkRequest = "memo_link_request" + TopicMemoLinkRevoke = "memo_link_revoke" + TopicMemoLinkRevoked = "memo_link_revoked" TopicChainBlock = "chain_block" TopicChainBlockHeight = "chain_block_height" diff --git a/db/item/memo/link_revoke.go b/db/item/memo/link_revoke.go new file mode 100644 index 00000000..5d716ce3 --- /dev/null +++ b/db/item/memo/link_revoke.go @@ -0,0 +1,51 @@ +package memo + +import ( + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/client" + "github.com/memocash/index/db/item/db" + "github.com/memocash/index/ref/bitcoin/memo" +) + +type LinkRevoke struct { + TxHash [32]byte + Addr [25]byte + AcceptTxHash [32]byte + Message string +} + +func (r *LinkRevoke) GetTopic() string { + return db.TopicMemoLinkRevoke +} + +func (r *LinkRevoke) GetShardSource() uint { + return client.GenShardSource(r.TxHash[:]) +} + +func (r *LinkRevoke) GetUid() []byte { + return jutil.ByteReverse(r.TxHash[:]) +} + +func (r *LinkRevoke) SetUid(uid []byte) { + if len(uid) != memo.TxHashLength { + panic("invalid uid size for link revoke") + } + copy(r.TxHash[:], jutil.ByteReverse(uid)) +} + +func (r *LinkRevoke) Serialize() []byte { + return jutil.CombineBytes( + r.Addr[:], + jutil.ByteReverse(r.AcceptTxHash[:]), + []byte(r.Message), + ) +} + +func (r *LinkRevoke) Deserialize(data []byte) { + if len(data) < memo.AddressLength+memo.TxHashLength { + panic("invalid data size for link revoke") + } + copy(r.Addr[:], data[:25]) + copy(r.AcceptTxHash[:], jutil.ByteReverse(data[25:57])) + r.Message = string(data[57:]) +} diff --git a/db/item/memo/link_revoked.go b/db/item/memo/link_revoked.go new file mode 100644 index 00000000..3030215a --- /dev/null +++ b/db/item/memo/link_revoked.go @@ -0,0 +1,43 @@ +package memo + +import ( + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/client" + "github.com/memocash/index/db/item/db" + "github.com/memocash/index/ref/bitcoin/memo" +) + +type LinkRevoked struct { + AcceptTxHash [32]byte + TxHash [32]byte +} + +func (r *LinkRevoked) GetTopic() string { + return db.TopicMemoLinkRevoked +} + +func (r *LinkRevoked) GetShardSource() uint { + return client.GenShardSource(r.AcceptTxHash[:]) +} + +func (r *LinkRevoked) GetUid() []byte { + return jutil.ByteReverse(r.AcceptTxHash[:]) +} + +func (r *LinkRevoked) SetUid(uid []byte) { + if len(uid) != memo.TxHashLength { + panic("invalid uid size for link revoked") + } + copy(r.AcceptTxHash[:], jutil.ByteReverse(uid)) +} + +func (r *LinkRevoked) Serialize() []byte { + return jutil.ByteReverse(r.TxHash[:]) +} + +func (r *LinkRevoked) Deserialize(data []byte) { + if len(data) != memo.TxHashLength { + panic("invalid data size for link revoked") + } + copy(r.TxHash[:], jutil.ByteReverse(data)) +} diff --git a/db/item/memo/main.go b/db/item/memo/main.go index 7f2db49e..80b6d09c 100644 --- a/db/item/memo/main.go +++ b/db/item/memo/main.go @@ -25,5 +25,7 @@ func GetTopics() []db.Object { &AddrLinkRequested{}, &LinkAccept{}, &LinkAccepted{}, + &LinkRevoke{}, + &LinkRevoked{}, } } diff --git a/node/obj/op_return/main.go b/node/obj/op_return/main.go index 53539ab2..81bbbc6b 100644 --- a/node/obj/op_return/main.go +++ b/node/obj/op_return/main.go @@ -44,6 +44,7 @@ func GetHandlers() ([]*Handler, error) { memoRoomUnfollowHandler, memoLinkRequestHandler, memoLinkAcceptHandler, + memoLinkRevokeHandler, slpTokenHandler, } for _, opReturn := range handlers { diff --git a/node/obj/op_return/memo_link_revoke.go b/node/obj/op_return/memo_link_revoke.go new file mode 100644 index 00000000..7906effa --- /dev/null +++ b/node/obj/op_return/memo_link_revoke.go @@ -0,0 +1,57 @@ +package op_return + +import ( + "context" + "fmt" + "github.com/jchavannes/btcd/chaincfg/chainhash" + "github.com/jchavannes/jgo/jutil" + "github.com/memocash/index/db/item" + "github.com/memocash/index/db/item/db" + dbMemo "github.com/memocash/index/db/item/memo" + "github.com/memocash/index/ref/bitcoin/memo" + "github.com/memocash/index/ref/bitcoin/tx/parse" +) + +var memoLinkRevokeHandler = &Handler{ + prefix: memo.PrefixLinkRevoke, + handle: func(ctx context.Context, info parse.OpReturn) error { + if len(info.PushData) < 2 { + if err := item.LogProcessError(&item.ProcessError{ + TxHash: info.TxHash, + Error: fmt.Sprintf("invalid set link revoke, incorrect push data (%d)", len(info.PushData)), + }); err != nil { + return fmt.Errorf("error saving process error memo link revoke incorrect push data; %w", err) + } + return nil + } + if len(info.PushData[1]) != memo.TxHashLength { + if err := item.LogProcessError(&item.ProcessError{ + TxHash: info.TxHash, + Error: fmt.Sprintf("error link revoke accept tx hash incorrect length: %d", len(info.PushData[1])), + }); err != nil { + return fmt.Errorf("error saving process error memo link revoke accept tx hash; %w", err) + } + return nil + } + var acceptTxHash chainhash.Hash + copy(acceptTxHash[:], jutil.ByteReverse(info.PushData[1])) + var message string + if len(info.PushData) > 2 { + message = string(info.PushData[2]) + } + var linkRevoke = &dbMemo.LinkRevoke{ + TxHash: info.TxHash, + Addr: info.Addr, + AcceptTxHash: acceptTxHash, + Message: message, + } + var linkRevoked = &dbMemo.LinkRevoked{ + TxHash: info.TxHash, + AcceptTxHash: acceptTxHash, + } + if err := db.Save([]db.Object{linkRevoke, linkRevoked}); err != nil { + return fmt.Errorf("error saving db lock memo link revoke object; %w", err) + } + return nil + }, +} From d40136ec1a44f97a8b01738e8b07a0712cba6377 Mon Sep 17 00:00:00 2001 From: Jason Chavannes Date: Tue, 18 Jun 2024 09:55:22 -0700 Subject: [PATCH 4/5] Include links in GraphQL profiles. Initial attach links to profiles function. Get functions for new link request DB items. --- db/item/memo/addr_link_request.go | 31 ++ db/item/memo/addr_link_requested.go | 31 ++ db/item/memo/link_request.go | 29 ++ graph/attach/memo_profile.go | 103 ++++++ graph/generated/generated.go | 505 ++++++++++++++++++++++++++++ graph/model/models.go | 9 + graph/schema/profile.graphqls | 9 + 7 files changed, 717 insertions(+) diff --git a/db/item/memo/addr_link_request.go b/db/item/memo/addr_link_request.go index 7a91282d..6513395f 100644 --- a/db/item/memo/addr_link_request.go +++ b/db/item/memo/addr_link_request.go @@ -1,10 +1,13 @@ package memo import ( + "context" + "fmt" "github.com/jchavannes/jgo/jutil" "github.com/memocash/index/db/client" "github.com/memocash/index/db/item/db" "github.com/memocash/index/ref/bitcoin/memo" + "github.com/memocash/index/ref/config" "time" ) @@ -44,3 +47,31 @@ func (r *AddrLinkRequest) Serialize() []byte { } func (r *AddrLinkRequest) Deserialize([]byte) {} + +func GetAddrLinkRequests(ctx context.Context, addrs [][25]byte) ([]*AddrLinkRequest, error) { + var shardPrefixes = make(map[uint32][][]byte) + for i := range addrs { + shard := client.GenShardSource32(addrs[i][:]) + shardPrefixes[shard] = append(shardPrefixes[shard], addrs[i][:]) + } + shardConfigs := config.GetQueueShards() + var addrLinkRequests []*AddrLinkRequest + for shard, prefixes := range shardPrefixes { + shardConfig := config.GetShardConfig(shard, shardConfigs) + dbClient := client.NewClient(shardConfig.GetHost()) + if err := dbClient.GetWOpts(client.Opts{ + Topic: db.TopicMemoAddrLinkRequest, + Prefixes: prefixes, + Max: client.ExLargeLimit, + Context: ctx, + }); err != nil { + return nil, fmt.Errorf("error getting db addr memo link requests by prefix; %w", err) + } + for _, msg := range dbClient.Messages { + var addrLinkRequest = new(AddrLinkRequest) + db.Set(addrLinkRequest, msg) + addrLinkRequests = append(addrLinkRequests, addrLinkRequest) + } + } + return addrLinkRequests, nil +} diff --git a/db/item/memo/addr_link_requested.go b/db/item/memo/addr_link_requested.go index 19f6c5c5..46e97911 100644 --- a/db/item/memo/addr_link_requested.go +++ b/db/item/memo/addr_link_requested.go @@ -1,10 +1,13 @@ package memo import ( + "context" + "fmt" "github.com/jchavannes/jgo/jutil" "github.com/memocash/index/db/client" "github.com/memocash/index/db/item/db" "github.com/memocash/index/ref/bitcoin/memo" + "github.com/memocash/index/ref/config" "time" ) @@ -44,3 +47,31 @@ func (r *AddrLinkRequested) Serialize() []byte { } func (r *AddrLinkRequested) Deserialize([]byte) {} + +func GetAddrLinkRequesteds(ctx context.Context, addrs [][25]byte) ([]*AddrLinkRequested, error) { + var shardPrefixes = make(map[uint32][][]byte) + for i := range addrs { + shard := client.GenShardSource32(addrs[i][:]) + shardPrefixes[shard] = append(shardPrefixes[shard], addrs[i][:]) + } + shardConfigs := config.GetQueueShards() + var addrLinkRequesteds []*AddrLinkRequested + for shard, prefixes := range shardPrefixes { + shardConfig := config.GetShardConfig(shard, shardConfigs) + dbClient := client.NewClient(shardConfig.GetHost()) + if err := dbClient.GetWOpts(client.Opts{ + Topic: db.TopicMemoAddrLinkRequested, + Prefixes: prefixes, + Max: client.ExLargeLimit, + Context: ctx, + }); err != nil { + return nil, fmt.Errorf("error getting db addr memo link requesteds by prefix; %w", err) + } + for _, msg := range dbClient.Messages { + var addrLinkRequested = new(AddrLinkRequested) + db.Set(addrLinkRequested, msg) + addrLinkRequesteds = append(addrLinkRequesteds, addrLinkRequested) + } + } + return addrLinkRequesteds, nil +} diff --git a/db/item/memo/link_request.go b/db/item/memo/link_request.go index 062546f5..1d0d3504 100644 --- a/db/item/memo/link_request.go +++ b/db/item/memo/link_request.go @@ -1,10 +1,13 @@ package memo import ( + "context" + "fmt" "github.com/jchavannes/jgo/jutil" "github.com/memocash/index/db/client" "github.com/memocash/index/db/item/db" "github.com/memocash/index/ref/bitcoin/memo" + "github.com/memocash/index/ref/config" ) type LinkRequest struct { @@ -49,3 +52,29 @@ func (r *LinkRequest) Deserialize(data []byte) { copy(r.ParentAddr[:], data[25:50]) r.Message = string(data[50:]) } + +func GetLinkRequests(ctx context.Context, txHashes [][32]byte) ([]*LinkRequest, error) { + var shardUids = make(map[uint32][][]byte) + for i := range txHashes { + shard := db.GetShardIdFromByte32(txHashes[i][:]) + shardUids[shard] = append(shardUids[shard], jutil.ByteReverse(txHashes[i][:])) + } + var linkRequests []*LinkRequest + for shard, uids := range shardUids { + shardConfig := config.GetShardConfig(shard, config.GetQueueShards()) + dbClient := client.NewClient(shardConfig.GetHost()) + if err := dbClient.GetWOpts(client.Opts{ + Context: ctx, + Topic: db.TopicMemoLinkRequest, + Uids: uids, + }); err != nil { + return nil, fmt.Errorf("error getting client message memo link requests; %w", err) + } + for _, msg := range dbClient.Messages { + var linkRequest = new(LinkRequest) + db.Set(linkRequest, msg) + linkRequests = append(linkRequests, linkRequest) + } + } + return linkRequests, nil +} diff --git a/graph/attach/memo_profile.go b/graph/attach/memo_profile.go index b405e35f..344bf5c1 100644 --- a/graph/attach/memo_profile.go +++ b/graph/attach/memo_profile.go @@ -292,3 +292,106 @@ func (a *MemoProfile) AttachPics() { } } } + +func (a *MemoProfile) AttachLinks() { + defer a.Wait.Done() + if !a.HasField([]string{"links"}) { + return + } + var allAddresses [][25]byte + var allLinkRequests []*memo.LinkRequest + var checkAddresses = a.getAddresses() + for len(checkAddresses) > 0 { + addrLinkRequests, err := memo.GetAddrLinkRequests(a.Ctx, checkAddresses) + if err != nil { + a.AddError(fmt.Errorf("error getting addr link requests for profile attach; %w", err)) + return + } + addrLinkRequesteds, err := memo.GetAddrLinkRequesteds(a.Ctx, checkAddresses) + if err != nil { + a.AddError(fmt.Errorf("error getting addr link requesteds for profile attach; %w", err)) + return + } + var linkRequestTxHashes [][32]byte + for _, addrLinkRequest := range addrLinkRequests { + linkRequestTxHashes = append(linkRequestTxHashes, addrLinkRequest.TxHash) + } + for _, addrLinkRequested := range addrLinkRequesteds { + linkRequestTxHashes = append(linkRequestTxHashes, addrLinkRequested.TxHash) + } + linkRequests, err := memo.GetLinkRequests(a.Ctx, linkRequestTxHashes) + if err != nil { + a.AddError(fmt.Errorf("error getting link requests for profile attach; %w", err)) + return + } + for _, linkRequest := range linkRequests { + var found bool + for _, allLinkRequest := range allLinkRequests { + if linkRequest.TxHash == allLinkRequest.TxHash { + found = true + break + } + } + if !found { + allLinkRequests = append(allLinkRequests, linkRequest) + } + } + allAddresses = checkAddresses + checkAddresses = nil + for _, linkRequest := range linkRequests { + var childAddrFound, parentAddrFound bool + for _, addr := range allAddresses { + if linkRequest.ChildAddr == addr { + childAddrFound = true + } else if linkRequest.ParentAddr == addr { + parentAddrFound = true + } + } + if !childAddrFound { + checkAddresses = append(checkAddresses, linkRequest.ChildAddr) + } else if !parentAddrFound { + checkAddresses = append(checkAddresses, linkRequest.ParentAddr) + } + } + } + a.Mutex.Lock() + defer a.Mutex.Unlock() + for _, profile := range a.Profiles { + var foundLinkRequests []*memo.LinkRequest + for _, linkRequest := range allLinkRequests { + if linkRequest.ChildAddr == profile.Address || linkRequest.ParentAddr == profile.Address { + foundLinkRequests = append(foundLinkRequests, linkRequest) + } + } + for more := true; more; { + more = false + for _, linkRequest := range allLinkRequests { + var shouldBeIncluded, alreadyIncluded bool + for _, foundLinkRequest := range foundLinkRequests { + if foundLinkRequest.TxHash == linkRequest.TxHash { + alreadyIncluded = true + break + } + if linkRequest.ChildAddr == foundLinkRequest.ParentAddr || + linkRequest.ParentAddr == foundLinkRequest.ChildAddr { + shouldBeIncluded = true + } + } + if alreadyIncluded { + continue + } else if shouldBeIncluded { + foundLinkRequests = append(foundLinkRequests, linkRequest) + more = true + } + } + } + for _, linkRequest := range foundLinkRequests { + // TODO: Include Link Request Message + profile.Links = append(profile.Links, &model.Link{ + ChildLock: &model.Lock{Address: linkRequest.ChildAddr}, + ParentLock: &model.Lock{Address: linkRequest.ParentAddr}, + RequestTx: &model.Tx{Hash: linkRequest.TxHash}, + }) + } + } +} diff --git a/graph/generated/generated.go b/graph/generated/generated.go index 09d71ffb..e3ebf71d 100644 --- a/graph/generated/generated.go +++ b/graph/generated/generated.go @@ -76,6 +76,14 @@ type ComplexityRoot struct { TxHash func(childComplexity int) int } + Link struct { + AcceptTx func(childComplexity int) int + ChildLock func(childComplexity int) int + ParentLock func(childComplexity int) int + RequestTx func(childComplexity int) int + RevokeTx func(childComplexity int) int + } + Lock struct { Address func(childComplexity int) int Profile func(childComplexity int) int @@ -102,6 +110,7 @@ type ComplexityRoot struct { Address func(childComplexity int) int Followers func(childComplexity int, start *model.Date) int Following func(childComplexity int, start *model.Date) int + Links func(childComplexity int) int Lock func(childComplexity int) int Name func(childComplexity int) int Pic func(childComplexity int) int @@ -441,6 +450,41 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Like.TxHash(childComplexity), true + case "Link.accept_tx": + if e.complexity.Link.AcceptTx == nil { + break + } + + return e.complexity.Link.AcceptTx(childComplexity), true + + case "Link.child_lock": + if e.complexity.Link.ChildLock == nil { + break + } + + return e.complexity.Link.ChildLock(childComplexity), true + + case "Link.parent_lock": + if e.complexity.Link.ParentLock == nil { + break + } + + return e.complexity.Link.ParentLock(childComplexity), true + + case "Link.request_tx": + if e.complexity.Link.RequestTx == nil { + break + } + + return e.complexity.Link.RequestTx(childComplexity), true + + case "Link.revoke_tx": + if e.complexity.Link.RevokeTx == nil { + break + } + + return e.complexity.Link.RevokeTx(childComplexity), true + case "Lock.address": if e.complexity.Lock.Address == nil { break @@ -573,6 +617,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Profile.Following(childComplexity, args["start"].(*model.Date)), true + case "Profile.links": + if e.complexity.Profile.Links == nil { + break + } + + return e.complexity.Profile.Links(childComplexity), true + case "Profile.lock": if e.complexity.Profile.Lock == nil { break @@ -1486,6 +1537,7 @@ var sources = []*ast.Source{ `, BuiltIn: false}, {Name: "../schema/profile.graphqls", Input: `type Profile { lock: Lock! + links: [Link] address: Address! name: SetName profile: SetProfile @@ -1552,6 +1604,14 @@ type Like { post: Post tip: Int64 } + +type Link { + parent_lock: Lock! + child_lock: Lock! + request_tx: Tx! + accept_tx: Tx + revoke_tx: Tx +} `, BuiltIn: false}, {Name: "../schema/query.graphqls", Input: `type Query { tx(hash: Hash!): Tx @@ -3181,6 +3241,290 @@ func (ec *executionContext) fieldContext_Like_tip(ctx context.Context, field gra return fc, nil } +func (ec *executionContext) _Link_parent_lock(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_parent_lock(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ParentLock, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Lock) + fc.Result = res + return ec.marshalNLock2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Link_parent_lock(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Link", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "address": + return ec.fieldContext_Lock_address(ctx, field) + case "profile": + return ec.fieldContext_Lock_profile(ctx, field) + case "txs": + return ec.fieldContext_Lock_txs(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Lock", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Link_child_lock(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_child_lock(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ChildLock, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Lock) + fc.Result = res + return ec.marshalNLock2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Link_child_lock(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Link", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "address": + return ec.fieldContext_Lock_address(ctx, field) + case "profile": + return ec.fieldContext_Lock_profile(ctx, field) + case "txs": + return ec.fieldContext_Lock_txs(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Lock", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Link_request_tx(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_request_tx(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.RequestTx, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Tx) + fc.Result = res + return ec.marshalNTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Link_request_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Link", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hash": + return ec.fieldContext_Tx_hash(ctx, field) + case "raw": + return ec.fieldContext_Tx_raw(ctx, field) + case "inputs": + return ec.fieldContext_Tx_inputs(ctx, field) + case "outputs": + return ec.fieldContext_Tx_outputs(ctx, field) + case "blocks": + return ec.fieldContext_Tx_blocks(ctx, field) + case "seen": + return ec.fieldContext_Tx_seen(ctx, field) + case "version": + return ec.fieldContext_Tx_version(ctx, field) + case "locktime": + return ec.fieldContext_Tx_locktime(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Tx", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Link_accept_tx(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_accept_tx(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.AcceptTx, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Tx) + fc.Result = res + return ec.marshalOTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Link_accept_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Link", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hash": + return ec.fieldContext_Tx_hash(ctx, field) + case "raw": + return ec.fieldContext_Tx_raw(ctx, field) + case "inputs": + return ec.fieldContext_Tx_inputs(ctx, field) + case "outputs": + return ec.fieldContext_Tx_outputs(ctx, field) + case "blocks": + return ec.fieldContext_Tx_blocks(ctx, field) + case "seen": + return ec.fieldContext_Tx_seen(ctx, field) + case "version": + return ec.fieldContext_Tx_version(ctx, field) + case "locktime": + return ec.fieldContext_Tx_locktime(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Tx", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Link_revoke_tx(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_revoke_tx(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.RevokeTx, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.Tx) + fc.Result = res + return ec.marshalOTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Link_revoke_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Link", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "hash": + return ec.fieldContext_Tx_hash(ctx, field) + case "raw": + return ec.fieldContext_Tx_raw(ctx, field) + case "inputs": + return ec.fieldContext_Tx_inputs(ctx, field) + case "outputs": + return ec.fieldContext_Tx_outputs(ctx, field) + case "blocks": + return ec.fieldContext_Tx_blocks(ctx, field) + case "seen": + return ec.fieldContext_Tx_seen(ctx, field) + case "version": + return ec.fieldContext_Tx_version(ctx, field) + case "locktime": + return ec.fieldContext_Tx_locktime(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Tx", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _Lock_address(ctx context.Context, field graphql.CollectedField, obj *model.Lock) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Lock_address(ctx, field) if err != nil { @@ -3260,6 +3604,8 @@ func (ec *executionContext) fieldContext_Lock_profile(ctx context.Context, field switch field.Name { case "lock": return ec.fieldContext_Profile_lock(ctx, field) + case "links": + return ec.fieldContext_Profile_links(ctx, field) case "address": return ec.fieldContext_Profile_address(ctx, field) case "name": @@ -3934,6 +4280,59 @@ func (ec *executionContext) fieldContext_Profile_lock(ctx context.Context, field return fc, nil } +func (ec *executionContext) _Profile_links(ctx context.Context, field graphql.CollectedField, obj *model.Profile) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Profile_links(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Links, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*model.Link) + fc.Result = res + return ec.marshalOLink2ᚕᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLink(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Profile_links(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Profile", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "parent_lock": + return ec.fieldContext_Link_parent_lock(ctx, field) + case "child_lock": + return ec.fieldContext_Link_child_lock(ctx, field) + case "request_tx": + return ec.fieldContext_Link_request_tx(ctx, field) + case "accept_tx": + return ec.fieldContext_Link_accept_tx(ctx, field) + case "revoke_tx": + return ec.fieldContext_Link_revoke_tx(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Link", field.Name) + }, + } + return fc, nil +} + func (ec *executionContext) _Profile_address(ctx context.Context, field graphql.CollectedField, obj *model.Profile) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Profile_address(ctx, field) if err != nil { @@ -4904,6 +5303,8 @@ func (ec *executionContext) fieldContext_Query_profiles(ctx context.Context, fie switch field.Name { case "lock": return ec.fieldContext_Profile_lock(ctx, field) + case "links": + return ec.fieldContext_Profile_links(ctx, field) case "address": return ec.fieldContext_Profile_address(ctx, field) case "name": @@ -8009,6 +8410,8 @@ func (ec *executionContext) fieldContext_Subscription_profiles(ctx context.Conte switch field.Name { case "lock": return ec.fieldContext_Profile_lock(ctx, field) + case "links": + return ec.fieldContext_Profile_links(ctx, field) case "address": return ec.fieldContext_Profile_address(ctx, field) case "name": @@ -11675,6 +12078,56 @@ func (ec *executionContext) _Like(ctx context.Context, sel ast.SelectionSet, obj return out } +var linkImplementors = []string{"Link"} + +func (ec *executionContext) _Link(ctx context.Context, sel ast.SelectionSet, obj *model.Link) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, linkImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Link") + case "parent_lock": + + out.Values[i] = ec._Link_parent_lock(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "child_lock": + + out.Values[i] = ec._Link_child_lock(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "request_tx": + + out.Values[i] = ec._Link_request_tx(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "accept_tx": + + out.Values[i] = ec._Link_accept_tx(ctx, field, obj) + + case "revoke_tx": + + out.Values[i] = ec._Link_revoke_tx(ctx, field, obj) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var lockImplementors = []string{"Lock"} func (ec *executionContext) _Lock(ctx context.Context, sel ast.SelectionSet, obj *model.Lock) graphql.Marshaler { @@ -11836,6 +12289,10 @@ func (ec *executionContext) _Profile(ctx context.Context, sel ast.SelectionSet, if out.Values[i] == graphql.Null { invalids++ } + case "links": + + out.Values[i] = ec._Profile_links(ctx, field, obj) + case "address": out.Values[i] = ec._Profile_address(ctx, field, obj) @@ -14230,6 +14687,54 @@ func (ec *executionContext) marshalOLike2ᚕᚖgithubᚗcomᚋmemocashᚋindex return ret } +func (ec *executionContext) marshalOLink2ᚕᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLink(ctx context.Context, sel ast.SelectionSet, v []*model.Link) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOLink2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLink(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOLink2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLink(ctx context.Context, sel ast.SelectionSet, v *model.Link) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Link(ctx, sel, v) +} + func (ec *executionContext) marshalOLock2ᚕᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx context.Context, sel ast.SelectionSet, v []*model.Lock) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/graph/model/models.go b/graph/model/models.go index 45df655e..e85eb79a 100644 --- a/graph/model/models.go +++ b/graph/model/models.go @@ -60,6 +60,7 @@ type Block struct { type Profile struct { Address Address `json:"address"` + Links []*Link `json:"links"` Name *SetName `json:"name"` Profile *SetProfile `json:"profile"` Pic *SetPic `json:"pic"` @@ -70,6 +71,14 @@ type Profile struct { Rooms []*RoomFollow `json:"rooms"` } +type Link struct { + ParentLock *Lock `json:"parent_lock"` + ChildLock *Lock `json:"child_lock"` + RequestTx *Tx `json:"request_tx"` + AcceptTx *Tx `json:"accept_tx"` + RevokeTx *Tx `json:"revoke_tx"` +} + type Follow struct { TxHash Hash `json:"tx_hash"` Address Address `json:"address"` diff --git a/graph/schema/profile.graphqls b/graph/schema/profile.graphqls index 8851c73f..a53d101b 100644 --- a/graph/schema/profile.graphqls +++ b/graph/schema/profile.graphqls @@ -1,5 +1,6 @@ type Profile { lock: Lock! + links: [Link] address: Address! name: SetName profile: SetProfile @@ -66,3 +67,11 @@ type Like { post: Post tip: Int64 } + +type Link { + parent_lock: Lock! + child_lock: Lock! + request_tx: Tx! + accept_tx: Tx + revoke_tx: Tx +} From 663da808dbd849e028aa46dea6d5ddb5763f16f7 Mon Sep 17 00:00:00 2001 From: Jason Chavannes Date: Wed, 19 Jun 2024 16:06:23 -0700 Subject: [PATCH 5/5] Use individual link objects. --- graph/attach/memo_profile.go | 10 +- graph/generated/generated.go | 663 +++++++++++++++++++++++++++++----- graph/model/models.go | 25 +- graph/schema/profile.graphqls | 25 +- 4 files changed, 619 insertions(+), 104 deletions(-) diff --git a/graph/attach/memo_profile.go b/graph/attach/memo_profile.go index 344bf5c1..5fbafcc4 100644 --- a/graph/attach/memo_profile.go +++ b/graph/attach/memo_profile.go @@ -386,11 +386,13 @@ func (a *MemoProfile) AttachLinks() { } } for _, linkRequest := range foundLinkRequests { - // TODO: Include Link Request Message profile.Links = append(profile.Links, &model.Link{ - ChildLock: &model.Lock{Address: linkRequest.ChildAddr}, - ParentLock: &model.Lock{Address: linkRequest.ParentAddr}, - RequestTx: &model.Tx{Hash: linkRequest.TxHash}, + Request: &model.LinkRequest{ + Child: &model.Lock{Address: linkRequest.ChildAddr}, + Parent: &model.Lock{Address: linkRequest.ParentAddr}, + Message: linkRequest.Message, + Tx: &model.Tx{Hash: linkRequest.TxHash}, + }, }) } } diff --git a/graph/generated/generated.go b/graph/generated/generated.go index e3ebf71d..375987bc 100644 --- a/graph/generated/generated.go +++ b/graph/generated/generated.go @@ -77,11 +77,26 @@ type ComplexityRoot struct { } Link struct { - AcceptTx func(childComplexity int) int - ChildLock func(childComplexity int) int - ParentLock func(childComplexity int) int - RequestTx func(childComplexity int) int - RevokeTx func(childComplexity int) int + Accept func(childComplexity int) int + Request func(childComplexity int) int + Revoke func(childComplexity int) int + } + + LinkAccept struct { + Message func(childComplexity int) int + Tx func(childComplexity int) int + } + + LinkRequest struct { + Child func(childComplexity int) int + Message func(childComplexity int) int + Parent func(childComplexity int) int + Tx func(childComplexity int) int + } + + LinkRevoke struct { + Message func(childComplexity int) int + Tx func(childComplexity int) int } Lock struct { @@ -450,40 +465,82 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Like.TxHash(childComplexity), true - case "Link.accept_tx": - if e.complexity.Link.AcceptTx == nil { + case "Link.accept": + if e.complexity.Link.Accept == nil { + break + } + + return e.complexity.Link.Accept(childComplexity), true + + case "Link.request": + if e.complexity.Link.Request == nil { break } - return e.complexity.Link.AcceptTx(childComplexity), true + return e.complexity.Link.Request(childComplexity), true - case "Link.child_lock": - if e.complexity.Link.ChildLock == nil { + case "Link.revoke": + if e.complexity.Link.Revoke == nil { break } - return e.complexity.Link.ChildLock(childComplexity), true + return e.complexity.Link.Revoke(childComplexity), true - case "Link.parent_lock": - if e.complexity.Link.ParentLock == nil { + case "LinkAccept.message": + if e.complexity.LinkAccept.Message == nil { break } - return e.complexity.Link.ParentLock(childComplexity), true + return e.complexity.LinkAccept.Message(childComplexity), true - case "Link.request_tx": - if e.complexity.Link.RequestTx == nil { + case "LinkAccept.tx": + if e.complexity.LinkAccept.Tx == nil { break } - return e.complexity.Link.RequestTx(childComplexity), true + return e.complexity.LinkAccept.Tx(childComplexity), true - case "Link.revoke_tx": - if e.complexity.Link.RevokeTx == nil { + case "LinkRequest.child": + if e.complexity.LinkRequest.Child == nil { break } - return e.complexity.Link.RevokeTx(childComplexity), true + return e.complexity.LinkRequest.Child(childComplexity), true + + case "LinkRequest.message": + if e.complexity.LinkRequest.Message == nil { + break + } + + return e.complexity.LinkRequest.Message(childComplexity), true + + case "LinkRequest.parent": + if e.complexity.LinkRequest.Parent == nil { + break + } + + return e.complexity.LinkRequest.Parent(childComplexity), true + + case "LinkRequest.tx": + if e.complexity.LinkRequest.Tx == nil { + break + } + + return e.complexity.LinkRequest.Tx(childComplexity), true + + case "LinkRevoke.message": + if e.complexity.LinkRevoke.Message == nil { + break + } + + return e.complexity.LinkRevoke.Message(childComplexity), true + + case "LinkRevoke.tx": + if e.complexity.LinkRevoke.Tx == nil { + break + } + + return e.complexity.LinkRevoke.Tx(childComplexity), true case "Lock.address": if e.complexity.Lock.Address == nil { @@ -1606,11 +1663,26 @@ type Like { } type Link { - parent_lock: Lock! - child_lock: Lock! - request_tx: Tx! - accept_tx: Tx - revoke_tx: Tx + request: LinkRequest! + accept: LinkAccept + revoke: LinkRevoke +} + +type LinkRequest { + child: Lock! + parent: Lock! + message: String! + tx: Tx! +} + +type LinkAccept { + message: String! + tx: Tx! +} + +type LinkRevoke { + message: String! + tx: Tx! } `, BuiltIn: false}, {Name: "../schema/query.graphqls", Input: `type Query { @@ -3241,8 +3313,8 @@ func (ec *executionContext) fieldContext_Like_tip(ctx context.Context, field gra return fc, nil } -func (ec *executionContext) _Link_parent_lock(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Link_parent_lock(ctx, field) +func (ec *executionContext) _Link_request(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_request(ctx, field) if err != nil { return graphql.Null } @@ -3255,7 +3327,7 @@ func (ec *executionContext) _Link_parent_lock(ctx context.Context, field graphql }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ParentLock, nil + return obj.Request, nil }) if err != nil { ec.Error(ctx, err) @@ -3267,12 +3339,12 @@ func (ec *executionContext) _Link_parent_lock(ctx context.Context, field graphql } return graphql.Null } - res := resTmp.(*model.Lock) + res := resTmp.(*model.LinkRequest) fc.Result = res - return ec.marshalNLock2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx, field.Selections, res) + return ec.marshalNLinkRequest2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLinkRequest(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Link_parent_lock(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Link_request(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Link", Field: field, @@ -3280,21 +3352,23 @@ func (ec *executionContext) fieldContext_Link_parent_lock(ctx context.Context, f IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "address": - return ec.fieldContext_Lock_address(ctx, field) - case "profile": - return ec.fieldContext_Lock_profile(ctx, field) - case "txs": - return ec.fieldContext_Lock_txs(ctx, field) + case "child": + return ec.fieldContext_LinkRequest_child(ctx, field) + case "parent": + return ec.fieldContext_LinkRequest_parent(ctx, field) + case "message": + return ec.fieldContext_LinkRequest_message(ctx, field) + case "tx": + return ec.fieldContext_LinkRequest_tx(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type Lock", field.Name) + return nil, fmt.Errorf("no field named %q was found under type LinkRequest", field.Name) }, } return fc, nil } -func (ec *executionContext) _Link_child_lock(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Link_child_lock(ctx, field) +func (ec *executionContext) _Link_accept(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_accept(ctx, field) if err != nil { return graphql.Null } @@ -3307,24 +3381,68 @@ func (ec *executionContext) _Link_child_lock(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ChildLock, nil + return obj.Accept, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + return graphql.Null + } + res := resTmp.(*model.LinkAccept) + fc.Result = res + return ec.marshalOLinkAccept2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLinkAccept(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Link_accept(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Link", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "message": + return ec.fieldContext_LinkAccept_message(ctx, field) + case "tx": + return ec.fieldContext_LinkAccept_tx(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type LinkAccept", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Link_revoke(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Link_revoke(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Revoke, nil + }) + if err != nil { + ec.Error(ctx, err) return graphql.Null } - res := resTmp.(*model.Lock) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*model.LinkRevoke) fc.Result = res - return ec.marshalNLock2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx, field.Selections, res) + return ec.marshalOLinkRevoke2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLinkRevoke(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Link_child_lock(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Link_revoke(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Link", Field: field, @@ -3332,21 +3450,19 @@ func (ec *executionContext) fieldContext_Link_child_lock(ctx context.Context, fi IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "address": - return ec.fieldContext_Lock_address(ctx, field) - case "profile": - return ec.fieldContext_Lock_profile(ctx, field) - case "txs": - return ec.fieldContext_Lock_txs(ctx, field) + case "message": + return ec.fieldContext_LinkRevoke_message(ctx, field) + case "tx": + return ec.fieldContext_LinkRevoke_tx(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type Lock", field.Name) + return nil, fmt.Errorf("no field named %q was found under type LinkRevoke", field.Name) }, } return fc, nil } -func (ec *executionContext) _Link_request_tx(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Link_request_tx(ctx, field) +func (ec *executionContext) _LinkAccept_message(ctx context.Context, field graphql.CollectedField, obj *model.LinkAccept) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkAccept_message(ctx, field) if err != nil { return graphql.Null } @@ -3359,7 +3475,51 @@ func (ec *executionContext) _Link_request_tx(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.RequestTx, nil + return obj.Message, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_LinkAccept_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "LinkAccept", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _LinkAccept_tx(ctx context.Context, field graphql.CollectedField, obj *model.LinkAccept) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkAccept_tx(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Tx, nil }) if err != nil { ec.Error(ctx, err) @@ -3376,9 +3536,9 @@ func (ec *executionContext) _Link_request_tx(ctx context.Context, field graphql. return ec.marshalNTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Link_request_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_LinkAccept_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Link", + Object: "LinkAccept", Field: field, IsMethod: false, IsResolver: false, @@ -3407,8 +3567,60 @@ func (ec *executionContext) fieldContext_Link_request_tx(ctx context.Context, fi return fc, nil } -func (ec *executionContext) _Link_accept_tx(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Link_accept_tx(ctx, field) +func (ec *executionContext) _LinkRequest_child(ctx context.Context, field graphql.CollectedField, obj *model.LinkRequest) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkRequest_child(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Child, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Lock) + fc.Result = res + return ec.marshalNLock2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_LinkRequest_child(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "LinkRequest", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "address": + return ec.fieldContext_Lock_address(ctx, field) + case "profile": + return ec.fieldContext_Lock_profile(ctx, field) + case "txs": + return ec.fieldContext_Lock_txs(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Lock", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _LinkRequest_parent(ctx context.Context, field graphql.CollectedField, obj *model.LinkRequest) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkRequest_parent(ctx, field) if err != nil { return graphql.Null } @@ -3421,23 +3633,122 @@ func (ec *executionContext) _Link_accept_tx(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.AcceptTx, nil + return obj.Parent, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Lock) + fc.Result = res + return ec.marshalNLock2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_LinkRequest_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "LinkRequest", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "address": + return ec.fieldContext_Lock_address(ctx, field) + case "profile": + return ec.fieldContext_Lock_profile(ctx, field) + case "txs": + return ec.fieldContext_Lock_txs(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Lock", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _LinkRequest_message(ctx context.Context, field graphql.CollectedField, obj *model.LinkRequest) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkRequest_message(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Message, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_LinkRequest_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "LinkRequest", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _LinkRequest_tx(ctx context.Context, field graphql.CollectedField, obj *model.LinkRequest) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkRequest_tx(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Tx, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } res := resTmp.(*model.Tx) fc.Result = res - return ec.marshalOTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) + return ec.marshalNTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Link_accept_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_LinkRequest_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Link", + Object: "LinkRequest", Field: field, IsMethod: false, IsResolver: false, @@ -3466,8 +3777,52 @@ func (ec *executionContext) fieldContext_Link_accept_tx(ctx context.Context, fie return fc, nil } -func (ec *executionContext) _Link_revoke_tx(ctx context.Context, field graphql.CollectedField, obj *model.Link) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Link_revoke_tx(ctx, field) +func (ec *executionContext) _LinkRevoke_message(ctx context.Context, field graphql.CollectedField, obj *model.LinkRevoke) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkRevoke_message(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Message, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_LinkRevoke_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "LinkRevoke", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _LinkRevoke_tx(ctx context.Context, field graphql.CollectedField, obj *model.LinkRevoke) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_LinkRevoke_tx(ctx, field) if err != nil { return graphql.Null } @@ -3480,23 +3835,26 @@ func (ec *executionContext) _Link_revoke_tx(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.RevokeTx, nil + return obj.Tx, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } res := resTmp.(*model.Tx) fc.Result = res - return ec.marshalOTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) + return ec.marshalNTx2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐTx(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Link_revoke_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_LinkRevoke_tx(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Link", + Object: "LinkRevoke", Field: field, IsMethod: false, IsResolver: false, @@ -4316,16 +4674,12 @@ func (ec *executionContext) fieldContext_Profile_links(ctx context.Context, fiel IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "parent_lock": - return ec.fieldContext_Link_parent_lock(ctx, field) - case "child_lock": - return ec.fieldContext_Link_child_lock(ctx, field) - case "request_tx": - return ec.fieldContext_Link_request_tx(ctx, field) - case "accept_tx": - return ec.fieldContext_Link_accept_tx(ctx, field) - case "revoke_tx": - return ec.fieldContext_Link_revoke_tx(ctx, field) + case "request": + return ec.fieldContext_Link_request(ctx, field) + case "accept": + return ec.fieldContext_Link_accept(ctx, field) + case "revoke": + return ec.fieldContext_Link_revoke(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Link", field.Name) }, @@ -12088,35 +12442,140 @@ func (ec *executionContext) _Link(ctx context.Context, sel ast.SelectionSet, obj switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Link") - case "parent_lock": + case "request": + + out.Values[i] = ec._Link_request(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "accept": + + out.Values[i] = ec._Link_accept(ctx, field, obj) + + case "revoke": + + out.Values[i] = ec._Link_revoke(ctx, field, obj) + + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var linkAcceptImplementors = []string{"LinkAccept"} + +func (ec *executionContext) _LinkAccept(ctx context.Context, sel ast.SelectionSet, obj *model.LinkAccept) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, linkAcceptImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("LinkAccept") + case "message": + + out.Values[i] = ec._LinkAccept_message(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "tx": + + out.Values[i] = ec._LinkAccept_tx(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var linkRequestImplementors = []string{"LinkRequest"} + +func (ec *executionContext) _LinkRequest(ctx context.Context, sel ast.SelectionSet, obj *model.LinkRequest) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, linkRequestImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("LinkRequest") + case "child": + + out.Values[i] = ec._LinkRequest_child(ctx, field, obj) + + if out.Values[i] == graphql.Null { + invalids++ + } + case "parent": - out.Values[i] = ec._Link_parent_lock(ctx, field, obj) + out.Values[i] = ec._LinkRequest_parent(ctx, field, obj) if out.Values[i] == graphql.Null { invalids++ } - case "child_lock": + case "message": - out.Values[i] = ec._Link_child_lock(ctx, field, obj) + out.Values[i] = ec._LinkRequest_message(ctx, field, obj) if out.Values[i] == graphql.Null { invalids++ } - case "request_tx": + case "tx": - out.Values[i] = ec._Link_request_tx(ctx, field, obj) + out.Values[i] = ec._LinkRequest_tx(ctx, field, obj) if out.Values[i] == graphql.Null { invalids++ } - case "accept_tx": + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + +var linkRevokeImplementors = []string{"LinkRevoke"} + +func (ec *executionContext) _LinkRevoke(ctx context.Context, sel ast.SelectionSet, obj *model.LinkRevoke) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, linkRevokeImplementors) + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("LinkRevoke") + case "message": - out.Values[i] = ec._Link_accept_tx(ctx, field, obj) + out.Values[i] = ec._LinkRevoke_message(ctx, field, obj) - case "revoke_tx": + if out.Values[i] == graphql.Null { + invalids++ + } + case "tx": - out.Values[i] = ec._Link_revoke_tx(ctx, field, obj) + out.Values[i] = ec._LinkRevoke_tx(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -13843,6 +14302,16 @@ func (ec *executionContext) marshalNLike2ᚖgithubᚗcomᚋmemocashᚋindexᚋgr return ec._Like(ctx, sel, v) } +func (ec *executionContext) marshalNLinkRequest2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLinkRequest(ctx context.Context, sel ast.SelectionSet, v *model.LinkRequest) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._LinkRequest(ctx, sel, v) +} + func (ec *executionContext) marshalNLock2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx context.Context, sel ast.SelectionSet, v *model.Lock) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -14735,6 +15204,20 @@ func (ec *executionContext) marshalOLink2ᚖgithubᚗcomᚋmemocashᚋindexᚋgr return ec._Link(ctx, sel, v) } +func (ec *executionContext) marshalOLinkAccept2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLinkAccept(ctx context.Context, sel ast.SelectionSet, v *model.LinkAccept) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._LinkAccept(ctx, sel, v) +} + +func (ec *executionContext) marshalOLinkRevoke2ᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLinkRevoke(ctx context.Context, sel ast.SelectionSet, v *model.LinkRevoke) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._LinkRevoke(ctx, sel, v) +} + func (ec *executionContext) marshalOLock2ᚕᚖgithubᚗcomᚋmemocashᚋindexᚋgraphᚋmodelᚐLock(ctx context.Context, sel ast.SelectionSet, v []*model.Lock) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/graph/model/models.go b/graph/model/models.go index e85eb79a..6deffaf8 100644 --- a/graph/model/models.go +++ b/graph/model/models.go @@ -72,11 +72,26 @@ type Profile struct { } type Link struct { - ParentLock *Lock `json:"parent_lock"` - ChildLock *Lock `json:"child_lock"` - RequestTx *Tx `json:"request_tx"` - AcceptTx *Tx `json:"accept_tx"` - RevokeTx *Tx `json:"revoke_tx"` + Request *LinkRequest `json:"request"` + Accept *LinkAccept `json:"accept"` + Revoke *LinkRevoke `json:"revoke"` +} + +type LinkRequest struct { + Child *Lock `json:"child"` + Parent *Lock `json:"parent"` + Message string `json:"message"` + Tx *Tx `json:"tx"` +} + +type LinkRevoke struct { + Message string `json:"message"` + Tx *Tx `json:"tx"` +} + +type LinkAccept struct { + Message string `json:"message"` + Tx *Tx `json:"tx"` } type Follow struct { diff --git a/graph/schema/profile.graphqls b/graph/schema/profile.graphqls index a53d101b..24201b7d 100644 --- a/graph/schema/profile.graphqls +++ b/graph/schema/profile.graphqls @@ -69,9 +69,24 @@ type Like { } type Link { - parent_lock: Lock! - child_lock: Lock! - request_tx: Tx! - accept_tx: Tx - revoke_tx: Tx + request: LinkRequest! + accept: LinkAccept + revoke: LinkRevoke +} + +type LinkRequest { + child: Lock! + parent: Lock! + message: String! + tx: Tx! +} + +type LinkAccept { + message: String! + tx: Tx! +} + +type LinkRevoke { + message: String! + tx: Tx! }