11package main
22
33import (
4- "bytes"
54 "context"
65 "encoding/json"
76 "fmt"
8- "net/http"
97 "os"
8+ "strconv"
109 "strings"
1110
12- clientTx "github.com/cosmos/cosmos-sdk/client/tx"
13- "github.com/cosmos/cosmos-sdk/codec"
14- "github.com/cosmos/cosmos-sdk/codec/types"
11+ "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
1512 "github.com/cosmos/cosmos-sdk/crypto/hd"
16- cosmoscryptoed "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
17- cosmoscryptosecp "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
18- cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
1913 sdk "github.com/cosmos/cosmos-sdk/types"
20- "github.com/cosmos/cosmos-sdk/types/tx"
21- "github.com/cosmos/cosmos-sdk/types/tx/signing"
22- xauthsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
23- authTx "github.com/cosmos/cosmos-sdk/x/auth/tx"
24- authType "github.com/cosmos/cosmos-sdk/x/auth/types"
2514 core "github.com/gitopia/git-remote-gitopia/core"
2615 gitopiaTypes "github.com/gitopia/gitopia/x/gitopia/types"
2716 "github.com/gitopia/gitopia/x/gitopia/utils"
@@ -34,11 +23,10 @@ import (
3423)
3524
3625const (
37- chainID = "internal-4"
3826 AccountAddressPrefix = "gitopia"
39- apiURL = "34.87.90.147 :9090"
40- objectsURL = "http://34.126.69.254 :5000"
41- saveToArweaveURL = "http://34.126.69.254 :5000/save"
27+ apiURL = "34.126.183.252 :9090"
28+ objectsURL = "http://34.87.64.22 :5000"
29+ saveToArweaveURL = "http://34.87.64.22 :5000/save"
4230 branchPrefix = "refs/heads/"
4331 tagPrefix = "refs/tags/"
4432)
@@ -70,10 +58,10 @@ type SaveToArweavePostBody struct {
7058}
7159
7260type GitopiaHandler struct {
73- queryClient gitopiaTypes.QueryClient
74- accountQueryClient authType.QueryClient
75- txClient tx.ServiceClient
61+ grpcConn * grpc.ClientConn
62+ queryClient gitopiaTypes.QueryClient
7663
64+ chainId string
7765 remoteUserId string
7866 remoteRepositoryName string
7967 remoteRepository gitopiaTypes.Repository
@@ -82,29 +70,41 @@ type GitopiaHandler struct {
8270}
8371
8472func (h * GitopiaHandler ) Initialize (remote * core.Remote ) error {
85- grpcConn , err := grpc .Dial (apiURL ,
73+ var err error
74+
75+ h .grpcConn , err = grpc .Dial (apiURL ,
8676 grpc .WithInsecure (),
8777 )
8878 if err != nil {
8979 return err
9080 }
9181 // defer grpcConn.Close()
9282
93- h .queryClient = gitopiaTypes .NewQueryClient (grpcConn )
94- h .accountQueryClient = authType .NewQueryClient (grpcConn )
95- h .txClient = tx .NewServiceClient (grpcConn )
83+ h .queryClient = gitopiaTypes .NewQueryClient (h .grpcConn )
84+ serviceClient := tmservice .NewServiceClient (h .grpcConn )
85+
86+ // Get chain id for signing transaction
87+ nodeInfoRes , err := serviceClient .GetNodeInfo (context .Background (), & tmservice.GetNodeInfoRequest {})
88+ if err != nil {
89+ return err
90+ }
91+ h .chainId = nodeInfoRes .DefaultNodeInfo .Network
9692
9793 // Get RepositoryId
9894 res , err := h .queryClient .AddressRepository (context .Background (), & gitopiaTypes.QueryGetAddressRepositoryRequest {
9995 Id : h .remoteUserId ,
10096 RepositoryName : h .remoteRepositoryName ,
10197 })
10298 if err != nil {
103- return fmt . Errorf ( "fatal: repository 'gitopia://%s/%s' not found. Please create it from the gitopia webapp" , h . remoteUserId , h . remoteRepositoryName )
99+ return err
104100 }
105101
106102 h .remoteRepository = * res .Repository
107103
104+ config := sdk .GetConfig ()
105+ config .SetBech32PrefixForAccount (AccountAddressPrefix , AccountPubKeyPrefix )
106+ config .Seal ()
107+
108108 return nil
109109}
110110
@@ -164,18 +164,8 @@ func (h *GitopiaHandler) Fetch(remote *core.Remote, sha, ref string) error {
164164
165165func (h * GitopiaHandler ) Push (remote * core.Remote , local string , remoteRef string ) (string , error ) {
166166 h .didPush = true
167- remoteURL := fmt .Sprintf ("%v/%v.git" , objectsURL , h .remoteRepository .Id )
168- remoteConfig := & goGitConfig.RemoteConfig {
169- Name : "gitopia-objects-store" ,
170- URLs : []string {remoteURL },
171- }
172-
173- _ , err := remote .Repo .CreateRemote (remoteConfig )
174- if err != nil {
175- return "" , err
176- }
177- defer remote .Repo .DeleteRemote ("gitopia-objects-store" )
178167
168+ // Read wallet file
179169 gitopiaWalletPath := os .Getenv ("GITOPIA_WALLET" )
180170 if gitopiaWalletPath == "" {
181171 return "" , fmt .Errorf ("fatal: GITOPIA_WALLET environment variable is not set" )
@@ -192,17 +182,14 @@ func (h *GitopiaHandler) Push(remote *core.Remote, local string, remoteRef strin
192182 return "" , fmt .Errorf ("fatal: error decoding wallet file" )
193183 }
194184
195- derivedPriv , err := hd .Secp256k1 .Derive ()(gitopiaWallet .Mnemonic , "" , gitopiaWallet .HDpath )
185+ // Generate private key
186+ hdPath := gitopiaWallet .HDpath + strconv .Itoa (gitopiaWallet .PathIncrement )
187+ derivedPriv , err := hd .Secp256k1 .Derive ()(gitopiaWallet .Mnemonic , "" , hdPath )
196188 if err != nil {
197189 return "" , err
198190 }
199191
200192 privKey := hd .Secp256k1 .Generate ()(derivedPriv )
201-
202- config := sdk .GetConfig ()
203- config .SetBech32PrefixForAccount (AccountAddressPrefix , AccountPubKeyPrefix )
204- config .Seal ()
205-
206193 walletAddress := sdk .AccAddress (privKey .PubKey ().Address ())
207194
208195 havePushPermission , err := h .havePushPermission (walletAddress .String ())
@@ -213,36 +200,65 @@ func (h *GitopiaHandler) Push(remote *core.Remote, local string, remoteRef strin
213200 return "" , fmt .Errorf ("fatal: you don't have write permissions to this repository" )
214201 }
215202
203+ var msg sdk.Msg
204+
205+ // Delete branch/tag
206+ if local == "" {
207+ if strings .HasPrefix (remoteRef , branchPrefix ) {
208+ remoteBranchName := strings .TrimPrefix (remoteRef , branchPrefix )
209+
210+ // Check if it's the default branch
211+ if remoteBranchName == h .remoteRepository .DefaultBranch {
212+ return "" , fmt .Errorf ("fatal: cannot delete default branch, %v" , remoteBranchName )
213+ }
214+
215+ msg = gitopiaTypes .NewMsgDeleteBranch (walletAddress .String (), h .remoteRepository .Id , remoteBranchName )
216+ } else if strings .HasPrefix (remoteRef , tagPrefix ) {
217+ remoteTagName := strings .TrimPrefix (remoteRef , tagPrefix )
218+ msg = gitopiaTypes .NewMsgDeleteTag (walletAddress .String (), h .remoteRepository .Id , remoteTagName )
219+ }
220+
221+ err := signAndBroadcastTx (h .grpcConn , walletAddress .String (), h .chainId , privKey , msg )
222+ if err != nil {
223+ return "" , err
224+ }
225+
226+ return local , nil
227+ }
228+
229+ remoteURL := fmt .Sprintf ("%v/%v.git" , objectsURL , h .remoteRepository .Id )
230+ remoteConfig := & goGitConfig.RemoteConfig {
231+ Name : "gitopia-objects-store" ,
232+ URLs : []string {remoteURL },
233+ }
234+
235+ _ , err = remote .Repo .CreateRemote (remoteConfig )
236+ if err != nil {
237+ return "" , err
238+ }
239+ defer remote .Repo .DeleteRemote ("gitopia-objects-store" )
240+
241+ force := false
242+ if strings .HasPrefix (local , "+" ) {
243+ local = strings .TrimPrefix (local , "+" )
244+ force = true
245+ }
246+
216247 pushOptions := & git.PushOptions {
217248 RemoteName : "gitopia-objects-store" ,
218249 RefSpecs : []goGitConfig.RefSpec {goGitConfig .RefSpec (fmt .Sprintf ("%s:%s" , local , remoteRef ))},
219250 Progress : os .Stdout ,
251+ Force : force ,
220252 }
221253
222254 err = remote .Repo .Push (pushOptions )
223255 if err != nil && err != git .NoErrAlreadyUpToDate {
224256 return "" , fmt .Errorf ("fatal: error pushing the git objects, %v" , err .Error ())
225257 }
226258
227- // Update ref on gitopia
228- interfaceRegistry := types .NewInterfaceRegistry ()
229- interfaceRegistry .RegisterInterface (
230- "cosmos.auth.v1beta1.AccountI" ,
231- (* authType .AccountI )(nil ),
232- & authType.BaseAccount {},
233- & authType.ModuleAccount {},
234- )
235- interfaceRegistry .RegisterInterface ("cosmos.crypto.PubKey" , (* cryptotypes .PubKey )(nil ))
236- interfaceRegistry .RegisterImplementations ((* cryptotypes .PubKey )(nil ), & cosmoscryptosecp.PubKey {})
237- interfaceRegistry .RegisterImplementations ((* cryptotypes .PubKey )(nil ), & cosmoscryptoed.PubKey {})
238- marshaler := codec .NewProtoCodec (interfaceRegistry )
239- txCfg := authTx .NewTxConfig (marshaler , authTx .DefaultSignModes )
240-
241- txBuilder := txCfg .NewTxBuilder ()
242-
243259 var newRemoteRefSha , prevRemoteRefSha string
244- var msg sdk.Msg
245260
261+ // Update ref on gitopia
246262 if strings .HasPrefix (local , branchPrefix ) {
247263 localCommitHash , err := remote .Repo .ResolveRevision (plumbing .Revision (local ))
248264 if err != nil {
@@ -282,98 +298,35 @@ func (h *GitopiaHandler) Push(remote *core.Remote, local string, remoteRef strin
282298 return "" , fmt .Errorf ("fatal: not a valid branch/tag, %v" , local )
283299 }
284300
285- txBuilder .SetMsgs (msg )
286- txBuilder .SetGasLimit (200000 )
287-
288- res , err := h .accountQueryClient .Account (context .Background (),
289- & authType.QueryAccountRequest {
290- Address : walletAddress .String (),
291- },
292- )
293- var acc authType.AccountI
294- if err := interfaceRegistry .UnpackAny (res .Account , & acc ); err != nil {
295- return "" , err
296- }
297-
298- sigV2 := signing.SignatureV2 {
299- PubKey : privKey .PubKey (),
300- Data : & signing.SingleSignatureData {
301- SignMode : txCfg .SignModeHandler ().DefaultMode (),
302- Signature : nil ,
303- },
304- Sequence : acc .GetSequence (),
305- }
306- err = txBuilder .SetSignatures (sigV2 )
307- if err != nil {
308- return "" , err
309- }
310-
311- signerData := xauthsigning.SignerData {
312- ChainID : chainID ,
313- AccountNumber : acc .GetAccountNumber (),
314- Sequence : acc .GetSequence (),
315- }
316-
317- sigV2 , err = clientTx .SignWithPrivKey (txCfg .SignModeHandler ().DefaultMode (), signerData ,
318- txBuilder , privKey , txCfg , acc .GetSequence ())
319- if err != nil {
320- return "" , err
321- }
322-
323- err = txBuilder .SetSignatures (sigV2 )
301+ err = signAndBroadcastTx (h .grpcConn , walletAddress .String (), h .chainId , privKey , msg )
324302 if err != nil {
325303 return "" , err
326304 }
327305
328- err = txBuilder .GetTx ().ValidateBasic ()
329- if err != nil {
330- fmt .Fprintf (os .Stderr , "fatal: tx validation failed: %v" , err .Error ())
331- }
332-
333- var txBytes []byte
334- txBytes , err = txCfg .TxEncoder ()(txBuilder .GetTx ())
335- if err != nil {
336- return "" , err
337- }
338-
339- var grpcRes * tx.BroadcastTxResponse
340- grpcRes , err = h .txClient .BroadcastTx (
341- context .Background (),
342- & tx.BroadcastTxRequest {
343- Mode : tx .BroadcastMode_BROADCAST_MODE_SYNC ,
344- TxBytes : txBytes ,
345- },
346- )
347- if err != nil {
348- return "" , err
349- }
350-
351- if grpcRes .TxResponse .Code != 0 {
352- return "" , fmt .Errorf ("fatal: failed to broadcast transaction, code: %v" , grpcRes .TxResponse .Code )
353- }
306+ _ = prevRemoteRefSha
354307
355308 // Queue task to upload objects to arweave
356- saveToArweavePostBody := SaveToArweavePostBody {
357- RepositoryID : h .remoteRepository .Id ,
358- RemoteRefName : remoteRef ,
359- NewRemoteRefSha : newRemoteRefSha ,
360- PrevRemoteRefSha : prevRemoteRefSha ,
361- }
362-
363- postBody , err := json .Marshal (saveToArweavePostBody )
364- if err != nil {
365- return "" , fmt .Errorf ("fatal: failed to serialize post data: %v" , err .Error ())
366- }
367- responseBody := bytes .NewBuffer (postBody )
368- resp , err := http .Post (saveToArweaveURL , "application/json" , responseBody )
369- if err != nil {
370- return "" , fmt .Errorf ("fatal: error posting saveToArweave: %v" , err .Error ())
371- }
372- defer resp .Body .Close ()
373-
374- if resp .StatusCode != http .StatusOK {
375- return "" , fmt .Errorf ("fatal: error saving to Arweave" )
376- }
309+ // saveToArweavePostBody := SaveToArweavePostBody{
310+ // RepositoryID: h.remoteRepository.Id,
311+ // RemoteRefName: remoteRef,
312+ // NewRemoteRefSha: newRemoteRefSha,
313+ // PrevRemoteRefSha: prevRemoteRefSha,
314+ // }
315+
316+ // postBody, err := json.Marshal(saveToArweavePostBody)
317+ // if err != nil {
318+ // return "", fmt.Errorf("fatal: failed to serialize post data: %v", err.Error())
319+ // }
320+ // responseBody := bytes.NewBuffer(postBody)
321+ // resp, err := http.Post(saveToArweaveURL, "application/json", responseBody)
322+ // if err != nil {
323+ // return "", fmt.Errorf("fatal: error posting saveToArweave: %v", err.Error())
324+ // }
325+ // defer resp.Body.Close()
326+
327+ // if resp.StatusCode != http.StatusOK {
328+ // return "", fmt.Errorf("fatal: error saving to Arweave")
329+ // }
377330
378331 return local , nil
379332}
0 commit comments