Add a config flag on dendrite to switch between zion contracts v1 / v2 (#1151)

Temporary flag to implement v2 smart contract integration. Once v2 is
done, will remove this flag.
This commit is contained in:
Tak Wai Wong 2022-12-28 18:56:40 -08:00 committed by GitHub
parent f901b88c55
commit 751030a658
6 changed files with 160 additions and 66 deletions

View file

@ -26,6 +26,7 @@ type EthereumAuthConfig struct {
NetworkUrl string `yaml:"network_url"` // Blockchain network provider URL
ConfigChainID string `yaml:"chain_id"` // Blockchain chain ID. Env variable can replace this property.
ConfigEnableAuthz string `yaml:"enable_authz"` // Enable / disable authorization during development. todo: remove this flag when feature is done.
ContractVersion string // todo: remove this setting when v2 migration is done.
chainID int
enableAuthz bool // todo: remove this flag when feature is done.
}

View file

@ -30,6 +30,7 @@ var (
version = flag.Bool("version", false, "Shows the current version and exits immediately.")
enableRegistrationWithoutVerification = flag.Bool("really-enable-open-registration", false, "This allows open registration without secondary verification (reCAPTCHA). This is NOT RECOMMENDED and will SIGNIFICANTLY increase the risk that your server will be used to send spam or conduct attacks, which may result in your server being banned from rooms.")
enableAuthorizationChecks = flag.Bool("enable-authz", false, "Enables authorization checks (aka space/channel gating).")
contractVersion = flag.String("contract-version", "v1", "Contract version to use. Valid values are v1 and v2. Default is v1. Remove this flag when v2 migration is done.")
)
// ParseFlags parses the commandline flags and uses them to create a config.
@ -58,7 +59,13 @@ func ParseFlags(monolith bool) *config.Dendrite {
// cmdline --enable-authz flag. env overrides it so that deployment scripts can set it.
// todo: remove this flag when feature is done.
cfg.ClientAPI.PublicKeyAuthentication.Ethereum.ConfigEnableAuthz = strconv.FormatBool(*enableAuthorizationChecks)
logrus.Info("enable-authz flag is set to ", *enableAuthorizationChecks)
logrus.Info("--enable-authz flag is set to ", *enableAuthorizationChecks)
// cmdline --contract-version. Contract version to use. Valid values are v1
// and v2. Default is v1.
// todo: Remove this flag when v2 migration is done.
cfg.ClientAPI.PublicKeyAuthentication.Ethereum.ContractVersion = *contractVersion
logrus.Info("--contract-version flag is set to ", *contractVersion)
return cfg
}

View file

@ -10,6 +10,10 @@ type SpaceManagerContractAddresses struct {
Tokengranted string `json:"tokengranted"`
}
type SpaceFactoryContractAddress struct {
SpaceFactory string `json:"spaceFactory"`
}
func loadSpaceManagerAddresses(byteValue []byte) (*SpaceManagerContractAddresses, error) {
var addresses SpaceManagerContractAddresses
@ -20,3 +24,14 @@ func loadSpaceManagerAddresses(byteValue []byte) (*SpaceManagerContractAddresses
return &addresses, nil
}
func loadSpaceFactoryAddress(byteValue []byte) (*SpaceFactoryContractAddress, error) {
var address SpaceFactoryContractAddress
err := json.Unmarshal(byteValue, &address)
if err != nil {
return nil, err
}
return &address, nil
}

View file

@ -1 +0,0 @@
{"spaceFactory": "0x5fc8d32690cc91d4c39d9d3abcbd16989f875707"}

View file

@ -3,30 +3,51 @@ package zion
import (
_ "embed"
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/matrix-org/dendrite/authorization"
roomserver "github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/setup/config"
zion_goerli "github.com/matrix-org/dendrite/zion/contracts/zion_goerli"
zion_localhost "github.com/matrix-org/dendrite/zion/contracts/zion_localhost"
zion_goerli "github.com/matrix-org/dendrite/zion/contracts/zion_goerli" // V1 smart contract
zion_localhost "github.com/matrix-org/dendrite/zion/contracts/zion_localhost" // v1 smart contract
//goerli_space_factory "github.com/matrix-org/dendrite/zion/contracts/goerli_space_factory" // v2 smart contract
//goerli_space "github.com/matrix-org/dendrite/zion/contracts/goerli_space" // v2 smart contract
// v2 smart contract
localhost_space_factory "github.com/matrix-org/dendrite/zion/contracts/localhost_space_factory" // v2 smart contract
log "github.com/sirupsen/logrus"
)
// V1 smart contract addresses
//
//go:embed contracts/zion_localhost/space-manager.json
var localhostJson []byte
var localhostSpaceManagerJson []byte
//go:embed contracts/zion_goerli/space-manager.json
var goerliJson []byte
var goerliSpaceManagerJson []byte
// V2 smart contract addresses
//
//go:embed contracts/localhost_space_factory/space-factory.json
var localhostSpaceFactoryJson []byte
// var goerliSpaceFactoryJson []byte
var ErrSpaceDisabled = errors.New("space disabled")
var ErrChannelDisabled = errors.New("channel disabled")
type ZionAuthorization struct {
chainId int
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli
store Store
ethClient *ethclient.Client
spaceManagerLocalhost *zion_localhost.ZionSpaceManagerLocalhost // v1 smart contract. Deprecating.
spaceManagerGoerli *zion_goerli.ZionSpaceManagerGoerli // v1 smart contract. Deprecating.
localhostSpaceFactory *localhost_space_factory.LocalhostSpaceFactory // v2 localhost SpaceFactory smart contract
//localhostSpaces map[string]localhost_space.LocalhostSpace // v2 localhost map from networkId to a space contract
//goerliSpaceFactory *goerli_space_factory.LocalhostSpaceFactory // v2 goerli SpaceFactory smart contract
//goerliSpaces map[string]goerli_space.LocalhostSpace // v2 goerli map from networkId to a space contract
store Store
}
func NewZionAuthorization(cfg *config.ClientAPI, roomQueryAPI roomserver.QueryEventsAPI) (authorization.Authorization, error) {
@ -35,30 +56,31 @@ func NewZionAuthorization(cfg *config.ClientAPI, roomQueryAPI roomserver.QueryEv
return nil, nil
}
ethClient, err := GetEthClient(cfg.PublicKeyAuthentication.Ethereum.NetworkUrl)
if err != nil {
log.Errorf("Cannot connect to eth client %v\n", cfg.PublicKeyAuthentication.Ethereum.NetworkUrl)
return nil, err
}
auth := ZionAuthorization{
store: NewStore(roomQueryAPI),
chainId: cfg.PublicKeyAuthentication.Ethereum.GetChainID(),
store: NewStore(roomQueryAPI),
chainId: cfg.PublicKeyAuthentication.Ethereum.GetChainID(),
ethClient: ethClient,
}
switch auth.chainId {
case 1337, 31337:
localhost, err := newZionSpaceManagerLocalhost(cfg.PublicKeyAuthentication.Ethereum.NetworkUrl)
if cfg.PublicKeyAuthentication.Ethereum.ContractVersion == "v2" {
err := auth.initializeContractsV2()
if err != nil {
log.Errorln("error instantiating ZionSpaceManagerLocalhost", err)
return nil, err
}
auth.spaceManagerLocalhost = localhost
case 5:
goerli, err := newZionSpaceManagerGoerli(cfg.PublicKeyAuthentication.Ethereum.NetworkUrl)
} else {
err := auth.initializeContractsV1()
if err != nil {
log.Errorln("error instantiating ZionSpaceManagerGoerli", err)
return nil, err
}
auth.spaceManagerGoerli = goerli
default:
log.Errorf("Unsupported chain id: %d\n", auth.chainId)
}
// no errors. return the auth object.
return &auth, nil
}
@ -100,6 +122,98 @@ func (za *ZionAuthorization) IsAllowed(args authorization.AuthorizationArgs) (bo
return false, nil
}
func newZionSpaceManagerLocalhost(ethClient *ethclient.Client) (*zion_localhost.ZionSpaceManagerLocalhost, error) {
jsonAddresses, err := loadSpaceManagerAddresses(localhostSpaceManagerJson)
if err != nil {
return nil, err
}
address := common.HexToAddress(jsonAddresses.Spacemanager)
spaceManager, err := zion_localhost.NewZionSpaceManagerLocalhost(address, ethClient)
if err != nil {
return nil, err
}
return spaceManager, nil
}
func newZionSpaceManagerGoerli(ethClient *ethclient.Client) (*zion_goerli.ZionSpaceManagerGoerli, error) {
addresses, err := loadSpaceManagerAddresses(goerliSpaceManagerJson)
if err != nil {
return nil, err
}
address := common.HexToAddress(addresses.Spacemanager)
spaceManager, err := zion_goerli.NewZionSpaceManagerGoerli(address, ethClient)
if err != nil {
return nil, err
}
return spaceManager, nil
}
func newSpaceFactoryLocalhost(ethClient *ethclient.Client) (*localhost_space_factory.LocalhostSpaceFactory, error) {
jsonAddress, err := loadSpaceFactoryAddress(localhostSpaceFactoryJson)
if err != nil {
return nil, err
}
address := common.HexToAddress(jsonAddress.SpaceFactory)
spaceFactory, err := localhost_space_factory.NewLocalhostSpaceFactory(address, ethClient)
if err != nil {
return nil, err
}
return spaceFactory, nil
}
func (za *ZionAuthorization) initializeContractsV1() error {
switch za.chainId {
case 1337, 31337:
localhost, err := newZionSpaceManagerLocalhost(za.ethClient)
if err != nil {
log.Errorln("error instantiating ZionSpaceManagerLocalhost", err)
return err
}
za.spaceManagerLocalhost = localhost
case 5:
goerli, err := newZionSpaceManagerGoerli(za.ethClient)
if err != nil {
log.Errorln("error instantiating ZionSpaceManagerGoerli", err)
return err
}
za.spaceManagerGoerli = goerli
default:
errMsg := fmt.Sprintf("Unsupported chain id: %d", za.chainId)
log.Error(errMsg)
return errors.New(errMsg)
}
// no errors.
return nil
}
func (za *ZionAuthorization) initializeContractsV2() error {
switch za.chainId {
case 1337, 31337:
localhost, err := newSpaceFactoryLocalhost(za.ethClient)
if err != nil {
log.Errorln("error instantiating ZionSpaceManagerLocalhost", err)
return err
}
za.localhostSpaceFactory = localhost
default:
errMsg := fmt.Sprintf("Unsupported chain id: %d", za.chainId)
log.Error(errMsg)
return errors.New(errMsg)
}
// no errors.
return nil
}
func (za *ZionAuthorization) isSpaceChannelDisabledLocalhost(roomInfo RoomInfo) (bool, error) {
if za.spaceManagerLocalhost == nil {
return false, errors.New("error fetching space manager contract")
@ -185,45 +299,3 @@ func (za *ZionAuthorization) isAllowedGoerli(
return false, nil
}
func newZionSpaceManagerLocalhost(endpointUrl string) (*zion_localhost.ZionSpaceManagerLocalhost, error) {
addresses, err := loadSpaceManagerAddresses(localhostJson)
if err != nil {
return nil, err
}
address := common.HexToAddress(addresses.Spacemanager)
client, err := GetEthClient(endpointUrl)
if err != nil {
return nil, err
}
spaceManager, err := zion_localhost.NewZionSpaceManagerLocalhost(address, client)
if err != nil {
return nil, err
}
return spaceManager, nil
}
func newZionSpaceManagerGoerli(endpointUrl string) (*zion_goerli.ZionSpaceManagerGoerli, error) {
addresses, err := loadSpaceManagerAddresses(goerliJson)
if err != nil {
return nil, err
}
address := common.HexToAddress((addresses.Spacemanager))
client, err := GetEthClient(endpointUrl)
if err != nil {
return nil, err
}
spaceManager, err := zion_goerli.NewZionSpaceManagerGoerli(address, client)
if err != nil {
return nil, err
}
return spaceManager, nil
}