github.com/klaytn/klaytn@v1.12.1/blockchain/system/kip113_test.go (about) 1 package system 2 3 import ( 4 "crypto/rand" 5 "math/big" 6 "testing" 7 8 "github.com/klaytn/klaytn/accounts/abi/bind" 9 "github.com/klaytn/klaytn/accounts/abi/bind/backends" 10 "github.com/klaytn/klaytn/blockchain" 11 "github.com/klaytn/klaytn/common" 12 contracts "github.com/klaytn/klaytn/contracts/system_contracts" 13 "github.com/klaytn/klaytn/crypto" 14 "github.com/klaytn/klaytn/crypto/bls" 15 "github.com/klaytn/klaytn/log" 16 "github.com/klaytn/klaytn/params" 17 "github.com/stretchr/testify/assert" 18 ) 19 20 func TestReadKip113(t *testing.T) { 21 log.EnableLogForTest(log.LvlCrit, log.LvlWarn) 22 var ( 23 senderKey, _ = crypto.GenerateKey() 24 sender = bind.NewKeyedTransactor(senderKey) 25 26 alloc = blockchain.GenesisAlloc{ 27 sender.From: { 28 Balance: big.NewInt(params.KLAY), 29 }, 30 } 31 backend = backends.NewSimulatedBackend(alloc) 32 33 nodeId = common.HexToAddress("0xaaaa") 34 _, pub1, pop1 = makeBlsKey() 35 _, pub2, _ = makeBlsKey() 36 ) 37 38 // Deploy Proxy contract 39 transactor, contractAddr := deployKip113Mock(t, sender, backend) 40 41 // With a valid record 42 transactor.Register(sender, nodeId, pub1, pop1) 43 backend.Commit() 44 45 caller, _ := contracts.NewKIP113Caller(contractAddr, backend) 46 47 opts := &bind.CallOpts{BlockNumber: nil} 48 owner, _ := caller.Owner(opts) 49 assert.Equal(t, sender.From, owner) 50 t.Logf("owner: %x", owner) 51 52 infos, err := ReadKip113All(backend, contractAddr, nil) 53 assert.Nil(t, err) 54 assert.Equal(t, 1, len(infos)) 55 assert.Equal(t, pub1, infos[nodeId].PublicKey) 56 assert.Equal(t, pop1, infos[nodeId].Pop) 57 assert.Nil(t, infos[nodeId].VerifyErr) // valid PublicKeyInfo 58 59 // With an invalid record 60 // Another register() call for the same nodeId overwrites the existing info. 61 transactor.Register(sender, nodeId, pub2, pop1) // pub vs. pop mismatch 62 backend.Commit() 63 64 // Returns one record with VerifyErr. 65 infos, err = ReadKip113All(backend, contractAddr, nil) 66 assert.Nil(t, err) 67 assert.Equal(t, 1, len(infos)) 68 assert.ErrorIs(t, infos[nodeId].VerifyErr, ErrKip113BadPop) // invalid PublicKeyInfo 69 } 70 71 func TestAllocKip113(t *testing.T) { 72 log.EnableLogForTest(log.LvlCrit, log.LvlWarn) 73 74 var ( 75 senderKey, _ = crypto.GenerateKey() 76 sender = bind.NewKeyedTransactor(senderKey) 77 78 nodeId1 = common.HexToAddress("0xaaaa") 79 nodeId2 = common.HexToAddress("0xbbbb") 80 _, pub1, pop1 = makeBlsKey() 81 _, pub2, pop2 = makeBlsKey() 82 83 abi, _ = contracts.KIP113MockMetaData.GetAbi() 84 input, _ = abi.Pack("initialize") 85 86 alloc = blockchain.GenesisAlloc{ 87 sender.From: { 88 Balance: big.NewInt(params.KLAY), 89 }, 90 } 91 backend = backends.NewSimulatedBackend(alloc) 92 ) 93 kip113Addr, _, _, _ := contracts.DeployKIP113Mock(sender, backend) 94 backend.Commit() 95 contractAddr, _, _, _ := contracts.DeployERC1967Proxy(sender, backend, kip113Addr, input) 96 backend.Commit() 97 var ( 98 allocProxyStorage = AllocProxy(kip113Addr) 99 allocKip113Storage = AllocKip113Proxy(AllocKip113Init{ 100 Infos: BlsPublicKeyInfos{ 101 nodeId1: {PublicKey: pub1, Pop: pop1}, 102 nodeId2: {PublicKey: pub2, Pop: pop2}, 103 }, 104 Owner: sender.From, 105 }) 106 allocLogicStorage = AllocKip113Logic() 107 ) 108 109 // 1. Merge two storage maps 110 allocStorage := MergeStorage(allocProxyStorage, allocKip113Storage) 111 112 // 2. Create storage by calling register() 113 contract, _ := contracts.NewKIP113MockTransactor(contractAddr, backend) 114 115 contract.Register(sender, nodeId1, pub1, pop1) 116 contract.Register(sender, nodeId2, pub2, pop2) 117 backend.Commit() 118 119 // 3. Compare the two states 120 compareStorage(t, backend, contractAddr, allocStorage) 121 compareStorage(t, backend, kip113Addr, allocLogicStorage) 122 } 123 124 func deployKip113Mock(t *testing.T, sender *bind.TransactOpts, backend *backends.SimulatedBackend, params ...interface{}) (*contracts.KIP113MockTransactor, common.Address) { 125 // Prepare input data for ERC1967Proxy constructor 126 abi, err := contracts.KIP113MockMetaData.GetAbi() 127 assert.Nil(t, err) 128 data, err := abi.Pack("initialize") 129 assert.Nil(t, err) 130 131 // Deploy Proxy contract 132 // 1. Deploy KIP113Mock implementation contract 133 implAddr, _, _, err := contracts.DeployKIP113Mock(sender, backend) 134 backend.Commit() 135 assert.Nil(t, err) 136 t.Logf("KIP113Mock impl at %x", implAddr) 137 138 // 2. Deploy ERC1967Proxy(KIP113Mock.address, _data) 139 contractAddr, _, _, err := contracts.DeployERC1967Proxy(sender, backend, implAddr, data) 140 backend.Commit() 141 assert.Nil(t, err) 142 t.Logf("ERC1967Proxy at %x", contractAddr) 143 144 // 3. Attach KIP113Mock contract to the proxy 145 transactor, _ := contracts.NewKIP113MockTransactor(contractAddr, backend) 146 147 return transactor, contractAddr 148 } 149 150 func compareStorage(t *testing.T, backend *backends.SimulatedBackend, contractAddr common.Address, allocStorage map[common.Hash]common.Hash) { 151 execStorage := make(map[common.Hash]common.Hash) 152 stateDB, _ := backend.BlockChain().State() 153 stateDB.ForEachStorage(contractAddr, func(key common.Hash, value common.Hash) bool { 154 execStorage[key] = value 155 return true 156 }) 157 158 for k, v := range allocStorage { 159 assert.Equal(t, v.Hex(), execStorage[k].Hex(), k.Hex()) 160 t.Logf("%x %x\n", k, v) 161 } 162 for k, v := range execStorage { 163 assert.Equal(t, v.Hex(), allocStorage[k].Hex(), k.Hex()) 164 } 165 } 166 167 func makeBlsKey() (priv, pub, pop []byte) { 168 ikm := make([]byte, 32) 169 rand.Read(ikm) 170 171 sk, _ := bls.GenerateKey(ikm) 172 pk := sk.PublicKey() 173 sig := bls.PopProve(sk) 174 175 priv = sk.Marshal() 176 pub = pk.Marshal() 177 pop = sig.Marshal() 178 if len(priv) != 32 || len(pub) != 48 || len(pop) != 96 { 179 panic("bad bls key") 180 } 181 return 182 }