You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

blockchain.go 7.8 kB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. package repo
  2. import (
  3. "code.gitea.io/gitea/models"
  4. "code.gitea.io/gitea/modules/base"
  5. "code.gitea.io/gitea/modules/blockchain"
  6. "code.gitea.io/gitea/modules/context"
  7. "code.gitea.io/gitea/modules/log"
  8. "encoding/json"
  9. "net/http"
  10. "strconv"
  11. )
  12. type BlockChainInitNotify struct {
  13. RepoId int64 `json:"repoId"`
  14. ContractAddress string `json:"contractAddress"`
  15. }
  16. type BlockChainCommitNotify struct {
  17. CommitID string `json:"commitId"`
  18. TransactionHash string `json:"txHash"`
  19. }
  20. const (
  21. tplBlockChainIndex base.TplName = "repo/blockchain/index"
  22. )
  23. // MustEnableDataset check if repository enable internal cb
  24. func MustEnableBlockChain(ctx *context.Context) {
  25. if !ctx.Repo.CanRead(models.UnitTypeBlockChain) {
  26. ctx.NotFound("MustEnableBlockChain", nil)
  27. return
  28. }
  29. }
  30. func BlockChainIndex(ctx *context.Context) {
  31. MustEnableBlockChain(ctx)
  32. repo := ctx.Repo.Repository
  33. if repo.ContractAddress == "" || ctx.User.PublicKey == ""{
  34. log.Error("the repo(%d) or the user(%d) has not been initialized in block_chain", repo.RepoID, ctx.User.ID)
  35. ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex)
  36. return
  37. }
  38. res, err := blockchain.GetBalance(repo.ContractAddress, ctx.User.PublicKey)
  39. if err != nil {
  40. log.Error("GetBalance(%s) failed:%v", ctx.User.PublicKey, err)
  41. ctx.HTML(http.StatusInternalServerError, tplBlockChainIndex)
  42. return
  43. }
  44. ctx.Data["balance"] = res.Data
  45. ctx.HTML(200, tplBlockChainIndex)
  46. }
  47. func HandleBlockChainInitNotify(ctx *context.Context) {
  48. var req BlockChainInitNotify
  49. data, _ := ctx.Req.Body().Bytes()
  50. json.Unmarshal(data, &req)
  51. repo, err := models.GetRepositoryByID(req.RepoId)
  52. if err != nil {
  53. log.Error("GetRepositoryByID failed:", err.Error())
  54. ctx.JSON(200, map[string]string{
  55. "code": "-1",
  56. "message": "internal error",
  57. })
  58. return
  59. }
  60. if repo.BlockChainStatus == models.RepoBlockChainSuccess && len(repo.ContractAddress) != 0 {
  61. log.Error("the repo has been RepoBlockChainSuccess:", req.RepoId)
  62. ctx.JSON(200, map[string]string{
  63. "code": "-1",
  64. "message": "the repo has been RepoBlockChainSuccess",
  65. })
  66. return
  67. }
  68. repo.BlockChainStatus = models.RepoBlockChainSuccess
  69. repo.ContractAddress = req.ContractAddress
  70. if err = models.UpdateRepositoryCols(repo, "block_chain_status", "contract_address"); err != nil {
  71. log.Error("UpdateRepositoryCols failed:", err.Error())
  72. ctx.JSON(200, map[string]string{
  73. "code": "-1",
  74. "message": "internal error",
  75. })
  76. return
  77. }
  78. ctx.JSON(200, map[string]string{
  79. "code": "0",
  80. "message": "",
  81. })
  82. }
  83. func HandleBlockChainCommitNotify(ctx *context.Context) {
  84. var req BlockChainCommitNotify
  85. data, _ := ctx.Req.Body().Bytes()
  86. if err := json.Unmarshal(data, &req); err != nil {
  87. log.Error("json.Unmarshal failed:", err.Error())
  88. ctx.JSON(200, map[string]string{
  89. "code": "-1",
  90. "message": "response data error",
  91. })
  92. return
  93. }
  94. blockChain, err := models.GetBlockChainByCommitID(req.CommitID)
  95. if err != nil {
  96. log.Error("GetRepositoryByID failed:", err.Error())
  97. ctx.JSON(200, map[string]string{
  98. "code": "-1",
  99. "message": "internal error",
  100. })
  101. return
  102. }
  103. if blockChain.Status == models.BlockChainCommitSuccess {
  104. log.Error("the commit has been BlockChainCommitReady:", blockChain.RepoID)
  105. ctx.JSON(200, map[string]string{
  106. "code": "-1",
  107. "message": "the commit has been BlockChainCommitReady",
  108. })
  109. return
  110. }
  111. blockChain.Status = models.BlockChainCommitSuccess
  112. blockChain.TransactionHash = req.TransactionHash
  113. if err = models.UpdateBlockChainCols(blockChain, "status", "transaction_hash"); err != nil {
  114. log.Error("UpdateBlockChainCols failed:", err.Error())
  115. ctx.JSON(200, map[string]string{
  116. "code": "-1",
  117. "message": "internal error",
  118. })
  119. return
  120. }
  121. ctx.JSON(200, map[string]string{
  122. "code": "0",
  123. "message": "",
  124. })
  125. }
  126. func HandleBlockChainUnSuccessRepos() {
  127. repos, err := models.GetBlockChainUnSuccessRepos()
  128. if err != nil {
  129. log.Error("GetBlockChainUnSuccessRepos failed:", err.Error())
  130. return
  131. }
  132. for _, repo := range repos {
  133. err = repo.GetOwner()
  134. if err != nil {
  135. log.Error("GetOwner(%s) failed:%v", repo.Name, err)
  136. continue
  137. }
  138. if len(repo.Owner.PrivateKey) == 0 || len(repo.Owner.PublicKey) == 0 {
  139. log.Error("the user has not been init in block_chain:", repo.Owner.Name)
  140. continue
  141. }
  142. strRepoID := strconv.FormatInt(repo.ID, 10)
  143. _, err = blockchain.NewRepo(strRepoID, repo.Owner.PublicKey, repo.Name)
  144. if err != nil {
  145. log.Error("blockchain.NewRepo(%s) failed:%v", strRepoID, err)
  146. }
  147. }
  148. return
  149. }
  150. func HandleBlockChainUnSuccessCommits() {
  151. blockChains, err := models.GetBlockChainUnSuccessCommits()
  152. if err != nil {
  153. log.Error("GetBlockChainUnSuccessCommits failed:", err.Error())
  154. return
  155. }
  156. for _, block_chain := range blockChains {
  157. _, err = blockchain.Contribute(block_chain.ContractAddress, block_chain.Contributor, block_chain.CommitID, block_chain.Amount)
  158. if err != nil {
  159. log.Error("blockchain.Contribute(%s) failed:%v", block_chain.CommitID, err)
  160. }
  161. }
  162. return
  163. }
  164. func HandleBlockChainUnSuccessUsers() {
  165. users, err := models.GetBlockChainUnSuccessUsers()
  166. if err != nil {
  167. log.Error("GetBlockChainUnSuccessUsers failed:", err.Error())
  168. return
  169. }
  170. for _, user := range users {
  171. result, err := blockchain.CreateBlockchainAccount()
  172. if err != nil {
  173. log.Error("blockchain.CreateBlockchainAccount(%s) failed:%v", user.Name, err)
  174. continue
  175. }
  176. user.PublicKey = result.Payload["publickey"].(string)
  177. user.PrivateKey = result.Payload["privatekey"].(string)
  178. models.UpdateUser(user)
  179. }
  180. return
  181. }
  182. func HandleBlockChainMergedPulls() {
  183. prs, err := models.GetUnTransformedMergedPullRequests()
  184. if err != nil {
  185. log.Error("GetUnTransformedMergedPullRequests failed:", err.Error())
  186. return
  187. }
  188. for _, pr := range prs {
  189. _, err = models.GetBlockChainByPrID(pr.ID)
  190. if err == nil {
  191. log.Info("the pr(%s) has been transformed", pr.MergedCommitID)
  192. continue
  193. }
  194. err = pr.LoadIssue()
  195. if err != nil {
  196. log.Error("LoadIssue(%s) failed:%v", pr.MergedCommitID, err)
  197. continue
  198. }
  199. poster, err := models.GetUserByID(pr.Issue.PosterID)
  200. if err != nil {
  201. log.Error("GetUserByID(%s) failed:%v", pr.MergedCommitID, err)
  202. continue
  203. }
  204. if len(poster.PrivateKey) == 0 || len(poster.PublicKey) == 0 {
  205. log.Error("the user has not been init in block_chain:", poster.Name)
  206. continue
  207. }
  208. repo, err := models.GetRepositoryByID(pr.HeadRepoID)
  209. if err != nil {
  210. log.Error("GetUserByID(%s) failed:%v", pr.MergedCommitID, err)
  211. continue
  212. }
  213. if len(repo.ContractAddress) == 0 {
  214. log.Error("the repo(%s) has not been initialized in block_chain", repo.Name)
  215. continue
  216. }
  217. blockChain := models.BlockChain{
  218. Contributor : poster.PublicKey,
  219. PrID : pr.ID,
  220. CommitID : pr.MergedCommitID,
  221. ContractAddress : repo.ContractAddress,
  222. Status : models.BlockChainCommitInit,
  223. Amount : int64(pr.Amount),
  224. UserID : poster.ID,
  225. RepoID : pr.HeadRepoID,
  226. }
  227. _, err = models.InsertBlockChain(&blockChain)
  228. if err != nil {
  229. log.Error("InsertBlockChain(%s) failed:%v", pr.MergedCommitID, err)
  230. continue
  231. }
  232. pr.IsTransformed = true
  233. pr.UpdateCols("is_transformed")
  234. _, err = blockchain.Contribute(repo.ContractAddress, poster.PublicKey, pr.MergedCommitID, int64(pr.Amount))
  235. if err != nil {
  236. log.Error("Contribute(%s) failed:%v", pr.MergedCommitID, err)
  237. }
  238. }
  239. return
  240. }
  241. func HandleBlockChainUnSuccessIssues() {
  242. issues, err := models.GetBlockChainUnSuccessCommits()
  243. if err != nil {
  244. log.Error("GetBlockChainUnSuccessIssues failed:", err.Error())
  245. return
  246. }
  247. for _, issue := range issues {
  248. _, err = blockchain.SetIssue(issue.ContractAddress, issue.Contributor, issue.ID, issue.Amount)
  249. if err != nil {
  250. log.Error("SetIssue(%s) failed:%v", issue.CommitID, err)
  251. }
  252. }
  253. return
  254. }