github.com/amazechain/amc@v0.1.3/internal/api/agg_sign.go (about) 1 // Copyright 2023 The AmazeChain Authors 2 // This file is part of the AmazeChain library. 3 // 4 // The AmazeChain library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The AmazeChain library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the AmazeChain library. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "context" 21 "encoding/hex" 22 "fmt" 23 "github.com/amazechain/amc/common" 24 "github.com/amazechain/amc/common/block" 25 "github.com/amazechain/amc/common/crypto" 26 "github.com/amazechain/amc/common/crypto/bls" 27 "github.com/amazechain/amc/common/crypto/bls/blst" 28 "github.com/amazechain/amc/common/types" 29 "github.com/amazechain/amc/contracts/deposit" 30 "github.com/amazechain/amc/internal/consensus" 31 "github.com/amazechain/amc/log" 32 event "github.com/amazechain/amc/modules/event/v2" 33 "github.com/amazechain/amc/modules/rawdb" 34 "github.com/amazechain/amc/modules/state" 35 "github.com/ledgerwatch/erigon-lib/kv" 36 "golang.org/x/crypto/sha3" 37 ) 38 39 var sigChannel = make(chan AggSign, 10) 40 41 var validVerifers = map[string]string{ 42 "AMC4541Fc1CCB4e042a3BaDFE46904F9D22d127B682": "157aee59b889a8a9e3ecec11e4f79f6c065e3d21c6da2222b916c54f8c820d9c", 43 "AMC9BA336835422BAeFc537d75642959d2a866500a3": "00121edadf6e723f2fe8c23d2359f57a7058986a1b8458d23eb29db7204afea7", 44 "AMCf13d680bA12717fE27d33caB983c5C755Ff74358": "5de474bbf3fee5dfda9047287f596c6e6c0271876305357e399fffba6a5f9a9f", 45 "AMCd1ff88affe38dfb65c621706dff6468ecd418bff": "4c1ad066cc2971c94a8aca6a7d3e4bdd86891922c5b1d39e6d0da8cad9262be4", 46 "AMCb9e94477f5f88b5e8da2e97e8506d6e4fcf04e5b": "2c02dd3cf600af9a8567e5cc5ff158c1b89e1f3ea21bff61f505d141a96a60ee", 47 } 48 49 //type WithCodeAndHash struct { 50 // CodeIndex []byte `json:"codeIndex"` 51 // Code []byte `json:"code"` 52 // Hash []byte `json:"hash"` 53 //} 54 55 //func ExportCodeAndHash(ctx context.Context, db kv.RwDB) (WithCodeAndHash, error) { 56 // var result WithCodeAndHash 57 // var err error 58 // errs := make(chan error, 1) 59 // ctx, cancel := context.WithCancel(ctx) 60 // defer cancel() 61 // 62 // var wg sync.WaitGroup 63 // wg.Add(2) 64 // // export header hash 65 // go func(ctx context.Context) { 66 // defer wg.Done() 67 // rtx, err := db.BeginRo(ctx) 68 // if nil != err { 69 // errs <- err 70 // return 71 // } 72 // defer rtx.Rollback() 73 // 74 // buf := new(bytes.Buffer) 75 // hashW := zlib.NewWriter(buf) 76 // defer hashW.Close() 77 // 78 // cur, err := rtx.Cursor(modules.HeaderCanonical) 79 // if nil != err { 80 // errs <- err 81 // return 82 // } 83 // defer cur.Close() 84 // 85 // select { 86 // case <-ctx.Done(): 87 // return 88 // default: 89 // for k, v, err := cur.First(); k != nil; k, v, err = cur.Next() { 90 // if nil != err { 91 // errs <- err 92 // return 93 // } 94 // //b, _ := modules.DecodeBlockNumber(k) 95 // //h := types.Hash{} 96 // //h.SetBytes(v) 97 // //log.Tracef("read hash, %d, %v", b, h) 98 // hashW.Write(v) 99 // } 100 // 101 // if err := hashW.Flush(); nil != err { 102 // errs <- err 103 // return 104 // } 105 // result.Hash = buf.Bytes() 106 // } 107 // }(ctx) 108 // 109 // // export code 110 // go func(ctx context.Context) { 111 // defer wg.Done() 112 // rtx, err := db.BeginRo(ctx) 113 // if nil != err { 114 // errs <- err 115 // return 116 // } 117 // defer rtx.Rollback() 118 // 119 // cur, err := rtx.Cursor(modules.Code) 120 // if nil != err { 121 // errs <- err 122 // return 123 // } 124 // defer cur.Close() 125 // 126 // indBuf := new(bytes.Buffer) 127 // indW := zlib.NewWriter(indBuf) 128 // defer indW.Close() 129 // codeBuf := new(bytes.Buffer) 130 // codeW := zlib.NewWriter(codeBuf) 131 // defer codeW.Close() 132 // index := uint64(0) 133 // 134 // select { 135 // case <-ctx.Done(): 136 // return 137 // default: 138 // for k, v, err := cur.First(); k != nil; k, v, err = cur.Next() { 139 // if nil != err { 140 // errs <- err 141 // return 142 // } 143 // indW.Write(k) 144 // indW.Write(modules.EncodeBlockNumber(index)) 145 // index += uint64(len(v)) 146 // indW.Write(modules.EncodeBlockNumber(index)) 147 // codeW.Write(v) 148 // } 149 // result.CodeIndex = indBuf.Bytes() 150 // result.Code = codeBuf.Bytes() 151 // } 152 // }(ctx) 153 // 154 // select { 155 // case e := <-errs: 156 // err = e 157 // cancel() 158 // default: 159 // wg.Wait() 160 // } 161 // close(errs) 162 // log.Tracef("export code and hash: %+v", result) 163 // return result, err 164 //} 165 166 type AggSign struct { 167 Number uint64 `json:"number"` 168 StateRoot types.Hash `json:"stateRoot"` 169 Sign types.Signature `json:"sign"` 170 Address types.Address `json:"address"` 171 PublicKey types.PublicKey `json:"-"` 172 } 173 174 func (s *AggSign) Check(root types.Hash) bool { 175 if s.StateRoot != root { 176 return false 177 } 178 sig, err := bls.SignatureFromBytes(s.Sign[:]) 179 if nil != err { 180 return false 181 } 182 183 pub, err := bls.PublicKeyFromBytes(s.PublicKey[:]) 184 if nil != err { 185 return false 186 } 187 return sig.Verify(pub, s.StateRoot[:]) 188 } 189 190 func DepositInfo(db kv.RwDB, key types.Address) *deposit.Info { 191 var info *deposit.Info 192 _ = db.View(context.Background(), func(tx kv.Tx) error { 193 info = deposit.GetDepositInfo(tx, key) 194 return nil 195 }) 196 return info 197 } 198 199 func IsDeposit(db kv.RwDB, addr types.Address) (bool, error) { 200 tx, err := db.BeginRo(context.Background()) 201 if nil != err { 202 return false, err 203 } 204 defer tx.Rollback() 205 206 return rawdb.IsDeposit(tx, addr), nil 207 } 208 209 func SignMerge(ctx context.Context, header *block.Header, depositNum uint64) (types.Signature, []*block.Verify, error) { 210 aggrSigns := make([]bls.Signature, 0) 211 verifiers := make([]*block.Verify, 0) 212 uniq := make(map[types.Address]struct{}) 213 214 LOOP: 215 for { 216 select { 217 case s := <-sigChannel: 218 log.Tracef("accept sign, %+v", s) 219 if s.Number != header.Number.Uint64() { 220 log.Tracef("discard sign: need block number %d, get %d", header.Number.Uint64(), s.Number) 221 continue 222 } 223 224 if _, ok := uniq[s.Address]; ok { 225 continue 226 } 227 228 if !s.Check(header.Root) { 229 log.Tracef("discard sign: sign check failed! %v", s) 230 continue 231 } 232 sig, err := bls.SignatureFromBytes(s.Sign[:]) 233 if nil != err { 234 return types.Signature{}, nil, err 235 } 236 237 aggrSigns = append(aggrSigns, sig) 238 verifiers = append(verifiers, &block.Verify{ 239 Address: s.Address, 240 PublicKey: s.PublicKey, 241 }) 242 uniq[s.Address] = struct{}{} 243 case <-ctx.Done(): 244 break LOOP 245 } 246 } 247 // todo enough sigs check 248 // 1 249 // uint64(len(aggrSigns)) < depositNum/2 250 // uint64(len(aggrSigns)) < 7 251 if uint64(len(aggrSigns)) < 3 { 252 return types.Signature{}, nil, consensus.ErrNotEnoughSign 253 } 254 255 aggS := blst.AggregateSignatures(aggrSigns) 256 var aggSign types.Signature 257 copy(aggSign[:], aggS.Marshal()) 258 return aggSign, verifiers, nil 259 } 260 261 func MachineVerify(ctx context.Context) error { 262 entire := make(chan common.MinedEntireEvent) 263 blocksSub := event.GlobalEvent.Subscribe(entire) 264 defer blocksSub.Unsubscribe() 265 266 errs := make(chan error) 267 defer close(errs) 268 269 for { 270 select { 271 case b := <-entire: 272 log.Tracef("machine verify accept entire, number: %d", b.Entire.Entire.Header.Number.Uint64()) 273 for k, s := range validVerifers { 274 go func(seckey string, address string) { 275 // recover private key 276 sByte, err := hex.DecodeString(seckey) 277 if nil != err { 278 errs <- err 279 return 280 } 281 var addr types.Address 282 if !addr.DecodeString(address) { 283 errs <- fmt.Errorf("unvalid address") 284 return 285 } 286 287 // before state verify 288 var hash types.Hash 289 hasher := sha3.NewLegacyKeccak256() 290 state.EncodeBeforeState(hasher, b.Entire.Entire.Snap.Items, b.Entire.Codes) 291 hasher.(crypto.KeccakState).Read(hash[:]) 292 if b.Entire.Entire.Header.MixDigest != hash { 293 log.Warn("misMatch before state hash", "want:", b.Entire.Entire.Header.MixDigest, "get:", hash, b.Entire.Entire.Header.Number.Uint64()) 294 return 295 } 296 297 // publicKey 298 var bs [32]byte 299 copy(bs[:], sByte) 300 pri, err := bls.SecretKeyFromRandom32Byte(bs) 301 if nil != err { 302 errs <- err 303 return 304 } 305 306 // Signature 307 sign := pri.Sign(b.Entire.Entire.Header.Root[:]) 308 tmp := AggSign{Number: b.Entire.Entire.Header.Number.Uint64()} 309 copy(tmp.StateRoot[:], b.Entire.Entire.Header.Root[:]) 310 copy(tmp.Sign[:], sign.Marshal()) 311 copy(tmp.PublicKey[:], pri.PublicKey().Marshal()) 312 tmp.Address = addr 313 // send res 314 sigChannel <- tmp 315 //log.Tracef("send verify sign, %+v", tmp) 316 }(s, k) 317 } 318 case <-ctx.Done(): 319 return nil 320 case err := <-errs: 321 return err 322 } 323 } 324 return nil 325 }