github.com/filecoin-project/specs-actors/v4@v4.0.2/actors/test/multisig_delete_self_test.go (about) 1 package test 2 3 import ( 4 "bytes" 5 "context" 6 "testing" 7 8 "github.com/filecoin-project/go-address" 9 "github.com/filecoin-project/go-state-types/big" 10 "github.com/filecoin-project/go-state-types/exitcode" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 14 "github.com/filecoin-project/specs-actors/v4/actors/builtin" 15 init_ "github.com/filecoin-project/specs-actors/v4/actors/builtin/init" 16 "github.com/filecoin-project/specs-actors/v4/actors/builtin/multisig" 17 "github.com/filecoin-project/specs-actors/v4/support/ipld" 18 vm "github.com/filecoin-project/specs-actors/v4/support/vm" 19 ) 20 21 func TestMultisigDeleteSelf2Of3RemovedIsProposer(t *testing.T) { 22 ctx := context.Background() 23 v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory()) 24 addrs := vm.CreateAccounts(ctx, t, v, 3, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778) 25 26 multisigParams := multisig.ConstructorParams{ 27 Signers: addrs, 28 NumApprovalsThreshold: 2, 29 } 30 31 paramBuf := new(bytes.Buffer) 32 err := multisigParams.MarshalCBOR(paramBuf) 33 require.NoError(t, err) 34 35 initParam := init_.ExecParams{ 36 CodeCID: builtin.MultisigActorCodeID, 37 ConstructorParams: paramBuf.Bytes(), 38 } 39 ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam) 40 initRet := ret.(*init_.ExecReturn) 41 assert.NotNil(t, initRet) 42 multisigAddr := initRet.IDAddress 43 44 removeParams := multisig.RemoveSignerParams{ 45 Signer: addrs[0], 46 Decrease: false, 47 } 48 49 paramBuf = new(bytes.Buffer) 50 err = removeParams.MarshalCBOR(paramBuf) 51 require.NoError(t, err) 52 53 proposeRemoveSignerParams := multisig.ProposeParams{ 54 To: multisigAddr, 55 Value: big.Zero(), 56 Method: builtin.MethodsMultisig.RemoveSigner, 57 Params: paramBuf.Bytes(), 58 } 59 60 // first proposal goes ok and should have txnid = 0 61 vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams) 62 // approval goes through 63 approveRemoveSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)} 64 vm.ApplyOk(t, v, addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams) 65 66 // txnid not found when third approval gets processed indicating that the transaction has gone through successfully 67 _, code := v.ApplyMessage(addrs[2], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams) 68 assert.Equal(t, exitcode.ErrNotFound, code) 69 70 } 71 72 func TestMultisigDeleteSelf2Of3RemovedIsApprover(t *testing.T) { 73 ctx := context.Background() 74 v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory()) 75 addrs := vm.CreateAccounts(ctx, t, v, 3, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778) 76 77 multisigParams := multisig.ConstructorParams{ 78 Signers: addrs, 79 NumApprovalsThreshold: 2, 80 } 81 82 paramBuf := new(bytes.Buffer) 83 err := multisigParams.MarshalCBOR(paramBuf) 84 require.NoError(t, err) 85 86 initParam := init_.ExecParams{ 87 CodeCID: builtin.MultisigActorCodeID, 88 ConstructorParams: paramBuf.Bytes(), 89 } 90 ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam) 91 initRet := ret.(*init_.ExecReturn) 92 assert.NotNil(t, initRet) 93 multisigAddr := initRet.IDAddress 94 95 removeParams := multisig.RemoveSignerParams{ 96 Signer: addrs[0], 97 Decrease: false, 98 } 99 100 paramBuf = new(bytes.Buffer) 101 err = removeParams.MarshalCBOR(paramBuf) 102 require.NoError(t, err) 103 104 proposeRemoveSignerParams := multisig.ProposeParams{ 105 To: multisigAddr, 106 Value: big.Zero(), 107 Method: builtin.MethodsMultisig.RemoveSigner, 108 Params: paramBuf.Bytes(), 109 } 110 111 // first proposal goes ok and should have txnid = 0 112 vm.ApplyOk(t, v, addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams) 113 // approval goes through 114 approveRemoveSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)} 115 vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams) 116 117 // txnid not found when third approval gets processed indicating that the transaction has gone through successfully 118 _, code := v.ApplyMessage(addrs[2], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams) 119 assert.Equal(t, exitcode.ErrNotFound, code) 120 121 } 122 123 func TestMultisigDeleteSelf2Of2(t *testing.T) { 124 ctx := context.Background() 125 v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory()) 126 addrs := vm.CreateAccounts(ctx, t, v, 2, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778) 127 128 multisigParams := multisig.ConstructorParams{ 129 Signers: addrs, 130 NumApprovalsThreshold: 2, 131 } 132 133 paramBuf := new(bytes.Buffer) 134 err := multisigParams.MarshalCBOR(paramBuf) 135 require.NoError(t, err) 136 137 initParam := init_.ExecParams{ 138 CodeCID: builtin.MultisigActorCodeID, 139 ConstructorParams: paramBuf.Bytes(), 140 } 141 ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam) 142 initRet := ret.(*init_.ExecReturn) 143 assert.NotNil(t, initRet) 144 multisigAddr := initRet.IDAddress 145 146 removeParams := multisig.RemoveSignerParams{ 147 Signer: addrs[0], 148 Decrease: true, 149 } 150 151 paramBuf = new(bytes.Buffer) 152 err = removeParams.MarshalCBOR(paramBuf) 153 require.NoError(t, err) 154 155 // first proposal goes ok and should have txnid = 0 156 proposeRemoveSignerParams := multisig.ProposeParams{ 157 To: multisigAddr, 158 Value: big.Zero(), 159 Method: builtin.MethodsMultisig.RemoveSigner, 160 Params: paramBuf.Bytes(), 161 } 162 vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams) 163 // approval goes through 164 approveRemoveSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)} 165 vm.ApplyOk(t, v, addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams) 166 167 // txnid not found when another approval gets processed indicating that the transaction has gone through successfully 168 _, code := v.ApplyMessage(addrs[1], multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveRemoveSignerParams) 169 assert.Equal(t, exitcode.ErrNotFound, code) 170 } 171 172 func TestMultisigSwapsSelf2Of3(t *testing.T) { 173 ctx := context.Background() 174 v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory()) 175 addrs := vm.CreateAccounts(ctx, t, v, 4, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778) 176 alice := addrs[0] 177 bob := addrs[1] 178 chuck := addrs[2] 179 dinesh := addrs[3] 180 181 multisigParams := multisig.ConstructorParams{ 182 Signers: []address.Address{alice, bob, chuck}, 183 NumApprovalsThreshold: 2, 184 } 185 186 paramBuf := new(bytes.Buffer) 187 err := multisigParams.MarshalCBOR(paramBuf) 188 require.NoError(t, err) 189 190 initParam := init_.ExecParams{ 191 CodeCID: builtin.MultisigActorCodeID, 192 ConstructorParams: paramBuf.Bytes(), 193 } 194 ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam) 195 initRet := ret.(*init_.ExecReturn) 196 assert.NotNil(t, initRet) 197 multisigAddr := initRet.IDAddress 198 199 // Case 1 swapped out is proposer (swap alice for dinesh, alice is removed) 200 swapParams := multisig.SwapSignerParams{ 201 From: alice, 202 To: dinesh, 203 } 204 205 paramBuf = new(bytes.Buffer) 206 err = swapParams.MarshalCBOR(paramBuf) 207 require.NoError(t, err) 208 209 proposeSwapSignerParams := multisig.ProposeParams{ 210 To: multisigAddr, 211 Value: big.Zero(), 212 Method: builtin.MethodsMultisig.SwapSigner, 213 Params: paramBuf.Bytes(), 214 } 215 216 // proposal from swapped address goes ok and should have txnid = 0 217 vm.ApplyOk(t, v, alice, multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeSwapSignerParams) 218 219 // approval goes through 220 approveSwapSignerParams := multisig.TxnIDParams{ID: multisig.TxnID(0)} 221 vm.ApplyOk(t, v, bob, multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveSwapSignerParams) 222 223 // Case 2 swapped out is approver (swap dinesh for alice, dinesh is removed) 224 swapParams2 := multisig.SwapSignerParams{ 225 From: dinesh, 226 To: alice, 227 } 228 229 paramBuf2 := new(bytes.Buffer) 230 err = swapParams2.MarshalCBOR(paramBuf2) 231 require.NoError(t, err) 232 233 proposeSwapSignerParams2 := multisig.ProposeParams{ 234 To: multisigAddr, 235 Value: big.Zero(), 236 Method: builtin.MethodsMultisig.SwapSigner, 237 Params: paramBuf2.Bytes(), 238 } 239 240 // proposal from regular address goes ok txnid = 1 241 vm.ApplyOk(t, v, bob, multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeSwapSignerParams2) 242 243 // approve from swapped address goes ok 244 approveSwapSignerParams2 := multisig.TxnIDParams{ID: multisig.TxnID(1)} 245 vm.ApplyOk(t, v, dinesh, multisigAddr, big.Zero(), builtin.MethodsMultisig.Approve, &approveSwapSignerParams2) 246 247 } 248 249 func TestMultisigDeleteSigner1Of2(t *testing.T) { 250 ctx := context.Background() 251 v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory()) 252 addrs := vm.CreateAccounts(ctx, t, v, 2, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778) 253 254 multisigParams := multisig.ConstructorParams{ 255 Signers: addrs, 256 NumApprovalsThreshold: 1, 257 } 258 259 paramBuf := new(bytes.Buffer) 260 err := multisigParams.MarshalCBOR(paramBuf) 261 require.NoError(t, err) 262 263 initParam := init_.ExecParams{ 264 CodeCID: builtin.MultisigActorCodeID, 265 ConstructorParams: paramBuf.Bytes(), 266 } 267 ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam) 268 initRet := ret.(*init_.ExecReturn) 269 assert.NotNil(t, initRet) 270 multisigAddr := initRet.IDAddress 271 272 removeParams := multisig.RemoveSignerParams{ 273 Signer: addrs[0], 274 Decrease: false, 275 } 276 277 paramBuf = new(bytes.Buffer) 278 err = removeParams.MarshalCBOR(paramBuf) 279 require.NoError(t, err) 280 281 proposeRemoveSignerParams := multisig.ProposeParams{ 282 To: multisigAddr, 283 Value: big.Zero(), 284 Method: builtin.MethodsMultisig.RemoveSigner, 285 Params: paramBuf.Bytes(), 286 } 287 // address 0 succeeds when trying to execute the transaction removing address 0 288 vm.ApplyOk(t, v, addrs[0], multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeRemoveSignerParams) 289 } 290 291 func TestMultisigSwapsSelf1Of2(t *testing.T) { 292 ctx := context.Background() 293 v := vm.NewVMWithSingletons(ctx, t, ipld.NewBlockStoreInMemory()) 294 addrs := vm.CreateAccounts(ctx, t, v, 3, big.Mul(big.NewInt(10_000), big.NewInt(1e18)), 93837778) 295 alice := addrs[0] 296 bob := addrs[1] 297 chuck := addrs[2] 298 299 multisigParams := multisig.ConstructorParams{ 300 Signers: []address.Address{alice, bob}, 301 NumApprovalsThreshold: 1, 302 } 303 304 paramBuf := new(bytes.Buffer) 305 err := multisigParams.MarshalCBOR(paramBuf) 306 require.NoError(t, err) 307 308 initParam := init_.ExecParams{ 309 CodeCID: builtin.MultisigActorCodeID, 310 ConstructorParams: paramBuf.Bytes(), 311 } 312 ret := vm.ApplyOk(t, v, addrs[0], builtin.InitActorAddr, big.Zero(), builtin.MethodsPower.CreateMiner, &initParam) 313 initRet := ret.(*init_.ExecReturn) 314 assert.NotNil(t, initRet) 315 multisigAddr := initRet.IDAddress 316 317 swapParams := multisig.SwapSignerParams{ 318 From: alice, 319 To: chuck, 320 } 321 322 paramBuf = new(bytes.Buffer) 323 err = swapParams.MarshalCBOR(paramBuf) 324 require.NoError(t, err) 325 326 proposeSwapSignerParams := multisig.ProposeParams{ 327 To: multisigAddr, 328 Value: big.Zero(), 329 Method: builtin.MethodsMultisig.SwapSigner, 330 Params: paramBuf.Bytes(), 331 } 332 333 // alice succeeds when trying to execute the transaction swapping alice for chuck 334 vm.ApplyOk(t, v, alice, multisigAddr, big.Zero(), builtin.MethodsMultisig.Propose, &proposeSwapSignerParams) 335 }