package repo import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/blockchain" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "encoding/json" "net/http" "strconv" ) type BlockChainInitNotify struct { RepoId int64 `json:"repoId"` ContractAddress string `json:"contractAddress"` } type BlockChainCommitNotify struct { CommitID string `json:"commitId"` TransactionHash string `json:"txHash"` } const ( tplBlockChainIndex base.TplName = "repo/blockchain/index" ) // MustEnableDataset check if repository enable internal cb func MustEnableBlockChain(ctx *context.Context) { if !ctx.Repo.CanRead(models.UnitTypeBlockChain) { ctx.NotFound("MustEnableBlockChain", nil) return } } func BlockChainIndex(ctx *context.Context) { //MustEnableBlockChain(ctx) repo := ctx.Repo.Repository if repo.ContractAddress == "" || ctx.User.PublicKey == ""{ log.Error("the repo(%d) or the user(%d) has not been initialized in block_chain", repo.RepoID, ctx.User.ID) ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex) return } res, err := blockchain.GetBalance(repo.ContractAddress, ctx.User.PublicKey) if err != nil { log.Error("GetBalance(%s) failed:%v", ctx.User.PublicKey, err) ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex) return } ctx.Data["balance"] = res.Data ctx.HTML(200, tplBlockChainIndex) } func HandleBlockChainInitNotify(ctx *context.Context) { var req BlockChainInitNotify data, _ := ctx.Req.Body().Bytes() json.Unmarshal(data, &req) repo, err := models.GetRepositoryByID(req.RepoId) if err != nil { log.Error("GetRepositoryByID failed:", err.Error()) ctx.JSON(200, map[string]string{ "code": "-1", "message": "internal error", }) return } if repo.BlockChainStatus == models.RepoBlockChainSuccess && len(repo.ContractAddress) != 0 { log.Error("the repo has been RepoBlockChainSuccess:", req.RepoId) ctx.JSON(200, map[string]string{ "code": "-1", "message": "the repo has been RepoBlockChainSuccess", }) return } repo.BlockChainStatus = models.RepoBlockChainSuccess repo.ContractAddress = req.ContractAddress if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil { log.Error("UpdateRepositoryCols failed:", err.Error()) ctx.JSON(200, map[string]string{ "code": "-1", "message": "internal error", }) return } ctx.JSON(200, map[string]string{ "code": "0", "message": "", }) } func HandleBlockChainCommitNotify(ctx *context.Context) { var req BlockChainCommitNotify data, _ := ctx.Req.Body().Bytes() if err := json.Unmarshal(data, &req); err != nil { log.Error("json.Unmarshal failed:", err.Error()) ctx.JSON(200, map[string]string{ "code": "-1", "message": "response data error", }) return } blockChain, err := models.GetBlockChainByCommitID(req.CommitID) if err != nil { log.Error("GetRepositoryByID failed:", err.Error()) ctx.JSON(200, map[string]string{ "code": "-1", "message": "internal error", }) return } if blockChain.Status == models.BlockChainCommitSuccess { log.Error("the commit has been BlockChainCommitReady:", blockChain.RepoID) ctx.JSON(200, map[string]string{ "code": "-1", "message": "the commit has been BlockChainCommitReady", }) return } blockChain.Status = models.BlockChainCommitSuccess blockChain.TransactionHash = req.TransactionHash if err = models.UpdateBlockChainCols(blockChain, "status", "transaction_hash"); err != nil { log.Error("UpdateBlockChainCols failed:", err.Error()) ctx.JSON(200, map[string]string{ "code": "-1", "message": "internal error", }) return } ctx.JSON(200, map[string]string{ "code": "0", "message": "", }) } func HandleBlockChainUnSuccessRepos() { repos, err := models.GetBlockChainUnSuccessRepos() if err != nil { log.Error("GetBlockChainUnSuccessRepos failed:", err.Error()) return } for _, repo := range repos { err = repo.GetOwner() if err != nil { log.Error("GetOwner(%s) failed:%v", repo.Name, err) continue } if len(repo.Owner.PrivateKey) == 0 || len(repo.Owner.PublicKey) == 0 { log.Error("the user has not been init in block_chain:", repo.Owner.Name) continue } strRepoID := strconv.FormatInt(repo.ID, 10) _, err = blockchain.NewRepo(strRepoID, repo.Owner.PublicKey, repo.Name) if err != nil { log.Error("blockchain.NewRepo(%s) failed:%v", strRepoID, err) } } return } func HandleBlockChainUnSuccessCommits() { blockChains, err := models.GetBlockChainUnSuccessCommits() if err != nil { log.Error("GetBlockChainUnSuccessCommits failed:", err.Error()) return } for _, block_chain := range blockChains { _, err = blockchain.Contribute(block_chain.ContractAddress, block_chain.Contributor, block_chain.CommitID, block_chain.Amount) if err != nil { log.Error("blockchain.Contribute(%s) failed:%v", block_chain.CommitID, err) } } return } func HandleBlockChainUnSuccessUsers() { users, err := models.GetBlockChainUnSuccessUsers() if err != nil { log.Error("GetBlockChainUnSuccessUsers failed:", err.Error()) return } for _, user := range users { result, err := blockchain.CreateBlockchainAccount() if err != nil { log.Error("blockchain.CreateBlockchainAccount(%s) failed:%v", user.Name, err) continue } user.PublicKey = result.Payload["publickey"].(string) user.PrivateKey = result.Payload["privatekey"].(string) models.UpdateUser(user) } return } func HandleBlockChainMergedPulls() { prs, err := models.GetUnTransformedMergedPullRequests() if err != nil { log.Error("GetUnTransformedMergedPullRequests failed:", err.Error()) return } for _, pr := range prs { _, err = models.GetBlockChainByPrID(pr.ID) if err == nil { log.Info("the pr(%s) has been transformed", pr.MergedCommitID) continue } err = pr.LoadIssue() if err != nil { log.Error("LoadIssue(%s) failed:%v", pr.MergedCommitID, err) continue } poster, err := models.GetUserByID(pr.Issue.PosterID) if err != nil { log.Error("GetUserByID(%s) failed:%v", pr.MergedCommitID, err) continue } if len(poster.PrivateKey) == 0 || len(poster.PublicKey) == 0 { log.Error("the user has not been init in block_chain:", poster.Name) continue } repo, err := models.GetRepositoryByID(pr.HeadRepoID) if err != nil { log.Error("GetUserByID(%s) failed:%v", pr.MergedCommitID, err) continue } if len(repo.ContractAddress) == 0 { log.Error("the repo(%s) has not been initialized in block_chain", repo.Name) continue } blockChain := models.BlockChain{ Contributor : poster.PublicKey, PrID : pr.ID, CommitID : pr.MergedCommitID, ContractAddress : repo.ContractAddress, Status : models.BlockChainCommitInit, Amount : int64(pr.Amount), UserID : poster.ID, RepoID : pr.HeadRepoID, } _, err = models.InsertBlockChain(&blockChain) if err != nil { log.Error("InsertBlockChain(%s) failed:%v", pr.MergedCommitID, err) continue } pr.IsTransformed = true pr.UpdateCols("is_transformed") _, err = blockchain.Contribute(repo.ContractAddress, poster.PublicKey, pr.MergedCommitID, int64(pr.Amount)) if err != nil { log.Error("Contribute(%s) failed:%v", pr.MergedCommitID, err) } } return } func HandleBlockChainUnSuccessIssues() { issues, err := models.GetBlockChainUnSuccessCommits() if err != nil { log.Error("GetBlockChainUnSuccessIssues failed:", err.Error()) return } for _, issue := range issues { _, err = blockchain.SetIssue(issue.ContractAddress, issue.Contributor, issue.ID, issue.Amount) if err != nil { log.Error("SetIssue(%s) failed:%v", issue.CommitID, err) } } return }