code: func vetNodeTxnOp(op *structs.TxnNodeOp, rule acl.Authorizer) error {
  	// Fast path if ACLs are not enabled.
  	if rule == nil {
  		return nil
  	}
  
  	node := op.Node
  
  	n := &api.Node{
  		Node:            node.Node,
  		ID:              string(node.ID),
  		Address:         node.Address,
  		Datacenter:      node.Datacenter,
  		TaggedAddresses: node.TaggedAddresses,
  		Meta:            node.Meta,
  	}
  
  	// Sentinel doesn't apply to deletes, only creates/updates, so we don't need the scopeFn.
  	var scope func() map[string]interface{}
  	if op.Verb != api.NodeDelete && op.Verb != api.NodeDeleteCAS {
  		scope = func() map[string]interface{} {
  			return sentinel.ScopeCatalogUpsert(n, nil)
  		}
  	}
  
  	if rule != nil && !rule.NodeWrite(node.Node, scope) {
  		return acl.ErrPermissionDenied
  	}
  
  	return nil
  }
docs: // vetNodeTxnOp applies the given ACL policy to a node transaction operation.