github.com/unicornultrafoundation/go-u2u@v1.0.0-rc1.0.20240205080301-e74a83d3fadc/gossip/sfc_test.go (about) 1 package gossip 2 3 // compile SFC with truffle 4 //go:generate bash -c "cd ../../u2u-sfc && git checkout 8ff03212140f8440f1dea2c63826528ceff91074" 5 //go:generate bash -c "docker run --name go-u2u-sfc-compiler -v $(pwd)/contract/solc:/src/build/contracts -v $(pwd)/../../u2u-sfc:/src -w /src node:18-buster bash -c 'export NPM_CONFIG_PREFIX=~; npm install --no-save; npm install --no-save truffle@5.2.4' && docker commit go-u2u-sfc-compiler go-u2u-sfc-compiler-image && docker rm go-u2u-sfc-compiler" 6 //go:generate bash -c "docker run --rm -v $(pwd)/contract/solc:/src/build/contracts -v $(pwd)/../../u2u-sfc:/src -w /src go-u2u-sfc-compiler-image bash -c 'export NPM_CONFIG_PREFIX=~; rm -f /src/build/contracts/*json; npm run build'" 7 //go:generate bash -c "cd ./contract/solc && for f in SFC.json SFCLib.json; do jq -j .bytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin; jq -j .deployedBytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin-runtime; jq -c .abi $DOLLAR{f} > $DOLLAR{f%.json}.abi; done" 8 //go:generate bash -c "docker run --rm -v $(pwd)/contract/solc:/src/build/contracts -v $(pwd)/../../u2u-sfc:/src -w /src go-u2u-sfc-compiler-image bash -c 'export NPM_CONFIG_PREFIX=~; sed -i s/runs:\\ 200,/runs:\\ 10000,/ /src/truffle-config.js; rm -f /src/build/contracts/*json; npm run build'" 9 //go:generate bash -c "cd ../../u2u-sfc && git checkout -- truffle-config.js; docker rmi go-u2u-sfc-compiler-image" 10 //go:generate bash -c "cd ./contract/solc && for f in NetworkInitializer.json NodeDriver.json NodeDriverAuth.json; do jq -j .bytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin; jq -j .deployedBytecode $DOLLAR{f} > $DOLLAR{f%.json}.bin-runtime; jq -c .abi $DOLLAR{f} > $DOLLAR{f%.json}.abi; done" 11 12 // wrap SFC with golang 13 //go:generate mkdir -p ./contract/sfc100 14 //go:generate go run github.com/unicornultrafoundation/go-u2u/libs/cmd/abigen --bin=./contract/solc/SFC.bin --abi=./contract/solc/SFC.abi --pkg=sfc100 --type=Contract --out=contract/sfc100/contract.go 15 //go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/SFC.bin-runtime; echo '\"') >> contract/sfc100/contract.go" 16 // wrap SFC lib with golang 17 //go:generate mkdir -p ./contract/sfclib100 18 //go:generate go run github.com/unicornultrafoundation/go-u2u/libs/cmd/abigen --bin=./contract/solc/SFCLib.bin --abi=./contract/solc/SFCLib.abi --pkg=sfclib100 --type=Contract --out=contract/sfclib100/contract.go 19 //go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/SFCLib.bin-runtime; echo '\"') >> contract/sfclib100/contract.go" 20 // wrap NetworkInitializer with golang 21 //go:generate mkdir -p ./contract/netinit100 22 //go:generate go run github.com/unicornultrafoundation/go-u2u/libs/cmd/abigen --bin=./contract/solc/NetworkInitializer.bin --abi=./contract/solc/NetworkInitializer.abi --pkg=netinit100 --type=Contract --out=contract/netinit100/contract.go 23 //go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/NetworkInitializer.bin-runtime; echo '\"') >> contract/netinit100/contract.go" 24 // wrap NodeDriver with golang 25 //go:generate mkdir -p ./contract/driver100 26 //go:generate go run github.com/unicornultrafoundation/go-u2u/libs/cmd/abigen --bin=./contract/solc/NodeDriver.bin --abi=./contract/solc/NodeDriver.abi --pkg=driver100 --type=Contract --out=contract/driver100/contract.go 27 //go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/NodeDriver.bin-runtime; echo '\"') >> contract/driver100/contract.go" 28 // wrap NodeDriverAuth with golang 29 //go:generate mkdir -p ./contract/driverauth100 30 //go:generate go run github.com/unicornultrafoundation/go-u2u/libs/cmd/abigen --bin=./contract/solc/NodeDriverAuth.bin --abi=./contract/solc/NodeDriverAuth.abi --pkg=driverauth100 --type=Contract --out=contract/driverauth100/contract.go 31 //go:generate bash -c "(echo -ne '\nvar ContractBinRuntime = \"'; cat contract/solc/NodeDriverAuth.bin-runtime; echo '\"') >> contract/driverauth100/contract.go" 32 33 import ( 34 "fmt" 35 "math/big" 36 "testing" 37 38 "github.com/stretchr/testify/require" 39 40 "github.com/unicornultrafoundation/go-helios/native/idx" 41 "github.com/unicornultrafoundation/go-u2u/common/hexutil" 42 "github.com/unicornultrafoundation/go-u2u/core/types" 43 "github.com/unicornultrafoundation/go-u2u/gossip/contract/driver100" 44 "github.com/unicornultrafoundation/go-u2u/gossip/contract/driverauth100" 45 "github.com/unicornultrafoundation/go-u2u/gossip/contract/netinit100" 46 "github.com/unicornultrafoundation/go-u2u/gossip/contract/sfc100" 47 "github.com/unicornultrafoundation/go-u2u/logger" 48 "github.com/unicornultrafoundation/go-u2u/u2u/contracts/driver" 49 "github.com/unicornultrafoundation/go-u2u/u2u/contracts/driverauth" 50 "github.com/unicornultrafoundation/go-u2u/u2u/contracts/evmwriter" 51 "github.com/unicornultrafoundation/go-u2u/u2u/contracts/netinit" 52 "github.com/unicornultrafoundation/go-u2u/u2u/contracts/sfc" 53 "github.com/unicornultrafoundation/go-u2u/utils" 54 ) 55 56 func TestSFC(t *testing.T) { 57 logger.SetTestMode(t) 58 logger.SetLevel("debug") 59 60 env := newTestEnv(2, 3) 61 defer env.Close() 62 63 var ( 64 sfc10 *sfc100.Contract 65 err error 66 ) 67 68 authDriver10, err := driverauth100.NewContract(driverauth.ContractAddress, env) 69 require.NoError(t, err) 70 rootDriver10, err := driver100.NewContract(driver.ContractAddress, env) 71 require.NoError(t, err) 72 73 admin := idx.ValidatorID(1) 74 adminAddr := env.Address(admin) 75 76 _ = true && 77 t.Run("Genesis SFC", func(t *testing.T) { 78 require := require.New(t) 79 80 exp := sfc.GetContractBin() 81 got, err := env.CodeAt(nil, sfc.ContractAddress, nil) 82 require.NoError(err) 83 require.Equal(exp, got, "genesis SFC contract") 84 require.Equal(exp, hexutil.MustDecode(sfc100.ContractBinRuntime), "genesis SFC contract version") 85 }) && 86 t.Run("Genesis Driver", func(t *testing.T) { 87 require := require.New(t) 88 89 exp := driver.GetContractBin() 90 got, err := env.CodeAt(nil, driver.ContractAddress, nil) 91 require.NoError(err) 92 require.Equal(exp, got, "genesis Driver contract") 93 require.Equal(exp, hexutil.MustDecode(driver100.ContractBinRuntime), "genesis Driver contract version") 94 }) && 95 t.Run("Genesis DriverAuth", func(t *testing.T) { 96 require := require.New(t) 97 98 exp := driverauth.GetContractBin() 99 got, err := env.CodeAt(nil, driverauth.ContractAddress, nil) 100 require.NoError(err) 101 require.Equal(exp, got, "genesis DriverAuth contract") 102 require.Equal(exp, hexutil.MustDecode(driverauth100.ContractBinRuntime), "genesis DriverAuth contract version") 103 }) && 104 t.Run("Network initializer", func(t *testing.T) { 105 require := require.New(t) 106 107 exp := netinit.GetContractBin() 108 got, err := env.CodeAt(nil, netinit.ContractAddress, nil) 109 require.NoError(err) 110 require.NotEmpty(exp, "genesis NetworkInitializer contract") 111 require.Empty(got, "genesis NetworkInitializer should be destructed") 112 require.Equal(exp, hexutil.MustDecode(netinit100.ContractBinRuntime), "genesis NetworkInitializer contract version") 113 }) && 114 t.Run("Builtin EvmWriter", func(t *testing.T) { 115 require := require.New(t) 116 117 exp := []byte{0} 118 got, err := env.CodeAt(nil, evmwriter.ContractAddress, nil) 119 require.NoError(err) 120 require.Equal(exp, got, "builtin EvmWriter contract") 121 }) && 122 t.Run("Some transfers I", func(t *testing.T) { 123 circleTransfers(t, env, 1) 124 }) && 125 t.Run("Check owners", func(t *testing.T) { 126 require := require.New(t) 127 128 opts := env.ReadOnly() 129 opts.From = adminAddr 130 131 isOwn, err := authDriver10.IsOwner(opts) 132 require.NoError(err) 133 require.True(isOwn) 134 }) && 135 t.Run("SFC upgrade", func(t *testing.T) { 136 require := require.New(t) 137 138 // create new 139 rr, err := env.ApplyTxs(nextEpoch, 140 env.Contract(admin, utils.ToU2U(0), sfc100.ContractBin), 141 ) 142 require.NoError(err) 143 require.Equal(1, rr.Len()) 144 require.Equal(types.ReceiptStatusSuccessful, rr[0].Status) 145 newImpl := rr[0].ContractAddress 146 require.NotEqual(sfc.ContractAddress, newImpl) 147 newSfcContractBinRuntime, err := env.CodeAt(nil, newImpl, nil) 148 require.NoError(err) 149 require.Equal(hexutil.MustDecode(sfc100.ContractBinRuntime), newSfcContractBinRuntime) 150 151 tx, err := authDriver10.CopyCode(env.Pay(admin), sfc.ContractAddress, newImpl) 152 require.NoError(err) 153 rr, err = env.ApplyTxs(sameEpoch, tx) 154 require.NoError(err) 155 require.Equal(1, rr.Len()) 156 require.Equal(types.ReceiptStatusSuccessful, rr[0].Status) 157 got, err := env.CodeAt(nil, sfc.ContractAddress, nil) 158 require.NoError(err) 159 require.Equal(newSfcContractBinRuntime, got, "new SFC contract") 160 161 sfc10, err = sfc100.NewContract(sfc.ContractAddress, env) 162 require.NoError(err) 163 sfcEpoch, err := sfc10.ContractCaller.CurrentEpoch(env.ReadOnly()) 164 require.NoError(err) 165 require.Equal(0, sfcEpoch.Cmp(big.NewInt(3)), "current SFC epoch %s", sfcEpoch.String()) 166 }) 167 168 t.Run("Direct driver", func(t *testing.T) { 169 require := require.New(t) 170 171 // create new 172 anyContractBin := driver100.ContractBin 173 rr, err := env.ApplyTxs(nextEpoch, 174 env.Contract(admin, utils.ToU2U(0), anyContractBin), 175 ) 176 require.NoError(err) 177 require.Equal(1, rr.Len()) 178 require.Equal(types.ReceiptStatusSuccessful, rr[0].Status) 179 newImpl := rr[0].ContractAddress 180 181 tx, err := rootDriver10.CopyCode(env.Pay(admin), sfc.ContractAddress, newImpl) 182 require.NoError(err) 183 rr, err = env.ApplyTxs(sameEpoch, tx) 184 require.NoError(err) 185 require.Equal(1, rr.Len()) 186 require.NotEqual(types.ReceiptStatusSuccessful, rr[0].Status) 187 }) 188 189 } 190 191 func circleTransfers(t *testing.T, env *testEnv, count uint64) { 192 require := require.New(t) 193 validatorsNum := env.store.GetValidators().Len() 194 195 // save start balances 196 balances := make([]*big.Int, validatorsNum) 197 for i := range balances { 198 balances[i] = env.State().GetBalance(env.Address(idx.ValidatorID(i + 1))) 199 } 200 201 for i := uint64(0); i < count; i++ { 202 // transfers 203 txs := make([]*types.Transaction, validatorsNum) 204 for i := idx.Validator(0); i < validatorsNum; i++ { 205 from := (i) % validatorsNum 206 to := (i + 1) % validatorsNum 207 txs[i] = env.Transfer(idx.ValidatorID(from+1), idx.ValidatorID(to+1), utils.ToU2U(100)) 208 } 209 210 rr, err := env.ApplyTxs(sameEpoch, txs...) 211 require.NoError(err) 212 for i, r := range rr { 213 fee := big.NewInt(0).Mul(new(big.Int).SetUint64(r.GasUsed), txs[i].GasPrice()) 214 balances[i] = big.NewInt(0).Sub(balances[i], fee) 215 } 216 } 217 218 // check balances 219 for i := range balances { 220 require.Equal( 221 balances[i], 222 env.State().GetBalance(env.Address(idx.ValidatorID(i+1))), 223 fmt.Sprintf("account%d", i), 224 ) 225 } 226 }